MessageNode.st
changeset 140 1ef1d1395146
parent 135 aa4f7b8f121e
child 148 ef0e604209ec
equal deleted inserted replaced
139:65eaf1a009f5 140:1ef1d1395146
     9  other person.  No title to or ownership of the software is
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
    13 ParseNode subclass:#MessageNode
    13 ParseNode subclass:#MessageNode
    14        instanceVariableNames:'receiver selector argArray lineNr'
    14 	 instanceVariableNames:'receiver selector argArray lineNr'
    15        classVariableNames:''
    15 	 classVariableNames:''
    16        poolDictionaries:''
    16 	 poolDictionaries:''
    17        category:'System-Compiler-Support'
    17 	 category:'System-Compiler-Support'
    18 !
    18 !
    19 
    19 
    20 !MessageNode class methodsFor:'documentation'!
    20 !MessageNode class methodsFor:'documentation'!
    21 
    21 
    22 copyright
    22 copyright
    31  other person.  No title to or ownership of the software is
    31  other person.  No title to or ownership of the software is
    32  hereby transferred.
    32  hereby transferred.
    33 "
    33 "
    34 !
    34 !
    35 
    35 
    36 version
       
    37     ^ '$Header: /cvs/stx/stx/libcomp/MessageNode.st,v 1.31 1995-11-11 15:30:33 cg Exp $'
       
    38 !
       
    39 
       
    40 documentation
    36 documentation
    41 "
    37 "
    42     node for parse-trees, representing message sends
    38     node for parse-trees, representing message sends
    43 "
    39 "
       
    40 !
       
    41 
       
    42 version
       
    43     ^ '$Header: /cvs/stx/stx/libcomp/MessageNode.st,v 1.32 1995-11-23 02:13:47 cg Exp $'
    44 ! !
    44 ! !
    45 
    45 
    46 !MessageNode class methodsFor:'instance creation'!
    46 !MessageNode class methodsFor:'instance creation'!
    47 
    47 
    48 receiver:recNode selector:selectorString 
    48 receiver:recNode selector:selectorString 
    49     ^ (self basicNew) receiver:recNode selector:selectorString args:nil lineno:0
    49     ^ (self basicNew) receiver:recNode selector:selectorString args:nil lineno:0
       
    50 !
       
    51 
       
    52 receiver:recNode selector:selectorString arg1:argNode1 arg2:argNode2 fold:folding
       
    53     |result recVal argVal selector|
       
    54 
       
    55     "
       
    56      This is just a demonstration - of how complex constants can be folded.
       
    57      This was inspired by some discussion in c.l.s about enhancing the language - I prefer
       
    58      enhancing the compiler ....
       
    59      The following optimization will convert '#(...) with:#(...) collect:[...]' into an array constant,
       
    60      allowing a constant arrays of complex objects.
       
    61 
       
    62      Notice: this method is normally disabled - its just a demo after all.
       
    63     "
       
    64     folding ifTrue:[
       
    65 	"do constant folding ..."
       
    66 	(recNode isConstant and:[argNode1 isConstant]) ifTrue:[
       
    67 	    "check if we can do it ..."
       
    68 	    selector := selectorString asSymbolIfInterned.
       
    69 	    selector notNil ifTrue:[
       
    70 		recVal := recNode evaluate.
       
    71 		(recVal respondsTo:selector) ifTrue:[
       
    72 		    "
       
    73 		     we could do much more here - but then, we need a dependency from
       
    74 		     the folded selectors method to the method we generate code for ...
       
    75 		     limit optimizations to those that will never change
       
    76 		     (or - if you change them - you will crash so bad ...)
       
    77 		    "
       
    78 		    argVal := argNode1 evaluate.
       
    79 		    ((recVal isMemberOf:Array) and:[argVal isMemberOf:Array]) ifTrue:[
       
    80 			(selector == #with:collect:) ifTrue:[
       
    81 			    (argNode2 isMemberOf:BlockNode) ifTrue:[
       
    82 				(SignalSet anySignal catch:[
       
    83 				    result := recVal perform:selector with:argVal with:(argNode2 evaluate).
       
    84 				]) ifTrue:[
       
    85 				    ^ 'error in constant expression'
       
    86 				].
       
    87 				^ ConstantNode type:(ConstantNode typeOfConstant:result) value:result
       
    88 			    ]
       
    89 			]
       
    90 		    ]
       
    91 		]
       
    92 	    ]
       
    93 	]
       
    94     ].
       
    95     ^ (self basicNew) receiver:recNode selector:selectorString args:(Array with:argNode1 with:argNode2) lineno:0
    50 !
    96 !
    51 
    97 
    52 receiver:recNode selector:selectorString arg:argNode
    98 receiver:recNode selector:selectorString arg:argNode
    53     ^ self receiver:recNode selector:selectorString arg:argNode fold:true
    99     ^ self receiver:recNode selector:selectorString arg:argNode fold:true
    54 !
   100 !
   130 "/      ]
   176 "/      ]
   131     ].
   177     ].
   132     ^ (self basicNew) receiver:recNode selector:selectorString args:(Array with:argNode) lineno:0
   178     ^ (self basicNew) receiver:recNode selector:selectorString args:(Array with:argNode) lineno:0
   133 !
   179 !
   134 
   180 
   135 receiver:recNode selector:selectorString arg1:argNode1 arg2:argNode2 fold:folding
       
   136     |result recVal argVal selector|
       
   137 
       
   138     "
       
   139      This is just a demonstration - of how complex constants can be folded.
       
   140      This was inspired by some discussion in c.l.s about enhancing the language - I prefer
       
   141      enhancing the compiler ....
       
   142      The following optimization will convert '#(...) with:#(...) collect:[...]' into an array constant,
       
   143      allowing a constant arrays of complex objects.
       
   144 
       
   145      Notice: this method is normally disabled - its just a demo after all.
       
   146     "
       
   147     folding ifTrue:[
       
   148 	"do constant folding ..."
       
   149 	(recNode isConstant and:[argNode1 isConstant]) ifTrue:[
       
   150 	    "check if we can do it ..."
       
   151 	    selector := selectorString asSymbolIfInterned.
       
   152 	    selector notNil ifTrue:[
       
   153 		recVal := recNode evaluate.
       
   154 		(recVal respondsTo:selector) ifTrue:[
       
   155 		    "
       
   156 		     we could do much more here - but then, we need a dependency from
       
   157 		     the folded selectors method to the method we generate code for ...
       
   158 		     limit optimizations to those that will never change
       
   159 		     (or - if you change them - you will crash so bad ...)
       
   160 		    "
       
   161 		    argVal := argNode1 evaluate.
       
   162 		    ((recVal isMemberOf:Array) and:[argVal isMemberOf:Array]) ifTrue:[
       
   163 			(selector == #with:collect:) ifTrue:[
       
   164 			    (argNode2 isMemberOf:BlockNode) ifTrue:[
       
   165 				(SignalSet anySignal catch:[
       
   166 				    result := recVal perform:selector with:argVal with:(argNode2 evaluate).
       
   167 				]) ifTrue:[
       
   168 				    ^ 'error in constant expression'
       
   169 				].
       
   170 				^ ConstantNode type:(ConstantNode typeOfConstant:result) value:result
       
   171 			    ]
       
   172 			]
       
   173 		    ]
       
   174 		]
       
   175 	    ]
       
   176 	]
       
   177     ].
       
   178     ^ (self basicNew) receiver:recNode selector:selectorString args:(Array with:argNode1 with:argNode2) lineno:0
       
   179 !
       
   180 
       
   181 receiver:recNode selector:selectorString args:anArray
   181 receiver:recNode selector:selectorString args:anArray
   182     ^ self receiver:recNode selector:selectorString args:anArray fold:true
   182     ^ self receiver:recNode selector:selectorString args:anArray fold:true
   183 !
   183 !
   184 
   184 
   185 receiver:recNode selector:selectorString args:argArray fold:folding
   185 receiver:recNode selector:selectorString args:argArray fold:folding
   203     ^ (self basicNew) receiver:recNode selector:selectorString args:argArray lineno:0
   203     ^ (self basicNew) receiver:recNode selector:selectorString args:argArray lineno:0
   204 
   204 
   205     "Modified: 3.9.1995 / 16:41:39 / claus"
   205     "Modified: 3.9.1995 / 16:41:39 / claus"
   206 ! !
   206 ! !
   207 
   207 
   208 !MessageNode methodsFor:'accessing'!
       
   209 
       
   210 receiver:r selector:s args:a lineno:l
       
   211     receiver := r.
       
   212     selector := s asSymbol.
       
   213     argArray := a.
       
   214     lineNr := l
       
   215 !
       
   216 
       
   217 receiver
       
   218     ^ receiver
       
   219 !
       
   220 
       
   221 selector
       
   222     ^ selector
       
   223 !
       
   224 
       
   225 args
       
   226     ^ argArray
       
   227 !
       
   228 
       
   229 arg1
       
   230     ^ argArray at:1
       
   231 !
       
   232 
       
   233 lineNumber
       
   234      ^ lineNr
       
   235 !
       
   236 
       
   237 lineNumber:num
       
   238      lineNr := num
       
   239 ! !
       
   240 
       
   241 !MessageNode methodsFor:'queries'!
       
   242 
       
   243 isMessage
       
   244     ^ true
       
   245 ! !
       
   246 
       
   247 !MessageNode class methodsFor:'queries'!
   208 !MessageNode class methodsFor:'queries'!
   248 
   209 
   249 hasLineNumber:sel
   210 hasLineNumber:sel
   250     "return true, if special send code needs lineNr"
   211     "return true, if special send code needs lineNr"
   251 
   212 
   253     (sel == #~~) ifTrue:[^ false].
   214     (sel == #~~) ifTrue:[^ false].
   254     (sel == #class) ifTrue:[^ false].
   215     (sel == #class) ifTrue:[^ false].
   255     (sel == #isNil) ifTrue:[^ false].
   216     (sel == #isNil) ifTrue:[^ false].
   256     (sel == #notNil) ifTrue:[^ false].
   217     (sel == #notNil) ifTrue:[^ false].
   257     ^ true
   218     ^ true
       
   219 !
       
   220 
       
   221 isBuiltIn1ArgSelector:sel
       
   222     "return true, if selector sel is built-in.
       
   223      (i.e. there is a single bytecode for it)"
       
   224 
       
   225     (sel == #at:) ifTrue:[^ true].
       
   226     (sel == #value:) ifTrue:[^ true].
       
   227     (sel == #bitAnd:) ifTrue:[^ true].
       
   228     (sel == #bitOr:) ifTrue:[^ true].
       
   229     (sel == #new:) ifTrue:[^ true].
       
   230     (sel == #basicNew:) ifTrue:[^ true].
       
   231     ^ false
       
   232 !
       
   233 
       
   234 isBuiltIn2ArgSelector:sel
       
   235     "return true, if selector sel is built-in.
       
   236      (i.e. there is a single bytecode for it)"
       
   237 
       
   238     (sel == #at:put:) ifTrue:[^ true].
       
   239     ^ false
   258 !
   240 !
   259 
   241 
   260 isBuiltInUnarySelector:sel
   242 isBuiltInUnarySelector:sel
   261     "return true, if unary selector sel is built-in. 
   243     "return true, if unary selector sel is built-in. 
   262      (i.e. there is a single bytecode for it)"
   244      (i.e. there is a single bytecode for it)"
   278     (sel == #notNil) ifTrue:[^ true].
   260     (sel == #notNil) ifTrue:[^ true].
   279     (sel == #not) ifTrue:[^ true].
   261     (sel == #not) ifTrue:[^ true].
   280     (sel == #new) ifTrue:[^ true].
   262     (sel == #new) ifTrue:[^ true].
   281     (sel == #basicNew) ifTrue:[^ true].
   263     (sel == #basicNew) ifTrue:[^ true].
   282     ^ false
   264     ^ false
   283 !
       
   284 
       
   285 isBuiltIn1ArgSelector:sel
       
   286     "return true, if selector sel is built-in.
       
   287      (i.e. there is a single bytecode for it)"
       
   288 
       
   289     (sel == #at:) ifTrue:[^ true].
       
   290     (sel == #value:) ifTrue:[^ true].
       
   291     (sel == #bitAnd:) ifTrue:[^ true].
       
   292     (sel == #bitOr:) ifTrue:[^ true].
       
   293     (sel == #new:) ifTrue:[^ true].
       
   294     (sel == #basicNew:) ifTrue:[^ true].
       
   295     ^ false
       
   296 !
       
   297 
       
   298 isBuiltIn2ArgSelector:sel
       
   299     "return true, if selector sel is built-in.
       
   300      (i.e. there is a single bytecode for it)"
       
   301 
       
   302     (sel == #at:put:) ifTrue:[^ true].
       
   303     ^ false
       
   304 ! !
   265 ! !
   305 
   266 
   306 !MessageNode methodsFor:'printing'!
   267 !MessageNode methodsFor:'accessing'!
   307 
   268 
   308 printOn:aStream indent:i
   269 arg1
   309     |needParen selectorParts index index2 arg|
   270     ^ argArray at:1
   310 
   271 !
   311     (#(whileTrue: whileFalse:) includes:selector) ifTrue:[
   272 
   312 	receiver isBlock ifTrue:[
   273 args
   313 	    ^ self printWhileOn:aStream indent:i
   274     ^ argArray
   314 	].
   275 !
   315     ].
   276 
   316 
   277 lineNumber
   317     index := 1.
   278      ^ lineNr
   318     selectorParts := OrderedCollection new.
   279 !
   319     [index == 0] whileFalse:[
   280 
   320 	index2 := selector indexOf:$: startingAt:index.
   281 lineNumber:num
   321 	index2 ~~ 0 ifTrue:[
   282      lineNr := num
   322 	    selectorParts add:(selector copyFrom:index to:index2).
   283 !
   323 	    index2 := index2 + 1
   284 
   324 	].
   285 receiver
   325 	index := index2
   286     ^ receiver
   326     ].
   287 !
   327 
   288 
   328     needParen := false.
   289 receiver:r selector:s args:a lineno:l
   329     receiver isMessage ifTrue:[
   290     receiver := r.
   330 	receiver isUnaryMessage ifFalse:[
   291     selector := s asSymbol.
   331 	    receiver isBinaryMessage ifFalse:[
   292     argArray := a.
   332 		needParen := true
   293     lineNr := l
   333 	    ].
   294 !
   334 	].
   295 
   335     ].
   296 selector
   336     needParen ifTrue:[
   297     ^ selector
   337 	aStream nextPutAll:'('
       
   338     ].
       
   339     receiver printOn:aStream indent:i.
       
   340     needParen ifTrue:[
       
   341 	aStream nextPutAll:')'
       
   342     ].
       
   343 
       
   344     1 to:(argArray size) do:[:argIndex |
       
   345 	aStream space.
       
   346 	(selectorParts at:argIndex) printOn:aStream.
       
   347 	aStream space.
       
   348 	arg := argArray at:argIndex.
       
   349 	needParen := false.
       
   350 	arg isMessage ifTrue:[
       
   351 	    arg isBinaryMessage ifFalse:[
       
   352 		arg isUnaryMessage ifFalse:[
       
   353 		    needParen := true
       
   354 		]
       
   355 	    ].
       
   356 	].
       
   357 	needParen ifTrue:[
       
   358 	    aStream nextPutAll:'('
       
   359 	].
       
   360 	arg printOn:aStream indent:i.
       
   361 	needParen ifTrue:[
       
   362 	    aStream nextPutAll:') '
       
   363 	].
       
   364     ]
       
   365 !
       
   366 
       
   367 printWhileOn:aStream indent:i
       
   368     |needParen arg|
       
   369 
       
   370     "special handling of whileTrue/whileFalse"
       
   371 
       
   372     aStream nextPutAll:'['.
       
   373     receiver statements printOn:aStream indent:i.
       
   374     aStream nextPutAll:'] whileTrue: '.
       
   375 
       
   376     arg := argArray at:1.
       
   377     needParen := false.
       
   378     arg isMessage ifTrue:[
       
   379 	arg isBinaryMessage ifFalse:[
       
   380 	    arg isUnaryMessage ifFalse:[
       
   381 		needParen := true
       
   382 	    ]
       
   383 	].
       
   384     ].
       
   385     needParen ifTrue:[
       
   386 	aStream nextPutAll:'('
       
   387     ].
       
   388     arg printOn:aStream indent:i.
       
   389     needParen ifTrue:[
       
   390 	aStream nextPutAll:') '
       
   391     ].
       
   392 ! !
   298 ! !
   393 
   299 
   394 !MessageNode methodsFor:'checks'!
   300 !MessageNode methodsFor:'checks'!
   395 
   301 
   396 plausibilityCheck
   302 plausibilityCheck
   479 	].
   385 	].
   480     ].
   386     ].
   481     ^ nil
   387     ^ nil
   482 ! !
   388 ! !
   483 
   389 
   484 !MessageNode methodsFor:'evaluating'!
   390 !MessageNode methodsFor:'code generation'!
   485 
   391 
   486 evaluate
   392 XXcodeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
   487     |r nargs argValueArray class|
   393     "generate code for [...] whilexxx:[ ... ]"
   488 
   394 
       
   395     |pos pos2 theReceiver theArg theByteCode optByteCode|
       
   396 
       
   397     (selector == #whileTrue:) ifTrue:[
       
   398 	theByteCode := #falseJump
       
   399     ] ifFalse:[
       
   400 	theByteCode := #trueJump
       
   401     ].
       
   402 
       
   403     theReceiver := receiver.
       
   404     optByteCode := self optimizedConditionFor:theReceiver with:theByteCode.
       
   405     optByteCode notNil ifTrue:[
       
   406 	((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
       
   407 	    theArg := receiver statements expression arg1
       
   408 	].
       
   409 	theReceiver := receiver statements expression receiver.
       
   410 	theByteCode := optByteCode
       
   411     ].
       
   412 
       
   413     valueNeeded ifTrue:[aStream nextPut:#pushNil].
       
   414     pos := aStream position.
       
   415     optByteCode notNil ifTrue:[
       
   416 	theReceiver codeOn:aStream inBlock:b for:aCompiler.
       
   417 	theArg notNil ifTrue:[
       
   418 	    theArg codeOn:aStream inBlock:b for:aCompiler
       
   419 	]
       
   420     ] ifFalse:[
       
   421 	theReceiver codeInlineOn:aStream inBlock:b for:aCompiler
       
   422     ].
       
   423 
       
   424     (lineNr between:1 and:255) ifTrue:[
       
   425 	aStream nextPut:#lineno; nextPut:lineNr.
       
   426     ].
       
   427 
       
   428     aStream nextPut:theByteCode.
       
   429     pos2 := aStream position.
       
   430     aStream nextPut:0.
       
   431     valueNeeded ifTrue:[aStream nextPut:#drop].
       
   432     (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   433     aStream nextPut:#jump; nextPut:pos.
       
   434     (aStream contents) at:pos2 put:(aStream position).
       
   435 !
       
   436 
       
   437 codeAndIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
   438     "generate code for (x and:[y]) ifxxx:[ ... ]"
       
   439 
       
   440     |theByteCode optByteCode theReceiver theArg pos1 pos2 pos3 code here jmp|
       
   441 
       
   442 
       
   443     theByteCode := #falseJump.
       
   444     theReceiver := receiver receiver.
       
   445 
       
   446     optByteCode := self optimizedConditionFor:theReceiver
       
   447 					 with:theByteCode.
       
   448     optByteCode notNil ifTrue:[
       
   449 	((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
       
   450 	    theArg := theReceiver arg1
       
   451 	].
       
   452 	theReceiver := theReceiver receiver.
       
   453 	theByteCode := optByteCode
       
   454     ].
       
   455     theReceiver codeOn:aStream inBlock:b for:aCompiler.
       
   456     theArg notNil ifTrue:[
       
   457 	theArg codeOn:aStream inBlock:b for:aCompiler
       
   458     ].
       
   459     aStream nextPut:theByteCode.
       
   460     pos1 := aStream position.
       
   461     aStream nextPut:0.
       
   462 
       
   463     theReceiver := receiver arg1.
       
   464     theReceiver codeInlineOn:aStream inBlock:b for:aCompiler.
       
   465     (selector == #ifTrue:) ifTrue:[
       
   466 	jmp := #falseJump
       
   467     ] ifFalse:[
       
   468 	jmp := #trueJump
       
   469     ].
       
   470     aStream nextPut:jmp.
       
   471     pos2 := aStream position.
       
   472     aStream nextPut:0.
       
   473 
       
   474     code := aStream contents.
       
   475     (selector == #ifFalse:) ifTrue:[
       
   476 	code at:pos1 put:(aStream position)
       
   477     ].
       
   478     (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   479 
       
   480     valueNeeded ifTrue:[
       
   481 	aStream nextPut:#jump.
       
   482 	pos3 := aStream position.
       
   483 	aStream nextPut:0.
       
   484 	here := aStream position.
       
   485 	(selector == #ifTrue:) ifTrue:[
       
   486 	    code at:pos1 put:here
       
   487 	].
       
   488 	code at:pos2 put:here.
       
   489 	aStream nextPut:#pushNil.
       
   490 	code at:pos3 put:(aStream position)
       
   491     ] ifFalse:[
       
   492 	here := aStream position.
       
   493 	(selector == #ifTrue:) ifTrue:[
       
   494 	    code at:pos1 put:here
       
   495 	].
       
   496 	code at:pos2 put:here
       
   497     ]
       
   498 !
       
   499 
       
   500 codeAndOrOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
   501     "generate code for x and/or:[y] - but not in an if"
       
   502 
       
   503     |pos theReceiver theByteCode|
       
   504 
       
   505 self halt.
       
   506     theReceiver := receiver.
       
   507     (selector == #and:) ifTrue:[
       
   508 	theByteCode := #falseJump
       
   509     ] ifFalse:[
       
   510 	theByteCode := #trueJump
       
   511     ].
       
   512 "
       
   513     (self canOptimizeConditionFor:receiver) ifTrue:[
       
   514 	theByteCode := self optimizedConditionFor:theReceiver
       
   515 					     with:theByteCode.
       
   516 	theReceiver := theReceiver receiver
       
   517     ].
       
   518 "
       
   519     theReceiver codeOn:aStream inBlock:b for:aCompiler.
       
   520     aStream nextPut:theByteCode.
       
   521     pos := aStream position.
       
   522     aStream nextPut:0.
       
   523     (argArray at: 1) codeInlineOn:aStream inBlock:b for:aCompiler.
       
   524     (aStream contents) at:pos put:(aStream position).
       
   525     valueNeeded ifFalse:[aStream nextPut:#drop]
       
   526 !
       
   527 
       
   528 codeForCascadeOn:aStream inBlock:b for:aCompiler
       
   529     "like codeOn, but always leave the receiver instead of the result"
       
   530 
       
   531     |nargs isBuiltIn code litIndex|
       
   532 
       
   533     argArray isNil ifTrue:[
       
   534 	nargs := 0
       
   535     ] ifFalse:[
       
   536 	nargs := argArray size
       
   537     ].
       
   538 
       
   539     isBuiltIn := false.
       
   540 
       
   541     (nargs == 0) ifTrue:[
       
   542 	isBuiltIn := self class isBuiltInUnarySelector:selector
       
   543     ].
       
   544     (nargs == 1) ifTrue:[
       
   545 	isBuiltIn := self class isBuiltIn1ArgSelector:selector
       
   546     ].
       
   547     (nargs == 2) ifTrue:[
       
   548 	isBuiltIn := self class isBuiltIn2ArgSelector:selector
       
   549     ].
       
   550 
       
   551     receiver codeOn:aStream inBlock:b for:aCompiler.
       
   552     aStream nextPut:#dup.
       
   553 
       
   554     "can we use a send-bytecode ?"
       
   555     isBuiltIn ifTrue:[
       
   556 	receiver isSuper ifFalse:[
       
   557 	    (nargs > 0) ifTrue:[
       
   558 		(argArray at:1) codeOn:aStream inBlock:b for:aCompiler.
       
   559 		(nargs > 1) ifTrue:[
       
   560 		    (argArray at:2) codeOn:aStream inBlock:b for:aCompiler
       
   561 		]
       
   562 	    ].
       
   563 	    aStream nextPut:selector.
       
   564 	    (self class hasLineNumber:selector) ifTrue:[
       
   565 		aStream nextPut:lineNr.
       
   566 	    ].
       
   567 	    aStream nextPut:#drop.
       
   568 	    ^ self
       
   569 	]
       
   570     ].
       
   571 
       
   572     "no - generate a send"
       
   573     argArray notNil ifTrue:[
       
   574 	argArray do:[:arg |
       
   575 	    arg codeOn:aStream inBlock:b for:aCompiler
       
   576 	]
       
   577     ].
       
   578     litIndex := aCompiler addLiteral:selector.
       
   579     litIndex <= 255 ifTrue:[
       
   580 	receiver isSuper ifTrue:[
       
   581 	    receiver isHere ifTrue:[
       
   582 		code := #hereSend
       
   583 	    ] ifFalse:[
       
   584 		code := #superSend.
       
   585 	    ].
       
   586 	    aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:nil; nextPut:#drop.
       
   587 	    ^ self
       
   588 	].
       
   589 	(nargs <= 3) ifTrue:[
       
   590 	    code := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3) at:(nargs+1).
       
   591 	    aStream nextPut:code; nextPut:lineNr; nextPut:litIndex.
       
   592 	    ^ self
       
   593 	].
       
   594 
       
   595 	aStream nextPut:#sendDrop; nextPut:lineNr; nextPut:litIndex; nextPut:nargs.
       
   596 	^ self
       
   597     ].
       
   598     "need 16bit litIndex"
   489     receiver isSuper ifTrue:[
   599     receiver isSuper ifTrue:[
   490 	r := receiver value.
       
   491 	receiver isHere ifTrue:[
   600 	receiver isHere ifTrue:[
   492 	    class := receiver definingClass.
   601 	    code := #hereSendL
   493 	] ifFalse:[
   602 	] ifFalse:[
   494 	    class := receiver definingClass superclass.
   603 	    code := #superSendL.
   495 	].
   604 	].
   496 	argArray notNil ifTrue:[
   605 	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:nil; nextPut:#drop.
   497 	    argValueArray := argArray collect:[:arg | arg evaluate].
   606 	^ self
   498 	] ifFalse:[
   607     ].
   499 	    argValueArray := #()
   608     aStream nextPut:#sendDropL; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs
   500 	].
   609 !
   501 	^ r perform:selector inClass:class withArguments:argValueArray
       
   502     ].
       
   503 
       
   504 
       
   505     argArray isNil ifTrue:[
       
   506 	^ (receiver evaluate) perform:selector
       
   507     ].
       
   508     nargs := argArray size.
       
   509     (nargs == 1) ifTrue:[
       
   510 	^ (receiver evaluate) perform:selector with:(argArray at:1) evaluate
       
   511     ].
       
   512     (nargs == 2) ifTrue:[
       
   513 	^ (receiver evaluate) perform:selector
       
   514 				 with:(argArray at:1) evaluate
       
   515 				 with:(argArray at:2) evaluate
       
   516     ].
       
   517     (nargs == 3) ifTrue:[
       
   518 	^ (receiver evaluate) perform:selector
       
   519 				 with:(argArray at:1) evaluate
       
   520 				 with:(argArray at:2) evaluate
       
   521 				 with:(argArray at:3) evaluate
       
   522     ].
       
   523     r := receiver evaluate.
       
   524     argValueArray := argArray collect:[:arg | arg evaluate].
       
   525     ^ r perform:selector withArguments:argValueArray
       
   526 !
       
   527 
       
   528 evaluateForCascade
       
   529     |r nargs argValueArray class|
       
   530 
       
   531     receiver isSuper ifTrue:[
       
   532 	r := receiver value.
       
   533 	class := receiver definingClass.
       
   534 	receiver isHere ifFalse:[
       
   535 	    class := class superclass.
       
   536 	].
       
   537 	argArray notNil ifTrue:[
       
   538 	    argValueArray := argArray collect:[:arg | arg evaluate].
       
   539 	] ifFalse:[
       
   540 	    argValueArray := #()
       
   541 	].
       
   542 	r perform:selector inClass:class withArguments:argValueArray.
       
   543 	^ r
       
   544     ].
       
   545 
       
   546     r := receiver evaluate.
       
   547     argArray isNil ifTrue:[
       
   548 	r perform:selector.
       
   549 	^ r
       
   550     ].
       
   551     nargs := argArray size.
       
   552     (nargs == 1) ifTrue:[
       
   553 	r perform:selector with:(argArray at:1) evaluate.
       
   554 	^ r
       
   555     ].
       
   556     (nargs == 2) ifTrue:[
       
   557 	r perform:selector with:(argArray at:1) evaluate
       
   558 			   with:(argArray at:2) evaluate.
       
   559 	^ r
       
   560     ].
       
   561     (nargs == 3) ifTrue:[
       
   562 	r perform:selector with:(argArray at:1) evaluate
       
   563 			   with:(argArray at:2) evaluate
       
   564 			   with:(argArray at:3) evaluate.
       
   565 	^ r
       
   566     ].
       
   567     argValueArray := argArray collect:[:arg | arg evaluate].
       
   568     r perform:selector withArguments:argValueArray.
       
   569     ^ r
       
   570 ! !
       
   571 
       
   572 !MessageNode methodsFor:'code generation'!
       
   573 
   610 
   574 codeForSideEffectOn:aStream inBlock:b for:aCompiler
   611 codeForSideEffectOn:aStream inBlock:b for:aCompiler
   575     self codeOn:aStream inBlock:b valueNeeded:false for:aCompiler
   612     self codeOn:aStream inBlock:b valueNeeded:false for:aCompiler
   576 !
   613 !
   577 
   614 
       
   615 codeIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
   616     "generate code for x ifxxx:[ ... ] yyy:[ ...]"
       
   617 
       
   618     |pos pos2 theReceiver theArg theByteCode optByteCode subsel code|
       
   619 
       
   620     theReceiver := receiver.
       
   621 
       
   622 "
       
   623     (theReceiver isMessage) ifTrue:[
       
   624 	subsel := theReceiver selector.
       
   625 	(subsel == #and:) ifTrue:[
       
   626 	    self codeAndIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   627 	    ^ self
       
   628 	].
       
   629 	(subsel == #or:) ifTrue:[
       
   630 	    self codeOrIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   631 	    ^ self
       
   632 	]
       
   633     ].
       
   634 "
       
   635     (selector == #ifTrue:ifFalse:) ifTrue:[
       
   636 	theByteCode := #falseJump
       
   637     ] ifFalse:[
       
   638 	(selector == #ifFalse:ifTrue:) ifTrue:[
       
   639 	    theByteCode := #trueJump
       
   640 	]
       
   641     ].
       
   642     optByteCode := self optimizedConditionFor:theReceiver
       
   643 					 with:theByteCode.
       
   644     optByteCode notNil ifTrue:[
       
   645 	((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
       
   646 	    theArg := theReceiver arg1
       
   647 	].
       
   648 	theReceiver := theReceiver receiver.
       
   649 	theByteCode := optByteCode
       
   650     ].
       
   651     theByteCode notNil ifTrue:[
       
   652 	theReceiver codeOn:aStream inBlock:b for:aCompiler.
       
   653 	theArg notNil ifTrue:[
       
   654 	    theArg codeOn:aStream inBlock:b for:aCompiler
       
   655 	].
       
   656 
       
   657 	(lineNr between:1 and:255) ifTrue:[
       
   658 	    aStream nextPut:#lineno; nextPut:lineNr.
       
   659 	].
       
   660 
       
   661 	aStream nextPut:theByteCode.
       
   662 	pos := aStream position.
       
   663 	aStream nextPut:0.
       
   664 	(argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   665 	aStream nextPut:#jump.
       
   666 	pos2 := aStream position.
       
   667 	aStream nextPut:0.
       
   668 	code := aStream contents.
       
   669 	code at:pos put:(aStream position).
       
   670 	(argArray at:2) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   671 	code at:pos2 put:(aStream position)
       
   672     ]
       
   673 !
       
   674 
       
   675 codeIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
   676     "generate code for x ifxxx:[ ... ]"
       
   677 
       
   678     |pos pos2 theReceiver theArg theByteCode optByteCode subsel code
       
   679      needLineNr|
       
   680 
       
   681     theReceiver := receiver.
       
   682 
       
   683     (theReceiver isMessage) ifTrue:[
       
   684 	subsel := theReceiver selector.
       
   685 	(subsel == #and:) ifTrue:[
       
   686 	    self codeAndIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   687 	    ^ self
       
   688 	].
       
   689 	(subsel == #or:) ifTrue:[
       
   690 	    self codeOrIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   691 	    ^ self
       
   692 	]
       
   693     ].
       
   694     (selector == #ifTrue:) ifTrue:[
       
   695 	theByteCode := #falseJump
       
   696     ] ifFalse:[
       
   697 	theByteCode := #trueJump
       
   698     ].
       
   699     optByteCode := self optimizedConditionFor:theReceiver
       
   700 					 with:theByteCode.
       
   701     optByteCode notNil ifTrue:[
       
   702 	((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
       
   703 	    theArg := theReceiver arg1
       
   704 	].
       
   705 	theReceiver := theReceiver receiver.
       
   706 	theByteCode := optByteCode
       
   707     ].
       
   708 
       
   709     theReceiver codeOn:aStream inBlock:b for:aCompiler.
       
   710     theArg notNil ifTrue:[
       
   711 	theArg codeOn:aStream inBlock:b for:aCompiler
       
   712     ].
       
   713 
       
   714     needLineNr := true.
       
   715     theArg isNil ifTrue:[
       
   716 	theReceiver isMessage ifTrue:[
       
   717 	    (self class hasLineNumber:(theReceiver selector)) ifTrue:[
       
   718 		theReceiver lineNumber == lineNr ifTrue:[
       
   719 		    needLineNr := false
       
   720 		]
       
   721 	    ]
       
   722 	]
       
   723     ].
       
   724 
       
   725     needLineNr ifTrue:[
       
   726 	(lineNr between:1 and:255) ifTrue:[
       
   727 	    aStream nextPut:#lineno; nextPut:lineNr.
       
   728 	]
       
   729     ].
       
   730 
       
   731     aStream nextPut:theByteCode.
       
   732     pos := aStream position.
       
   733     aStream nextPut:0.
       
   734     (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   735 
       
   736     code := aStream contents.
       
   737     valueNeeded ifTrue:[
       
   738 	aStream nextPut:#jump.
       
   739 	pos2 := aStream position.
       
   740 	aStream nextPut:0.
       
   741 	code at:pos put:(aStream position).
       
   742 	aStream nextPut:#pushNil.
       
   743 	code at:pos2 put:(aStream position)
       
   744     ] ifFalse:[
       
   745 	code at:pos put:(aStream position)
       
   746     ]
       
   747 !
       
   748 
   578 codeOn:aStream inBlock:b for:aCompiler
   749 codeOn:aStream inBlock:b for:aCompiler
   579     self codeOn:aStream inBlock:b valueNeeded:true for:aCompiler
   750     self codeOn:aStream inBlock:b valueNeeded:true for:aCompiler
       
   751 !
       
   752 
       
   753 codeOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
   754     |recType nargs isBuiltIn litIndex cls clsLitIndex code|
       
   755 
       
   756     argArray isNil ifTrue:[
       
   757 	nargs := 0
       
   758     ] ifFalse:[
       
   759 	nargs := argArray size
       
   760     ].
       
   761 
       
   762     isBuiltIn := false.
       
   763     recType := receiver type.
       
   764 
       
   765     (nargs == 0) ifTrue:[
       
   766 	(recType == #ThisContext) ifTrue:[
       
   767 	    valueNeeded ifFalse:[
       
   768 		"for now, only do it in methods"
       
   769 		b isNil ifTrue:[
       
   770 		    (selector == #restart) ifTrue:[
       
   771 			aStream nextPut:#jump; nextPut:1.      "jump to start"
       
   772 			^ self
       
   773 		    ].
       
   774 		].
       
   775 		(selector == #return) ifTrue:[  "^ nil"
       
   776 		    aStream nextPut:#retNil.
       
   777 		    ^ self
       
   778 		].
       
   779 	    ]
       
   780 	].
       
   781 
       
   782 	receiver isBlock ifTrue:[
       
   783 	    selector == #value ifTrue:[
       
   784 		receiver codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   785 		^ self
       
   786 	    ].
       
   787 	].
       
   788 	isBuiltIn := self class isBuiltInUnarySelector:selector
       
   789     ].
       
   790 
       
   791     (nargs == 1) ifTrue:[
       
   792 	(recType == #ThisContext) ifTrue:[
       
   793 	    valueNeeded ifFalse:[
       
   794 		(selector == #return:) ifTrue:[
       
   795 		    (argArray at:1) codeOn:aStream inBlock:b for:aCompiler.  "^ value"
       
   796 		    aStream nextPut:#retTop.
       
   797 		    ^ self
       
   798 		].
       
   799 	     ].
       
   800 	].
       
   801 
       
   802 	((argArray at:1) isBlock) ifTrue:[
       
   803 	    ((selector == #ifTrue:) or:[selector == #ifFalse:]) ifTrue:[
       
   804 		receiver isBlock ifFalse:[
       
   805 		    self codeIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   806 		    ^ self
       
   807 		].
       
   808 	    ].
       
   809 "
       
   810 	    ((selector == #and:) or:[selector == #or:]) ifTrue:[
       
   811 		self codeAndOrOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   812 		^ self
       
   813 	    ].
       
   814 "
       
   815 	    (selector == #timesRepeat:) ifTrue:[
       
   816 		(receiver isConstant and:[receiver evaluate isNumber]) ifTrue:[
       
   817 		    self codeTimesRepeatOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   818 		    ^ self
       
   819 		]
       
   820 	    ].
       
   821 
       
   822 	    ((selector == #whileTrue:) or:[selector == #whileFalse:]) ifTrue:[
       
   823 		(receiver isBlock) ifTrue:[
       
   824 		    self codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   825 		    ^ self
       
   826 		]
       
   827 	    ]
       
   828 	].
       
   829 	isBuiltIn := self class isBuiltIn1ArgSelector:selector
       
   830     ].
       
   831 
       
   832     (nargs == 2) ifTrue:[
       
   833 	((selector == #ifTrue:ifFalse:) or:[selector == #ifFalse:ifTrue:]) ifTrue:[
       
   834 	    receiver isBlock ifFalse:[
       
   835 		(argArray at:1) isBlock ifTrue:[
       
   836 		    (argArray at:2) isBlock ifTrue:[
       
   837 			self codeIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   838 			^ self
       
   839 		    ]
       
   840 		]
       
   841 	    ]
       
   842 	].
       
   843 	isBuiltIn := self class isBuiltIn2ArgSelector:selector
       
   844     ].
       
   845 
       
   846     "can we use a send-bytecode ?"
       
   847     isBuiltIn ifTrue:[
       
   848 	receiver isSuper ifFalse:[
       
   849 	    receiver codeOn:aStream inBlock:b for:aCompiler.
       
   850 	    (nargs > 0) ifTrue:[
       
   851 		(argArray at:1) codeOn:aStream inBlock:b for:aCompiler.
       
   852 		(nargs > 1) ifTrue:[
       
   853 		    (argArray at:2) codeOn:aStream inBlock:b for:aCompiler
       
   854 		]
       
   855 	    ].
       
   856 	    aStream nextPut:selector.
       
   857 	    (self class hasLineNumber:selector) ifTrue:[
       
   858 		aStream nextPut:lineNr.
       
   859 	    ].
       
   860 	    valueNeeded ifFalse:[
       
   861 		aStream nextPut:#drop
       
   862 	    ].
       
   863 	    ^ self
       
   864 	]
       
   865     ].
       
   866 
       
   867     ((nargs == 0) and:[selector == #yourself]) ifTrue:[
       
   868 	"yourself is often added to get the receiver -
       
   869 	 we get it without the yourself-message"
       
   870 
       
   871 	valueNeeded ifTrue:[
       
   872 	    receiver codeOn:aStream inBlock:b for:aCompiler
       
   873 	].
       
   874 	^ self
       
   875     ].
       
   876 
       
   877     "no - generate a send"
       
   878 
       
   879     receiver isSuper ifTrue:[
       
   880 	cls := aCompiler targetClass.
       
   881 	receiver isHere ifTrue:[
       
   882 	    code := #hereSend.
       
   883 	] ifFalse:[
       
   884 	    code := #superSend.
       
   885 	    cls := cls superclass.
       
   886 	].
       
   887 	clsLitIndex := aCompiler addLiteral:cls.
       
   888     ] ifFalse:[
       
   889 	clsLitIndex := 0.
       
   890     ].
       
   891 
       
   892     litIndex := aCompiler addLiteral:selector.
       
   893     (litIndex <= 255 and:[clsLitIndex <= 255]) ifTrue:[
       
   894 	(recType ~~ #Self) ifTrue:[
       
   895 	    receiver codeOn:aStream inBlock:b for:aCompiler
       
   896 	].
       
   897 	argArray notNil ifTrue:[
       
   898 	    argArray do:[:arg |
       
   899 		arg codeOn:aStream inBlock:b for:aCompiler
       
   900 	    ]
       
   901 	].
       
   902 
       
   903 	receiver isSuper ifTrue:[
       
   904 	    aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:clsLitIndex.
       
   905 	    valueNeeded ifFalse:[
       
   906 		aStream nextPut:#drop
       
   907 	    ].
       
   908 	    ^ self
       
   909 	].
       
   910 
       
   911 	(nargs <= 3) ifTrue:[
       
   912 	    |codes|
       
   913 
       
   914 	    valueNeeded ifTrue:[
       
   915 		(receiver type == #Self) ifTrue:[
       
   916 		    codes := #(sendSelf0 sendSelf1 sendSelf2 sendSelf3)
       
   917 		] ifFalse:[
       
   918 		    codes := #(send0 send1 send2 send3)
       
   919 		]
       
   920 	    ] ifFalse:[
       
   921 		(receiver type == #Self) ifTrue:[
       
   922 		    codes := #(sendSelfDrop0 sendSelfDrop1 sendSelfDrop2 sendSelfDrop3)
       
   923 		] ifFalse:[
       
   924 		    codes := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3)
       
   925 		]
       
   926 	    ].
       
   927 	    aStream nextPut:(codes at:(nargs + 1)); nextPut:lineNr; nextPut:litIndex.
       
   928 	    ^ self
       
   929 	].
       
   930 
       
   931 	(recType == #Self) ifTrue:[
       
   932 	    code := #sendSelf
       
   933 	] ifFalse:[
       
   934 	    valueNeeded ifTrue:[
       
   935 		code := #send
       
   936 	    ] ifFalse:[
       
   937 		code := #sendDrop
       
   938 	    ]
       
   939 	].
       
   940 	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs.
       
   941 	valueNeeded ifFalse:[
       
   942 	    (recType == #Self) ifTrue:[
       
   943 		aStream nextPut:#drop
       
   944 	    ]
       
   945 	].
       
   946 	^ self
       
   947     ].
       
   948 
       
   949     "needs 16bit literal index"
       
   950 
       
   951     receiver isSuper ifTrue:[
       
   952 	argArray notNil ifTrue:[
       
   953 	    argArray do:[:arg |
       
   954 		arg codeOn:aStream inBlock:b for:aCompiler
       
   955 	    ]
       
   956 	].
       
   957 	receiver isHere ifTrue:[
       
   958 	    code := #hereSendL
       
   959 	] ifFalse:[
       
   960 	    code := #superSendL.
       
   961 	].
       
   962 	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:clsLitIndex; nextPut:0.
       
   963     ] ifFalse:[
       
   964 	recType ~~ #Self ifTrue:[
       
   965 	    receiver codeOn:aStream inBlock:b for:aCompiler.
       
   966 	].
       
   967 	argArray notNil ifTrue:[
       
   968 	    argArray do:[:arg |
       
   969 		arg codeOn:aStream inBlock:b for:aCompiler
       
   970 	    ]
       
   971 	].
       
   972 
       
   973 	recType == #Self ifTrue:[
       
   974 	    code := #sendSelfL
       
   975 	] ifFalse:[
       
   976 	    code := #sendL
       
   977 	].
       
   978 	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs.
       
   979     ].
       
   980     valueNeeded ifFalse:[
       
   981 	aStream nextPut:#drop
       
   982     ].
       
   983 
       
   984     "Modified: 3.9.1995 / 12:55:42 / claus"
       
   985 !
       
   986 
       
   987 codeOrIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
   988     "generate code for (x or:[y]) ifxxx:[ ... ]"
       
   989 
       
   990     |theByteCode optByteCode theReceiver theArg pos1 pos2 pos3 code here jmp|
       
   991 
       
   992     theByteCode := #trueJump.
       
   993     theReceiver := receiver receiver.
       
   994 
       
   995     optByteCode := self optimizedConditionFor:theReceiver with:theByteCode.
       
   996     optByteCode notNil ifTrue:[
       
   997 	((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
       
   998 	    theArg := theReceiver arg1
       
   999 	].
       
  1000 	theReceiver := theReceiver receiver.
       
  1001 	theByteCode := optByteCode
       
  1002     ].
       
  1003     theReceiver codeOn:aStream inBlock:b for:aCompiler.
       
  1004     theArg notNil ifTrue:[
       
  1005 	theArg codeOn:aStream inBlock:b for:aCompiler
       
  1006     ].
       
  1007     aStream nextPut:theByteCode.
       
  1008     pos1 := aStream position.
       
  1009     aStream nextPut:0.
       
  1010 
       
  1011 
       
  1012     theReceiver := receiver arg1.
       
  1013 
       
  1014 "new:"
       
  1015     (selector == #ifTrue:) ifTrue:[
       
  1016 	theByteCode := #falseJump
       
  1017     ] ifFalse:[
       
  1018 	theByteCode := #trueJump
       
  1019     ].
       
  1020     optByteCode := self optimizedConditionFor:theReceiver with:theByteCode.
       
  1021     optByteCode notNil ifTrue:[
       
  1022 	theReceiver isBlock ifTrue:[
       
  1023 	    theReceiver := theReceiver statements expression
       
  1024 	].
       
  1025 	((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
       
  1026 	    theArg := theReceiver arg1
       
  1027 	].
       
  1028 	theReceiver := theReceiver receiver.
       
  1029 	theByteCode := optByteCode.
       
  1030 
       
  1031 	theReceiver codeOn:aStream inBlock:b for:aCompiler.
       
  1032 	theArg notNil ifTrue:[
       
  1033 	    theArg codeOn:aStream inBlock:b for:aCompiler
       
  1034 	].
       
  1035 	aStream nextPut:theByteCode.
       
  1036 
       
  1037     ] ifFalse:[
       
  1038 "org"
       
  1039 	theReceiver codeInlineOn:aStream inBlock:b for:aCompiler.
       
  1040 	(selector == #ifTrue:) ifTrue:[
       
  1041 	    jmp := #falseJump
       
  1042 	] ifFalse:[
       
  1043 	    jmp := #trueJump
       
  1044 	].
       
  1045 	aStream nextPut:jmp
       
  1046     ].
       
  1047     pos2 := aStream position.
       
  1048     aStream nextPut:0.
       
  1049     (selector == #ifTrue:) ifTrue:[
       
  1050 	(aStream contents) at:pos1 put:(aStream position)
       
  1051     ].
       
  1052     (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
  1053 
       
  1054     code := aStream contents.
       
  1055     valueNeeded ifTrue:[
       
  1056 	aStream nextPut:#jump.
       
  1057 	pos3 := aStream position.
       
  1058 	aStream nextPut:0.
       
  1059 	here := aStream position.
       
  1060 	(selector == #ifFalse:) ifTrue:[
       
  1061 	    code at:pos1 put:here
       
  1062 	].
       
  1063 	code at:pos2 put:here.
       
  1064 	aStream nextPut:#pushNil.
       
  1065 	code at:pos3 put:(aStream position)
       
  1066     ] ifFalse:[
       
  1067 	here := aStream position.
       
  1068 	(selector == #ifFalse:) ifTrue:[
       
  1069 	    code at:pos1 put:here
       
  1070 	].
       
  1071 	code at:pos2 put:here
       
  1072     ]
       
  1073 !
       
  1074 
       
  1075 codeSendOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
  1076     "like code on, but assumes that receiver has already been
       
  1077      coded onto stack - needed for cascade"
       
  1078 
       
  1079     |nargs isBuiltIn code litIndex|
       
  1080 
       
  1081     argArray isNil ifTrue:[
       
  1082 	nargs := 0
       
  1083     ] ifFalse:[
       
  1084 	nargs := argArray size
       
  1085     ].
       
  1086 
       
  1087     isBuiltIn := false.
       
  1088 
       
  1089     (nargs == 0) ifTrue:[
       
  1090 	isBuiltIn := self class isBuiltInUnarySelector:selector
       
  1091     ].
       
  1092     (nargs == 1) ifTrue:[
       
  1093 	isBuiltIn := self class isBuiltIn1ArgSelector:selector
       
  1094     ].
       
  1095     (nargs == 2) ifTrue:[
       
  1096 	isBuiltIn := self class isBuiltIn2ArgSelector:selector
       
  1097     ].
       
  1098 
       
  1099     "can we use a send-bytecode ?"
       
  1100     isBuiltIn ifTrue:[
       
  1101 	receiver isSuper ifFalse:[
       
  1102 	    (nargs > 0) ifTrue:[
       
  1103 		(argArray at:1) codeOn:aStream inBlock:b for:aCompiler.
       
  1104 		(nargs > 1) ifTrue:[
       
  1105 		    (argArray at:2) codeOn:aStream inBlock:b for:aCompiler
       
  1106 		]
       
  1107 	    ].
       
  1108 	    aStream nextPut:selector.
       
  1109 	    (self class hasLineNumber:selector) ifTrue:[
       
  1110 		aStream nextPut:lineNr.
       
  1111 	    ].
       
  1112 	    valueNeeded ifFalse:[
       
  1113 		aStream nextPut:#drop
       
  1114 	    ].
       
  1115 	    ^ self
       
  1116 	]
       
  1117     ].
       
  1118 
       
  1119     argArray notNil ifTrue:[
       
  1120 	argArray do:[:arg |
       
  1121 	    arg codeOn:aStream inBlock:b for:aCompiler
       
  1122 	]
       
  1123     ].
       
  1124 
       
  1125     receiver isSuper ifTrue:[
       
  1126 	litIndex := aCompiler addLiteral:selector.
       
  1127 	litIndex <= 255 ifTrue:[
       
  1128 	    receiver isHere ifTrue:[
       
  1129 		code := #hereSend
       
  1130 	    ] ifFalse:[
       
  1131 		code := #superSend.
       
  1132 	    ].
       
  1133 	    aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:nil.
       
  1134 	] ifFalse:[
       
  1135 	    receiver isHere ifTrue:[
       
  1136 		code := #hereSendL
       
  1137 	    ] ifFalse:[
       
  1138 		code := #superSendL.
       
  1139 	    ].
       
  1140 	    aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:nil.
       
  1141 	].
       
  1142 	valueNeeded ifFalse:[
       
  1143 	    aStream nextPut:#drop
       
  1144 	].
       
  1145 	^ self
       
  1146     ].
       
  1147     (nargs == 0) ifTrue:[
       
  1148 	(selector == #yourself) ifTrue:[
       
  1149 	    "yourself is often added to get the receiver -
       
  1150 	     we get it without the yourself-message"
       
  1151 
       
  1152 	    valueNeeded ifFalse:[
       
  1153 		aStream nextPut:#drop
       
  1154 	    ].
       
  1155 	    ^ self
       
  1156 	].
       
  1157     ].
       
  1158 
       
  1159     litIndex := aCompiler addLiteral:selector.
       
  1160     litIndex <= 255 ifTrue:[
       
  1161 	(nargs <= 3) ifTrue:[
       
  1162 	    valueNeeded ifTrue:[
       
  1163 		code := #(send0 send1 send2 send3) at:(nargs+1).
       
  1164 	    ] ifFalse:[
       
  1165 		code := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3) at:(nargs+1).
       
  1166 	    ].
       
  1167 	    aStream nextPut:code; nextPut:lineNr; nextPut:litIndex.
       
  1168 	    ^ self
       
  1169 	].
       
  1170 
       
  1171 	valueNeeded ifTrue:[
       
  1172 	    code := #send
       
  1173 	] ifFalse:[
       
  1174 	    code := #sendDrop
       
  1175 	].
       
  1176 	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs.
       
  1177 	^ self
       
  1178     ].
       
  1179 
       
  1180     valueNeeded ifTrue:[
       
  1181 	code := #sendL
       
  1182     ] ifFalse:[
       
  1183 	code := #sendDropL
       
  1184     ].
       
  1185     aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs
       
  1186 !
       
  1187 
       
  1188 codeTimesRepeatOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
  1189     "generate code for n timesRepeat:[ ... ]"
       
  1190 
       
  1191     |pos pos2 theReceiver|
       
  1192 
       
  1193     theReceiver := receiver.
       
  1194     theReceiver codeOn:aStream inBlock:b for:aCompiler.
       
  1195     valueNeeded ifTrue:[aStream nextPut:#dup].
       
  1196 
       
  1197     pos := aStream position.
       
  1198 "/    aStream nextPut:#dup; nextPut:#push0; nextPut:#>; nextPut:lineNr; nextPut:#falseJump.
       
  1199 "/    aStream nextPut:#dup; nextPut:#gt0; nextPut:lineNr; nextPut:#falseJump.
       
  1200     aStream nextPut:#pushgt0; nextPut:lineNr; nextPut:#falseJump.
       
  1201     pos2 := aStream position.
       
  1202     aStream nextPut:0.
       
  1203 
       
  1204     (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler.
       
  1205     aStream nextPut:#minus1; nextPut:lineNr; nextPut:#jump; nextPut:pos.
       
  1206 
       
  1207     (aStream contents) at:pos2 put:(aStream position).
       
  1208     aStream nextPut:#drop.
       
  1209 !
       
  1210 
       
  1211 codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
  1212     "generate code for [...] whilexxx:[ ... ]"
       
  1213 
       
  1214     |pos pos2 theReceiver theArg theByteCode optByteCode|
       
  1215 
       
  1216     (selector == #whileTrue:) ifTrue:[
       
  1217 	theByteCode := #falseJump
       
  1218     ] ifFalse:[
       
  1219 	theByteCode := #trueJump
       
  1220     ].
       
  1221 
       
  1222     theReceiver := receiver.
       
  1223     optByteCode := self optimizedConditionFor:theReceiver with:theByteCode.
       
  1224     optByteCode notNil ifTrue:[
       
  1225 	((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
       
  1226 	    theArg := receiver statements expression arg1
       
  1227 	].
       
  1228 	theReceiver := receiver statements expression receiver.
       
  1229 	theByteCode := optByteCode
       
  1230     ].
       
  1231 
       
  1232 "/ OLD:
       
  1233 "/    valueNeeded ifTrue:[aStream nextPut:#pushNil].
       
  1234 "/
       
  1235     pos := aStream position.
       
  1236     optByteCode notNil ifTrue:[
       
  1237 	theReceiver codeOn:aStream inBlock:b for:aCompiler.
       
  1238 	theArg notNil ifTrue:[
       
  1239 	    theArg codeOn:aStream inBlock:b for:aCompiler
       
  1240 	]
       
  1241     ] ifFalse:[
       
  1242 	theReceiver codeInlineOn:aStream inBlock:b for:aCompiler
       
  1243     ].
       
  1244 
       
  1245     (lineNr between:1 and:255) ifTrue:[
       
  1246 	aStream nextPut:#lineno; nextPut:lineNr.
       
  1247     ].
       
  1248 
       
  1249     aStream nextPut:theByteCode.
       
  1250     pos2 := aStream position.
       
  1251     aStream nextPut:0.
       
  1252 "/ OLD:
       
  1253 "/    valueNeeded ifTrue:[aStream nextPut:#drop].
       
  1254 "/
       
  1255 "/ OLD:
       
  1256 "/    (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
  1257 "/ NEW:
       
  1258     (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler.
       
  1259     aStream nextPut:#jump; nextPut:pos.
       
  1260     (aStream contents) at:pos2 put:(aStream position).
       
  1261 "/ NEW:
       
  1262     valueNeeded ifTrue:[aStream nextPut:#pushNil].
   580 !
  1263 !
   581 
  1264 
   582 optimizedConditionFor:aReceiver with:aByteCode
  1265 optimizedConditionFor:aReceiver with:aByteCode
   583     |rec sel|
  1266     |rec sel|
   584 
  1267 
   655 	    (aByteCode == #falseJump) ifTrue:[^ #eqJump].
  1338 	    (aByteCode == #falseJump) ifTrue:[^ #eqJump].
   656 	    (aByteCode == #trueJump) ifTrue:[^ #notEqJump]
  1339 	    (aByteCode == #trueJump) ifTrue:[^ #notEqJump]
   657 	]
  1340 	]
   658     ].
  1341     ].
   659     ^ nil
  1342     ^ nil
   660 !
  1343 ! !
   661 
  1344 
   662 codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
  1345 !MessageNode methodsFor:'evaluating'!
   663     "generate code for [...] whilexxx:[ ... ]"
  1346 
   664 
  1347 evaluate
   665     |pos pos2 theReceiver theArg theByteCode optByteCode|
  1348     |r nargs argValueArray class|
   666 
  1349 
   667     (selector == #whileTrue:) ifTrue:[
  1350     receiver isSuper ifTrue:[
   668 	theByteCode := #falseJump
  1351 	r := receiver value.
   669     ] ifFalse:[
  1352 	receiver isHere ifTrue:[
   670 	theByteCode := #trueJump
  1353 	    class := receiver definingClass.
   671     ].
  1354 	] ifFalse:[
   672 
  1355 	    class := receiver definingClass superclass.
   673     theReceiver := receiver.
  1356 	].
   674     optByteCode := self optimizedConditionFor:theReceiver with:theByteCode.
  1357 	argArray notNil ifTrue:[
   675     optByteCode notNil ifTrue:[
  1358 	    argValueArray := argArray collect:[:arg | arg evaluate].
   676 	((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
  1359 	] ifFalse:[
   677 	    theArg := receiver statements expression arg1
  1360 	    argValueArray := #()
   678 	].
  1361 	].
   679 	theReceiver := receiver statements expression receiver.
  1362 	^ r perform:selector inClass:class withArguments:argValueArray
   680 	theByteCode := optByteCode
  1363     ].
   681     ].
  1364 
   682 
  1365 
   683 "/ OLD:
  1366     argArray isNil ifTrue:[
   684 "/    valueNeeded ifTrue:[aStream nextPut:#pushNil].
  1367 	^ (receiver evaluate) perform:selector
   685 "/
  1368     ].
   686     pos := aStream position.
  1369     nargs := argArray size.
   687     optByteCode notNil ifTrue:[
  1370     (nargs == 1) ifTrue:[
   688 	theReceiver codeOn:aStream inBlock:b for:aCompiler.
  1371 	^ (receiver evaluate) perform:selector with:(argArray at:1) evaluate
   689 	theArg notNil ifTrue:[
  1372     ].
   690 	    theArg codeOn:aStream inBlock:b for:aCompiler
  1373     (nargs == 2) ifTrue:[
   691 	]
  1374 	^ (receiver evaluate) perform:selector
   692     ] ifFalse:[
  1375 				 with:(argArray at:1) evaluate
   693 	theReceiver codeInlineOn:aStream inBlock:b for:aCompiler
  1376 				 with:(argArray at:2) evaluate
   694     ].
  1377     ].
   695 
  1378     (nargs == 3) ifTrue:[
   696     (lineNr between:1 and:255) ifTrue:[
  1379 	^ (receiver evaluate) perform:selector
   697 	aStream nextPut:#lineno; nextPut:lineNr.
  1380 				 with:(argArray at:1) evaluate
   698     ].
  1381 				 with:(argArray at:2) evaluate
   699 
  1382 				 with:(argArray at:3) evaluate
   700     aStream nextPut:theByteCode.
  1383     ].
   701     pos2 := aStream position.
  1384     r := receiver evaluate.
   702     aStream nextPut:0.
  1385     argValueArray := argArray collect:[:arg | arg evaluate].
   703 "/ OLD:
  1386     ^ r perform:selector withArguments:argValueArray
   704 "/    valueNeeded ifTrue:[aStream nextPut:#drop].
  1387 !
   705 "/
  1388 
   706 "/ OLD:
  1389 evaluateForCascade
   707 "/    (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
  1390     |r nargs argValueArray class|
   708 "/ NEW:
  1391 
   709     (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler.
  1392     receiver isSuper ifTrue:[
   710     aStream nextPut:#jump; nextPut:pos.
  1393 	r := receiver value.
   711     (aStream contents) at:pos2 put:(aStream position).
  1394 	class := receiver definingClass.
   712 "/ NEW:
  1395 	receiver isHere ifFalse:[
   713     valueNeeded ifTrue:[aStream nextPut:#pushNil].
  1396 	    class := class superclass.
   714 !
  1397 	].
   715 
  1398 	argArray notNil ifTrue:[
   716 XXcodeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
  1399 	    argValueArray := argArray collect:[:arg | arg evaluate].
   717     "generate code for [...] whilexxx:[ ... ]"
  1400 	] ifFalse:[
   718 
  1401 	    argValueArray := #()
   719     |pos pos2 theReceiver theArg theByteCode optByteCode|
  1402 	].
   720 
  1403 	r perform:selector inClass:class withArguments:argValueArray.
   721     (selector == #whileTrue:) ifTrue:[
  1404 	^ r
   722 	theByteCode := #falseJump
  1405     ].
   723     ] ifFalse:[
  1406 
   724 	theByteCode := #trueJump
  1407     r := receiver evaluate.
   725     ].
  1408     argArray isNil ifTrue:[
   726 
  1409 	r perform:selector.
   727     theReceiver := receiver.
  1410 	^ r
   728     optByteCode := self optimizedConditionFor:theReceiver with:theByteCode.
  1411     ].
   729     optByteCode notNil ifTrue:[
  1412     nargs := argArray size.
   730 	((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
  1413     (nargs == 1) ifTrue:[
   731 	    theArg := receiver statements expression arg1
  1414 	r perform:selector with:(argArray at:1) evaluate.
   732 	].
  1415 	^ r
   733 	theReceiver := receiver statements expression receiver.
  1416     ].
   734 	theByteCode := optByteCode
  1417     (nargs == 2) ifTrue:[
   735     ].
  1418 	r perform:selector with:(argArray at:1) evaluate
   736 
  1419 			   with:(argArray at:2) evaluate.
   737     valueNeeded ifTrue:[aStream nextPut:#pushNil].
  1420 	^ r
   738     pos := aStream position.
  1421     ].
   739     optByteCode notNil ifTrue:[
  1422     (nargs == 3) ifTrue:[
   740 	theReceiver codeOn:aStream inBlock:b for:aCompiler.
  1423 	r perform:selector with:(argArray at:1) evaluate
   741 	theArg notNil ifTrue:[
  1424 			   with:(argArray at:2) evaluate
   742 	    theArg codeOn:aStream inBlock:b for:aCompiler
  1425 			   with:(argArray at:3) evaluate.
   743 	]
  1426 	^ r
   744     ] ifFalse:[
  1427     ].
   745 	theReceiver codeInlineOn:aStream inBlock:b for:aCompiler
  1428     argValueArray := argArray collect:[:arg | arg evaluate].
   746     ].
  1429     r perform:selector withArguments:argValueArray.
   747 
  1430     ^ r
   748     (lineNr between:1 and:255) ifTrue:[
  1431 ! !
   749 	aStream nextPut:#lineno; nextPut:lineNr.
  1432 
   750     ].
  1433 !MessageNode methodsFor:'printing'!
   751 
  1434 
   752     aStream nextPut:theByteCode.
  1435 printOn:aStream indent:i
   753     pos2 := aStream position.
  1436     |needParen selectorParts index index2 arg|
   754     aStream nextPut:0.
  1437 
   755     valueNeeded ifTrue:[aStream nextPut:#drop].
  1438     (#(whileTrue: whileFalse:) includes:selector) ifTrue:[
   756     (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
  1439 	receiver isBlock ifTrue:[
   757     aStream nextPut:#jump; nextPut:pos.
  1440 	    ^ self printWhileOn:aStream indent:i
   758     (aStream contents) at:pos2 put:(aStream position).
  1441 	].
   759 !
  1442     ].
   760 
  1443 
   761 codeTimesRepeatOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
  1444     index := 1.
   762     "generate code for n timesRepeat:[ ... ]"
  1445     selectorParts := OrderedCollection new.
   763 
  1446     [index == 0] whileFalse:[
   764     |pos pos2 theReceiver|
  1447 	index2 := selector indexOf:$: startingAt:index.
   765 
  1448 	index2 ~~ 0 ifTrue:[
   766     theReceiver := receiver.
  1449 	    selectorParts add:(selector copyFrom:index to:index2).
   767     theReceiver codeOn:aStream inBlock:b for:aCompiler.
  1450 	    index2 := index2 + 1
   768     valueNeeded ifTrue:[aStream nextPut:#dup].
  1451 	].
   769 
  1452 	index := index2
   770     pos := aStream position.
  1453     ].
   771 "/    aStream nextPut:#dup; nextPut:#push0; nextPut:#>; nextPut:lineNr; nextPut:#falseJump.
  1454 
   772 "/    aStream nextPut:#dup; nextPut:#gt0; nextPut:lineNr; nextPut:#falseJump.
  1455     needParen := false.
   773     aStream nextPut:#pushgt0; nextPut:lineNr; nextPut:#falseJump.
  1456     receiver isMessage ifTrue:[
   774     pos2 := aStream position.
  1457 	receiver isUnaryMessage ifFalse:[
   775     aStream nextPut:0.
  1458 	    receiver isBinaryMessage ifFalse:[
   776 
  1459 		needParen := true
   777     (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler.
  1460 	    ].
   778     aStream nextPut:#minus1; nextPut:lineNr; nextPut:#jump; nextPut:pos.
  1461 	].
   779 
  1462     ].
   780     (aStream contents) at:pos2 put:(aStream position).
  1463     needParen ifTrue:[
   781     aStream nextPut:#drop.
  1464 	aStream nextPutAll:'('
   782 !
  1465     ].
   783 
  1466     receiver printOn:aStream indent:i.
   784 codeIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
  1467     needParen ifTrue:[
   785     "generate code for x ifxxx:[ ... ] yyy:[ ...]"
  1468 	aStream nextPutAll:')'
   786 
  1469     ].
   787     |pos pos2 theReceiver theArg theByteCode optByteCode subsel code|
  1470 
   788 
  1471     1 to:(argArray size) do:[:argIndex |
   789     theReceiver := receiver.
  1472 	aStream space.
   790 
  1473 	(selectorParts at:argIndex) printOn:aStream.
   791 "
  1474 	aStream space.
   792     (theReceiver isMessage) ifTrue:[
  1475 	arg := argArray at:argIndex.
   793 	subsel := theReceiver selector.
  1476 	needParen := false.
   794 	(subsel == #and:) ifTrue:[
  1477 	arg isMessage ifTrue:[
   795 	    self codeAndIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
  1478 	    arg isBinaryMessage ifFalse:[
   796 	    ^ self
  1479 		arg isUnaryMessage ifFalse:[
   797 	].
  1480 		    needParen := true
   798 	(subsel == #or:) ifTrue:[
  1481 		]
   799 	    self codeOrIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
  1482 	    ].
   800 	    ^ self
  1483 	].
   801 	]
  1484 	needParen ifTrue:[
   802     ].
  1485 	    aStream nextPutAll:'('
   803 "
  1486 	].
   804     (selector == #ifTrue:ifFalse:) ifTrue:[
  1487 	arg printOn:aStream indent:i.
   805 	theByteCode := #falseJump
  1488 	needParen ifTrue:[
   806     ] ifFalse:[
  1489 	    aStream nextPutAll:') '
   807 	(selector == #ifFalse:ifTrue:) ifTrue:[
  1490 	].
   808 	    theByteCode := #trueJump
       
   809 	]
       
   810     ].
       
   811     optByteCode := self optimizedConditionFor:theReceiver
       
   812 					 with:theByteCode.
       
   813     optByteCode notNil ifTrue:[
       
   814 	((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
       
   815 	    theArg := theReceiver arg1
       
   816 	].
       
   817 	theReceiver := theReceiver receiver.
       
   818 	theByteCode := optByteCode
       
   819     ].
       
   820     theByteCode notNil ifTrue:[
       
   821 	theReceiver codeOn:aStream inBlock:b for:aCompiler.
       
   822 	theArg notNil ifTrue:[
       
   823 	    theArg codeOn:aStream inBlock:b for:aCompiler
       
   824 	].
       
   825 
       
   826 	(lineNr between:1 and:255) ifTrue:[
       
   827 	    aStream nextPut:#lineno; nextPut:lineNr.
       
   828 	].
       
   829 
       
   830 	aStream nextPut:theByteCode.
       
   831 	pos := aStream position.
       
   832 	aStream nextPut:0.
       
   833 	(argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   834 	aStream nextPut:#jump.
       
   835 	pos2 := aStream position.
       
   836 	aStream nextPut:0.
       
   837 	code := aStream contents.
       
   838 	code at:pos put:(aStream position).
       
   839 	(argArray at:2) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   840 	code at:pos2 put:(aStream position)
       
   841     ]
  1491     ]
   842 !
  1492 !
   843 
  1493 
   844 codeIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
  1494 printWhileOn:aStream indent:i
   845     "generate code for x ifxxx:[ ... ]"
  1495     |needParen arg|
   846 
  1496 
   847     |pos pos2 theReceiver theArg theByteCode optByteCode subsel code
  1497     "special handling of whileTrue/whileFalse"
   848      needLineNr|
  1498 
   849 
  1499     aStream nextPutAll:'['.
   850     theReceiver := receiver.
  1500     receiver statements printOn:aStream indent:i.
   851 
  1501     aStream nextPutAll:'] whileTrue: '.
   852     (theReceiver isMessage) ifTrue:[
  1502 
   853 	subsel := theReceiver selector.
  1503     arg := argArray at:1.
   854 	(subsel == #and:) ifTrue:[
  1504     needParen := false.
   855 	    self codeAndIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
  1505     arg isMessage ifTrue:[
   856 	    ^ self
  1506 	arg isBinaryMessage ifFalse:[
   857 	].
  1507 	    arg isUnaryMessage ifFalse:[
   858 	(subsel == #or:) ifTrue:[
  1508 		needParen := true
   859 	    self codeOrIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   860 	    ^ self
       
   861 	]
       
   862     ].
       
   863     (selector == #ifTrue:) ifTrue:[
       
   864 	theByteCode := #falseJump
       
   865     ] ifFalse:[
       
   866 	theByteCode := #trueJump
       
   867     ].
       
   868     optByteCode := self optimizedConditionFor:theReceiver
       
   869 					 with:theByteCode.
       
   870     optByteCode notNil ifTrue:[
       
   871 	((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
       
   872 	    theArg := theReceiver arg1
       
   873 	].
       
   874 	theReceiver := theReceiver receiver.
       
   875 	theByteCode := optByteCode
       
   876     ].
       
   877 
       
   878     theReceiver codeOn:aStream inBlock:b for:aCompiler.
       
   879     theArg notNil ifTrue:[
       
   880 	theArg codeOn:aStream inBlock:b for:aCompiler
       
   881     ].
       
   882 
       
   883     needLineNr := true.
       
   884     theArg isNil ifTrue:[
       
   885 	theReceiver isMessage ifTrue:[
       
   886 	    (self class hasLineNumber:(theReceiver selector)) ifTrue:[
       
   887 		theReceiver lineNumber == lineNr ifTrue:[
       
   888 		    needLineNr := false
       
   889 		]
       
   890 	    ]
  1509 	    ]
   891 	]
  1510 	].
   892     ].
  1511     ].
   893 
  1512     needParen ifTrue:[
   894     needLineNr ifTrue:[
  1513 	aStream nextPutAll:'('
   895 	(lineNr between:1 and:255) ifTrue:[
  1514     ].
   896 	    aStream nextPut:#lineno; nextPut:lineNr.
  1515     arg printOn:aStream indent:i.
   897 	]
  1516     needParen ifTrue:[
   898     ].
  1517 	aStream nextPutAll:') '
   899 
  1518     ].
   900     aStream nextPut:theByteCode.
       
   901     pos := aStream position.
       
   902     aStream nextPut:0.
       
   903     (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   904 
       
   905     code := aStream contents.
       
   906     valueNeeded ifTrue:[
       
   907 	aStream nextPut:#jump.
       
   908 	pos2 := aStream position.
       
   909 	aStream nextPut:0.
       
   910 	code at:pos put:(aStream position).
       
   911 	aStream nextPut:#pushNil.
       
   912 	code at:pos2 put:(aStream position)
       
   913     ] ifFalse:[
       
   914 	code at:pos put:(aStream position)
       
   915     ]
       
   916 !
       
   917 
       
   918 codeAndIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
   919     "generate code for (x and:[y]) ifxxx:[ ... ]"
       
   920 
       
   921     |theByteCode optByteCode theReceiver theArg pos1 pos2 pos3 code here jmp|
       
   922 
       
   923 
       
   924     theByteCode := #falseJump.
       
   925     theReceiver := receiver receiver.
       
   926 
       
   927     optByteCode := self optimizedConditionFor:theReceiver
       
   928 					 with:theByteCode.
       
   929     optByteCode notNil ifTrue:[
       
   930 	((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
       
   931 	    theArg := theReceiver arg1
       
   932 	].
       
   933 	theReceiver := theReceiver receiver.
       
   934 	theByteCode := optByteCode
       
   935     ].
       
   936     theReceiver codeOn:aStream inBlock:b for:aCompiler.
       
   937     theArg notNil ifTrue:[
       
   938 	theArg codeOn:aStream inBlock:b for:aCompiler
       
   939     ].
       
   940     aStream nextPut:theByteCode.
       
   941     pos1 := aStream position.
       
   942     aStream nextPut:0.
       
   943 
       
   944     theReceiver := receiver arg1.
       
   945     theReceiver codeInlineOn:aStream inBlock:b for:aCompiler.
       
   946     (selector == #ifTrue:) ifTrue:[
       
   947 	jmp := #falseJump
       
   948     ] ifFalse:[
       
   949 	jmp := #trueJump
       
   950     ].
       
   951     aStream nextPut:jmp.
       
   952     pos2 := aStream position.
       
   953     aStream nextPut:0.
       
   954 
       
   955     code := aStream contents.
       
   956     (selector == #ifFalse:) ifTrue:[
       
   957 	code at:pos1 put:(aStream position)
       
   958     ].
       
   959     (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
   960 
       
   961     valueNeeded ifTrue:[
       
   962 	aStream nextPut:#jump.
       
   963 	pos3 := aStream position.
       
   964 	aStream nextPut:0.
       
   965 	here := aStream position.
       
   966 	(selector == #ifTrue:) ifTrue:[
       
   967 	    code at:pos1 put:here
       
   968 	].
       
   969 	code at:pos2 put:here.
       
   970 	aStream nextPut:#pushNil.
       
   971 	code at:pos3 put:(aStream position)
       
   972     ] ifFalse:[
       
   973 	here := aStream position.
       
   974 	(selector == #ifTrue:) ifTrue:[
       
   975 	    code at:pos1 put:here
       
   976 	].
       
   977 	code at:pos2 put:here
       
   978     ]
       
   979 !
       
   980 
       
   981 codeOrIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
   982     "generate code for (x or:[y]) ifxxx:[ ... ]"
       
   983 
       
   984     |theByteCode optByteCode theReceiver theArg pos1 pos2 pos3 code here jmp|
       
   985 
       
   986     theByteCode := #trueJump.
       
   987     theReceiver := receiver receiver.
       
   988 
       
   989     optByteCode := self optimizedConditionFor:theReceiver with:theByteCode.
       
   990     optByteCode notNil ifTrue:[
       
   991 	((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
       
   992 	    theArg := theReceiver arg1
       
   993 	].
       
   994 	theReceiver := theReceiver receiver.
       
   995 	theByteCode := optByteCode
       
   996     ].
       
   997     theReceiver codeOn:aStream inBlock:b for:aCompiler.
       
   998     theArg notNil ifTrue:[
       
   999 	theArg codeOn:aStream inBlock:b for:aCompiler
       
  1000     ].
       
  1001     aStream nextPut:theByteCode.
       
  1002     pos1 := aStream position.
       
  1003     aStream nextPut:0.
       
  1004 
       
  1005 
       
  1006     theReceiver := receiver arg1.
       
  1007 
       
  1008 "new:"
       
  1009     (selector == #ifTrue:) ifTrue:[
       
  1010 	theByteCode := #falseJump
       
  1011     ] ifFalse:[
       
  1012 	theByteCode := #trueJump
       
  1013     ].
       
  1014     optByteCode := self optimizedConditionFor:theReceiver with:theByteCode.
       
  1015     optByteCode notNil ifTrue:[
       
  1016 	theReceiver isBlock ifTrue:[
       
  1017 	    theReceiver := theReceiver statements expression
       
  1018 	].
       
  1019 	((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
       
  1020 	    theArg := theReceiver arg1
       
  1021 	].
       
  1022 	theReceiver := theReceiver receiver.
       
  1023 	theByteCode := optByteCode.
       
  1024 
       
  1025 	theReceiver codeOn:aStream inBlock:b for:aCompiler.
       
  1026 	theArg notNil ifTrue:[
       
  1027 	    theArg codeOn:aStream inBlock:b for:aCompiler
       
  1028 	].
       
  1029 	aStream nextPut:theByteCode.
       
  1030 
       
  1031     ] ifFalse:[
       
  1032 "org"
       
  1033 	theReceiver codeInlineOn:aStream inBlock:b for:aCompiler.
       
  1034 	(selector == #ifTrue:) ifTrue:[
       
  1035 	    jmp := #falseJump
       
  1036 	] ifFalse:[
       
  1037 	    jmp := #trueJump
       
  1038 	].
       
  1039 	aStream nextPut:jmp
       
  1040     ].
       
  1041     pos2 := aStream position.
       
  1042     aStream nextPut:0.
       
  1043     (selector == #ifTrue:) ifTrue:[
       
  1044 	(aStream contents) at:pos1 put:(aStream position)
       
  1045     ].
       
  1046     (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
  1047 
       
  1048     code := aStream contents.
       
  1049     valueNeeded ifTrue:[
       
  1050 	aStream nextPut:#jump.
       
  1051 	pos3 := aStream position.
       
  1052 	aStream nextPut:0.
       
  1053 	here := aStream position.
       
  1054 	(selector == #ifFalse:) ifTrue:[
       
  1055 	    code at:pos1 put:here
       
  1056 	].
       
  1057 	code at:pos2 put:here.
       
  1058 	aStream nextPut:#pushNil.
       
  1059 	code at:pos3 put:(aStream position)
       
  1060     ] ifFalse:[
       
  1061 	here := aStream position.
       
  1062 	(selector == #ifFalse:) ifTrue:[
       
  1063 	    code at:pos1 put:here
       
  1064 	].
       
  1065 	code at:pos2 put:here
       
  1066     ]
       
  1067 !
       
  1068 
       
  1069 codeAndOrOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
  1070     "generate code for x and/or:[y] - but not in an if"
       
  1071 
       
  1072     |pos theReceiver theByteCode|
       
  1073 
       
  1074 self halt.
       
  1075     theReceiver := receiver.
       
  1076     (selector == #and:) ifTrue:[
       
  1077 	theByteCode := #falseJump
       
  1078     ] ifFalse:[
       
  1079 	theByteCode := #trueJump
       
  1080     ].
       
  1081 "
       
  1082     (self canOptimizeConditionFor:receiver) ifTrue:[
       
  1083 	theByteCode := self optimizedConditionFor:theReceiver
       
  1084 					     with:theByteCode.
       
  1085 	theReceiver := theReceiver receiver
       
  1086     ].
       
  1087 "
       
  1088     theReceiver codeOn:aStream inBlock:b for:aCompiler.
       
  1089     aStream nextPut:theByteCode.
       
  1090     pos := aStream position.
       
  1091     aStream nextPut:0.
       
  1092     (argArray at: 1) codeInlineOn:aStream inBlock:b for:aCompiler.
       
  1093     (aStream contents) at:pos put:(aStream position).
       
  1094     valueNeeded ifFalse:[aStream nextPut:#drop]
       
  1095 !
       
  1096 
       
  1097 codeOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
  1098     |recType nargs isBuiltIn litIndex cls clsLitIndex code|
       
  1099 
       
  1100     argArray isNil ifTrue:[
       
  1101 	nargs := 0
       
  1102     ] ifFalse:[
       
  1103 	nargs := argArray size
       
  1104     ].
       
  1105 
       
  1106     isBuiltIn := false.
       
  1107     recType := receiver type.
       
  1108 
       
  1109     (nargs == 0) ifTrue:[
       
  1110 	(recType == #ThisContext) ifTrue:[
       
  1111 	    valueNeeded ifFalse:[
       
  1112 		"for now, only do it in methods"
       
  1113 		b isNil ifTrue:[
       
  1114 		    (selector == #restart) ifTrue:[
       
  1115 			aStream nextPut:#jump; nextPut:1.      "jump to start"
       
  1116 			^ self
       
  1117 		    ].
       
  1118 		].
       
  1119 		(selector == #return) ifTrue:[  "^ nil"
       
  1120 		    aStream nextPut:#retNil.
       
  1121 		    ^ self
       
  1122 		].
       
  1123 	    ]
       
  1124 	].
       
  1125 
       
  1126 	receiver isBlock ifTrue:[
       
  1127 	    selector == #value ifTrue:[
       
  1128 		receiver codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
  1129 		^ self
       
  1130 	    ].
       
  1131 	].
       
  1132 	isBuiltIn := self class isBuiltInUnarySelector:selector
       
  1133     ].
       
  1134 
       
  1135     (nargs == 1) ifTrue:[
       
  1136 	(recType == #ThisContext) ifTrue:[
       
  1137 	    valueNeeded ifFalse:[
       
  1138 		(selector == #return:) ifTrue:[
       
  1139 		    (argArray at:1) codeOn:aStream inBlock:b for:aCompiler.  "^ value"
       
  1140 		    aStream nextPut:#retTop.
       
  1141 		    ^ self
       
  1142 		].
       
  1143 	     ].
       
  1144 	].
       
  1145 
       
  1146 	((argArray at:1) isBlock) ifTrue:[
       
  1147 	    ((selector == #ifTrue:) or:[selector == #ifFalse:]) ifTrue:[
       
  1148 		receiver isBlock ifFalse:[
       
  1149 		    self codeIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
  1150 		    ^ self
       
  1151 		].
       
  1152 	    ].
       
  1153 "
       
  1154 	    ((selector == #and:) or:[selector == #or:]) ifTrue:[
       
  1155 		self codeAndOrOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
  1156 		^ self
       
  1157 	    ].
       
  1158 "
       
  1159 	    (selector == #timesRepeat:) ifTrue:[
       
  1160 		(receiver isConstant and:[receiver evaluate isNumber]) ifTrue:[
       
  1161 		    self codeTimesRepeatOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
  1162 		    ^ self
       
  1163 		]
       
  1164 	    ].
       
  1165 
       
  1166 	    ((selector == #whileTrue:) or:[selector == #whileFalse:]) ifTrue:[
       
  1167 		(receiver isBlock) ifTrue:[
       
  1168 		    self codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
  1169 		    ^ self
       
  1170 		]
       
  1171 	    ]
       
  1172 	].
       
  1173 	isBuiltIn := self class isBuiltIn1ArgSelector:selector
       
  1174     ].
       
  1175 
       
  1176     (nargs == 2) ifTrue:[
       
  1177 	((selector == #ifTrue:ifFalse:) or:[selector == #ifFalse:ifTrue:]) ifTrue:[
       
  1178 	    receiver isBlock ifFalse:[
       
  1179 		(argArray at:1) isBlock ifTrue:[
       
  1180 		    (argArray at:2) isBlock ifTrue:[
       
  1181 			self codeIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
       
  1182 			^ self
       
  1183 		    ]
       
  1184 		]
       
  1185 	    ]
       
  1186 	].
       
  1187 	isBuiltIn := self class isBuiltIn2ArgSelector:selector
       
  1188     ].
       
  1189 
       
  1190     "can we use a send-bytecode ?"
       
  1191     isBuiltIn ifTrue:[
       
  1192 	receiver isSuper ifFalse:[
       
  1193 	    receiver codeOn:aStream inBlock:b for:aCompiler.
       
  1194 	    (nargs > 0) ifTrue:[
       
  1195 		(argArray at:1) codeOn:aStream inBlock:b for:aCompiler.
       
  1196 		(nargs > 1) ifTrue:[
       
  1197 		    (argArray at:2) codeOn:aStream inBlock:b for:aCompiler
       
  1198 		]
       
  1199 	    ].
       
  1200 	    aStream nextPut:selector.
       
  1201 	    (self class hasLineNumber:selector) ifTrue:[
       
  1202 		aStream nextPut:lineNr.
       
  1203 	    ].
       
  1204 	    valueNeeded ifFalse:[
       
  1205 		aStream nextPut:#drop
       
  1206 	    ].
       
  1207 	    ^ self
       
  1208 	]
       
  1209     ].
       
  1210 
       
  1211     ((nargs == 0) and:[selector == #yourself]) ifTrue:[
       
  1212 	"yourself is often added to get the receiver -
       
  1213 	 we get it without the yourself-message"
       
  1214 
       
  1215 	valueNeeded ifTrue:[
       
  1216 	    receiver codeOn:aStream inBlock:b for:aCompiler
       
  1217 	].
       
  1218 	^ self
       
  1219     ].
       
  1220 
       
  1221     "no - generate a send"
       
  1222 
       
  1223     receiver isSuper ifTrue:[
       
  1224 	cls := aCompiler targetClass.
       
  1225 	receiver isHere ifTrue:[
       
  1226 	    code := #hereSend.
       
  1227 	] ifFalse:[
       
  1228 	    code := #superSend.
       
  1229 	    cls := cls superclass.
       
  1230 	].
       
  1231 	clsLitIndex := aCompiler addLiteral:cls.
       
  1232     ] ifFalse:[
       
  1233 	clsLitIndex := 0.
       
  1234     ].
       
  1235 
       
  1236     litIndex := aCompiler addLiteral:selector.
       
  1237     (litIndex <= 255 and:[clsLitIndex <= 255]) ifTrue:[
       
  1238 	(recType ~~ #Self) ifTrue:[
       
  1239 	    receiver codeOn:aStream inBlock:b for:aCompiler
       
  1240 	].
       
  1241 	argArray notNil ifTrue:[
       
  1242 	    argArray do:[:arg |
       
  1243 		arg codeOn:aStream inBlock:b for:aCompiler
       
  1244 	    ]
       
  1245 	].
       
  1246 
       
  1247 	receiver isSuper ifTrue:[
       
  1248 	    aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:clsLitIndex.
       
  1249 	    valueNeeded ifFalse:[
       
  1250 		aStream nextPut:#drop
       
  1251 	    ].
       
  1252 	    ^ self
       
  1253 	].
       
  1254 
       
  1255 	(nargs <= 3) ifTrue:[
       
  1256 	    |codes|
       
  1257 
       
  1258 	    valueNeeded ifTrue:[
       
  1259 		(receiver type == #Self) ifTrue:[
       
  1260 		    codes := #(sendSelf0 sendSelf1 sendSelf2 sendSelf3)
       
  1261 		] ifFalse:[
       
  1262 		    codes := #(send0 send1 send2 send3)
       
  1263 		]
       
  1264 	    ] ifFalse:[
       
  1265 		(receiver type == #Self) ifTrue:[
       
  1266 		    codes := #(sendSelfDrop0 sendSelfDrop1 sendSelfDrop2 sendSelfDrop3)
       
  1267 		] ifFalse:[
       
  1268 		    codes := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3)
       
  1269 		]
       
  1270 	    ].
       
  1271 	    aStream nextPut:(codes at:(nargs + 1)); nextPut:lineNr; nextPut:litIndex.
       
  1272 	    ^ self
       
  1273 	].
       
  1274 
       
  1275 	(recType == #Self) ifTrue:[
       
  1276 	    code := #sendSelf
       
  1277 	] ifFalse:[
       
  1278 	    valueNeeded ifTrue:[
       
  1279 		code := #send
       
  1280 	    ] ifFalse:[
       
  1281 		code := #sendDrop
       
  1282 	    ]
       
  1283 	].
       
  1284 	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs.
       
  1285 	valueNeeded ifFalse:[
       
  1286 	    (recType == #Self) ifTrue:[
       
  1287 		aStream nextPut:#drop
       
  1288 	    ]
       
  1289 	].
       
  1290 	^ self
       
  1291     ].
       
  1292 
       
  1293     "needs 16bit literal index"
       
  1294 
       
  1295     receiver isSuper ifTrue:[
       
  1296 	argArray notNil ifTrue:[
       
  1297 	    argArray do:[:arg |
       
  1298 		arg codeOn:aStream inBlock:b for:aCompiler
       
  1299 	    ]
       
  1300 	].
       
  1301 	receiver isHere ifTrue:[
       
  1302 	    code := #hereSendL
       
  1303 	] ifFalse:[
       
  1304 	    code := #superSendL.
       
  1305 	].
       
  1306 	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:clsLitIndex; nextPut:0.
       
  1307     ] ifFalse:[
       
  1308 	recType ~~ #Self ifTrue:[
       
  1309 	    receiver codeOn:aStream inBlock:b for:aCompiler.
       
  1310 	].
       
  1311 	argArray notNil ifTrue:[
       
  1312 	    argArray do:[:arg |
       
  1313 		arg codeOn:aStream inBlock:b for:aCompiler
       
  1314 	    ]
       
  1315 	].
       
  1316 
       
  1317 	recType == #Self ifTrue:[
       
  1318 	    code := #sendSelfL
       
  1319 	] ifFalse:[
       
  1320 	    code := #sendL
       
  1321 	].
       
  1322 	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs.
       
  1323     ].
       
  1324     valueNeeded ifFalse:[
       
  1325 	aStream nextPut:#drop
       
  1326     ].
       
  1327 
       
  1328     "Modified: 3.9.1995 / 12:55:42 / claus"
       
  1329 !
       
  1330 
       
  1331 codeSendOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
       
  1332     "like code on, but assumes that receiver has already been
       
  1333      coded onto stack - needed for cascade"
       
  1334 
       
  1335     |nargs isBuiltIn code litIndex|
       
  1336 
       
  1337     argArray isNil ifTrue:[
       
  1338 	nargs := 0
       
  1339     ] ifFalse:[
       
  1340 	nargs := argArray size
       
  1341     ].
       
  1342 
       
  1343     isBuiltIn := false.
       
  1344 
       
  1345     (nargs == 0) ifTrue:[
       
  1346 	isBuiltIn := self class isBuiltInUnarySelector:selector
       
  1347     ].
       
  1348     (nargs == 1) ifTrue:[
       
  1349 	isBuiltIn := self class isBuiltIn1ArgSelector:selector
       
  1350     ].
       
  1351     (nargs == 2) ifTrue:[
       
  1352 	isBuiltIn := self class isBuiltIn2ArgSelector:selector
       
  1353     ].
       
  1354 
       
  1355     "can we use a send-bytecode ?"
       
  1356     isBuiltIn ifTrue:[
       
  1357 	receiver isSuper ifFalse:[
       
  1358 	    (nargs > 0) ifTrue:[
       
  1359 		(argArray at:1) codeOn:aStream inBlock:b for:aCompiler.
       
  1360 		(nargs > 1) ifTrue:[
       
  1361 		    (argArray at:2) codeOn:aStream inBlock:b for:aCompiler
       
  1362 		]
       
  1363 	    ].
       
  1364 	    aStream nextPut:selector.
       
  1365 	    (self class hasLineNumber:selector) ifTrue:[
       
  1366 		aStream nextPut:lineNr.
       
  1367 	    ].
       
  1368 	    valueNeeded ifFalse:[
       
  1369 		aStream nextPut:#drop
       
  1370 	    ].
       
  1371 	    ^ self
       
  1372 	]
       
  1373     ].
       
  1374 
       
  1375     argArray notNil ifTrue:[
       
  1376 	argArray do:[:arg |
       
  1377 	    arg codeOn:aStream inBlock:b for:aCompiler
       
  1378 	]
       
  1379     ].
       
  1380 
       
  1381     receiver isSuper ifTrue:[
       
  1382 	litIndex := aCompiler addLiteral:selector.
       
  1383 	litIndex <= 255 ifTrue:[
       
  1384 	    receiver isHere ifTrue:[
       
  1385 		code := #hereSend
       
  1386 	    ] ifFalse:[
       
  1387 		code := #superSend.
       
  1388 	    ].
       
  1389 	    aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:nil.
       
  1390 	] ifFalse:[
       
  1391 	    receiver isHere ifTrue:[
       
  1392 		code := #hereSendL
       
  1393 	    ] ifFalse:[
       
  1394 		code := #superSendL.
       
  1395 	    ].
       
  1396 	    aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:nil.
       
  1397 	].
       
  1398 	valueNeeded ifFalse:[
       
  1399 	    aStream nextPut:#drop
       
  1400 	].
       
  1401 	^ self
       
  1402     ].
       
  1403     (nargs == 0) ifTrue:[
       
  1404 	(selector == #yourself) ifTrue:[
       
  1405 	    "yourself is often added to get the receiver -
       
  1406 	     we get it without the yourself-message"
       
  1407 
       
  1408 	    valueNeeded ifFalse:[
       
  1409 		aStream nextPut:#drop
       
  1410 	    ].
       
  1411 	    ^ self
       
  1412 	].
       
  1413     ].
       
  1414 
       
  1415     litIndex := aCompiler addLiteral:selector.
       
  1416     litIndex <= 255 ifTrue:[
       
  1417 	(nargs <= 3) ifTrue:[
       
  1418 	    valueNeeded ifTrue:[
       
  1419 		code := #(send0 send1 send2 send3) at:(nargs+1).
       
  1420 	    ] ifFalse:[
       
  1421 		code := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3) at:(nargs+1).
       
  1422 	    ].
       
  1423 	    aStream nextPut:code; nextPut:lineNr; nextPut:litIndex.
       
  1424 	    ^ self
       
  1425 	].
       
  1426 
       
  1427 	valueNeeded ifTrue:[
       
  1428 	    code := #send
       
  1429 	] ifFalse:[
       
  1430 	    code := #sendDrop
       
  1431 	].
       
  1432 	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs.
       
  1433 	^ self
       
  1434     ].
       
  1435 
       
  1436     valueNeeded ifTrue:[
       
  1437 	code := #sendL
       
  1438     ] ifFalse:[
       
  1439 	code := #sendDropL
       
  1440     ].
       
  1441     aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs
       
  1442 !
       
  1443 
       
  1444 codeForCascadeOn:aStream inBlock:b for:aCompiler
       
  1445     "like codeOn, but always leave the receiver instead of the result"
       
  1446 
       
  1447     |nargs isBuiltIn code litIndex|
       
  1448 
       
  1449     argArray isNil ifTrue:[
       
  1450 	nargs := 0
       
  1451     ] ifFalse:[
       
  1452 	nargs := argArray size
       
  1453     ].
       
  1454 
       
  1455     isBuiltIn := false.
       
  1456 
       
  1457     (nargs == 0) ifTrue:[
       
  1458 	isBuiltIn := self class isBuiltInUnarySelector:selector
       
  1459     ].
       
  1460     (nargs == 1) ifTrue:[
       
  1461 	isBuiltIn := self class isBuiltIn1ArgSelector:selector
       
  1462     ].
       
  1463     (nargs == 2) ifTrue:[
       
  1464 	isBuiltIn := self class isBuiltIn2ArgSelector:selector
       
  1465     ].
       
  1466 
       
  1467     receiver codeOn:aStream inBlock:b for:aCompiler.
       
  1468     aStream nextPut:#dup.
       
  1469 
       
  1470     "can we use a send-bytecode ?"
       
  1471     isBuiltIn ifTrue:[
       
  1472 	receiver isSuper ifFalse:[
       
  1473 	    (nargs > 0) ifTrue:[
       
  1474 		(argArray at:1) codeOn:aStream inBlock:b for:aCompiler.
       
  1475 		(nargs > 1) ifTrue:[
       
  1476 		    (argArray at:2) codeOn:aStream inBlock:b for:aCompiler
       
  1477 		]
       
  1478 	    ].
       
  1479 	    aStream nextPut:selector.
       
  1480 	    (self class hasLineNumber:selector) ifTrue:[
       
  1481 		aStream nextPut:lineNr.
       
  1482 	    ].
       
  1483 	    aStream nextPut:#drop.
       
  1484 	    ^ self
       
  1485 	]
       
  1486     ].
       
  1487 
       
  1488     "no - generate a send"
       
  1489     argArray notNil ifTrue:[
       
  1490 	argArray do:[:arg |
       
  1491 	    arg codeOn:aStream inBlock:b for:aCompiler
       
  1492 	]
       
  1493     ].
       
  1494     litIndex := aCompiler addLiteral:selector.
       
  1495     litIndex <= 255 ifTrue:[
       
  1496 	receiver isSuper ifTrue:[
       
  1497 	    receiver isHere ifTrue:[
       
  1498 		code := #hereSend
       
  1499 	    ] ifFalse:[
       
  1500 		code := #superSend.
       
  1501 	    ].
       
  1502 	    aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:nil; nextPut:#drop.
       
  1503 	    ^ self
       
  1504 	].
       
  1505 	(nargs <= 3) ifTrue:[
       
  1506 	    code := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3) at:(nargs+1).
       
  1507 	    aStream nextPut:code; nextPut:lineNr; nextPut:litIndex.
       
  1508 	    ^ self
       
  1509 	].
       
  1510 
       
  1511 	aStream nextPut:#sendDrop; nextPut:lineNr; nextPut:litIndex; nextPut:nargs.
       
  1512 	^ self
       
  1513     ].
       
  1514     "need 16bit litIndex"
       
  1515     receiver isSuper ifTrue:[
       
  1516 	receiver isHere ifTrue:[
       
  1517 	    code := #hereSendL
       
  1518 	] ifFalse:[
       
  1519 	    code := #superSendL.
       
  1520 	].
       
  1521 	aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:nil; nextPut:#drop.
       
  1522 	^ self
       
  1523     ].
       
  1524     aStream nextPut:#sendDropL; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs
       
  1525 ! !
  1519 ! !
       
  1520 
       
  1521 !MessageNode methodsFor:'queries'!
       
  1522 
       
  1523 isMessage
       
  1524     ^ true
       
  1525 ! !
       
  1526