--- a/MessageNode.st Thu Jun 26 13:22:48 1997 +0200
+++ b/MessageNode.st Fri Jun 27 14:08:18 1997 +0200
@@ -762,7 +762,7 @@
codeOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
|recType nargs isBuiltIn litIndex cls clsLitIndex code isSpecial
- specialCode stackTop arg1 arg2|
+ specialCode stackTop arg1 arg2 arg3 okToInline|
argArray isNil ifTrue:[
nargs := 0
@@ -871,24 +871,40 @@
].
selector == #to:do: ifTrue:[
- (receiver isConstant
- and:[receiver type == #Integer]) ifTrue:[
- (arg1 isConstant
- and:[arg1 type == #Integer]) ifTrue:[
- receiver value <= arg1 value ifTrue:[
- arg2 isBlock ifTrue:[
- arg2 numArgs == 1 ifTrue:[
- ^ self codeToDoOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
- ]
- ].
- ]
- ]
+ okToInline := true.
+
+ (arg2 isBlock and:[arg2 numArgs == 1]) ifFalse:[
+ okToInline := false.
+ ].
+ okToInline ifTrue:[
+ ^ self codeToDoOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
]
].
isBuiltIn := aCompiler isBuiltIn2ArgSelector:selector forReceiver:receiver.
].
+ (nargs == 3) ifTrue:[
+ arg1 := argArray at:1.
+ arg2 := argArray at:2.
+ arg3 := argArray at:3.
+
+ selector == #to:by:do: ifTrue:[
+ okToInline := true.
+
+ (arg2 isConstant and:[arg2 type == #Integer]) ifFalse:[
+ "/ step must be a constant (need to know how to compare)
+ okToInline := false.
+ ].
+ (arg3 isBlock and:[arg3 numArgs == 1]) ifFalse:[
+ okToInline := false.
+ ].
+ okToInline ifTrue:[
+ ^ self codeToByDoOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
+ ]
+ ].
+ ].
+
isBuiltIn ifFalse:[
specialCode := aCompiler specialSendCodeFor:selector.
isSpecial := specialCode notNil.
@@ -1048,7 +1064,7 @@
].
"Modified: 3.9.1995 / 12:55:42 / claus"
- "Modified: 26.6.1997 / 13:22:08 / cg"
+ "Modified: 27.6.1997 / 13:41:41 / cg"
!
codeOrIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
@@ -1407,20 +1423,27 @@
"Modified: 27.5.1997 / 14:28:49 / cg"
!
-codeToDoOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
- "generate code for n to:n do:[:unusedArg | ... ]"
+codeToByDoOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
+ "generate code for a to:b by:c do:[:arg | ... ]"
- |pos pos2 start stop lateEval theBlock loopVarIndex|
+ |pos pos2 start stop step lateEval theBlock loopVarIndex
+ stepVal stopVarIndex|
- "/ NOTICE: could compile it as a timesRepeat, if
+ "/ NOTICE: could compile it as a timesRepeat-like loop, if
"/ the loop-counter is not accessed within the loop-block.
"/ This generates somewhat (15%) faster code, but makes
"/ debugging somewhat difficult (no loop-value seen in debugger).
start := receiver.
stop := (argArray at:1).
- stop isConstant ifFalse:[self halt:'should not happen'].
- (stop evaluate isMemberOf:SmallInteger) ifFalse:[self halt:'should not happen'].
+ step := (argArray at:2).
+
+"/ stop isConstant ifFalse:[self halt:'should not happen'].
+"/ (stop evaluate isMemberOf:SmallInteger) ifFalse:[self halt:'should not happen'].
+
+ step isConstant ifFalse:[self halt:'should not happen'].
+ stepVal := step evaluate.
+ (stepVal isMemberOf:SmallInteger) ifFalse:[self halt:'should not happen'].
start codeOn:aStream inBlock:b for:aCompiler.
@@ -1438,10 +1461,172 @@
].
].
+ "/ if stop is not constant, and not an argVar,
+ "/ evaluate it into a temp slot ...
+
+ (stop isConstant and:[stop type == #Integer]) ifFalse:[
+ "/ a method/blockArg is constant as well ...
+ (stop isVariable and:[stop isArgument]) ifFalse:[
+ stop codeOn:aStream inBlock:b for:aCompiler.
+
+ b isNil ifTrue:[
+ stopVarIndex := aCompiler addTempVar.
+ aStream nextPut:#storeMethodVar; nextPut:stopVarIndex.
+ ] ifFalse:[
+ stopVarIndex := b addTempVar.
+ aStream nextPut:#storeBlockVar; nextPut:stopVarIndex.
+ ].
+ ]
+ ].
+
pos := aStream position.
aStream nextPut:#dup.
- stop codeOn:aStream inBlock:b for:aCompiler.
+ stopVarIndex notNil ifTrue:[
+ b isNil ifTrue:[
+ aStream nextPut:#pushMethodVar; nextPut:stopVarIndex.
+ ] ifFalse:[
+ aStream nextPut:#pushBlockVar; nextPut:stopVarIndex.
+ ]
+ ] ifFalse:[
+ stop codeOn:aStream inBlock:b for:aCompiler.
+ ].
+ stepVal > 0 ifTrue:[
+ aStream nextPut:#>.
+ ] ifFalse:[
+ aStream nextPut:#<.
+ ].
+ (aCompiler hasLineNumber:selector) ifTrue:[
+ aStream nextPut:lineNr.
+ ].
+ aStream nextPut:#trueJump.
+ pos2 := aStream position.
+ aStream nextPut:0.
+
+ theBlock := argArray at:3.
+
+ "/ need a temporary in the outer context for
+ "/ the loop ...
+ b isNil ifTrue:[
+ loopVarIndex := aCompiler addTempVar.
+ aStream nextPut:#dup.
+ aStream nextPut:#storeMethodVar; nextPut:loopVarIndex.
+ ] ifFalse:[
+ loopVarIndex := b addTempVar.
+ aStream nextPut:#dup.
+ aStream nextPut:#storeBlockVar; nextPut:loopVarIndex.
+ ].
+ theBlock indexOfFirstTemp:loopVarIndex.
+
+ theBlock codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler.
+
+ "/ increment/decrement counter & jump back.
+
+ stepVal == 1 ifTrue:[
+ aStream nextPut:#plus1; nextPut:lineNr.
+ ] ifFalse:[
+ stepVal == -1 ifTrue:[
+ aStream nextPut:#minus1; nextPut:lineNr.
+ ] ifFalse:[
+ step codeOn:aStream inBlock:b for:aCompiler.
+ aStream nextPut:#+.
+ (aCompiler hasLineNumber:#+) ifTrue:[
+ aStream nextPut:lineNr.
+ ].
+ ]
+ ].
+
+ aStream nextPut:#jump; nextPut:pos.
+
+ (aStream contents) at:pos2 put:(aStream position).
+ aStream nextPut:#drop. "/ drop run variable
+ lateEval ifTrue:[
+ start codeOn:aStream inBlock:b for:aCompiler.
+ ].
+
+ "/ no need to nil-out loop-tempVar to help GC
+ "/ (its integer, anyway).
+
+ b isNil ifTrue:[
+ aCompiler removeTempVar
+ ] ifFalse:[
+ b removeTempVar
+ ].
+
+ stopVarIndex notNil ifTrue:[
+ b isNil ifTrue:[
+ aCompiler removeTempVar
+ ] ifFalse:[
+ b removeTempVar
+ ]
+ ].
+
+ "Created: 27.6.1997 / 12:48:18 / cg"
+ "Modified: 27.6.1997 / 13:43:06 / cg"
+!
+
+codeToDoOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
+ "generate code for n to:n do:[:unusedArg | ... ]"
+
+ |pos pos2 start stop lateEval theBlock loopVarIndex
+ stopVarIndex|
+
+ "/ NOTICE: could compile it as a timesRepeat, if
+ "/ the loop-counter is not accessed within the loop-block.
+ "/ This generates somewhat (15%) faster code, but makes
+ "/ debugging somewhat difficult (no loop-value seen in debugger).
+
+ start := receiver.
+ stop := (argArray at:1).
+"/ stop isConstant ifFalse:[self halt:'should not happen'].
+"/ (stop evaluate isMemberOf:SmallInteger) ifFalse:[self halt:'should not happen'].
+
+ start codeOn:aStream inBlock:b for:aCompiler.
+
+ lateEval := false.
+
+ valueNeeded ifTrue:[
+ "/ easily reconstructable - no need to keep on stack
+ start isConstant ifTrue:[
+ (start evaluate isMemberOf:SmallInteger) ifTrue:[
+ lateEval := true.
+ ]
+ ].
+ lateEval ifFalse:[
+ aStream nextPut:#dup
+ ].
+ ].
+
+ "/ if stop is not constant, and not an argVar,
+ "/ evaluate it into a temp slot ...
+
+ (stop isConstant and:[stop type == #Integer]) ifFalse:[
+ "/ a method/blockArg is constant as well ...
+ (stop isVariable and:[stop isArgument]) ifFalse:[
+ stop codeOn:aStream inBlock:b for:aCompiler.
+
+ b isNil ifTrue:[
+ stopVarIndex := aCompiler addTempVar.
+ aStream nextPut:#storeMethodVar; nextPut:stopVarIndex.
+ ] ifFalse:[
+ stopVarIndex := b addTempVar.
+ aStream nextPut:#storeBlockVar; nextPut:stopVarIndex.
+ ].
+ ]
+ ].
+
+ pos := aStream position.
+
+ aStream nextPut:#dup.
+ stopVarIndex notNil ifTrue:[
+ b isNil ifTrue:[
+ aStream nextPut:#pushMethodVar; nextPut:stopVarIndex.
+ ] ifFalse:[
+ aStream nextPut:#pushBlockVar; nextPut:stopVarIndex.
+ ]
+ ] ifFalse:[
+ stop codeOn:aStream inBlock:b for:aCompiler.
+ ].
aStream nextPut:#>.
(aCompiler hasLineNumber:selector) ifTrue:[
aStream nextPut:lineNr.
@@ -1484,10 +1669,18 @@
aCompiler removeTempVar
] ifFalse:[
b removeTempVar
- ]
+ ].
+
+ stopVarIndex notNil ifTrue:[
+ b isNil ifTrue:[
+ aCompiler removeTempVar
+ ] ifFalse:[
+ b removeTempVar
+ ]
+ ].
"Created: 26.6.1997 / 10:58:47 / cg"
- "Modified: 26.6.1997 / 11:04:05 / cg"
+ "Modified: 27.6.1997 / 13:21:54 / cg"
!
codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
@@ -1929,5 +2122,5 @@
!MessageNode class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libcomp/MessageNode.st,v 1.73 1997-06-26 11:22:48 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libcomp/MessageNode.st,v 1.74 1997-06-27 12:08:18 cg Exp $'
! !