--- a/MessageNode.st Tue Nov 09 10:34:29 1999 +0100
+++ b/MessageNode.st Tue Nov 09 10:35:56 1999 +0100
@@ -114,94 +114,86 @@
so that constant classVars can be inlined.
"
folding notNil ifTrue:[
- selector := selectorString asSymbolIfInterned.
- selector notNil ifTrue:[
-
- "/
- "/ do constant folding ...
- "/
- canFold := false.
-
- (recNode isGlobal and:[argNode isConstant]) ifTrue:[
- globalName := recNode name.
- recVal := recNode evaluate.
-
- (globalName = 'SmallInteger') ifTrue:[
- ( #( bitMaskFor: ) includes:selector)
- ifTrue:[
- canFold := true
- ]
- ].
- (globalName = 'Float') ifTrue:[
- ( #( pi unity zero ) includes:selector)
- ifTrue:[
- (recVal respondsTo:selector) ifTrue:[
- canFold := true
- ]
- ]
- ]
- ].
-
- (recNode isConstant and:[argNode isConstant]) ifTrue:[
- "check if we can do it ..."
- recVal := recNode evaluate.
- "
- we could do much more here - but then, we need a dependency from
- the folded selectors method to the method we generate code for ...
- limit optimizations to those that will never change
- (or - if you change them - you will crash so bad ...)
- "
- argVal := argNode evaluate.
- (recVal respondsToArithmetic and:[argVal respondsToArithmetic]) ifTrue:[
- ( #( + - * / // \\ min: max: quo:) includes:selector) ifTrue:[
- (#( / // \\ ) includes:selector) ifTrue:[
- argVal = 0 ifTrue:[
- ^ 'division by zero in constant expression'
- ].
- ].
- canFold := true
- ].
- ( #( @ ) includes:selector) ifTrue:[
- canFold := (folding == #full)
- ]
- ].
- (recVal isInteger and:[argVal isInteger]) ifTrue:[
- ( #( bitShift: bitOr: ) includes:selector) ifTrue:[
- canFold := true
- ]
- ].
- (recVal isMemberOf:String) ifTrue:[
- (argVal isInteger and:[selector == #at:]) ifTrue:[
- canFold := (folding >= #level2) or:[folding == #full].
- ].
- ((argVal isMemberOf:String) and:[selector == #',']) ifTrue:[
- canFold := (folding >= #level2) or:[folding == #full].
- ]
- ].
- ].
-
- canFold ifTrue:[
- (recVal respondsTo:selector) ifTrue:[
- SignalSet anySignal handle:[:ex |
- ^ 'error in constant expression (' , ex errorString , ')'
- ] do:[
- result := recVal perform:selector with:argVal.
- ].
- ^ ConstantNode type:(ConstantNode typeOfConstant:result) value:result
- ]
- ]
- ].
-
- "/
- "/ #perform with a constant selector
- "/
- (selector == #perform:
- and:[argNode isConstant]) ifTrue:[
- argVal := argNode evaluate.
- argVal isSymbol ifTrue:[
- ^ UnaryNode receiver:recNode selector:argVal fold:folding
- ]
- ].
+ selector := selectorString asSymbolIfInterned.
+ selector notNil ifTrue:[
+
+ "/
+ "/ do constant folding ...
+ "/
+ canFold := false.
+
+ (recNode isGlobal and:[argNode isConstant]) ifTrue:[
+ globalName := recNode name.
+ recVal := recNode evaluate.
+
+ (globalName = 'SmallInteger') ifTrue:[
+ ( #( bitMaskFor: ) includes:selector)
+ ifTrue:[
+ canFold := true
+ ]
+ ].
+ ].
+
+ (recNode isConstant and:[argNode isConstant]) ifTrue:[
+ "check if we can do it ..."
+ recVal := recNode evaluate.
+ "
+ we could do much more here - but then, we need a dependency from
+ the folded selectors method to the method we generate code for ...
+ limit optimizations to those that will never change
+ (or - if you change them - you will crash so bad ...)
+ "
+ argVal := argNode evaluate.
+ (recVal respondsToArithmetic and:[argVal respondsToArithmetic]) ifTrue:[
+ ( #( + - * / // \\ min: max: quo:) includes:selector) ifTrue:[
+ (#( / // \\ ) includes:selector) ifTrue:[
+ argVal = 0 ifTrue:[
+ ^ 'division by zero in constant expression'
+ ].
+ ].
+ canFold := true
+ ].
+ ( #( @ ) includes:selector) ifTrue:[
+ canFold := (folding == #full)
+ ]
+ ].
+ (recVal isInteger and:[argVal isInteger]) ifTrue:[
+ ( #( bitShift: bitOr: ) includes:selector) ifTrue:[
+ canFold := true
+ ]
+ ].
+ (recVal isMemberOf:String) ifTrue:[
+ (argVal isInteger and:[selector == #at:]) ifTrue:[
+ canFold := (folding >= #level2) or:[folding == #full].
+ ].
+ ((argVal isMemberOf:String) and:[selector == #',']) ifTrue:[
+ canFold := (folding >= #level2) or:[folding == #full].
+ ]
+ ].
+ ].
+
+ canFold ifTrue:[
+ (recVal respondsTo:selector) ifTrue:[
+ SignalSet anySignal handle:[:ex |
+ ^ 'error in constant expression (' , ex errorString , ')'
+ ] do:[
+ result := recVal perform:selector with:argVal.
+ ].
+ ^ ConstantNode type:(ConstantNode typeOfConstant:result) value:result
+ ]
+ ]
+ ].
+
+ "/
+ "/ #perform with a constant selector
+ "/
+ (selector == #perform:
+ and:[argNode isConstant]) ifTrue:[
+ argVal := argNode evaluate.
+ argVal isSymbol ifTrue:[
+ ^ UnaryNode receiver:recNode selector:argVal fold:folding
+ ]
+ ].
].
^ (self basicNew) receiver:recNode selector:selectorString args:(Array with:argNode) lineno:0
@@ -882,75 +874,81 @@
theReceiver := receiver.
+ theReceiver isConstant ifTrue:[
+ (self tryFoldedIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler) ifTrue:[
+ ^ self
+ ].
+ ].
+
(theReceiver isMessage) ifTrue:[
- subsel := theReceiver selector.
- (subsel == #and:) ifTrue:[
- self codeAndIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
- ^ self
- ].
- (subsel == #or:) ifTrue:[
- self codeOrIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
- ^ self
- ]
+ subsel := theReceiver selector.
+ (subsel == #and:) ifTrue:[
+ self codeAndIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+ ^ self
+ ].
+ (subsel == #or:) ifTrue:[
+ self codeOrIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+ ^ self
+ ]
].
(selector == #ifTrue:ifFalse:) ifTrue:[
- theByteCode := #falseJump
+ theByteCode := #falseJump
] ifFalse:[
- (selector == #ifFalse:ifTrue:) ifTrue:[
- theByteCode := #trueJump
- ]
+ (selector == #ifFalse:ifTrue:) ifTrue:[
+ theByteCode := #trueJump
+ ]
].
optByteCode := self optimizedConditionFor:theReceiver
- with:theByteCode.
+ with:theByteCode.
optByteCode notNil ifTrue:[
- ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
- theArg := theReceiver arg1
- ].
- theReceiver := theReceiver receiver.
- theByteCode := optByteCode
+ ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
+ theArg := theReceiver arg1
+ ].
+ theReceiver := theReceiver receiver.
+ theByteCode := optByteCode
].
theByteCode notNil ifTrue:[
- theReceiver codeOn:aStream inBlock:b for:aCompiler.
-
- needLineNr := true.
- theArg isNil ifTrue:[
- theReceiver isMessage ifTrue:[
- (aCompiler hasLineNumber:(theReceiver selector)) ifTrue:[
- theReceiver lineNumber == lineNr ifTrue:[
- needLineNr := false
- ]
- ]
- ]
- ] ifFalse:[
- theArg codeOn:aStream inBlock:b for:aCompiler
- ].
-
- needLineNr ifTrue:[
- (lineNr between:1 and:255) ifTrue:[
- aStream nextPut:#lineno; nextPut:lineNr.
- ]
- ].
-
- aStream nextPut:theByteCode.
- pos := aStream position.
- aStream nextPut:0.
- block1 := argArray at:1.
- block1 codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
- needJump := true.
- (block1 isBlock and:[block1 endsWithReturn]) ifTrue:[
- needJump := false
- ].
- needJump ifTrue:[
- aStream nextPut:#jump.
- pos2 := aStream position.
- aStream nextPut:0.
- ].
- code := aStream contents.
- code at:pos put:(aStream position).
- (argArray at:2) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
- needJump ifTrue:[
- code at:pos2 put:(aStream position)
- ]
+ theReceiver codeOn:aStream inBlock:b for:aCompiler.
+
+ needLineNr := true.
+ theArg isNil ifTrue:[
+ theReceiver isMessage ifTrue:[
+ (aCompiler hasLineNumber:(theReceiver selector)) ifTrue:[
+ theReceiver lineNumber == lineNr ifTrue:[
+ needLineNr := false
+ ]
+ ]
+ ]
+ ] ifFalse:[
+ theArg codeOn:aStream inBlock:b for:aCompiler
+ ].
+
+ needLineNr ifTrue:[
+ (lineNr between:1 and:255) ifTrue:[
+ aStream nextPut:#lineno; nextPut:lineNr.
+ ]
+ ].
+
+ aStream nextPut:theByteCode.
+ pos := aStream position.
+ aStream nextPut:0.
+ block1 := argArray at:1.
+ block1 codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+ needJump := true.
+ (block1 isBlock and:[block1 endsWithReturn]) ifTrue:[
+ needJump := false
+ ].
+ needJump ifTrue:[
+ aStream nextPut:#jump.
+ pos2 := aStream position.
+ aStream nextPut:0.
+ ].
+ code := aStream contents.
+ code at:pos put:(aStream position).
+ (argArray at:2) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+ needJump ifTrue:[
+ code at:pos2 put:(aStream position)
+ ]
]
"Modified: 9.11.1996 / 19:53:52 / cg"
@@ -1074,57 +1072,63 @@
theReceiver := receiver.
+ theReceiver isConstant ifTrue:[
+ (self tryFoldedIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler) ifTrue:[
+ ^ self
+ ].
+ ].
+
(theReceiver isMessage) ifTrue:[
- subsel := theReceiver selector.
-
- (subsel == #and:) ifTrue:[
- theReceiver arg1 isBlock ifTrue:[
- self codeAndIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
- ^ self
- ]
- ].
- (subsel == #or:) ifTrue:[
- theReceiver arg1 isBlock ifTrue:[
- self codeOrIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
- ^ self
- ]
- ].
+ subsel := theReceiver selector.
+
+ (subsel == #and:) ifTrue:[
+ theReceiver arg1 isBlock ifTrue:[
+ self codeAndIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+ ^ self
+ ]
+ ].
+ (subsel == #or:) ifTrue:[
+ theReceiver arg1 isBlock ifTrue:[
+ self codeOrIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+ ^ self
+ ]
+ ].
].
(selector == #ifTrue:) ifTrue:[
- theByteCode := #falseJump
+ theByteCode := #falseJump
] ifFalse:[
- theByteCode := #trueJump
+ theByteCode := #trueJump
].
optByteCode := self optimizedConditionFor:theReceiver
- with:theByteCode.
+ with:theByteCode.
optByteCode notNil ifTrue:[
- ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
- theArg := theReceiver arg1
- ].
- theReceiver := theReceiver receiver.
- theByteCode := optByteCode
+ ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
+ theArg := theReceiver arg1
+ ].
+ theReceiver := theReceiver receiver.
+ theByteCode := optByteCode
].
theReceiver codeOn:aStream inBlock:b for:aCompiler.
theArg notNil ifTrue:[
- theArg codeOn:aStream inBlock:b for:aCompiler
+ theArg codeOn:aStream inBlock:b for:aCompiler
].
needLineNr := true.
theArg isNil ifTrue:[
- theReceiver isMessage ifTrue:[
- (aCompiler hasLineNumber:(theReceiver selector)) ifTrue:[
- theReceiver lineNumber == lineNr ifTrue:[
- needLineNr := false
- ]
- ]
- ]
+ theReceiver isMessage ifTrue:[
+ (aCompiler hasLineNumber:(theReceiver selector)) ifTrue:[
+ theReceiver lineNumber == lineNr ifTrue:[
+ needLineNr := false
+ ]
+ ]
+ ]
].
needLineNr ifTrue:[
- (lineNr between:1 and:255) ifTrue:[
- aStream nextPut:#lineno; nextPut:lineNr.
- ]
+ (lineNr between:1 and:255) ifTrue:[
+ aStream nextPut:#lineno; nextPut:lineNr.
+ ]
].
aStream nextPut:theByteCode.
@@ -1134,14 +1138,14 @@
code := aStream contents.
valueNeeded ifTrue:[
- aStream nextPut:#jump.
- pos2 := aStream position.
- aStream nextPut:0.
- code at:pos put:(aStream position).
- aStream nextPut:#pushNil.
- code at:pos2 put:(aStream position)
+ aStream nextPut:#jump.
+ pos2 := aStream position.
+ aStream nextPut:0.
+ code at:pos put:(aStream position).
+ aStream nextPut:#pushNil.
+ code at:pos2 put:(aStream position)
] ifFalse:[
- code at:pos put:(aStream position)
+ code at:pos put:(aStream position)
]
"Modified: / 28.10.1997 / 18:33:42 / cg"
@@ -2512,6 +2516,42 @@
]
].
^ nil
+!
+
+tryFoldedIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
+ |rVal branch|
+
+ receiver isConstant ifTrue:[
+ rVal := receiver evaluate.
+ rVal == true ifTrue:[
+ ((selector == #ifTrue:) or:[selector == #ifTrue:ifFalse:]) ifTrue:[
+ branch := (argArray at: 1).
+ ].
+ (selector == #ifFalse:ifTrue:) ifTrue:[
+ branch := (argArray at: 2).
+ ].
+ (selector == #ifFalse:) ifTrue:[
+ ^ true.
+ ].
+ ].
+ rVal == false ifTrue:[
+ ((selector == #ifFalse:) or:[selector == #ifFalse:ifTrue:]) ifTrue:[
+ branch := (argArray at: 1).
+ ].
+ (selector == #ifTrue:ifFalse:) ifTrue:[
+ branch := (argArray at: 2).
+ ].
+ (selector == #ifTrue:) ifTrue:[
+ ^ true.
+ ].
+ ].
+ branch notNil ifTrue:[
+ branch codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+ ^ true.
+ ]
+ ].
+ ^ false
+
! !
!MessageNode methodsFor:'enumeration'!
@@ -2749,5 +2789,5 @@
!MessageNode class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libcomp/MessageNode.st,v 1.104 1999-07-15 11:16:37 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libcomp/MessageNode.st,v 1.105 1999-11-09 09:35:56 cg Exp $'
! !