diff -r 16411f243a75 -r 7e8ef3583a43 MessageNode.st --- 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 $' ! !