MessageNode.st
changeset 992 7e8ef3583a43
parent 910 eb4849c04fff
child 993 902eec8d132b
--- 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 $'
 ! !