use dup if possible when pushing args
authorClaus Gittinger <cg@exept.de>
Sun, 14 Apr 1996 01:05:55 +0200
changeset 245 8a78aa886351
parent 244 2ce60e837d52
child 246 abf09d4821fe
use dup if possible when pushing args
MessageNd.st
MessageNode.st
--- a/MessageNd.st	Sun Apr 14 01:04:47 1996 +0200
+++ b/MessageNd.st	Sun Apr 14 01:05:55 1996 +0200
@@ -723,247 +723,261 @@
 !
 
 codeOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
-    |recType nargs isBuiltIn litIndex cls clsLitIndex code isSpecial|
+    |recType nargs isBuiltIn litIndex cls clsLitIndex code isSpecial
+     stackTop|
 
     argArray isNil ifTrue:[
-	nargs := 0
+        nargs := 0
     ] ifFalse:[
-	nargs := argArray size
+        nargs := argArray size
     ].
 
     isBuiltIn := isSpecial := false.
     recType := receiver type.
 
     (nargs == 0) ifTrue:[
-	(recType == #ThisContext) ifTrue:[
-	    valueNeeded ifFalse:[
-		"for now, only do it in methods"
-		b isNil ifTrue:[
-		    (selector == #restart) ifTrue:[
-			aStream nextPut:#jump; nextPut:1.      "jump to start"
-			^ self
-		    ].
-		].
-		(selector == #return) ifTrue:[  "^ nil"
-		    aStream nextPut:#retNil.
-		    ^ self
-		].
-	    ]
-	].
+        (recType == #ThisContext) ifTrue:[
+            valueNeeded ifFalse:[
+                "for now, only do it in methods"
+                b isNil ifTrue:[
+                    (selector == #restart) ifTrue:[
+                        aStream nextPut:#jump; nextPut:1.      "jump to start"
+                        ^ self
+                    ].
+                ].
+                (selector == #return) ifTrue:[  "^ nil"
+                    aStream nextPut:#retNil.
+                    ^ self
+                ].
+            ]
+        ].
 
-	receiver isBlock ifTrue:[
-	    selector == #value ifTrue:[
-		receiver codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-		^ self
-	    ].
-	    ((selector == #whileTrue) or:[selector == #whileFalse]) ifTrue:[
-		self codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-		^ self
-	    ].
-	].
-	isBuiltIn := aCompiler isBuiltInUnarySelector:selector.
-	isBuiltIn ifFalse:[
-	    isSpecial := aCompiler isSpecialSendSelector:selector
-	]
+        receiver isBlock ifTrue:[
+            selector == #value ifTrue:[
+                receiver codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+                ^ self
+            ].
+            ((selector == #whileTrue) or:[selector == #whileFalse]) ifTrue:[
+                self codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+                ^ self
+            ].
+        ].
+        isBuiltIn := aCompiler isBuiltInUnarySelector:selector.
+        isBuiltIn ifFalse:[
+            isSpecial := aCompiler isSpecialSendSelector:selector
+        ]
     ].
 
     (nargs == 1) ifTrue:[
-	(recType == #ThisContext) ifTrue:[
-	    valueNeeded ifFalse:[
-		(selector == #return:) ifTrue:[
-		    (argArray at:1) codeOn:aStream inBlock:b for:aCompiler.  "^ value"
-		    aStream nextPut:#retTop.
-		    ^ self
-		].
-	     ].
-	].
+        (recType == #ThisContext) ifTrue:[
+            valueNeeded ifFalse:[
+                (selector == #return:) ifTrue:[
+                    (argArray at:1) codeOn:aStream inBlock:b for:aCompiler.  "^ value"
+                    aStream nextPut:#retTop.
+                    ^ self
+                ].
+             ].
+        ].
 
-	((argArray at:1) isBlock) ifTrue:[
-	    ((selector == #ifTrue:) or:[selector == #ifFalse:]) ifTrue:[
-		receiver isBlock ifFalse:[
-		    self codeIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-		    ^ self
-		].
-	    ].
+        ((argArray at:1) isBlock) ifTrue:[
+            ((selector == #ifTrue:) or:[selector == #ifFalse:]) ifTrue:[
+                receiver isBlock ifFalse:[
+                    self codeIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+                    ^ self
+                ].
+            ].
 "
-	    ((selector == #and:) or:[selector == #or:]) ifTrue:[
-		self codeAndOrOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-		^ self
-	    ].
+            ((selector == #and:) or:[selector == #or:]) ifTrue:[
+                self codeAndOrOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+                ^ self
+            ].
 "
-	    (selector == #timesRepeat:) ifTrue:[
-		(receiver isConstant and:[receiver evaluate isNumber]) ifTrue:[
-		    self codeTimesRepeatOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-		    ^ self
-		]
-	    ].
+            (selector == #timesRepeat:) ifTrue:[
+                (receiver isConstant and:[receiver evaluate isNumber]) ifTrue:[
+                    self codeTimesRepeatOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+                    ^ self
+                ]
+            ].
 
-	    ((selector == #whileTrue:) or:[selector == #whileFalse:]) ifTrue:[
-		(receiver isBlock) ifTrue:[
-		    self codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-		    ^ self
-		]
-	    ]
-	].
-	isBuiltIn := aCompiler isBuiltIn1ArgSelector:selector
+            ((selector == #whileTrue:) or:[selector == #whileFalse:]) ifTrue:[
+                (receiver isBlock) ifTrue:[
+                    self codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+                    ^ self
+                ]
+            ]
+        ].
+        isBuiltIn := aCompiler isBuiltIn1ArgSelector:selector
     ].
 
     (nargs == 2) ifTrue:[
-	((selector == #ifTrue:ifFalse:) or:[selector == #ifFalse:ifTrue:]) ifTrue:[
-	    receiver isBlock ifFalse:[
-		(argArray at:1) isBlock ifTrue:[
-		    (argArray at:2) isBlock ifTrue:[
-			self codeIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-			^ self
-		    ]
-		]
-	    ]
-	].
-	isBuiltIn := aCompiler isBuiltIn2ArgSelector:selector
+        ((selector == #ifTrue:ifFalse:) or:[selector == #ifFalse:ifTrue:]) ifTrue:[
+            receiver isBlock ifFalse:[
+                (argArray at:1) isBlock ifTrue:[
+                    (argArray at:2) isBlock ifTrue:[
+                        self codeIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+                        ^ self
+                    ]
+                ]
+            ]
+        ].
+        isBuiltIn := aCompiler isBuiltIn2ArgSelector:selector
     ].
 
     "can we use a send-bytecode ?"
     (isBuiltIn or:[isSpecial]) ifTrue:[
-	receiver isSuper ifFalse:[
-	    receiver codeOn:aStream inBlock:b for:aCompiler.
-	    (nargs > 0) ifTrue:[
-		(argArray at:1) codeOn:aStream inBlock:b for:aCompiler.
-		(nargs > 1) ifTrue:[
-		    (argArray at:2) codeOn:aStream inBlock:b for:aCompiler
-		]
-	    ].
-	    aStream nextPut:selector.
-	    (aCompiler hasLineNumber:selector) ifTrue:[
-		aStream nextPut:lineNr.
-	    ].
-	    isSpecial ifTrue:[
-		aStream nextPut:(aCompiler specialSendCodeFor:selector)
-	    ].
-	    valueNeeded ifFalse:[
-		aStream nextPut:#drop
-	    ].
-	    ^ self
-	]
+        receiver isSuper ifFalse:[
+            receiver codeOn:aStream inBlock:b for:aCompiler.
+            (nargs > 0) ifTrue:[
+                (argArray at:1) codeOn:aStream inBlock:b for:aCompiler.
+                (nargs > 1) ifTrue:[
+                    (argArray at:2) codeOn:aStream inBlock:b for:aCompiler
+                ]
+            ].
+            aStream nextPut:selector.
+            (aCompiler hasLineNumber:selector) ifTrue:[
+                aStream nextPut:lineNr.
+            ].
+            isSpecial ifTrue:[
+                aStream nextPut:(aCompiler specialSendCodeFor:selector)
+            ].
+            valueNeeded ifFalse:[
+                aStream nextPut:#drop
+            ].
+            ^ self
+        ]
     ].
 
     ((nargs == 0) and:[selector == #yourself]) ifTrue:[
-	"yourself is often added to get the receiver -
-	 we get it without the yourself-message"
+        "yourself is often added to get the receiver -
+         we get it without the yourself-message"
 
-	valueNeeded ifTrue:[
-	    receiver codeOn:aStream inBlock:b for:aCompiler
-	].
-	^ self
+        valueNeeded ifTrue:[
+            receiver codeOn:aStream inBlock:b for:aCompiler
+        ].
+        ^ self
     ].
 
     "no - generate a send"
 
     receiver isSuper ifTrue:[
-	cls := aCompiler targetClass.
-	receiver isHere ifTrue:[
-	    code := #hereSend.
-	] ifFalse:[
-	    code := #superSend.
-	    cls := cls superclass.
-	].
-	clsLitIndex := aCompiler addLiteral:cls.
+        cls := aCompiler targetClass.
+        receiver isHere ifTrue:[
+            code := #hereSend.
+        ] ifFalse:[
+            code := #superSend.
+            cls := cls superclass.
+        ].
+        clsLitIndex := aCompiler addLiteral:cls.
     ] ifFalse:[
-	clsLitIndex := 0.
+        clsLitIndex := 0.
     ].
 
     litIndex := aCompiler addLiteral:selector.
     (litIndex <= 255 and:[clsLitIndex <= 255]) ifTrue:[
-	(recType ~~ #Self) ifTrue:[
-	    receiver codeOn:aStream inBlock:b for:aCompiler
-	].
-	argArray notNil ifTrue:[
-	    argArray do:[:arg |
-		arg codeOn:aStream inBlock:b for:aCompiler
-	    ]
-	].
+        stackTop := nil.
 
-	receiver isSuper ifTrue:[
-	    aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:clsLitIndex.
-	    valueNeeded ifFalse:[
-		aStream nextPut:#drop
-	    ].
-	    ^ self
-	].
+        (recType ~~ #Self) ifTrue:[
+            receiver codeOn:aStream inBlock:b for:aCompiler.
+            receiver isConstant ifTrue:[ 
+                stackTop := receiver
+            ]
+        ].
+        argArray notNil ifTrue:[
+            argArray do:[:arg |
+                (stackTop notNil 
+                and:[arg canReuseAsArg:stackTop]) ifTrue:[
+                    aStream nextPut:#dup.
+"/ 'reuse:' print. stackTop print. ' in ' print. aCompiler selector printNL.
+                ] ifFalse:[
+                    arg codeOn:aStream inBlock:b for:aCompiler.
+                    stackTop := arg.
+                ]
+            ]
+        ].
 
-	(nargs <= 3) ifTrue:[
-	    |codes|
+        receiver isSuper ifTrue:[
+            aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:clsLitIndex.
+            valueNeeded ifFalse:[
+                aStream nextPut:#drop
+            ].
+            ^ self
+        ].
+
+        (nargs <= 3) ifTrue:[
+            |codes|
 
-	    valueNeeded ifTrue:[
-		(receiver type == #Self) ifTrue:[
-		    codes := #(sendSelf0 sendSelf1 sendSelf2 sendSelf3)
-		] ifFalse:[
-		    codes := #(send0 send1 send2 send3)
-		]
-	    ] ifFalse:[
-		(receiver type == #Self) ifTrue:[
-		    codes := #(sendSelfDrop0 sendSelfDrop1 sendSelfDrop2 sendSelfDrop3)
-		] ifFalse:[
-		    codes := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3)
-		]
-	    ].
-	    aStream nextPut:(codes at:(nargs + 1)); nextPut:lineNr; nextPut:litIndex.
-	    ^ self
-	].
+            valueNeeded ifTrue:[
+                (receiver type == #Self) ifTrue:[
+                    codes := #(sendSelf0 sendSelf1 sendSelf2 sendSelf3)
+                ] ifFalse:[
+                    codes := #(send0 send1 send2 send3)
+                ]
+            ] ifFalse:[
+                (receiver type == #Self) ifTrue:[
+                    codes := #(sendSelfDrop0 sendSelfDrop1 sendSelfDrop2 sendSelfDrop3)
+                ] ifFalse:[
+                    codes := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3)
+                ]
+            ].
+            aStream nextPut:(codes at:(nargs + 1)); nextPut:lineNr; nextPut:litIndex.
+            ^ self
+        ].
 
-	(recType == #Self) ifTrue:[
-	    code := #sendSelf
-	] ifFalse:[
-	    valueNeeded ifTrue:[
-		code := #send
-	    ] ifFalse:[
-		code := #sendDrop
-	    ]
-	].
-	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs.
-	valueNeeded ifFalse:[
-	    (recType == #Self) ifTrue:[
-		aStream nextPut:#drop
-	    ]
-	].
-	^ self
+        (recType == #Self) ifTrue:[
+            code := #sendSelf
+        ] ifFalse:[
+            valueNeeded ifTrue:[
+                code := #send
+            ] ifFalse:[
+                code := #sendDrop
+            ]
+        ].
+        aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs.
+        valueNeeded ifFalse:[
+            (recType == #Self) ifTrue:[
+                aStream nextPut:#drop
+            ]
+        ].
+        ^ self
     ].
 
     "needs 16bit literal index"
 
     receiver isSuper ifTrue:[
-	argArray notNil ifTrue:[
-	    argArray do:[:arg |
-		arg codeOn:aStream inBlock:b for:aCompiler
-	    ]
-	].
-	receiver isHere ifTrue:[
-	    code := #hereSendL
-	] ifFalse:[
-	    code := #superSendL.
-	].
-	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:clsLitIndex; nextPut:0.
+        argArray notNil ifTrue:[
+            argArray do:[:arg |
+                arg codeOn:aStream inBlock:b for:aCompiler
+            ]
+        ].
+        receiver isHere ifTrue:[
+            code := #hereSendL
+        ] ifFalse:[
+            code := #superSendL.
+        ].
+        aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:clsLitIndex; nextPut:0.
     ] ifFalse:[
-	recType ~~ #Self ifTrue:[
-	    receiver codeOn:aStream inBlock:b for:aCompiler.
-	].
-	argArray notNil ifTrue:[
-	    argArray do:[:arg |
-		arg codeOn:aStream inBlock:b for:aCompiler
-	    ]
-	].
+        recType ~~ #Self ifTrue:[
+            receiver codeOn:aStream inBlock:b for:aCompiler.
+        ].
+        argArray notNil ifTrue:[
+            argArray do:[:arg |
+                arg codeOn:aStream inBlock:b for:aCompiler
+            ]
+        ].
 
-	recType == #Self ifTrue:[
-	    code := #sendSelfL
-	] ifFalse:[
-	    code := #sendL
-	].
-	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs.
+        recType == #Self ifTrue:[
+            code := #sendSelfL
+        ] ifFalse:[
+            code := #sendL
+        ].
+        aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs.
     ].
     valueNeeded ifFalse:[
-	aStream nextPut:#drop
+        aStream nextPut:#drop
     ].
 
     "Modified: 3.9.1995 / 12:55:42 / claus"
+    "Modified: 14.4.1996 / 01:05:40 / cg"
 !
 
 codeOrIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
@@ -1561,5 +1575,5 @@
 !MessageNode class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libcomp/Attic/MessageNd.st,v 1.43 1996-03-21 15:19:27 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libcomp/Attic/MessageNd.st,v 1.44 1996-04-13 23:05:55 cg Exp $'
 ! !
--- a/MessageNode.st	Sun Apr 14 01:04:47 1996 +0200
+++ b/MessageNode.st	Sun Apr 14 01:05:55 1996 +0200
@@ -723,247 +723,261 @@
 !
 
 codeOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
-    |recType nargs isBuiltIn litIndex cls clsLitIndex code isSpecial|
+    |recType nargs isBuiltIn litIndex cls clsLitIndex code isSpecial
+     stackTop|
 
     argArray isNil ifTrue:[
-	nargs := 0
+        nargs := 0
     ] ifFalse:[
-	nargs := argArray size
+        nargs := argArray size
     ].
 
     isBuiltIn := isSpecial := false.
     recType := receiver type.
 
     (nargs == 0) ifTrue:[
-	(recType == #ThisContext) ifTrue:[
-	    valueNeeded ifFalse:[
-		"for now, only do it in methods"
-		b isNil ifTrue:[
-		    (selector == #restart) ifTrue:[
-			aStream nextPut:#jump; nextPut:1.      "jump to start"
-			^ self
-		    ].
-		].
-		(selector == #return) ifTrue:[  "^ nil"
-		    aStream nextPut:#retNil.
-		    ^ self
-		].
-	    ]
-	].
+        (recType == #ThisContext) ifTrue:[
+            valueNeeded ifFalse:[
+                "for now, only do it in methods"
+                b isNil ifTrue:[
+                    (selector == #restart) ifTrue:[
+                        aStream nextPut:#jump; nextPut:1.      "jump to start"
+                        ^ self
+                    ].
+                ].
+                (selector == #return) ifTrue:[  "^ nil"
+                    aStream nextPut:#retNil.
+                    ^ self
+                ].
+            ]
+        ].
 
-	receiver isBlock ifTrue:[
-	    selector == #value ifTrue:[
-		receiver codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-		^ self
-	    ].
-	    ((selector == #whileTrue) or:[selector == #whileFalse]) ifTrue:[
-		self codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-		^ self
-	    ].
-	].
-	isBuiltIn := aCompiler isBuiltInUnarySelector:selector.
-	isBuiltIn ifFalse:[
-	    isSpecial := aCompiler isSpecialSendSelector:selector
-	]
+        receiver isBlock ifTrue:[
+            selector == #value ifTrue:[
+                receiver codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+                ^ self
+            ].
+            ((selector == #whileTrue) or:[selector == #whileFalse]) ifTrue:[
+                self codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+                ^ self
+            ].
+        ].
+        isBuiltIn := aCompiler isBuiltInUnarySelector:selector.
+        isBuiltIn ifFalse:[
+            isSpecial := aCompiler isSpecialSendSelector:selector
+        ]
     ].
 
     (nargs == 1) ifTrue:[
-	(recType == #ThisContext) ifTrue:[
-	    valueNeeded ifFalse:[
-		(selector == #return:) ifTrue:[
-		    (argArray at:1) codeOn:aStream inBlock:b for:aCompiler.  "^ value"
-		    aStream nextPut:#retTop.
-		    ^ self
-		].
-	     ].
-	].
+        (recType == #ThisContext) ifTrue:[
+            valueNeeded ifFalse:[
+                (selector == #return:) ifTrue:[
+                    (argArray at:1) codeOn:aStream inBlock:b for:aCompiler.  "^ value"
+                    aStream nextPut:#retTop.
+                    ^ self
+                ].
+             ].
+        ].
 
-	((argArray at:1) isBlock) ifTrue:[
-	    ((selector == #ifTrue:) or:[selector == #ifFalse:]) ifTrue:[
-		receiver isBlock ifFalse:[
-		    self codeIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-		    ^ self
-		].
-	    ].
+        ((argArray at:1) isBlock) ifTrue:[
+            ((selector == #ifTrue:) or:[selector == #ifFalse:]) ifTrue:[
+                receiver isBlock ifFalse:[
+                    self codeIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+                    ^ self
+                ].
+            ].
 "
-	    ((selector == #and:) or:[selector == #or:]) ifTrue:[
-		self codeAndOrOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-		^ self
-	    ].
+            ((selector == #and:) or:[selector == #or:]) ifTrue:[
+                self codeAndOrOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+                ^ self
+            ].
 "
-	    (selector == #timesRepeat:) ifTrue:[
-		(receiver isConstant and:[receiver evaluate isNumber]) ifTrue:[
-		    self codeTimesRepeatOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-		    ^ self
-		]
-	    ].
+            (selector == #timesRepeat:) ifTrue:[
+                (receiver isConstant and:[receiver evaluate isNumber]) ifTrue:[
+                    self codeTimesRepeatOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+                    ^ self
+                ]
+            ].
 
-	    ((selector == #whileTrue:) or:[selector == #whileFalse:]) ifTrue:[
-		(receiver isBlock) ifTrue:[
-		    self codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-		    ^ self
-		]
-	    ]
-	].
-	isBuiltIn := aCompiler isBuiltIn1ArgSelector:selector
+            ((selector == #whileTrue:) or:[selector == #whileFalse:]) ifTrue:[
+                (receiver isBlock) ifTrue:[
+                    self codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+                    ^ self
+                ]
+            ]
+        ].
+        isBuiltIn := aCompiler isBuiltIn1ArgSelector:selector
     ].
 
     (nargs == 2) ifTrue:[
-	((selector == #ifTrue:ifFalse:) or:[selector == #ifFalse:ifTrue:]) ifTrue:[
-	    receiver isBlock ifFalse:[
-		(argArray at:1) isBlock ifTrue:[
-		    (argArray at:2) isBlock ifTrue:[
-			self codeIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-			^ self
-		    ]
-		]
-	    ]
-	].
-	isBuiltIn := aCompiler isBuiltIn2ArgSelector:selector
+        ((selector == #ifTrue:ifFalse:) or:[selector == #ifFalse:ifTrue:]) ifTrue:[
+            receiver isBlock ifFalse:[
+                (argArray at:1) isBlock ifTrue:[
+                    (argArray at:2) isBlock ifTrue:[
+                        self codeIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+                        ^ self
+                    ]
+                ]
+            ]
+        ].
+        isBuiltIn := aCompiler isBuiltIn2ArgSelector:selector
     ].
 
     "can we use a send-bytecode ?"
     (isBuiltIn or:[isSpecial]) ifTrue:[
-	receiver isSuper ifFalse:[
-	    receiver codeOn:aStream inBlock:b for:aCompiler.
-	    (nargs > 0) ifTrue:[
-		(argArray at:1) codeOn:aStream inBlock:b for:aCompiler.
-		(nargs > 1) ifTrue:[
-		    (argArray at:2) codeOn:aStream inBlock:b for:aCompiler
-		]
-	    ].
-	    aStream nextPut:selector.
-	    (aCompiler hasLineNumber:selector) ifTrue:[
-		aStream nextPut:lineNr.
-	    ].
-	    isSpecial ifTrue:[
-		aStream nextPut:(aCompiler specialSendCodeFor:selector)
-	    ].
-	    valueNeeded ifFalse:[
-		aStream nextPut:#drop
-	    ].
-	    ^ self
-	]
+        receiver isSuper ifFalse:[
+            receiver codeOn:aStream inBlock:b for:aCompiler.
+            (nargs > 0) ifTrue:[
+                (argArray at:1) codeOn:aStream inBlock:b for:aCompiler.
+                (nargs > 1) ifTrue:[
+                    (argArray at:2) codeOn:aStream inBlock:b for:aCompiler
+                ]
+            ].
+            aStream nextPut:selector.
+            (aCompiler hasLineNumber:selector) ifTrue:[
+                aStream nextPut:lineNr.
+            ].
+            isSpecial ifTrue:[
+                aStream nextPut:(aCompiler specialSendCodeFor:selector)
+            ].
+            valueNeeded ifFalse:[
+                aStream nextPut:#drop
+            ].
+            ^ self
+        ]
     ].
 
     ((nargs == 0) and:[selector == #yourself]) ifTrue:[
-	"yourself is often added to get the receiver -
-	 we get it without the yourself-message"
+        "yourself is often added to get the receiver -
+         we get it without the yourself-message"
 
-	valueNeeded ifTrue:[
-	    receiver codeOn:aStream inBlock:b for:aCompiler
-	].
-	^ self
+        valueNeeded ifTrue:[
+            receiver codeOn:aStream inBlock:b for:aCompiler
+        ].
+        ^ self
     ].
 
     "no - generate a send"
 
     receiver isSuper ifTrue:[
-	cls := aCompiler targetClass.
-	receiver isHere ifTrue:[
-	    code := #hereSend.
-	] ifFalse:[
-	    code := #superSend.
-	    cls := cls superclass.
-	].
-	clsLitIndex := aCompiler addLiteral:cls.
+        cls := aCompiler targetClass.
+        receiver isHere ifTrue:[
+            code := #hereSend.
+        ] ifFalse:[
+            code := #superSend.
+            cls := cls superclass.
+        ].
+        clsLitIndex := aCompiler addLiteral:cls.
     ] ifFalse:[
-	clsLitIndex := 0.
+        clsLitIndex := 0.
     ].
 
     litIndex := aCompiler addLiteral:selector.
     (litIndex <= 255 and:[clsLitIndex <= 255]) ifTrue:[
-	(recType ~~ #Self) ifTrue:[
-	    receiver codeOn:aStream inBlock:b for:aCompiler
-	].
-	argArray notNil ifTrue:[
-	    argArray do:[:arg |
-		arg codeOn:aStream inBlock:b for:aCompiler
-	    ]
-	].
+        stackTop := nil.
 
-	receiver isSuper ifTrue:[
-	    aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:clsLitIndex.
-	    valueNeeded ifFalse:[
-		aStream nextPut:#drop
-	    ].
-	    ^ self
-	].
+        (recType ~~ #Self) ifTrue:[
+            receiver codeOn:aStream inBlock:b for:aCompiler.
+            receiver isConstant ifTrue:[ 
+                stackTop := receiver
+            ]
+        ].
+        argArray notNil ifTrue:[
+            argArray do:[:arg |
+                (stackTop notNil 
+                and:[arg canReuseAsArg:stackTop]) ifTrue:[
+                    aStream nextPut:#dup.
+"/ 'reuse:' print. stackTop print. ' in ' print. aCompiler selector printNL.
+                ] ifFalse:[
+                    arg codeOn:aStream inBlock:b for:aCompiler.
+                    stackTop := arg.
+                ]
+            ]
+        ].
 
-	(nargs <= 3) ifTrue:[
-	    |codes|
+        receiver isSuper ifTrue:[
+            aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:clsLitIndex.
+            valueNeeded ifFalse:[
+                aStream nextPut:#drop
+            ].
+            ^ self
+        ].
+
+        (nargs <= 3) ifTrue:[
+            |codes|
 
-	    valueNeeded ifTrue:[
-		(receiver type == #Self) ifTrue:[
-		    codes := #(sendSelf0 sendSelf1 sendSelf2 sendSelf3)
-		] ifFalse:[
-		    codes := #(send0 send1 send2 send3)
-		]
-	    ] ifFalse:[
-		(receiver type == #Self) ifTrue:[
-		    codes := #(sendSelfDrop0 sendSelfDrop1 sendSelfDrop2 sendSelfDrop3)
-		] ifFalse:[
-		    codes := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3)
-		]
-	    ].
-	    aStream nextPut:(codes at:(nargs + 1)); nextPut:lineNr; nextPut:litIndex.
-	    ^ self
-	].
+            valueNeeded ifTrue:[
+                (receiver type == #Self) ifTrue:[
+                    codes := #(sendSelf0 sendSelf1 sendSelf2 sendSelf3)
+                ] ifFalse:[
+                    codes := #(send0 send1 send2 send3)
+                ]
+            ] ifFalse:[
+                (receiver type == #Self) ifTrue:[
+                    codes := #(sendSelfDrop0 sendSelfDrop1 sendSelfDrop2 sendSelfDrop3)
+                ] ifFalse:[
+                    codes := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3)
+                ]
+            ].
+            aStream nextPut:(codes at:(nargs + 1)); nextPut:lineNr; nextPut:litIndex.
+            ^ self
+        ].
 
-	(recType == #Self) ifTrue:[
-	    code := #sendSelf
-	] ifFalse:[
-	    valueNeeded ifTrue:[
-		code := #send
-	    ] ifFalse:[
-		code := #sendDrop
-	    ]
-	].
-	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs.
-	valueNeeded ifFalse:[
-	    (recType == #Self) ifTrue:[
-		aStream nextPut:#drop
-	    ]
-	].
-	^ self
+        (recType == #Self) ifTrue:[
+            code := #sendSelf
+        ] ifFalse:[
+            valueNeeded ifTrue:[
+                code := #send
+            ] ifFalse:[
+                code := #sendDrop
+            ]
+        ].
+        aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs.
+        valueNeeded ifFalse:[
+            (recType == #Self) ifTrue:[
+                aStream nextPut:#drop
+            ]
+        ].
+        ^ self
     ].
 
     "needs 16bit literal index"
 
     receiver isSuper ifTrue:[
-	argArray notNil ifTrue:[
-	    argArray do:[:arg |
-		arg codeOn:aStream inBlock:b for:aCompiler
-	    ]
-	].
-	receiver isHere ifTrue:[
-	    code := #hereSendL
-	] ifFalse:[
-	    code := #superSendL.
-	].
-	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:clsLitIndex; nextPut:0.
+        argArray notNil ifTrue:[
+            argArray do:[:arg |
+                arg codeOn:aStream inBlock:b for:aCompiler
+            ]
+        ].
+        receiver isHere ifTrue:[
+            code := #hereSendL
+        ] ifFalse:[
+            code := #superSendL.
+        ].
+        aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:clsLitIndex; nextPut:0.
     ] ifFalse:[
-	recType ~~ #Self ifTrue:[
-	    receiver codeOn:aStream inBlock:b for:aCompiler.
-	].
-	argArray notNil ifTrue:[
-	    argArray do:[:arg |
-		arg codeOn:aStream inBlock:b for:aCompiler
-	    ]
-	].
+        recType ~~ #Self ifTrue:[
+            receiver codeOn:aStream inBlock:b for:aCompiler.
+        ].
+        argArray notNil ifTrue:[
+            argArray do:[:arg |
+                arg codeOn:aStream inBlock:b for:aCompiler
+            ]
+        ].
 
-	recType == #Self ifTrue:[
-	    code := #sendSelfL
-	] ifFalse:[
-	    code := #sendL
-	].
-	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs.
+        recType == #Self ifTrue:[
+            code := #sendSelfL
+        ] ifFalse:[
+            code := #sendL
+        ].
+        aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs.
     ].
     valueNeeded ifFalse:[
-	aStream nextPut:#drop
+        aStream nextPut:#drop
     ].
 
     "Modified: 3.9.1995 / 12:55:42 / claus"
+    "Modified: 14.4.1996 / 01:05:40 / cg"
 !
 
 codeOrIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
@@ -1561,5 +1575,5 @@
 !MessageNode class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libcomp/MessageNode.st,v 1.43 1996-03-21 15:19:27 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libcomp/MessageNode.st,v 1.44 1996-04-13 23:05:55 cg Exp $'
 ! !