'From Croquet1.0beta of 11 April 2006 [latest update: #1] on 6 August 2008 at 12:52:55 pm'! Object subclass: #Compiler instanceVariableNames: 'sourceStream requestor class category context parserClass cacheDoItNode parser ' classVariableNames: '' poolDictionaries: '' category: 'Compiler-Kernel'! InstructionClient subclass: #InstructionPrinter instanceVariableNames: 'method scanner stream oldPC indent indentSpanOfFollowingJump innerIndents printPC ' classVariableNames: '' poolDictionaries: '' category: 'Kernel-Methods'! ParseNode subclass: #BlockNode instanceVariableNames: 'arguments statements returns nArgsNode size remoteCopyNode temporaries optimized blockExtent remoteTempNode copiedValues closureCreationNode startOfLastStatement' classVariableNames: '' poolDictionaries: '' category: 'Compiler-ParseNodes'! MethodNode subclass: #BytecodeAgnosticMethodNode instanceVariableNames: 'locationCounter localsPool' classVariableNames: '' poolDictionaries: '' category: 'Compiler-ParseNodes'! !BytecodeAgnosticMethodNode commentStamp: '' prior: 0! I am a version of MethodNode that is able to work with different BytecodeEncoders, and is hence able to generate methods using different bytecode sets.! ]style[(151)i! Encoder subclass: #BytecodeEncoder instanceVariableNames: 'stream position rootNode blockExtentsToLocals' classVariableNames: '' poolDictionaries: '' category: 'Compiler-Kernel'! !BytecodeEncoder commentStamp: '' prior: 0! I am an abstract superclass for different bytecode set encoders. Subclasses inherit the literal management of Encoder and encapsulate the mapping of opcodes to specific bytecodes.! BytecodeEncoder subclass: #EncoderForLongFormV3 instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Compiler-Kernel'! !EncoderForLongFormV3 commentStamp: '' prior: 0! I am an alternate to EncoderForV3 that tries to use thje longest forms of bytecodes possible so as to avoid using as many bytecode as possible to allow for the unused portions of the bytecode set this makes available to be reassigned. I do not use the following ranges 0 through 111 0- 15 0000iiii Push Receiver Variable #iiii 16- 31 0001iiii Push Temporary Location #iiii 32- 63 001iiiii Push Literal Constant #iiiii 64- 95 010iiiii Push Literal Variable #iiiii 96-103 01100iii Pop and Store Receiver Variable #iii 104-111 01101iii Pop and Store Temporary Location #iii 138-159 138-143 Unused. 144-151 10010iii Jump iii + 1 (i.e., 1 through 8). 152-159 10011iii Pop and Jump 0n False iii +1 (i.e., 1 through 8). 176-255 176-191 1011iiii Send Arithmetic Message #iiii 192-207 1100iiii Send Special Message #iiii 208-223 1101iiii Send Literal Selector #iiii With No Arguments 224-239 1110iiii Send Literal Selector #iiii With 1 Argument 240-255 1111iiii Send Literal Selector #iiii With 2 Arguments = 112 + (160 - 138) + (256 - 176) = 214, or 84% of the bytecodes! BytecodeEncoder subclass: #EncoderForV3 instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Compiler-Kernel'! !EncoderForV3 commentStamp: '' prior: 0! I add behaviour to Encoder to size and emit bytecodes for the Squeak V3.x VM bytecode set. The intention is for another subclass to restrict the range of bytecodes used to long forms only, allowing the bytecode set to be redefined by avoiding using the many short forms. The short forms may then be reassigned.! ParseNode subclass: #LeafNode instanceVariableNames: 'key code index ' classVariableNames: '' poolDictionaries: '' category: 'Compiler-ParseNodes'! ParseNode subclass: #MessageNode instanceVariableNames: 'receiver selector precedence special arguments sizes equalNode caseErrorNode ' classVariableNames: 'MacroEmitters MacroPrinters MacroSelectors MacroSizers MacroTransformers StdTypers ThenFlag NewStyleMacroEmitters NewStyleMacroSizers ' poolDictionaries: '' category: 'Compiler-ParseNodes'! InstructionPrinter subclass: #RelativeInstructionPrinter instanceVariableNames: 'printCode labels labelling' classVariableNames: '' poolDictionaries: '' category: 'Kernel-Methods'! Warning subclass: #UndeclaredVariableWarning instanceVariableNames: 'name selector class' classVariableNames: '' poolDictionaries: '' category: 'Compiler-Support'! LeafNode subclass: #VariableNode instanceVariableNames: 'name' classVariableNames: '' poolDictionaries: '' category: 'Compiler-ParseNodes'! VariableNode subclass: #LiteralVariableNode instanceVariableNames: 'splNode readNode writeNode ' classVariableNames: '' poolDictionaries: '' category: 'Compiler-ParseNodes'! VariableNode subclass: #TempVariableNode instanceVariableNames: 'isAnArg hasRefs hasDefs scope definingScope readingScopes writingScopes remoteNode' classVariableNames: '' poolDictionaries: '' category: 'Compiler-ParseNodes'! !BytecodeAgnosticMethodNode methodsFor: 'code generation (new scheme)' stamp: 'eem 7/24/2008 10:05'! generate: trailer "The receiver is the root of a parse tree. Answer a CompiledMethod. The argument, trailer, is the reference to the source code that is stored with every CompiledMethod." | blkSize nLits literals stack method | self generate: trailer ifQuick: [:m | m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. encoder supportsClosureOpcodes ifTrue: [self ensureClosureAnalysisDone. encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := block sizeCodeForEvaluatedValue: encoder. method := CompiledMethod newBytes: blkSize trailerBytes: trailer nArgs: arguments size nTemps: (encoder supportsClosureOpcodes ifTrue: [| locals | locals := arguments, temporaries. encoder noteBlockExtent: block blockExtent hasLocals: locals. locals size] ifFalse: [encoder maxTemp]) nStack: 0 nLits: (nLits := (literals := encoder allLiterals) size) primitive: primitive. nLits > 255 ifTrue: [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. block emitCodeForEvaluatedValue: stack encoder: encoder. stack position ~= 1 ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size. method properties: properties. ^method! ! !BytecodeEncoder methodsFor: 'initialize-release' stamp: 'eem 7/24/2008 17:24'! streamToMethod: aCompiledMethod stream := WriteStream with: aCompiledMethod. stream position: aCompiledMethod initialPC - 1! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 7/27/2008 00:39'! nextPut: aByte "For sizing make the encoder its own stream and keep track of position with this version of nextPut:" position := position + 1! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 18:22'! sizeBranchPopFalse: distance ^self sizeOpcodeSelector: #genBranchPopFalse: withArguments: {distance}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 18:22'! sizeBranchPopTrue: distance ^self sizeOpcodeSelector: #genBranchPopTrue: withArguments: {distance}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 17:28'! sizeDup ^self sizeOpcodeSelector: #genDup withArguments: #()! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 17:40'! sizeJumpLong: distance ^self sizeOpcodeSelector: #genJumpLong: withArguments: {distance}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 17:40'! sizeJump: distance ^self sizeOpcodeSelector: #genJump: withArguments: {distance}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 7/27/2008 00:39'! sizeOpcodeSelector: genSelector withArguments: args stream := self. position := 0. self perform: genSelector withArguments: args. ^position! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 17:28'! sizePop ^self sizeOpcodeSelector: #genPop withArguments: #()! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 6/19/2008 08:54'! sizePushInstVarLong: instVarIndex ^self sizeOpcodeSelector: #genPushInstVarLong: withArguments: {instVarIndex}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 16:22'! sizePushInstVar: instVarIndex ^self sizeOpcodeSelector: #genPushInstVar: withArguments: {instVarIndex}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 17:43'! sizePushLiteralVar: literalIndex ^self sizeOpcodeSelector: #genPushLiteralVar: withArguments: {literalIndex}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 17:43'! sizePushLiteral: literalIndex ^self sizeOpcodeSelector: #genPushLiteral: withArguments: {literalIndex}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 16:21'! sizePushReceiver ^self sizeOpcodeSelector: #genPushReceiver withArguments: #()! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 17:37'! sizePushSpecialLiteral: specialLiteral ^self sizeOpcodeSelector: #genPushSpecialLiteral: withArguments: {specialLiteral}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 17:26'! sizePushTemp: tempIndex ^self sizeOpcodeSelector: #genPushTemp: withArguments: {tempIndex}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 17:28'! sizePushThisContext ^self sizeOpcodeSelector: #genPushThisContext withArguments: #()! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/15/2008 09:07'! sizeReturnReceiver ^self sizeOpcodeSelector: #genReturnReceiver withArguments: #()! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 17:38'! sizeReturnSpecialLiteral: specialLiteral ^self sizeOpcodeSelector: #genReturnSpecialLiteral: withArguments: {specialLiteral}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 17:34'! sizeReturnTop ^self sizeOpcodeSelector: #genReturnTop withArguments: #()! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/15/2008 09:06'! sizeReturnTopToCaller ^self sizeOpcodeSelector: #genReturnTopToCaller withArguments: #()! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 16:11'! sizeSendSuper: selectorLiteralIndex numArgs: nArgs ^self sizeOpcodeSelector: #genSendSuper:numArgs: withArguments: {selectorLiteralIndex. nArgs}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 16:11'! sizeSend: selectorLiteralIndex numArgs: nArgs ^self sizeOpcodeSelector: #genSend:numArgs: withArguments: {selectorLiteralIndex. nArgs}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 6/19/2008 08:54'! sizeStoreInstVarLong: instVarIndex ^self sizeOpcodeSelector: #genStoreInstVarLong: withArguments: {instVarIndex}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 17:44'! sizeStoreInstVar: instVarIndex ^self sizeOpcodeSelector: #genStoreInstVar: withArguments: {instVarIndex}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 17:43'! sizeStoreLiteralVar: literalIndex ^self sizeOpcodeSelector: #genStoreLiteralVar: withArguments: {literalIndex}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 6/19/2008 08:54'! sizeStorePopInstVarLong: instVarIndex ^self sizeOpcodeSelector: #genStorePopInstVarLong: withArguments: {instVarIndex}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/15/2008 10:00'! sizeStorePopInstVar: instVarIndex ^self sizeOpcodeSelector: #genStorePopInstVar: withArguments: {instVarIndex}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/15/2008 10:20'! sizeStorePopLiteralVar: literalIndex ^self sizeOpcodeSelector: #genStorePopLiteralVar: withArguments: {literalIndex}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 17:36'! sizeStorePopTemp: tempIndex ^self sizeOpcodeSelector: #genStorePopTemp: withArguments: {tempIndex}! ! !BytecodeEncoder methodsFor: 'opcode sizing' stamp: 'eem 5/14/2008 17:45'! sizeStoreTemp: tempIndex ^self sizeOpcodeSelector: #genStoreTemp: withArguments: {tempIndex}! ! !BytecodeEncoder methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:52'! outOfRangeError: string index: index range: rangeStart to: rangeEnd "For now..." ^self error: thisContext sender method selector, ' ', string , ' index ', index printString , ' is out of range ', rangeStart printString, ' to ', rangeEnd printString! ! !BytecodeEncoder methodsFor: 'accessing' stamp: 'eem 5/29/2008 09:36'! methodNodeClass ^BytecodeAgnosticMethodNode! ! !BytecodeEncoder methodsFor: 'accessing' stamp: 'eem 5/14/2008 17:47'! methodStreamPosition ^stream position! ! !BytecodeEncoder methodsFor: 'testing' stamp: 'eem 7/17/2008 12:34'! supportsClosureOpcodes "Answer if the receiver supports the genPushNewArray:/genPushConsArray: genPushRemoteTemp:inVectorAt: genStoreRemoteTemp:inVectorAt: genStorePopRemoteTemp:inVectorAt: genPushClosureCopyCopiedValues:numArgs:jumpSize: opcodes" ^false! ! !BytecodeEncoder methodsFor: 'special literal encodings' stamp: 'eem 5/14/2008 16:02'! if: code isSpecialLiteralForPush: aBlock "If code is that of a special literal for push then evaluate aBlock with the special literal The special literals for push are nil true false -1 0 1 & 2 which have special encodings in the blue book bytecode set. Answer whether it was a special literal." ^(code between: LdTrue and: LdNil + 4) and: [aBlock value: (#(true false nil -1 0 1 2) at: code - LdSelf). true]! ! !BytecodeEncoder methodsFor: 'special literal encodings' stamp: 'eem 5/14/2008 17:49'! if: code isSpecialLiteralForReturn: aBlock "If code is that of a special literal for return then evaluate aBlock with the special literal. The special literals for return are nil true false which have special encodings in the blue book bytecode set. Answer whether it was a special literal." ^(code between: LdTrue and: LdNil) and: [aBlock value: (#(true false nil) at: code - LdSelf). true]! ! !BytecodeEncoder methodsFor: 'temps' stamp: 'eem 6/23/2008 10:55'! bindAndJuggle: name "This is used to insert a new temp and reorcder temps on editing. It doesn't really work for closure compilation since we have multiple locations for temps. Simply signal a reparse is necessary." ReparseAfterSourceEditing signal! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:52'! genBranchPopFalse: distance "See BlueBook page 596" distance < 0 ifTrue: [^self outOfRangeError: 'distance' index: distance range: 0 to: 1023]. distance < 1024 ifTrue: ["172-175 101011ii jjjjjjjj Pop and Jump On False ii *256+jjjjjjjj" stream nextPut: 172 + (distance bitShift: -8); nextPut: distance + 1024 \\ 256. ^self]. ^self outOfRangeError: 'distance' index: distance range: 0 to: 1023! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:53'! genBranchPopTrue: distance "See BlueBook page 596" distance < 0 ifTrue: [^self outOfRangeError: 'distance' index: distance range: 0 to: 1023]. distance < 1024 ifTrue: ["168-171 101010ii jjjjjjjj Pop and Jump On True ii *256+jjjjjjjj" stream nextPut: 168 + (distance bitShift: -8); nextPut: distance + 1024 \\ 256. ^self]. ^self outOfRangeError: 'distance' index: distance range: 0 to: 1023! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/15/2008 14:12'! genDup "See BlueBook page 596" "136 10001000 Duplicate Stack Top" stream nextPut: 136! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:53'! genJumpLong: distance "See BlueBook page 596" (distance >= -1024 and: [distance < 1024]) ifTrue: ["160-167 10100iii jjjjjjjj Jump(iii - 4) *256+jjjjjjjj" stream nextPut: 160 + (distance + 1024 bitShift: -8); nextPut: distance + 1024 \\ 256. ^self]. ^self outOfRangeError: 'distance' index: distance range: -1024 to: 1023! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/15/2008 14:20'! genJump: distance "See BlueBook page 596" ^self genJumpLong: distance! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/15/2008 14:12'! genPop "See BlueBook page 596" "135 10000111 Pop Stack Top" stream nextPut: 135! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 6/19/2008 08:51'! genPushInstVarLong: instVarIndex "See BlueBook page 596" "See also MaybeContextInstanceVariableNode" (instVarIndex >= 0 and: [instVarIndex < 256]) ifTrue: ["132 10000100 iiijjjjj kkkkkkkk (Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj" stream nextPut: 132; nextPut: 64; nextPut: instVarIndex. ^self]. ^self outOfRangeError: 'index' index: instVarIndex range: 0 to: 255! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 6/19/2008 08:46'! genPushInstVar: instVarIndex "See BlueBook page 596" (instVarIndex >= 0 and: [instVarIndex < 64]) ifTrue: ["128 10000000 jjkkkkkk Push (Receiver Variable, Temporary Location, Literal Constant, Literal Variable) [jj] #kkkkkk" stream nextPut: 128; nextPut: instVarIndex. ^self]. self genPushInstVarLong: instVarIndex! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:54'! genPushLiteralVar: literalIndex "See BlueBook page 596" literalIndex < 0 ifTrue: [^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255]. literalIndex < 64 ifTrue: ["128 10000000 jjkkkkkk Push (Receiver Variable, Temporary Location, Literal Constant, Literal Variable) [jj] #kkkkkk" stream nextPut: 128; nextPut: 192 + literalIndex. ^self]. literalIndex < 256 ifTrue: ["132 10000100 iiijjjjj kkkkkkkk (Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj" stream nextPut: 132; nextPut: 128; nextPut: literalIndex. ^self]. ^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:54'! genPushLiteral: literalIndex "See BlueBook page 596" literalIndex < 0 ifTrue: [^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255]. literalIndex < 64 ifTrue: ["128 10000000 jjkkkkkk Push (Receiver Variable, Temporary Location, Literal Constant, Literal Variable) [jj] #kkkkkk" stream nextPut: 128; nextPut: 128 + literalIndex. ^self]. literalIndex < 256 ifTrue: ["132 10000100 iiijjjjj kkkkkkkk (Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj" stream nextPut: 132; nextPut: 96; nextPut: literalIndex. ^self]. ^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/15/2008 14:12'! genPushReceiver "See BlueBook page 596" "112-119 01110iii Push (receiver, true, false, nil, -1, 0, 1, 2) [iii]" stream nextPut: 112! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/15/2008 14:12'! genPushSpecialLiteral: aLiteral "112-119 01110iii Push (receiver, true, false, nil, -1, 0, 1, 2) [iii]" | index | index := #(true false nil -1 0 1 2) indexOf: aLiteral ifAbsent: 0. index = 0 ifTrue: [^self error: 'push special literal: ', aLiteral printString, ' is not one of true false nil -1 0 1 2']. stream nextPut: index + 112! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:54'! genPushTemp: tempIndex "See BlueBook page 596" tempIndex < 0 ifTrue: [^self outOfRangeError: 'index' index: tempIndex range: 0 to: 63]. tempIndex < 64 ifTrue: ["128 10000000 jjkkkkkk Push (Receiver Variable, Temporary Location, Literal Constant, Literal Variable) [jj] #kkkkkk" stream nextPut: 128; nextPut: 64 + tempIndex. ^self]. ^self outOfRangeError: 'index' index: tempIndex range: 0 to: 63! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/15/2008 14:12'! genPushThisContext "See BlueBook page 596" "137 10001001 Push Active Context" stream nextPut: 137! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/15/2008 14:12'! genReturnReceiver "See BlueBook page 596" "120-123 011110ii Return (receiver, true, false, nil) [ii] From Message" stream nextPut: 120! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/15/2008 14:12'! genReturnSpecialLiteral: aLiteral "120-123 011110ii Return (receiver, true, false, nil) [ii] From Message" | index | index := #(true false nil) indexOf: aLiteral ifAbsent: 0. index = 0 ifTrue: [^self error: 'return special literal: ', aLiteral printString, ' is not one of true false nil']. stream nextPut: 120 + index! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/15/2008 14:12'! genReturnTop "See BlueBook page 596" "124-125 0111110i Return Stack Top From (Message, Block) [i]" stream nextPut: 124! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/15/2008 14:12'! genReturnTopToCaller "See BlueBook page 596" "124-125 0111110i Return Stack Top From (Message, Block) [i]" stream nextPut: 125! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:55'! genSendSuper: selectorLiteralIndex numArgs: nArgs "See BlueBook page 596 (with exceptions for 132 & 134)" nArgs < 0 ifTrue: [^self outOfRangeError: 'numArgs' index: nArgs range: 0 to: 31 "!!!!"]. selectorLiteralIndex < 0 ifTrue: [^self outOfRangeError: 'selector literal index' index: selectorLiteralIndex range: 0 to: 255]. (selectorLiteralIndex < 32 and: [nArgs < 8]) ifTrue: [" 133 10000011 jjjkkkkk Send Literal Selector #kkkkk To Superclass With jjj Arguments" stream nextPut: 133; nextPut: ((nArgs bitShift: 5) + selectorLiteralIndex). ^self]. (selectorLiteralIndex <= 255 and: [nArgs <= 31]) ifTrue: ["In Squeak V3 132 10000100 jjjjjjjj kkkkkkkk Send Literal Selector #kkkkkkkk With jjjjjjjj Arguments is replaced by 132 10000100 ooojjjjj kkkkkkkk ooo = 0 => Send Literal Selector #kkkkkkkk With jjjjj Arguments ooo = 1 => Send Literal Selector #kkkkkkkk To Superclass With jjjjj Arguments" stream nextPut: 132; nextPut: 32 + nArgs; nextPut: selectorLiteralIndex. ^self]. nArgs > 31 ifTrue: [^self outOfRangeError: 'numArgs' index: nArgs range: 0 to: 31]. selectorLiteralIndex > 255 ifTrue: [^self outOfRangeError: 'selector literal index' index: selectorLiteralIndex range: 0 to: 255]! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:56'! genSend: selectorLiteralIndex numArgs: nArgs "See BlueBook page 596 (with exceptions for 132 & 134)" nArgs < 0 ifTrue: [^self outOfRangeError: 'numArgs' index: nArgs range: 0 to: 31 "!!!!"]. selectorLiteralIndex < 0 ifTrue: ["No special selector sends in long form." ^self outOfRangeError: 'selector literal index' index: selectorLiteralIndex range: 0 to: 255]. (selectorLiteralIndex < 32 and: [nArgs < 8]) ifTrue: [" 131 10000011 jjjkkkkk Send Literal Selector #kkkkk With jjj Arguments" stream nextPut: 131; nextPut: ((nArgs bitShift: 5) + selectorLiteralIndex). ^self]. (selectorLiteralIndex < 64 and: [nArgs < 4]) ifTrue: ["In Squeak V3 134 10000110 jjjjjjjj kkkkkkkk Send Literal Selector #kkkkkkkk To Superclass With jjjjjjjj Arguments is replaced by 134 10000110 jjkkkkkk Send Literal Selector #kkkkkk With jj Arguments" stream nextPut: 134; nextPut: ((nArgs bitShift: 6) + selectorLiteralIndex). ^self]. (selectorLiteralIndex <= 255 and: [nArgs <= 31]) ifTrue: ["In Squeak V3 132 10000100 jjjjjjjj kkkkkkkk Send Literal Selector #kkkkkkkk With jjjjjjjj Arguments is replaced by 132 10000100 ooojjjjj kkkkkkkk ooo = 0 => Send Literal Selector #kkkkkkkk With jjjjj Arguments ooo = 1 => Send Literal Selector #kkkkkkkk To Superclass With jjjjj Arguments" stream nextPut: 132; nextPut: nArgs; nextPut: selectorLiteralIndex. ^self]. nArgs > 31 ifTrue: [^self outOfRangeError: 'numArgs' index: nArgs range: 0 to: 31]. selectorLiteralIndex > 255 ifTrue: [^self outOfRangeError: 'selector literal index' index: selectorLiteralIndex range: 0 to: 255]! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 6/19/2008 08:51'! genStoreInstVarLong: instVarIndex "See BlueBook page 596" "See also MaybeContextInstanceVariableNode" (instVarIndex >= 0 and: [instVarIndex < 256]) ifTrue: ["132 10000100 iiijjjjj kkkkkkkk (Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj" stream nextPut: 132; nextPut: 160; nextPut: instVarIndex. ^self]. ^self outOfRangeError: 'index' index: instVarIndex range: 0 to: 255! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 6/19/2008 08:48'! genStoreInstVar: instVarIndex "See BlueBook page 596" (instVarIndex >= 0 and: [instVarIndex < 64]) ifTrue: ["129 10000001 jjkkkkkk Store (Receiver Variable, Temporary Location, Illegal, Literal Variable) [jj] #kkkkkk" stream nextPut: 129; nextPut: instVarIndex. ^self]. self genStoreInstVarLong: instVarIndex! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:57'! genStoreLiteralVar: literalIndex "See BlueBook page 596" literalIndex < 0 ifTrue: [^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255]. literalIndex < 64 ifTrue: ["129 10000001 jjkkkkkk Store (Receiver Variable, Temporary Location, Illegal, Literal Variable) [jj] #kkkkkk" stream nextPut: 129; nextPut: 192 + literalIndex. ^self]. literalIndex <= 255 ifTrue: ["132 10000100 iiijjjjj kkkkkkkk (Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj" stream nextPut: 132; nextPut: 224; nextPut: literalIndex. ^self]. ^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 6/19/2008 08:51'! genStorePopInstVarLong: instVarIndex "See BlueBook page 596" "See also MaybeContextInstanceVariableNode" (instVarIndex >= 0 and: [instVarIndex < 256]) ifTrue: ["132 10000100 iiijjjjj kkkkkkkk (Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj" stream nextPut: 132; nextPut: 192; nextPut: instVarIndex. ^self]. ^self outOfRangeError: 'index' index: instVarIndex range: 0 to: 255! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 6/19/2008 08:50'! genStorePopInstVar: instVarIndex "See BlueBook page 596" (instVarIndex >= 0 and: [instVarIndex < 64]) ifTrue: ["130 10000010 jjkkkkkk Pop and Store (Receiver Variable, Temporary Location, Illegal, Literal Variable) [jj] #kkkkkk" stream nextPut: 130; nextPut: instVarIndex. ^self]. self genStorePopInstVarLong: instVarIndex! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:58'! genStorePopLiteralVar: literalIndex "See BlueBook page 596" literalIndex < 0 ifTrue: [^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255]. literalIndex < 64 ifTrue: ["130 10000010 jjkkkkkk Pop and Store (Receiver Variable, Temporary Location, Illegal, Literal Variable) [jj] #kkkkkk" stream nextPut: 130; nextPut: 192 + literalIndex. ^self]. literalIndex <= 255 ifTrue: ["132 10000100 iiijjjjj kkkkkkkk (Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj" stream nextPut: 132; nextPut: 224; nextPut: literalIndex. self genPop. ^self]. ^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:58'! genStorePopTemp: tempIndex "See BlueBook page 596" tempIndex < 0 ifTrue: [^self outOfRangeError: 'index' index: tempIndex range: 0 to: 63]. tempIndex < 64 ifTrue: ["130 10000010 jjkkkkkk Pop and Store (Receiver Variable, Temporary Location, Illegal, Literal Variable) [jj] #kkkkkk" stream nextPut: 130; nextPut: 64 + tempIndex. ^self]. ^self outOfRangeError: 'index' index: tempIndex range: 0 to: 63! ! !EncoderForLongFormV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:58'! genStoreTemp: tempIndex "See BlueBook page 596" tempIndex < 0 ifTrue: [^self outOfRangeError: 'index' index: tempIndex range: 0 to: 63]. tempIndex < 64 ifTrue: ["129 10000001 jjkkkkkk Store (Receiver Variable, Temporary Location, Illegal, Literal Variable) [jj] #kkkkkk" stream nextPut: 129; nextPut: 64 + tempIndex. ^self]. ^self outOfRangeError: 'index' index: tempIndex range: 0 to: 63! ! !EncoderForLongFormV3 methodsFor: 'initialize-release' stamp: 'eem 5/15/2008 14:11'! initScopeAndLiteralTables super initScopeAndLiteralTables. "Start with an empty selector set to avoid the special selectors." selectorSet := Dictionary new: 16! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:59'! genBranchPopFalse: distance "See BlueBook page 596" distance < 0 ifTrue: [^self outOfRangeError: 'distance' index: distance range: 0 to: 1023]. (distance > 0 and: [distance < 9]) ifTrue: ["152-159 10011iii Pop and Jump 0n False iii +1 (i.e., 1 through 8)" stream nextPut: 152 + distance - 1. ^self]. distance < 1024 ifTrue: ["172-175 101011ii jjjjjjjj Pop and Jump On False ii *256+jjjjjjjj" stream nextPut: 172 + (distance bitShift: -8); nextPut: distance + 1024 \\ 256. ^self]. ^self outOfRangeError: 'distance' index: distance range: 0 to: 1023! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:59'! genBranchPopTrue: distance "See BlueBook page 596" distance < 0 ifTrue: [^self outOfRangeError: 'distance' index: distance range: 0 to: 1023]. distance < 1024 ifTrue: ["168-171 101010ii jjjjjjjj Pop and Jump On True ii *256+jjjjjjjj" stream nextPut: 168 + (distance bitShift: -8); nextPut: distance + 1024 \\ 256. ^self]. ^self outOfRangeError: 'distance' index: distance range: 0 to: 1023! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/15/2008 09:40'! genDup "See BlueBook page 596" "136 10001000 Duplicate Stack Top" stream nextPut: 136! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:59'! genJumpLong: distance "See BlueBook page 596" (distance >= -1024 and: [distance < 1024]) ifTrue: ["160-167 10100iii jjjjjjjj Jump(iii - 4) *256+jjjjjjjj" stream nextPut: 160 + (distance + 1024 bitShift: -8); nextPut: distance + 1024 \\ 256. ^self]. ^self outOfRangeError: 'distance' index: distance range: -1024 to: 1023! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/14/2008 17:41'! genJump: distance "See BlueBook page 596" (distance > 0 and: [distance < 9]) ifTrue: ["144-151 10010iii Jump iii + 1 (i.e., 1 through 8)" stream nextPut: 144 + distance - 1. ^self]. "160-167 10100iii jjjjjjjj Jump(iii - 4) *256+jjjjjjjj" ^self genJumpLong: distance! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/14/2008 17:27'! genPop "See BlueBook page 596" "135 10000111 Pop Stack Top" stream nextPut: 135! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 6/19/2008 08:51'! genPushInstVarLong: instVarIndex "See BlueBook page 596" "See also MaybeContextInstanceVariableNode" (instVarIndex >= 0 and: [instVarIndex < 256]) ifTrue: ["132 10000100 iiijjjjj kkkkkkkk (Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj" stream nextPut: 132; nextPut: 64; nextPut: instVarIndex. ^self]. ^self outOfRangeError: 'index' index: instVarIndex range: 0 to: 255! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 6/19/2008 08:40'! genPushInstVar: instVarIndex "See BlueBook page 596" instVarIndex >= 0 ifTrue: [instVarIndex < 16 ifTrue: ["0-15 0000iiii Push Receiver Variable #iiii" stream nextPut: 0 + instVarIndex. ^self]. instVarIndex < 64 ifTrue: ["128 10000000 jjkkkkkk Push (Receiver Variable, Temporary Location, Literal Constant, Literal Variable) [jj] #kkkkkk" stream nextPut: 128; nextPut: instVarIndex. ^self]]. self genPushInstVarLong: instVarIndex! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 16:59'! genPushLiteralVar: literalIndex "See BlueBook page 596" literalIndex < 0 ifTrue: [^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255]. literalIndex < 32 ifTrue: ["64-95 010iiiii Push Literal Variable #iiiii" stream nextPut: 64 + literalIndex. ^self]. literalIndex < 64 ifTrue: ["128 10000000 jjkkkkkk Push (Receiver Variable, Temporary Location, Literal Constant, Literal Variable) [jj] #kkkkkk" stream nextPut: 128; nextPut: 192 + literalIndex. ^self]. literalIndex < 256 ifTrue: ["132 10000100 iiijjjjj kkkkkkkk (Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj" stream nextPut: 132; nextPut: 128; nextPut: literalIndex. ^self]. ^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 17:00'! genPushLiteral: literalIndex "See BlueBook page 596" literalIndex < 0 ifTrue: [^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255]. literalIndex < 32 ifTrue: ["32-63 001iiiii Push Literal Constant #iiiii" stream nextPut: 32 + literalIndex. ^self]. literalIndex < 64 ifTrue: ["128 10000000 jjkkkkkk Push (Receiver Variable, Temporary Location, Literal Constant, Literal Variable) [jj] #kkkkkk" stream nextPut: 128; nextPut: 128 + literalIndex. ^self]. literalIndex < 256 ifTrue: ["132 10000100 iiijjjjj kkkkkkkk (Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj" stream nextPut: 132; nextPut: 96; nextPut: literalIndex. ^self]. ^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/14/2008 16:16'! genPushReceiver "See BlueBook page 596" "112-119 01110iii Push (receiver, true, false, nil, -1, 0, 1, 2) [iii]" stream nextPut: 112! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/14/2008 17:38'! genPushSpecialLiteral: aLiteral "112-119 01110iii Push (receiver, true, false, nil, -1, 0, 1, 2) [iii]" | index | index := #(true false nil -1 0 1 2) indexOf: aLiteral ifAbsent: 0. index = 0 ifTrue: [^self error: 'push special literal: ', aLiteral printString, ' is not one of true false nil -1 0 1 2']. stream nextPut: index + 112! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 17:00'! genPushTemp: tempIndex "See BlueBook page 596" tempIndex < 0 ifTrue: [^self outOfRangeError: 'index' index: tempIndex range: 0 to: 63]. tempIndex < 16 ifTrue: ["16-31 0001iiii Push Temporary Location #iiii" stream nextPut: 16 + tempIndex. ^self]. tempIndex < 64 ifTrue: ["128 10000000 jjkkkkkk Push (Receiver Variable, Temporary Location, Literal Constant, Literal Variable) [jj] #kkkkkk" stream nextPut: 128; nextPut: 64 + tempIndex. ^self]. ^self outOfRangeError: 'index' index: tempIndex range: 0 to: 63! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/14/2008 17:36'! genPushThisContext "See BlueBook page 596" "137 10001001 Push Active Context" stream nextPut: 137! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/14/2008 17:40'! genReturnReceiver "See BlueBook page 596" "120-123 011110ii Return (receiver, true, false, nil) [ii] From Message" stream nextPut: 120! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/14/2008 17:39'! genReturnSpecialLiteral: aLiteral "120-123 011110ii Return (receiver, true, false, nil) [ii] From Message" | index | index := #(true false nil) indexOf: aLiteral ifAbsent: 0. index = 0 ifTrue: [^self error: 'return special literal: ', aLiteral printString, ' is not one of true false nil']. stream nextPut: 120 + index! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/14/2008 17:35'! genReturnTop "See BlueBook page 596" "124-125 0111110i Return Stack Top From (Message, Block) [i]" stream nextPut: 124! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/14/2008 17:35'! genReturnTopToCaller "See BlueBook page 596" "124-125 0111110i Return Stack Top From (Message, Block) [i]" stream nextPut: 125! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 17:00'! genSendSuper: selectorLiteralIndex numArgs: nArgs "See BlueBook page 596 (with exceptions for 132 & 134)" nArgs < 0 ifTrue: [^self outOfRangeError: 'numArgs' index: nArgs range: 0 to: 31 "!!!!"]. selectorLiteralIndex < 0 ifTrue: [^self outOfRangeError: 'selector literal index' index: selectorLiteralIndex range: 0 to: 255]. (selectorLiteralIndex < 32 and: [nArgs < 8]) ifTrue: [" 133 10000011 jjjkkkkk Send Literal Selector #kkkkk To Superclass With jjj Arguments" stream nextPut: 133; nextPut: ((nArgs bitShift: 5) + selectorLiteralIndex). ^self]. (selectorLiteralIndex < 256 and: [nArgs < 32]) ifTrue: ["In Squeak V3 132 10000100 jjjjjjjj kkkkkkkk Send Literal Selector #kkkkkkkk With jjjjjjjj Arguments is replaced by 132 10000100 ooojjjjj kkkkkkkk ooo = 0 => Send Literal Selector #kkkkkkkk With jjjjj Arguments ooo = 1 => Send Literal Selector #kkkkkkkk To Superclass With jjjjj Arguments" stream nextPut: 132; nextPut: 32 + nArgs; nextPut: selectorLiteralIndex. ^self]. nArgs >= 32 ifTrue: [^self outOfRangeError: 'numArgs' index: nArgs range: 0 to: 31]. selectorLiteralIndex >= 256 ifTrue: [^self outOfRangeError: 'selector literal index' index: selectorLiteralIndex range: 0 to: 255]! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 17:00'! genSend: selectorLiteralIndex numArgs: nArgs "See BlueBook page 596 (with exceptions for 132 & 134)" nArgs < 0 ifTrue: [^self outOfRangeError: 'numArgs' index: nArgs range: 0 to: 31 "!!!!"]. selectorLiteralIndex < 0 ifTrue: ["Special selector sends. 176-191 1011iiii Send Arithmetic Message #iiii 192-207 1100iiii Send Special Message #iiii" self flag: #yuck. (selectorLiteralIndex negated between: 176 and: 207) ifFalse: [^self outOfRangeError: 'special selector code' index: selectorLiteralIndex negated range: 176 to: 207]. stream nextPut: selectorLiteralIndex negated. ^self]. (selectorLiteralIndex < 16 and: [nArgs < 3]) ifTrue: [" 208-223 1101iiii Send Literal Selector #iiii With No Arguments 224-239 1110iiii Send Literal Selector #iiii With 1 Argument 240-255 1111iiii Send Literal Selector #iiii With 2 Arguments" stream nextPut: 208 + (nArgs * 16) + selectorLiteralIndex. ^self]. (selectorLiteralIndex < 32 and: [nArgs < 8]) ifTrue: [" 131 10000011 jjjkkkkk Send Literal Selector #kkkkk With jjj Arguments" stream nextPut: 131; nextPut: ((nArgs bitShift: 5) + selectorLiteralIndex). ^self]. (selectorLiteralIndex < 64 and: [nArgs < 4]) ifTrue: ["In Squeak V3 134 10000110 jjjjjjjj kkkkkkkk Send Literal Selector #kkkkkkkk To Superclass With jjjjjjjj Arguments is replaced by 134 10000110 jjkkkkkk Send Literal Selector #kkkkkk With jj Arguments" stream nextPut: 134; nextPut: ((nArgs bitShift: 6) + selectorLiteralIndex). ^self]. (selectorLiteralIndex < 256 and: [nArgs < 32]) ifTrue: ["In Squeak V3 132 10000100 jjjjjjjj kkkkkkkk Send Literal Selector #kkkkkkkk With jjjjjjjj Arguments is replaced by 132 10000100 ooojjjjj kkkkkkkk ooo = 0 => Send Literal Selector #kkkkkkkk With jjjjj Arguments ooo = 1 => Send Literal Selector #kkkkkkkk To Superclass With jjjjj Arguments" stream nextPut: 132; nextPut: nArgs; nextPut: selectorLiteralIndex. ^self]. nArgs >= 32 ifTrue: [^self outOfRangeError: 'numArgs' index: nArgs range: 0 to: 31]. selectorLiteralIndex >= 256 ifTrue: [^self outOfRangeError: 'selector literal index' index: selectorLiteralIndex range: 0 to: 255]! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 6/19/2008 08:51'! genStoreInstVarLong: instVarIndex "See BlueBook page 596" "See also MaybeContextInstanceVariableNode" (instVarIndex >= 0 and: [instVarIndex < 256]) ifTrue: ["132 10000100 iiijjjjj kkkkkkkk (Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj" stream nextPut: 132; nextPut: 160; nextPut: instVarIndex. ^self]. ^self outOfRangeError: 'index' index: instVarIndex range: 0 to: 255! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 6/19/2008 08:37'! genStoreInstVar: instVarIndex "See BlueBook page 596" (instVarIndex >= 0 and: [instVarIndex < 64]) ifTrue: ["129 10000001 jjkkkkkk Store (Receiver Variable, Temporary Location, Illegal, Literal Variable) [jj] #kkkkkk" stream nextPut: 129; nextPut: instVarIndex. ^self]. self genStoreInstVarLong: instVarIndex! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 17:01'! genStoreLiteralVar: literalIndex "See BlueBook page 596" literalIndex < 0 ifTrue: [^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255]. literalIndex < 64 ifTrue: ["129 10000001 jjkkkkkk Store (Receiver Variable, Temporary Location, Illegal, Literal Variable) [jj] #kkkkkk" stream nextPut: 129; nextPut: 192 + literalIndex. ^self]. literalIndex < 256 ifTrue: ["132 10000100 iiijjjjj kkkkkkkk (Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj" stream nextPut: 132; nextPut: 224; nextPut: literalIndex. ^self]. ^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 6/19/2008 08:52'! genStorePopInstVarLong: instVarIndex "See BlueBook page 596" "See also MaybeContextInstanceVariableNode" (instVarIndex >= 0 and: [instVarIndex < 256]) ifTrue: ["132 10000100 iiijjjjj kkkkkkkk (Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj" stream nextPut: 132; nextPut: 192; nextPut: instVarIndex. ^self]. ^self outOfRangeError: 'index' index: instVarIndex range: 0 to: 255! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 6/19/2008 08:43'! genStorePopInstVar: instVarIndex "See BlueBook page 596" instVarIndex >= 0 ifTrue: [instVarIndex < 8 ifTrue: ["96-103 01100iii Pop and Store Receiver Variable #iii" stream nextPut: 96 + instVarIndex. ^self]. instVarIndex < 64 ifTrue: ["130 10000010 jjkkkkkk Pop and Store (Receiver Variable, Temporary Location, Illegal, Literal Variable) [jj] #kkkkkk" stream nextPut: 130; nextPut: instVarIndex. ^self]]. self genStorePopInstVarLong: instVarIndex! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 17:01'! genStorePopLiteralVar: literalIndex "See BlueBook page 596" literalIndex < 0 ifTrue: [^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255]. literalIndex < 64 ifTrue: ["130 10000010 jjkkkkkk Pop and Store (Receiver Variable, Temporary Location, Illegal, Literal Variable) [jj] #kkkkkk" stream nextPut: 130; nextPut: 192 + literalIndex. ^self]. literalIndex < 256 ifTrue: ["132 10000100 iiijjjjj kkkkkkkk (Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj" stream nextPut: 132; nextPut: 224; nextPut: literalIndex. self genPop. ^self]. ^self outOfRangeError: 'index' index: literalIndex range: 0 to: 255! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 17:01'! genStorePopTemp: tempIndex "See BlueBook page 596" tempIndex < 0 ifTrue: [^self outOfRangeError: 'index' index: tempIndex range: 0 to: 63]. tempIndex < 8 ifTrue: ["104-111 01101iii Pop and Store Temporary Location #iii" stream nextPut: 104 + tempIndex. ^self]. tempIndex < 64 ifTrue: ["130 10000010 jjkkkkkk Pop and Store (Receiver Variable, Temporary Location, Illegal, Literal Variable) [jj] #kkkkkk" stream nextPut: 130; nextPut: 64 + tempIndex. ^self]. ^self outOfRangeError: 'index' index: tempIndex range: 0 to: 63! ! !EncoderForV3 methodsFor: 'bytecode generation' stamp: 'eem 5/30/2008 17:01'! genStoreTemp: tempIndex "See BlueBook page 596" tempIndex < 0 ifTrue: [^self outOfRangeError: 'index' index: tempIndex range: 0 to: 63]. tempIndex < 64 ifTrue: ["129 10000001 jjkkkkkk Store (Receiver Variable, Temporary Location, Illegal, Literal Variable) [jj] #kkkkkk" stream nextPut: 129; nextPut: 64 + tempIndex. ^self]. ^self outOfRangeError: 'index' index: tempIndex range: 0 to: 63! ! !RelativeInstructionPrinter methodsFor: 'initialize-release' stamp: 'eem 5/15/2008 10:56'! printCode: aBoolean printCode := aBoolean! ! !RelativeInstructionPrinter methodsFor: 'printing' stamp: 'eem 5/15/2008 10:56'! printCode ^printCode ~~ false! ! !RelativeInstructionPrinter methodsFor: 'printing' stamp: 'eem 5/21/2008 12:24'! printInstructionsOn: aStream "Append to the stream, aStream, a description of each bytecode in the instruction stream." | label | labelling := true. labels := Array new: method size + 1 withAll: false. super printInstructionsOn: (String new: 1024) writeStream. label := 0. labels withIndexDo: [:bool :index| bool ifTrue: [labels at: index put: 'L', (label := label + 1) printString]]. labelling := false. super printInstructionsOn: aStream! ! !RelativeInstructionPrinter methodsFor: 'printing' stamp: 'eem 5/15/2008 13:17'! printInstructionsOn: aStream do: aBlock "Append to the stream, aStream, a description of each bytecode in the instruction stream. Evaluate aBlock with the receiver, the scanner and the stream after each instruction." | label | labelling := true. labels := Array new: method size withAll: false. super printInstructionsOn: (String new: 1024) writeStream do: [:ig :no :re|]. label := 0. labels withIndexDo: [:bool :index| bool ifTrue: [labels at: index put: 'L', (label := label + 1) printString]]. labelling := false. super printInstructionsOn: aStream do: aBlock! ! !RelativeInstructionPrinter methodsFor: 'printing' stamp: 'eem 5/29/2008 13:49'! print: instruction "Append to the receiver a description of the bytecode, instruction." stream tab: self indent. labelling ifTrue: [stream print: oldPC - method initialPC; space] ifFalse: [stream tab]. stream tab: (innerIndents at: oldPC). self printCode ifTrue: [stream nextPut: $<. oldPC to: scanner pc - 1 do: [:i | | code | code := (method at: i) radix: 16. stream nextPut: (code size < 2 ifTrue: [$0] ifFalse: [code at: 1]); nextPut: code last; space]. stream skip: -1; nextPut: $>; space]. stream nextPutAll: instruction. stream cr. labelling ifFalse: [(labels at: scanner pc + 1) ~~ false ifTrue: [stream nextPutAll: (labels at: scanner pc + 1); nextPut: $:; cr]]. oldPC := scanner pc! ! !RelativeInstructionPrinter methodsFor: 'instruction decoding' stamp: 'eem 5/15/2008 11:29'! jump: offset "Print the Unconditional Jump bytecode." labelling ifTrue: [labels at: scanner pc + offset + 1 put: true. self print: 'jumpBy: ', offset printString, ' to: ', (scanner pc + offset - method initialPC) printString] ifFalse: [self print: 'jumpTo: ', (labels at: scanner pc + offset + 1)]! ! !RelativeInstructionPrinter methodsFor: 'instruction decoding' stamp: 'eem 5/15/2008 11:29'! jump: offset if: condition "Print the Conditional Jump bytecode." labelling ifTrue: [labels at: scanner pc + offset + 1 put: true. self print: (condition ifTrue: ['jumpTrueBy: '] ifFalse: ['jumpFalseBy: ']), offset printString, ' to: ', (labelling ifTrue: [(scanner pc + offset - method initialPC) printString] ifFalse: [labels at: scanner pc + offset])] ifFalse: [self print: (condition ifTrue: ['jumpTrueTo: '] ifFalse: ['jumpFalseTo: ']), (labels at: scanner pc + offset + 1)]! ! !RelativeInstructionPrinter methodsFor: 'instruction decoding' stamp: 'eem 5/16/2008 17:10'! send: selector super: supered numArgs: numArgs "Print the Send Message With Selector, selector, bytecode. The argument, supered, indicates whether the receiver of the message is specified with 'super' in the source method. The arguments of the message are found in the top numArguments locations on the stack and the receiver just below them." self print: (supered ifTrue: ['superSend: '] ifFalse: ['send: ']) , selector storeString , (numArgs = 1 ifTrue: [' (1 arg)'] ifFalse: [' (', numArgs printString, ' args)'])! ! !UndeclaredVariableWarning methodsFor: 'initialize-release' stamp: 'eem 7/27/2008 17:37'! name: aString selector: aSymbolOrNil class: aBehavior name := aString. selector := aSymbolOrNil. class := aBehavior! ! !UndeclaredVariableWarning methodsFor: 'exceptionDescription' stamp: 'eem 7/29/2008 15:09'! defaultAction "The user should be notified of the occurrence of an exceptional occurrence and given an option of continuing or aborting the computation. The description of the occurrence should include any text specified as the argument of the #signal: message." selector ifNotNil: [Transcript nextPutAll: class name, '>>', selector, ' ']. Transcript show: '(' , name , ' is Undeclared) '. ^true! ! !CompiledMethod methodsFor: 'printing' stamp: 'eem 5/15/2008 11:04'! abstractSymbolic "Answer a String that contains a list of all the byte codes in a method with a short description of each, using relative addresses and not including code bytes." | aStream | aStream := WriteStream on: (String new: 1000). self longPrintRelativeOn: aStream indent: 0. ^aStream contents! ! !Compiler methodsFor: 'public access' stamp: 'eem 5/15/2008 15:07'! parser: aParser parser := aParser! ! !InstructionPrinter methodsFor: 'accessing' stamp: 'eem 5/29/2008 13:50'! printPC ^printPC! ! !InstructionPrinter methodsFor: 'accessing' stamp: 'eem 5/29/2008 13:50'! printPC: aBoolean printPC := aBoolean! ! !InstructionStream methodsFor: 'scanning' stamp: 'eem 6/16/2008 09:52'! firstByte "Answer the first byte of the current bytecode." ^self method at: pc! ! !InstructionStream methodsFor: 'scanning' stamp: 'eem 6/16/2008 09:53'! fourthByte "Answer the fourth byte of the current bytecode." ^self method at: pc + 3! ! !InstructionStream methodsFor: 'scanning' stamp: 'eem 6/16/2008 09:52'! secondByte "Answer the second byte of the current bytecode." ^self method at: pc + 1! ! !InstructionStream methodsFor: 'scanning' stamp: 'eem 6/16/2008 09:52'! thirdByte "Answer the third byte of the current bytecode." ^self method at: pc + 2! ! !MethodProperties methodsFor: 'testing' stamp: 'eem 5/15/2008 09:25'! hasAtLeastTheSamePropertiesAs: aMethodProperties "Answer if the recever has at least the same properties as the argument. N.B. The receiver may have additional properties and still answer true." aMethodProperties keysAndValuesDo: [:k :v| properties ifNil: [^false]. ^(properties at: k ifAbsent: [^false]) = v]. ^true! ! !ParseNode methodsFor: 'private' stamp: 'eem 5/14/2008 17:29'! notYetImplemented self flag: 'remove eventually'. self error: 'Not yet implemented (', thisContext sender printString, ')'! ! !ParseNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 14:52'! emitCodeForBlockValue: stack encoder: encoder "Generate code for evaluating the last statement in a block" ^self emitCodeForValue: stack encoder: encoder! ! !ParseNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:37'! emitCodeForBranchOn: condition dist: dist pop: stack encoder: encoder stack pop: 1. dist = 0 ifTrue: [^encoder genPop]. condition ifTrue: [encoder genBranchPopTrue: dist] ifFalse: [encoder genBranchPopFalse: dist]! ! !ParseNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:38'! emitCodeForEffect: stack encoder: encoder self emitCodeForValue: stack encoder: encoder. encoder genPop. stack pop: 1! ! !ParseNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:39'! emitCodeForJump: dist encoder: encoder dist = 0 ifFalse: [encoder genJump: dist]! ! !ParseNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:38'! emitCodeForReturn: stack encoder: encoder self emitCodeForValue: stack encoder: encoder. encoder genReturnTop! ! !ParseNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 14:52'! sizeCodeForBlockValue: encoder "Answer the size for evaluating the last statement in a block" ^self sizeCodeForValue: encoder! ! !ParseNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:53'! sizeCodeForEffect: encoder ^(self sizeCodeForValue: encoder) + encoder sizePop! ! !ParseNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:57'! sizeCodeForReturn: encoder ^(self sizeCodeForValue: encoder) + encoder sizeReturnTop! ! !BlockNode methodsFor: 'accessing' stamp: 'eem 7/27/2008 15:57'! arguments ^arguments! ! !BlockNode methodsFor: 'accessing' stamp: 'eem 7/27/2008 15:57'! temporaries ^temporaries! ! !BlockNode methodsFor: 'code generation (new scheme)' stamp: 'eem 6/2/2008 13:29'! emitCodeExceptLast: stack encoder: encoder | position nextToLast | position := stack position. nextToLast := statements size - 1. 1 to: nextToLast do: [:i | | statement | statement := statements at: i. statement emitCodeForEffect: stack encoder: encoder. self assert: stack position = position].! ! !BlockNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/21/2008 11:28'! emitCodeForEvaluatedEffect: stack encoder: encoder | position | position := stack position. self returns ifTrue: [self emitCodeForEvaluatedValue: stack encoder: encoder. stack pop: 1] ifFalse: [self emitCodeExceptLast: stack encoder: encoder. statements last emitCodeForEffect: stack encoder: encoder]. self assert: stack position = position! ! !BlockNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/21/2008 11:36'! emitCodeForEvaluatedValue: stack encoder: encoder | position | position := stack position. self emitCodeExceptLast: stack encoder: encoder. statements last emitCodeForBlockValue: stack encoder: encoder. self assert: stack position - 1 = position! ! !BlockNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/20/2008 16:55'! emitCodeForValue: stack encoder: encoder self generateAsClosure ifTrue: [^self emitCodeForClosureValue: stack encoder: encoder]. encoder genPushThisContext. stack push: 1. nArgsNode emitCodeForValue: stack encoder: encoder. remoteCopyNode emitCode: stack args: 1 encoder: encoder. "Force a two byte jump." encoder genJumpLong: size. stack push: arguments size. arguments reverseDo: [:arg | arg emitCodeForStorePop: stack encoder: encoder]. self emitCodeForEvaluatedValue: stack encoder: encoder. self returns ifFalse: [encoder genReturnTopToCaller. pc := encoder methodStreamPosition]. stack pop: 1! ! !BlockNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/29/2008 15:21'! sizeCodeExceptLast: encoder | codeSize | codeSize := 0. 1 to: statements size - 1 do: [:i | | statement | statement := statements at: i. codeSize := codeSize + (statement sizeCodeForEffect: encoder)]. ^codeSize! ! !BlockNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 17:13'! sizeCodeForEvaluatedEffect: encoder ^self returns ifTrue: [self sizeCodeForEvaluatedValue: encoder] ifFalse: [(self sizeCodeExceptLast: encoder) + (statements last sizeCodeForEffect: encoder)]! ! !BlockNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 14:52'! sizeCodeForEvaluatedValue: encoder ^(self sizeCodeExceptLast: encoder) + (statements last sizeCodeForBlockValue: encoder)! ! !BlockNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/20/2008 16:55'! sizeCodeForValue: encoder self generateAsClosure ifTrue: [^self sizeCodeForClosureValue: encoder]. nArgsNode := encoder encodeLiteral: arguments size. remoteCopyNode := encoder encodeSelector: #blockCopy:. size := self sizeCodeForEvaluatedValue: encoder. self returns ifFalse: [size := size + encoder sizeReturnTopToCaller]. "endBlock" arguments := arguments collect: "Chance to prepare debugger remote temps" [:arg | arg asStorableNode: encoder]. arguments do: [:arg | size := size + (arg sizeCodeForStorePop: encoder)]. ^encoder sizePushThisContext + (nArgsNode sizeCodeForValue: encoder) + (remoteCopyNode sizeCode: encoder args: 1 super: false) + (encoder sizeJumpLong: size) + size! ! !BraceNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/30/2008 17:40'! emitCodeForValue: stack encoder: encoder (encoder supportsClosureOpcodes "Hack; we have no way of knowing how much stack space is available" and: [elements size <= self maxElementsForConsArray]) ifTrue: [elements do: [:node| node emitCodeForValue: stack encoder: encoder]. encoder genPushConsArray: elements size. stack pop: elements size; push: 1. ^self]. ^emitNode emitCodeForValue: stack encoder: encoder! ! !BraceNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/30/2008 17:22'! sizeCodeForValue: encoder (encoder supportsClosureOpcodes "Hack; we have no way of knowing how much stack space is available" and: [elements size <= self maxElementsForConsArray]) ifTrue: [^(elements inject: 0 into: [:sum :node| sum + (node sizeCodeForValue: encoder)]) + (encoder sizePushConsArray: elements size)]. emitNode := elements size <= 4 ifTrue: ["Short form: Array braceWith: a with: b ... " MessageNode new receiver: (encoder encodeVariable: #Array) selector: (self selectorForShortForm: elements size) arguments: elements precedence: 3 from: encoder] ifFalse: ["Long form: (Array braceStream: N) nextPut: a; nextPut: b; ...; braceArray" CascadeNode new receiver: (MessageNode new receiver: (encoder encodeVariable: #Array) selector: #braceStream: arguments: (Array with: (encoder encodeLiteral: elements size)) precedence: 3 from: encoder) messages: ((elements collect: [:elt | MessageNode new receiver: nil selector: #nextPut: arguments: (Array with: elt) precedence: 3 from: encoder]) copyWith: (MessageNode new receiver: nil selector: #braceArray arguments: (Array new) precedence: 1 from: encoder))]. ^emitNode sizeCodeForValue: encoder! ! !CascadeNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/15/2008 09:41'! emitCodeForValue: stack encoder: encoder receiver emitCodeForValue: stack encoder: encoder. 1 to: messages size - 1 do: [:i | encoder genDup. stack push: 1. (messages at: i) emitCodeForValue: stack encoder: encoder. encoder genPop. stack pop: 1]. messages last emitCodeForValue: stack encoder: encoder! ! !CascadeNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/15/2008 09:39'! sizeCodeForValue: encoder | size | size := (receiver sizeCodeForValue: encoder) + (messages size - 1 * (encoder sizeDup + encoder sizePop)). messages do: [:aMessage | size := size + (aMessage sizeCodeForValue: encoder)]. ^size! ! !Encoder methodsFor: 'results' stamp: 'eem 5/19/2008 10:25'! associationForClass | name assoc | assoc := Smalltalk associationAt: class name ifAbsent:[nil]. assoc value == class ifTrue:[^assoc]. name := Smalltalk keyAtIdentityValue: class ifAbsent: [^Association new value: class]. ^Smalltalk associationAt: name! ! !LeafNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 14:52'! emitCodeForEffect: stack encoder: encoder ^self! ! !LeafNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/20/2008 15:25'! emitCodeForLoad: stack encoder: encoder "Default is to do nothing. Subclasses may need to override."! ! !LeafNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 14:52'! sizeCodeForEffect: encoder ^0! ! !LeafNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/20/2008 15:24'! sizeCodeForLoad: encoder "Default is to do nothing. Subclasses may need to override." ^0! ! !LeafNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/19/2008 15:10'! sizeCodeForValue: encoder self subclassResponsibility! ! !LiteralNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:19'! emitCodeForValue: stack encoder: encoder stack push: 1. (encoder if: code isSpecialLiteralForPush: [:specialLiteral| encoder genPushSpecialLiteral: specialLiteral]) ifFalse: [encoder genPushLiteral: index]! ! !LiteralNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 17:03'! sizeCodeForValue: encoder self reserve: encoder. (encoder if: code isSpecialLiteralForPush: [:specialLiteral| ^encoder sizePushSpecialLiteral: specialLiteral]) ifFalse: [^encoder sizePushLiteral: index]! ! !MessageNode methodsFor: 'code generation (new scheme)' stamp: 'eem 7/29/2008 20:18'! emitCodeForCase: stack encoder: encoder value: forValue | braceNode sizeStream | forValue ifFalse: [^super emitCodeForEffect: stack encoder: encoder]. braceNode := arguments first. sizeStream := ReadStream on: sizes. receiver emitCodeForValue: stack encoder: encoder. braceNode casesForwardDo: [:keyNode :valueNode :last | | thenSize elseSize | thenSize := sizeStream next. elseSize := sizeStream next. last ifFalse: [encoder genDup. stack push: 1]. keyNode emitCodeForEvaluatedValue: stack encoder: encoder. equalNode emitCode: stack args: 1 encoder: encoder. self emitCodeForBranchOn: false dist: thenSize pop: stack encoder: encoder. last ifFalse: [encoder genPop. stack pop: 1]. valueNode emitCodeForEvaluatedValue: stack encoder: encoder. last ifTrue: [stack pop: 1]. valueNode returns ifFalse: [self emitCodeForJump: elseSize encoder: encoder]]. arguments size = 2 ifTrue: [arguments last emitCodeForEvaluatedValue: stack encoder: encoder] "otherwise: [...]" ifFalse: [NodeSelf emitCodeForValue: stack encoder: encoder. caseErrorNode emitCode: stack args: 0 encoder: encoder]! ! !MessageNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 18:13'! emitCodeForEffect: stack encoder: encoder "For #ifTrue:ifFalse: and #whileTrue: / #whileFalse: style messages, the pc is set to the jump instruction, so that mustBeBoolean exceptions can be shown correctly." special > 0 ifTrue: [pc := 0. self perform: (NewStyleMacroEmitters at: special) with: stack with: encoder with: false] ifFalse: [super emitCodeForEffect: stack encoder: encoder]! ! !MessageNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:28'! emitCodeForIfNil: stack encoder: encoder value: forValue | theNode theSize ifNotNilSelector | theNode := arguments first. theSize := sizes at: 1. ifNotNilSelector := #ifNotNil:. receiver emitCodeForValue: stack encoder: encoder. forValue ifTrue: [encoder genDup. stack push: 1]. encoder genPushSpecialLiteral: nil. stack push: 1. equalNode emitCode: stack args: 1 encoder: encoder. self emitCodeForBranchOn: (selector key == ifNotNilSelector) dist: theSize pop: stack encoder: encoder. pc := encoder methodStreamPosition. forValue ifTrue: [encoder genPop. stack pop: 1. theNode emitCodeForEvaluatedValue: stack encoder: encoder] ifFalse: [theNode emitCodeForEvaluatedEffect: stack encoder: encoder]! ! !MessageNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 17:12'! emitCodeForIf: stack encoder: encoder value: forValue | thenExpr thenSize elseExpr elseSize | thenSize := sizes at: 1. elseSize := sizes at: 2. (forValue not and: [elseSize * thenSize > 0]) ifTrue: "Two-armed IFs forEffect share a single pop" [^super emitCodeForEffect: stack encoder: encoder]. thenExpr := arguments at: 1. elseExpr := arguments at: 2. receiver emitCodeForValue: stack encoder: encoder. forValue ifTrue: "Code all forValue as two-armed" [self emitCodeForBranchOn: false dist: thenSize pop: stack encoder: encoder. pc := encoder methodStreamPosition. thenExpr emitCodeForEvaluatedValue: stack encoder: encoder. stack pop: 1. "then and else alternate; they don't accumulate" thenExpr returns not ifTrue: "...not ifTrue: avoids using ifFalse: alone during this compile)" "Elide jump over else after a return" [self emitCodeForJump: elseSize encoder: encoder]. elseExpr emitCodeForEvaluatedValue: stack encoder: encoder] ifFalse: "One arm is empty here (two-arms code forValue)" [thenSize > 0 ifTrue: [self emitCodeForBranchOn: false dist: thenSize pop: stack encoder: encoder. pc := encoder methodStreamPosition. thenExpr emitCodeForEvaluatedEffect: stack encoder: encoder] ifFalse: [self emitCodeForBranchOn: true dist: elseSize pop: stack encoder: encoder. pc := encoder methodStreamPosition. elseExpr emitCodeForEvaluatedEffect: stack encoder: encoder]]! ! !MessageNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:31'! emitCodeForToDo: stack encoder: encoder value: forValue " var _ rcvr. L1: [var <= arg1] Bfp(L2) [block body. var _ var + inc] Jmp(L1) L2: " | loopSize initStmt limitInit test block incStmt blockSize | initStmt := arguments at: 4. limitInit := arguments at: 7. test := arguments at: 5. block := arguments at: 3. incStmt := arguments at: 6. blockSize := sizes at: 1. loopSize := sizes at: 2. limitInit == nil ifFalse: [limitInit emitCodeForEffect: stack encoder: encoder]. initStmt emitCodeForEffect: stack encoder: encoder. test emitCodeForValue: stack encoder: encoder. self emitCodeForBranchOn: false dist: blockSize pop: stack encoder: encoder. pc := encoder methodStreamPosition. block emitCodeForEvaluatedEffect: stack encoder: encoder. incStmt emitCodeForEffect: stack encoder: encoder. self emitCodeForJump: 0 - loopSize encoder: encoder. forValue ifTrue: [encoder genPushSpecialLiteral: nil. stack push: 1]! ! !MessageNode methodsFor: 'code generation (new scheme)' stamp: 'eem 6/5/2008 16:48'! emitCodeForValue: stack encoder: encoder "For #ifTrue:ifFalse: and #whileTrue: / #whileFalse: style messages, the pc is set to the jump instruction, so that mustBeBoolean exceptions can be shown correctly." special > 0 ifTrue: [pc := 0. self perform: (NewStyleMacroEmitters at: special) with: stack with: encoder with: true] ifFalse: [receiver ~~ nil ifTrue: [receiver emitCodeForValue: stack encoder: encoder]. arguments do: [:argument | argument emitCodeForValue: stack encoder: encoder]. pc := encoder methodStreamPosition + 1. "debug pc is first byte of the send, i.e. the next byte". selector emitCode: stack args: arguments size encoder: encoder super: receiver == NodeSuper]! ! !MessageNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:36'! emitCodeForWhile: stack encoder: encoder value: forValue "L1: ... Bfp(L2)|Btp(L2) ... Jmp(L1) L2: " | cond stmt stmtSize loopSize | cond := receiver. stmt := arguments at: 1. stmtSize := sizes at: 1. loopSize := sizes at: 2. cond emitCodeForEvaluatedValue: stack encoder: encoder. self emitCodeForBranchOn: (selector key == #whileFalse:) "Bfp for whileTrue" dist: stmtSize pop: stack encoder: encoder. "Btp for whileFalse" pc := encoder methodStreamPosition. stmt emitCodeForEvaluatedEffect: stack encoder: encoder. self emitCodeForJump: 0 - loopSize encoder: encoder. forValue ifTrue: [encoder genPushSpecialLiteral: nil. stack push: 1]! ! !MessageNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/15/2008 11:36'! sizeCodeForCase: encoder value: forValue | braceNode sizeIndex thenSize elseSize | forValue not ifTrue: [^super sizeCodeForEffect: encoder]. equalNode := encoder encodeSelector: #=. braceNode := arguments first. sizes := Array new: 2 * braceNode numElements. sizeIndex := sizes size. elseSize := arguments size = 2 ifTrue: [arguments last sizeCodeForEvaluatedValue: encoder] "otherwise: [...]" ifFalse: [caseErrorNode := encoder encodeSelector: #caseError. (NodeSelf sizeCodeForValue: encoder) + (caseErrorNode sizeCode: encoder args: 0 super: false)]. "self caseError" braceNode casesReverseDo: [:keyNode :valueNode :last | sizes at: sizeIndex put: elseSize. thenSize := valueNode sizeCodeForEvaluatedValue: encoder. last ifFalse: [thenSize := thenSize + encoder sizePop]. valueNode returns ifFalse: [thenSize := thenSize + (self sizeCode: encoder forJump: elseSize)]. sizes at: sizeIndex-1 put: thenSize. last ifFalse: [elseSize := elseSize + encoder sizeDup]. elseSize := elseSize + (keyNode sizeCodeForEvaluatedValue: encoder) + (equalNode sizeCode: encoder args: 1 super: false) + (self sizeCode: encoder forBranchOn: false dist: thenSize) + thenSize. sizeIndex := sizeIndex - 2]. ^(receiver sizeCodeForValue: encoder) + elseSize! ! !MessageNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 18:16'! sizeCodeForEffect: encoder special > 0 ifTrue: [^self perform: (NewStyleMacroSizers at: special) with: encoder with: false]. ^super sizeCodeForEffect: encoder! ! !MessageNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/15/2008 09:57'! sizeCodeForIfNil: encoder value: forValue | theNode theSize theSelector | equalNode := encoder encodeSelector: #==. sizes := Array new: 1. theNode := arguments first. theSelector := #ifNotNil:. forValue ifTrue: [sizes at: 1 put: (theSize := (encoder sizePop + (theNode sizeCodeForEvaluatedValue: encoder))). ^(receiver sizeCodeForValue: encoder) + encoder sizeDup + (encoder sizePushSpecialLiteral: nil) + (equalNode sizeCode: encoder args: 1 super: false) + (self sizeCode: encoder forBranchOn: selector key == theSelector dist: theSize) + theSize] ifFalse: [sizes at: 1 put: (theSize := (theNode sizeCodeForEvaluatedEffect: encoder)). ^(receiver sizeCodeForValue: encoder) + (encoder sizePushSpecialLiteral: nil) + (equalNode sizeCode: encoder args: 1 super: false) + (self sizeCode: encoder forBranchOn: selector key == theSelector dist: theSize) + theSize]! ! !MessageNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 17:15'! sizeCodeForIf: encoder value: forValue | thenExpr elseExpr branchSize thenSize elseSize | thenExpr := arguments at: 1. elseExpr := arguments at: 2. (forValue or: [(thenExpr isJust: NodeNil) or: [elseExpr isJust: NodeNil]]) not "(...not ifTrue: avoids using ifFalse: alone during this compile)" ifTrue: "Two-armed IFs forEffect share a single pop" [^super sizeCodeForEffect: encoder]. forValue ifTrue: "Code all forValue as two-armed" [elseSize := elseExpr sizeCodeForEvaluatedValue: encoder. thenSize := (thenExpr sizeCodeForEvaluatedValue: encoder) + (thenExpr returns ifTrue: [0] "Elide jump over else after a return" ifFalse: [self sizeCode: encoder forJump: elseSize]). branchSize := self sizeCode: encoder forBranchOn: false dist: thenSize] ifFalse: "One arm is empty here (two-arms code forValue)" [(elseExpr isJust: NodeNil) ifTrue: [elseSize := 0. thenSize := thenExpr sizeCodeForEvaluatedEffect: encoder. branchSize := self sizeCode: encoder forBranchOn: false dist: thenSize] ifFalse: [thenSize := 0. elseSize := elseExpr sizeCodeForEvaluatedEffect: encoder. branchSize := self sizeCode: encoder forBranchOn: true dist: elseSize]]. sizes := Array with: thenSize with: elseSize. ^(receiver sizeCodeForValue: encoder) + branchSize + thenSize + elseSize! ! !MessageNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/19/2008 15:09'! sizeCodeForToDo: encoder value: forValue " var := rcvr. L1: [var <= arg1] Bfp(L2) [block body. var := var + inc] Jmp(L1) L2: " | loopSize initStmt test block incStmt blockSize initSize limitInit | block := arguments at: 3. initStmt := arguments at: 4. test := arguments at: 5. incStmt := arguments at: 6. limitInit := arguments at: 7. initSize := initStmt sizeCodeForEffect: encoder. limitInit == nil ifFalse: [initSize := initSize + (limitInit sizeCodeForEffect: encoder)]. blockSize := (block sizeCodeForEvaluatedEffect: encoder) + (incStmt sizeCodeForEffect: encoder) + (encoder sizeJumpLong: -1). loopSize := (test sizeCodeForValue: encoder) + (self sizeCode: encoder forBranchOn: false dist: blockSize) + blockSize. sizes := Array with: blockSize with: loopSize. ^initSize + loopSize + (forValue ifTrue: [encoder sizePushSpecialLiteral: nil] ifFalse: [0])! ! !MessageNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 18:17'! sizeCodeForValue: encoder | total argSize | special > 0 ifTrue: [^self perform: (NewStyleMacroSizers at: special) with: encoder with: true]. receiver == NodeSuper ifTrue: [selector := selector copy "only necess for splOops"]. total := selector sizeCode: encoder args: arguments size super: receiver == NodeSuper. receiver == nil ifFalse: [total := total + (receiver sizeCodeForValue: encoder)]. sizes := arguments collect: [:arg | argSize := arg sizeCodeForValue: encoder. total := total + argSize. argSize]. ^total! ! !MessageNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/15/2008 10:00'! sizeCodeForWhile: encoder value: forValue "L1: ... Bfp(L2) ... Jmp(L1) L2: nil (nil for value only); justStmt, wholeLoop, justJump." | cond stmt stmtSize loopSize branchSize | cond := receiver. stmt := arguments at: 1. stmtSize := (stmt sizeCodeForEvaluatedEffect: encoder) + (encoder sizeJumpLong: 1). branchSize := self sizeCode: encoder forBranchOn: selector key == #whileFalse: "Btp for whileFalse" dist: stmtSize. loopSize := (cond sizeCodeForEvaluatedValue: encoder) + branchSize + stmtSize. sizes := Array with: stmtSize with: loopSize. ^loopSize + (forValue ifTrue: [encoder sizePushSpecialLiteral: nil] ifFalse: [0])! ! !MessageAsTempNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 14:52'! emitCodeForStorePop: stack encoder: encoder "This node has the form {expr storeAt: offset inTempFrame: homeContext}, where the expr, the block argument, is already on the stack." ^self emitCodeForEffect: stack encoder: encoder! ! !MessageAsTempNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 14:52'! sizeCodeForStorePop: encoder "This node has the form {expr storeAt: offset inTempFrame: homeContext}, where the expr, the block argument, is already on the stack." ^self sizeCodeForEffect: encoder! ! !Parser methodsFor: 'public access' stamp: 'eem 5/14/2008 15:24'! encoderClass: anEncoderClass encoder notNil ifTrue: [self error: 'encoder already set']. encoder := anEncoderClass new! ! !ReturnNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:40'! emitCodeForReturn: stack encoder: encoder expr emitCodeForReturn: stack encoder: encoder. pc := encoder methodStreamPosition! ! !ReturnNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:40'! emitCodeForValue: stack encoder: encoder expr emitCodeForReturn: stack encoder: encoder. pc := encoder methodStreamPosition! ! !ReturnNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 14:52'! sizeCodeForReturn: encoder ^expr sizeCodeForReturn: encoder! ! !ReturnNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 14:52'! sizeCodeForValue: encoder ^expr sizeCodeForReturn: encoder! ! !SelectorNode methodsFor: 'code generation' stamp: 'eem 5/14/2008 16:08'! reserve: encoder "If this is a yet unused literal of type -code, reserve it." code < 0 ifTrue: [code := self code: (index := encoder sharableLitIndex: key) type: 0 - code]! ! !SelectorNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 14:52'! emitCodeForEffect: stack encoder: encoder self shouldNotImplement! ! !SelectorNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 14:52'! emitCodeForValue: stack encoder: encoder self shouldNotImplement! ! !SelectorNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 14:52'! emitCode: stack args: nArgs encoder: encoder self emitCode: stack args: nArgs encoder: encoder super: false! ! !SelectorNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 17:47'! emitCode: stack args: nArgs encoder: encoder super: supered stack pop: nArgs. ^supered ifTrue: [encoder genSendSuper: index numArgs: nArgs] ifFalse: [encoder genSend: (code < Send ifTrue: [code negated] ifFalse: [index]) numArgs: nArgs]! ! !SelectorNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 14:52'! sizeCodeForEffect: encoder self shouldNotImplement! ! !SelectorNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 14:52'! sizeCodeForValue: encoder self shouldNotImplement! ! !SelectorNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:15'! sizeCode: encoder args: nArgs super: supered self reserve: encoder. ^supered ifTrue: [code < Send "i.e. its a special selector" ifTrue: [code := self code: (index := encoder sharableLitIndex: key) type: 5]. encoder sizeSendSuper: index numArgs: nArgs] ifFalse: [self flag: #yuck. "special selector sends cause this problem" encoder sizeSend: (code < Send ifTrue: [code negated] ifFalse: [index]) numArgs: nArgs]! ! !VariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 14:52'! emitCodeForLoad: stack encoder: encoder "Do nothing"! ! !VariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:41'! emitCodeForReturn: stack encoder: encoder encoder if: code isSpecialLiteralForReturn: [:specialLiteral| "short returns" encoder genReturnSpecialLiteral: specialLiteral. stack push: 1 "doesnt seem right". ^self]. (self code = LdSelf or: [self code = LdSuper]) ifTrue: ["short returns" encoder genReturnReceiver. stack push: 1 "doesnt seem right". ^self]. super emitCodeForReturn: stack encoder: encoder! ! !VariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:41'! emitCodeForStorePop: stack encoder: encoder self type ~= 1 ifTrue: [self halt]. encoder genStorePopInstVar: index. stack pop: 1! ! !VariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 18:08'! emitCodeForStore: stack encoder: encoder self shouldNotImplement! ! !VariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 18:07'! emitCodeForValue: stack encoder: encoder stack push: 1. encoder if: code isSpecialLiteralForPush: [:specialLiteral| ^encoder genPushSpecialLiteral: specialLiteral]. (code = LdSelf or: [code = LdSuper]) ifTrue: [^encoder genPushReceiver]. code = LdThisContext ifTrue: [^encoder genPushThisContext]. self flag: 'probably superfluous'. self halt. ^encoder genPushInstVar: index! ! !VariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 16:58'! sizeCodeForReturn: encoder encoder if: code isSpecialLiteralForPush: [:specialLiteral| ^encoder sizeReturnSpecialLiteral: specialLiteral]. (self code = LdSelf or: [self code = LdSuper]) ifTrue: [^encoder sizeReturnReceiver]. ^super sizeCodeForReturn: encoder! ! !VariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 18:09'! sizeCodeForStorePop: encoder self shouldNotImplement! ! !VariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 18:09'! sizeCodeForStore: encoder self shouldNotImplement! ! !InstanceVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 18:08'! emitCodeForStore: stack encoder: encoder encoder genStoreInstVar: index! ! !InstanceVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 18:08'! emitCodeForValue: stack encoder: encoder stack push: 1. ^encoder genPushInstVar: index! ! !InstanceVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 18:07'! sizeCodeForStorePop: encoder ^encoder sizeStorePopInstVar: index! ! !InstanceVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 17:57'! sizeCodeForStore: encoder ^encoder sizeStoreInstVar: index! ! !LiteralVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/15/2008 09:44'! emitCodeForLoad: stack encoder: encoder writeNode ifNotNil: [encoder genPushLiteral: index. stack push: 1]! ! !LiteralVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/15/2008 10:09'! emitCodeForStorePop: stack encoder: encoder writeNode ifNil: [stack pop: 1. ^encoder genStorePopLiteralVar: index]. self emitCodeForStore: stack encoder: encoder. encoder genPop. stack pop: 1.! ! !LiteralVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/15/2008 10:43'! emitCodeForStore: stack encoder: encoder writeNode ifNil: [^encoder genStoreLiteralVar: index]. "THIS IS WRONG!!!! THE VALUE IS LOST FROM THE STACK!!!! The various value: methods on Association ReadOnlyVariableBinding etc _do not_ return the value assigned; they return the receiver." "Should generate something more like push expr push lit push temp (index of expr) send value: pop or use e.g. valueForStore:" self flag: #bogus. writeNode emitCode: stack args: 1 encoder: encoder super: false! ! !LiteralVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 18:11'! emitCodeForValue: stack encoder: encoder stack push: 1. ^encoder genPushLiteralVar: index! ! !LiteralVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/15/2008 09:45'! sizeCodeForLoad: encoder ^writeNode ifNil: [0] ifNotNil: [encoder sizePushLiteral: index]! ! !LiteralVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/15/2008 10:17'! sizeCodeForStorePop: encoder self reserve: encoder. ^(key isVariableBinding and: [key isSpecialWriteBinding]) ifTrue: [(self sizeCodeForStorePop: encoder) + encoder sizePop] ifFalse: [encoder sizeStorePopLiteralVar: index]! ! !LiteralVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 17:06'! sizeCodeForStore: encoder self reserve: encoder. (key isVariableBinding and: [key isSpecialWriteBinding]) ifFalse: [^encoder sizeStoreLiteralVar: index]. code < 0 ifTrue: [self flag: #dubious. self code: (self code: self index type: LdLitType)]. "THIS IS WRONG!!!! THE VALUE IS LOST FROM THE STACK!!!! The various value: methods on Association ReadOnlyVariableBinding etc _do not_ return the value assigned; they return the receiver." "Should generate something more like push expr push lit push temp (index of expr) send value: pop" self flag: #bogus. writeNode := encoder encodeSelector: #value:. ^(encoder sizePushLiteralVar: index) + (writeNode sizeCode: encoder args: 1 super: false)! ! !LiteralVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 17:03'! sizeCodeForValue: encoder self reserve: encoder. ^encoder sizePushLiteralVar: index! ! !TempVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/20/2008 14:54'! emitCodeForStorePop: stack encoder: encoder remoteNode ~~ nil ifTrue: [^remoteNode emitCodeForStorePopInto: self stack: stack encoder: encoder]. encoder genStorePopTemp: index. stack pop: 1! ! !TempVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/20/2008 14:53'! emitCodeForStore: stack encoder: encoder remoteNode ~~ nil ifTrue: [^remoteNode emitCodeForStoreInto: self stack: stack encoder: encoder]. encoder genStoreTemp: index! ! !TempVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/20/2008 14:53'! emitCodeForValue: stack encoder: encoder remoteNode ~~ nil ifTrue: [^remoteNode emitCodeForValueOf: self stack: stack encoder: encoder]. encoder genPushTemp: index. stack push: 1! ! !TempVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/20/2008 14:52'! sizeCodeForStorePop: encoder remoteNode ~~ nil ifTrue: [^remoteNode sizeCodeForStorePopInto: self encoder: encoder]. self reserve: encoder. ^encoder sizeStorePopTemp: index! ! !TempVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/20/2008 14:52'! sizeCodeForStore: encoder remoteNode ~~ nil ifTrue: [^remoteNode sizeCodeForStoreInto: self encoder: encoder]. self reserve: encoder. ^encoder sizeStoreTemp: index! ! !TempVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/20/2008 14:51'! sizeCodeForValue: encoder remoteNode ~~ nil ifTrue: [^remoteNode sizeCodeForValueOf: self encoder: encoder]. self reserve: encoder. ^encoder sizePushTemp: index! ! !CompiledMethod methodsFor: 'comparing' stamp: 'eem 7/29/2008 14:46'! = method | numLits | "Answer whether the receiver implements the same code as the argument, method." (method isKindOf: CompiledMethod) ifFalse: [^false]. self size = method size ifFalse: [^false]. self header = method header ifFalse: [^false]. self initialPC to: self endPC do: [:i | (self at: i) = (method at: i) ifFalse: [^false]]. (numLits := self numLiterals) ~= method numLiterals ifTrue: [^false]. "``Dont bother checking FFI and named primitives'' (#(117 120) includes: self primitive) ifTrue: [^ true]." 1 to: numLits do: [:i| | lit1 lit2 | lit1 := self literalAt: i. lit2 := method literalAt: i. lit1 = lit2 ifFalse: [(i = 1 and: [#(117 120) includes: self primitive]) ifTrue: [lit1 isArray ifTrue: [(lit2 isArray and: [lit1 allButLast = lit2 allButLast]) ifFalse: [^false]] ifFalse: "ExternalLibraryFunction" [(lit1 analogousCodeTo: lit2) ifFalse: [^false]]] ifFalse: [i = (numLits - 1) ifTrue: "properties" [(lit1 analogousCodeTo: lit2) ifFalse: [^false]] ifFalse: [lit1 isFloat ifTrue: ["Floats match if values are close, due to roundoff error." (lit1 closeTo: lit2) ifFalse: [^false]. self flag: 'just checking'. self halt] ifFalse: ["any other discrepancy is a failure" ^ false]]]]]. ^true! ! !CompiledMethod methodsFor: 'printing' stamp: 'eem 5/15/2008 10:57'! longPrintRelativeOn: aStream indent: tabs "List of all the byte codes in a method with a short description of each" self isQuick ifTrue: [^self longPrintOn: aStream indent: tabs]. self primitive = 0 ifFalse: [aStream tab: tabs. self printPrimitiveOn: aStream]. (RelativeInstructionPrinter on: self) indent: tabs; printCode: false; printInstructionsOn: aStream. ! ! !CompiledMethod methodsFor: 'printing' stamp: 'eem 5/29/2008 13:59'! symbolicLinesDo: aBlock "Evaluate aBlock with each of the lines in the symbolic output." | aStream pc | aStream := ReadWriteStream on: (String new: 64). self isQuick ifTrue: [self longPrintOn: aStream. aBlock value: 0 value: aStream contents. ^self]. self primitive ~= 0 ifTrue: [self printPrimitiveOn: aStream. aBlock value: 1 value: aStream contents. aStream resetContents]. pc := self initialPC. (InstructionPrinter on: self) indent: 0; printPC: false; "explorer provides pc anyway" printInstructionsOn: aStream do: [:printer :scanner :stream| | line index | line := stream contents allButLast. (line includes: Character cr) ifTrue: [line := (line copyUpTo: Character cr), '...'' (continues)']. (index := line indexOf: $>) > 0 ifTrue: [[(line at: index + 1) isSeparator] whileTrue: [index := index + 1]. line := ((line copyFrom: 1 to: index) copyReplaceAll: (String with: Character tab) with: (String new: 8 withAll: Character space)), (line copyFrom: index + 1 to: line size)]. aBlock value: pc value: line. pc := scanner pc. stream resetContents]! ! !CompiledMethod methodsFor: 'literals' stamp: 'eem 5/24/2008 15:35'! indexOfLiteral: literal "Answer the literal index of the argument, literal, or zero if none." | max | max := self numLiterals. max := self hasNewPropertyFormat ifTrue: [max - 1] "exclude superclass + properties" ifFalse: [max + 1]. 2 to: max do: [:index | literal == (self objectAt: index) ifTrue: [^index - 1]]. ^0! ! !CompiledMethod methodsFor: 'scanning' stamp: 'eem 6/19/2008 09:21'! readsField: varIndex "Answer whether the receiver loads the instance variable indexed by the argument." "eem 5/24/2008 Rewritten to no longer assume the compiler uses the most compact encoding available (for EncoderForLongFormV3 support)." | varIndexCode scanner | varIndexCode := varIndex - 1. self isReturnField ifTrue: [^self returnField = varIndexCode]. ^(scanner := InstructionStream on: self) scanFor: [:b| b < 16 ifTrue: [b = varIndexCode] ifFalse: [b = 128 ifTrue: [scanner followingByte = varIndexCode and: [varIndexCode <= 63]] ifFalse: [b = 132 and: [(scanner followingByte between: 64 and: 95) and: [scanner thirdByte = varIndexCode]]]]]! ! !CompiledMethod methodsFor: 'scanning' stamp: 'eem 5/24/2008 16:19'! readsRef: literalAssociation "Answer whether the receiver loads the argument." "eem 5/24/2008 Rewritten to no longer assume the compler uses the most compact encoding available (for EncoderForLongFormV3 support)." | litIndex scanner | (litIndex := self indexOfLiteral: literalAssociation) = 0 ifTrue: [^false]. litIndex := litIndex - 1. ^(scanner := InstructionStream on: self) scanFor: [:b| b >= 64 and: [b <= 95 ifTrue: [b - 64 = litIndex] ifFalse: [b = 128 ifTrue: [scanner followingByte - 192 = litIndex] ifFalse: [b = 132 and: [(scanner followingByte between: 128 and: 159) and: [scanner thirdByte = litIndex]]]]]]! ! !CompiledMethod methodsFor: 'scanning' stamp: 'eem 5/24/2008 16:21'! writesField: varIndex "Answer whether the receiver stores into the instance variable indexed by the argument." "eem 5/24/2008 Rewritten to no longer assume the compler uses the most compact encoding available (for EncoderForLongFormV3 support)." | varIndexCode scanner | self isQuick ifTrue: [^false]. varIndexCode := varIndex - 1. ^(scanner := InstructionStream on: self) scanFor: [:b| b >= 96 and: [b <= 103 ifTrue: [b - 96 = varIndexCode] ifFalse: [(b = 129 or: [b = 130]) ifTrue: [scanner followingByte = varIndexCode and: [varIndexCode <= 63]] ifFalse: [b = 132 and: [(scanner followingByte between: 160 and: 223) and: [scanner thirdByte = varIndexCode]]]]]]! ! !CompiledMethod methodsFor: 'scanning' stamp: 'eem 5/24/2008 16:14'! writesRef: literalAssociation "Answer whether the receiver stores into the argument." "eem 5/24/2008 Rewritten to no longer assume the compler uses the most compact encoding available (for EncoderForLongFormV3 support)." | litIndex scanner | (litIndex := self indexOfLiteral: literalAssociation) = 0 ifTrue: [^false]. litIndex := litIndex - 1. ^(scanner := InstructionStream on: self) scanFor: [:b| (b = 129 or: [b = 130]) ifTrue: [scanner followingByte - 192 = litIndex] ifFalse: [b = 132 and: [scanner followingByte >= 224 and: [scanner thirdByte = litIndex]]]]! ! !Compiler methodsFor: 'public access' stamp: 'eem 5/15/2008 15:13'! parser parser ifNil: [parser := self parserClass new]. ^parser! ! !Compiler methodsFor: 'public access' stamp: 'eem 5/15/2008 15:05'! parserClass ^parser ifNil: [self class parserClass] ifNotNil: [parser class]! ! !Compiler methodsFor: 'public access' stamp: 'eem 5/15/2008 15:06'! parserClass: aParserClass parser := aParserClass new! ! !Compiler methodsFor: 'public access' stamp: 'eem 5/15/2008 15:11'! parse: textOrStream in: aClass notifying: req "Compile the argument, textOrStream, with respect to the class, aClass, and answer the MethodNode that is the root of the resulting parse tree. Notify the argument, req, if an error occurs. The failBlock is defaulted to an empty block." self from: textOrStream class: aClass context: nil notifying: req. ^self parser parse: sourceStream class: class noPattern: false context: context notifying: requestor ifFail: []! ! !Compiler methodsFor: 'private' stamp: 'eem 5/15/2008 15:10'! format: aStream noPattern: noPattern ifFail: failBlock ^self parser parse: aStream class: class noPattern: noPattern context: context notifying: requestor ifFail: [^failBlock value]! ! !Compiler methodsFor: 'private' stamp: 'eem 5/15/2008 15:11'! translate: aStream noPattern: noPattern ifFail: failBlock ^self parser parse: aStream class: class category: category noPattern: noPattern context: context notifying: requestor ifFail: [^failBlock value]! ! !Compiler class methodsFor: 'accessing' stamp: 'eem 5/15/2008 15:12'! new ^ super new parser: self parserClass new! ! !ExternalLibraryFunction methodsFor: 'comparing' stamp: 'eem 7/29/2008 14:48'! analogousCodeTo: anObject ^(anObject isKindOf: ExternalLibraryFunction) and: [flags = anObject flags and: [argTypes = anObject argTypes and: [name = anObject name and: [module = anObject module]]]]! ! !InstructionPrinter methodsFor: 'accessing' stamp: 'eem 5/29/2008 14:00'! method: aMethod method := aMethod. printPC := true. indentSpanOfFollowingJump := false! ! !InstructionPrinter methodsFor: 'initialize-release' stamp: 'eem 5/29/2008 13:26'! printInstructionsOn: aStream "Append to the stream, aStream, a description of each bytecode in the instruction stream." | end | stream := aStream. scanner := InstructionStream on: method. end := method endPC. oldPC := scanner pc. innerIndents := Array new: end withAll: 0. [scanner pc <= end] whileTrue: [scanner interpretNextInstructionFor: self]! ! !InstructionPrinter methodsFor: 'initialize-release' stamp: 'eem 8/4/2008 16:26'! printInstructionsOn: aStream do: aBlock "Append to the stream, aStream, a description of each bytecode in the instruction stream. Evaluate aBlock with the receiver, the scanner and the stream after each instruction." | end | stream := aStream. scanner := InstructionStream on: method. end := method endPC. oldPC := scanner pc. innerIndents := Array new: end withAll: 0. [scanner pc <= end] whileTrue: [scanner interpretNextInstructionFor: self. aBlock value: self value: scanner value: stream]! ! !InstructionPrinter methodsFor: 'instruction decoding' stamp: 'eem 5/29/2008 14:02'! jump: offset "Print the Unconditional Jump bytecode." self print: 'jumpTo: ' , (scanner pc + offset) printString. indentSpanOfFollowingJump ifTrue: [indentSpanOfFollowingJump := false. innerIndents atAll: (scanner pc to: scanner pc + offset - 1) put: (innerIndents at: scanner pc - 1) + 1]! ! !InstructionPrinter methodsFor: 'instruction decoding' stamp: 'eem 5/29/2008 14:02'! send: selector super: supered numArgs: numberArguments "Print the Send Message With Selector, selector, bytecode. The argument, supered, indicates whether the receiver of the message is specified with 'super' in the source method. The arguments of the message are found in the top numArguments locations on the stack and the receiver just below them." self print: (supered ifTrue: ['superSend: '] ifFalse: ['send: ']) , selector. indentSpanOfFollowingJump := #(blockCopy: #closureCopy:copiedValues:) includes: selector! ! !InstructionPrinter methodsFor: 'printing' stamp: 'eem 5/29/2008 13:53'! print: instruction "Append to the receiver a description of the bytecode, instruction." | code | stream tab: self indent. printPC ifTrue: [stream print: oldPC; space]. stream tab: (innerIndents at: oldPC). stream nextPut: $<. oldPC to: scanner pc - 1 do: [:i | code := (method at: i) radix: 16. stream nextPut: (code size < 2 ifTrue: [$0] ifFalse: [code at: 1]). stream nextPut: code last; space]. stream skip: -1. stream nextPut: $>. stream space. stream nextPutAll: instruction. stream cr. oldPC := scanner pc. "(InstructionPrinter compiledMethodAt: #print:) symbolic." ! ! !InstructionStream methodsFor: 'testing' stamp: 'eem 6/19/2008 23:32'! willReallySend "Answer whether the next bytecode is a real message-send, not blockCopy:." | byte | byte := self method at: pc. ^byte >= 131 and: [byte ~~ 200 and: [byte >= 176 "special send or short send" or: [byte <= 134 "long sends" and: [| litIndex | "long form support demands we check the selector" litIndex := byte = 132 ifTrue: [(self method at: pc + 1) // 32 > 1 ifTrue: [^false]. self method at: pc + 2] ifFalse: [byte = 134 ifTrue: [(self method at: pc + 1) bitAnd: 2r111111] ifFalse: [(self method at: pc + 1) bitAnd: 2r11111]]. (self method literalAt: litIndex + 1) ~~ #blockCopy:]]]]! ! !InstructionStream methodsFor: 'testing' stamp: 'eem 5/16/2008 16:22'! willSend "Answer whether the next bytecode is a message-send." | byte | byte := self method at: pc. ^byte >= 131 and: [byte >= 176 "special send or short send" or: [byte <= 134]] "long sends"! ! !ContextPart methodsFor: 'debugger access' stamp: 'eem 6/10/2008 09:42'! tempNames "Answer a SequenceableCollection of the names of the receiver's temporary variables, which are strings." ^ self debuggerMap tempNamesForContext: self! ! !ContextPart methodsFor: 'debugger access' stamp: 'eem 6/10/2008 09:47'! tempsAndValues "Return a string of the temporary variabls and their current values" ^self debuggerMap tempsAndValuesForContext: self! ! !MethodProperties methodsFor: 'testing' stamp: 'eem 5/15/2008 09:36'! analogousCodeTo: aMethodProperties pragmas ifNil: [aMethodProperties pragmas notEmpty ifTrue: [^false]] ifNotNil: [aMethodProperties pragmas empty ifTrue: [^false]. pragmas size ~= aMethodProperties pragmas size ifTrue: [^false]. pragmas with: aMethodProperties pragmas do: [:mine :others| (mine analogousCodeTo: others) ifFalse: [^false]]]. ^(self hasAtLeastTheSamePropertiesAs: aMethodProperties) and: [aMethodProperties hasAtLeastTheSamePropertiesAs: self]! ! !ParseNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 17:13'! sizeCode: encoder forBranchOn: condition dist: dist dist = 0 ifTrue: [^encoder sizePop]. ^condition ifTrue: [encoder sizeBranchPopTrue: dist] ifFalse: [encoder sizeBranchPopFalse: dist]! ! !ParseNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/15/2008 09:52'! sizeCode: encoder forJump: dist ^dist = 0 ifTrue: [0] ifFalse: [encoder sizeJump: dist]! ! !AssignmentNode methodsFor: 'code generation (new scheme)' stamp: 'eem 6/4/2008 11:27'! emitCodeForEffect: stack encoder: encoder variable emitCodeForLoad: stack encoder: encoder. value emitCodeForValue: stack encoder: encoder. pc := encoder methodStreamPosition + 1. "debug pc is first byte of the store, i.e. the next byte". variable emitCodeForStorePop: stack encoder: encoder! ! !AssignmentNode methodsFor: 'code generation (new scheme)' stamp: 'eem 6/4/2008 11:27'! emitCodeForValue: stack encoder: encoder variable emitCodeForLoad: stack encoder: encoder. value emitCodeForValue: stack encoder: encoder. pc := encoder methodStreamPosition + 1. "debug pc is first byte of the store, i.e. the next byte". variable emitCodeForStore: stack encoder: encoder! ! !AssignmentNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/20/2008 15:16'! sizeCodeForEffect: encoder ^(variable sizeCodeForLoad: encoder) + (value sizeCodeForValue: encoder) + (variable sizeCodeForStorePop: encoder)! ! !AssignmentNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/20/2008 15:16'! sizeCodeForValue: encoder ^(variable sizeCodeForLoad: encoder) + (value sizeCodeForValue: encoder) + (variable sizeCodeForStore: encoder)! ! !BlockNode methodsFor: 'testing' stamp: 'eem 7/17/2008 12:20'! generateAsClosure "Answer if we're compiling under the closure regime. If blockExtent has been set by analyseTempsWithin:rootNode: et al then we're compiling under the closure regime." ^blockExtent ~~ nil! ! !BlockNode methodsFor: 'printing' stamp: 'eem 5/6/2008 14:28'! printArgumentsOn: aStream indent: level arguments size = 0 ifTrue: [^ self]. arguments do: [:arg | aStream nextPut: $:; nextPutAll: arg key; space]. aStream nextPut: $|; space. "If >0 args and >1 statement, put all statements on separate lines" statements size > 1 ifTrue: [aStream crtab: level]! ! !Encoder methodsFor: 'accessing' stamp: 'eem 5/29/2008 09:36'! methodNodeClass ^MethodNode! ! !Encoder methodsFor: 'encoding' stamp: 'eem 5/16/2008 18:30'! sharableLitIndex: literal "Special access prevents multiple entries for post-allocated super send special selectors" 1 to: literalStream position do: [:index| (litSet literalEquality: literal and: (literalStream originalContents at: index)) ifTrue: [^index - 1]]. ^self litIndex: literal! ! !Encoder methodsFor: 'encoding' stamp: 'eem 7/27/2008 17:41'! undeclared: name | sym | requestor interactive ifTrue: [requestor requestor == #error: ifTrue: [requestor error: 'Undeclared']. ^self notify: 'Undeclared']. "Allow knowlegeable clients to squash the undeclared warning if they want (e.g. Diffing pretty printers that are simply formatting text). As this breaks compilation it should only be used by clients that want to discard the result of the compilation. To squash the warning use e.g. [Compiler format: code in: class notifying: nil decorated: false] on: UndeclaredVariableWarning do: [:ex| ex resume: false]" sym := name asSymbol. ^(UndeclaredVariableWarning new name: name selector: selector class: class) signal ifTrue: [Undeclared at: sym put: nil. self global: (Undeclared associationAt: sym) name: sym] ifFalse: [self global: (Association key: sym) name: sym]! ! !Encoder methodsFor: 'results' stamp: 'eem 5/19/2008 10:34'! allLiterals (literalStream isKindOf: WriteStream) ifTrue: [self litIndex: nil. self litIndex: self associationForClass]. ^literalStream contents! ! !LeafNode methodsFor: 'initialize-release' stamp: 'eem 5/14/2008 15:56'! key: object index: i type: type key := object. code := (self code: i type: type). index := i! ! !LeafNode methodsFor: 'code generation' stamp: 'eem 5/14/2008 15:57'! reserve: encoder "If this is a yet unused literal of type -code, reserve it." code < 0 ifTrue: [code := self code: (index := encoder litIndex: key) type: 0 - code]! ! !LeafNode methodsFor: 'copying' stamp: 'eem 7/12/2008 17:24'! veryDeepInner: deepCopier "Copy all of my instance variables. Some need to be not copied at all, but shared. Warning!!!! Every instance variable defined in this class must be handled. We must also implement veryDeepFixupWith:. See DeepCopier class comment." super veryDeepInner: deepCopier. "key := key. Weakly copied" code := code veryDeepCopyWith: deepCopier. index := index veryDeepCopyWith: deepCopier. ! ! !MessageNode class methodsFor: 'class initialization' stamp: 'eem 5/14/2008 18:15'! initialize "MessageNode initialize" MacroSelectors := #( ifTrue: ifFalse: ifTrue:ifFalse: ifFalse:ifTrue: and: or: whileFalse: whileTrue: whileFalse whileTrue to:do: to:by:do: caseOf: caseOf:otherwise: ifNil: ifNotNil: ifNil:ifNotNil: ifNotNil:ifNil:). MacroTransformers := #( transformIfTrue: transformIfFalse: transformIfTrueIfFalse: transformIfFalseIfTrue: transformAnd: transformOr: transformWhile: transformWhile: transformWhile: transformWhile: transformToDo: transformToDo: transformCase: transformCase: transformIfNil: transformIfNil: transformIfNilIfNotNil: transformIfNotNilIfNil:). MacroEmitters := #( emitIf:on:value: emitIf:on:value: emitIf:on:value: emitIf:on:value: emitIf:on:value: emitIf:on:value: emitWhile:on:value: emitWhile:on:value: emitWhile:on:value: emitWhile:on:value: emitToDo:on:value: emitToDo:on:value: emitCase:on:value: emitCase:on:value: emitIfNil:on:value: emitIfNil:on:value: emitIf:on:value: emitIf:on:value:). NewStyleMacroEmitters := #( emitCodeForIf:encoder:value: emitCodeForIf:encoder:value: emitCodeForIf:encoder:value: emitCodeForIf:encoder:value: emitCodeForIf:encoder:value: emitCodeForIf:encoder:value: emitCodeForWhile:encoder:value: emitCodeForWhile:encoder:value: emitCodeForWhile:encoder:value: emitCodeForWhile:encoder:value: emitCodeForToDo:encoder:value: emitCodeForToDo:encoder:value: emitCodeForCase:encoder:value: emitCodeForCase:encoder:value: emitCodeForIfNil:encoder:value: emitCodeForIfNil:encoder:value: emitCodeForIf:encoder:value: emitCodeForIf:encoder:value:). MacroSizers := #( sizeIf:value: sizeIf:value: sizeIf:value: sizeIf:value: sizeIf:value: sizeIf:value: sizeWhile:value: sizeWhile:value: sizeWhile:value: sizeWhile:value: sizeToDo:value: sizeToDo:value: sizeCase:value: sizeCase:value: sizeIfNil:value: sizeIfNil:value: sizeIf:value: sizeIf:value:). NewStyleMacroSizers := #( sizeCodeForIf:value: sizeCodeForIf:value: sizeCodeForIf:value: sizeCodeForIf:value: sizeCodeForIf:value: sizeCodeForIf:value: sizeCodeForWhile:value: sizeCodeForWhile:value: sizeCodeForWhile:value: sizeCodeForWhile:value: sizeCodeForToDo:value: sizeCodeForToDo:value: sizeCodeForCase:value: sizeCodeForCase:value: sizeCodeForIfNil:value: sizeCodeForIfNil:value: sizeCodeForIf:value: sizeCodeForIf:value:). MacroPrinters := #( printIfOn:indent: printIfOn:indent: printIfOn:indent: printIfOn:indent: printIfOn:indent: printIfOn:indent: printWhileOn:indent: printWhileOn:indent: printWhileOn:indent: printWhileOn:indent: printToDoOn:indent: printToDoOn:indent: printCaseOn:indent: printCaseOn:indent: printIfNil:indent: printIfNil:indent: printIfNilNotNil:indent: printIfNilNotNil:indent:)! ! !Parser methodsFor: 'public access' stamp: 'eem 6/19/2008 09:38'! encoder encoder isNil ifTrue: [encoder := Encoder new]. ^encoder! ! !Parser methodsFor: 'public access' stamp: 'eem 7/2/2008 11:24'! parse: sourceStream class: class category: aCategory noPattern: noPattern context: ctxt notifying: req ifFail: aBlock "Answer a MethodNode for the argument, sourceStream, that is the root of a parse tree. Parsing is done with respect to the argument, class, to find instance, class, and pool variables; and with respect to the argument, ctxt, to find temporary variables. Errors in parsing are reported to the argument, req, if not nil; otherwise aBlock is evaluated. The argument noPattern is a Boolean that is true if the the sourceStream does not contain a method header (i.e., for DoIts)." | methNode repeatNeeded myStream s p | category := aCategory. myStream := sourceStream. [repeatNeeded := false. p := myStream position. s := myStream upToEnd. myStream position: p. self init: myStream notifying: req failBlock: [^ aBlock value]. doitFlag := noPattern. failBlock:= aBlock. [methNode := self method: noPattern context: ctxt encoder: (self encoder init: class context: ctxt notifying: self)] on: ReparseAfterSourceEditing do: [ :ex | repeatNeeded := true. myStream := ReadStream on: requestor text string]. repeatNeeded] whileTrue: [encoder := self encoder class new]. methNode sourceText: s. ^methNode ! ! !Parser methodsFor: 'expression types' stamp: 'eem 5/29/2008 09:36'! newMethodNode ^self encoder methodNodeClass new! ! !VariableNode methodsFor: 'initialize-release' stamp: 'eem 5/14/2008 16:01'! name: varName key: objRef index: i type: type "Only used for initting global (litInd) variables" ^self name: varName key: objRef code: (self code: (index := i) type: type)! ! !VariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 17:54'! sizeCodeForValue: encoder self reserve: encoder. encoder if: code isSpecialLiteralForPush: [:specialLiteral| "i.e. the pseudo-variables nil true & false" ^encoder sizePushSpecialLiteral: specialLiteral]. (code = LdSelf or: [code = LdSuper]) ifTrue: [^encoder sizePushReceiver]. code = LdThisContext ifTrue: [^encoder sizePushThisContext]. self flag: 'probably superfluous'. self halt. ^encoder sizePushInstVar: index! ! !InstanceVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/15/2008 10:05'! emitCodeForStorePop: stack encoder: encoder encoder genStorePopInstVar: index. stack pop: 1! ! !InstanceVariableNode methodsFor: 'code generation (new scheme)' stamp: 'eem 5/14/2008 17:53'! sizeCodeForValue: encoder ^encoder sizePushInstVar: index! ! !TempVariableNode reorganize! ('initialize-release' isArg: name:index:type:scope: nowHasDef nowHasRef scope:) ('testing' assignmentCheck:at: isArg isRemote isTemp isUndefTemp isUnusedTemp remoteNode scope) ('printing' printDefinitionForClosureAnalysisOn: printOn:indent: printWithClosureAnalysisOn:indent:) ('tiles' asMorphicSyntaxIn:) ('code generation (new scheme)' emitCodeForLoad:encoder: emitCodeForStorePop:encoder: emitCodeForStore:encoder: emitCodeForValue:encoder: sizeCodeForLoad: sizeCodeForStorePop: sizeCodeForStore: sizeCodeForValue:) ('code generation (closures)' addReadWithin:at: addWriteWithin:at: analyseClosure: analyseTempsWithin:rootNode: beingAssignedToAnalyseTempsWithin:rootNode: definingScope: index: isDefinedWithinBlockExtent: isIndirectTempVector isReferencedWithinBlockExtent: referenceScopesAndIndicesDo:) ('visiting' accept:) ('debugger access' cleanUpForRegeneration) ! VariableNode subclass: #LiteralVariableNode instanceVariableNames: 'readNode writeNode' classVariableNames: '' poolDictionaries: '' category: 'Compiler-ParseNodes'! !InstanceVariableNode reorganize! ('initialize-release' name:index:) ('code generation (new scheme)' emitCodeForStorePop:encoder: emitCodeForStore:encoder: emitCodeForValue:encoder: sizeCodeForStorePop: sizeCodeForStore: sizeCodeForValue:) ('visiting' accept:) ! UndeclaredVariableWarning removeSelector: #name:selector:! !UndeclaredVariableWarning reorganize! ('initialize-release' name:selector:class:) ('exceptionDescription' defaultAction) ! MessageNode initialize! ParseNode subclass: #MessageNode instanceVariableNames: 'receiver selector precedence special arguments sizes equalNode caseErrorNode' classVariableNames: 'MacroEmitters MacroPrinters MacroSelectors MacroSizers MacroTransformers NewStyleMacroEmitters NewStyleMacroSizers StdTypers ThenFlag' poolDictionaries: '' category: 'Compiler-ParseNodes'! ParseNode subclass: #LeafNode instanceVariableNames: 'key code index' classVariableNames: '' poolDictionaries: '' category: 'Compiler-ParseNodes'! EncoderForV3 removeSelector: #if:isSpecialLiteralForReturn:! BytecodeEncoder removeSelector: #resetStream! Encoder removeSelector: #associationFor:! !Encoder reorganize! ('initialize-release' fillDict:with:mapping:to: initScopeAndLiteralTables init:context:notifying: noteSuper nTemps:literals:class: release temps:literals:class:) ('accessing' methodNodeClass selector selector:) ('encoding' cantStoreInto: doItInContextName encodeLiteral: encodeSelector: encodeVariable: encodeVariable:ifUnknown: encodeVariable:sourceRange:ifUnknown: litIndex: sharableLitIndex: undeclared:) ('temps' autoBind: bindAndJuggle: bindArg: bindBlockArg:within: bindBlockTemp: bindBlockTemp:within: bindTemp: bindTemp:in: maxTemp newTemp:) ('results' allLiterals associationForClass literals tempNames tempNodes tempsAndBlockArgs unusedTempNames) ('error handling' notify: notify:at: requestor:) ('source mapping' globalSourceRanges noteSourceRange:forNode: rawSourceRanges sourceMap sourceRangeFor:) ('visiting' accept:) ('private' classEncoding global:name: interactive lookupInPools:ifFound: name:key:class:type:set: possibleNamesFor: possibleVariablesFor: reallyBind: warnAboutShadowed:) ! BlockNode removeSelector: #returnSelfIfNoOther! ParseNode removeSelector: #emitCodeForLong:code:encoder:! ParseNode removeSelector: #emitCodeForShortOrLong:code:encoder:! ParseNode removeSelector: #sizeCodeForBranchOn:dist:! ParseNode removeSelector: #sizeCodeForJump:! ParseNode removeSelector: #sizeCodeForShortOrLong:! InstructionClient subclass: #InstructionPrinter instanceVariableNames: 'method scanner stream oldPC innerIndents indent printPC indentSpanOfFollowingJump' classVariableNames: '' poolDictionaries: '' category: 'Kernel-Methods'! !InstructionPrinter reorganize! ('accessing' indent method method: printPC printPC:) ('initialize-release' indent: printInstructionsOn: printInstructionsOn:do:) ('instruction decoding' blockReturnTop doDup doPop jump: jump:if: methodReturnConstant: methodReturnReceiver methodReturnTop popIntoLiteralVariable: popIntoReceiverVariable: popIntoRemoteTemp:inVectorAt: popIntoTemporaryVariable: pushActiveContext pushClosureCopyNumCopiedValues:numArgs:blockSize: pushConsArrayWithElements: pushConstant: pushLiteralVariable: pushNewArrayOfSize: pushReceiver pushReceiverVariable: pushRemoteTemp:inVectorAt: pushTemporaryVariable: send:super:numArgs: storeIntoLiteralVariable: storeIntoReceiverVariable: storeIntoRemoteTemp:inVectorAt: storeIntoTemporaryVariable:) ('printing' print:) ! Compiler removeSelector: #cacheDoItNode:! Object subclass: #Compiler instanceVariableNames: 'sourceStream requestor class category context parser' classVariableNames: '' poolDictionaries: '' category: 'Compiler-Kernel'! !Compiler reorganize! ('error handling' notify: notify:at:) ('public access' compile:in:classified:notifying:ifFail: compile:in:notifying:ifFail: compileNoPattern:in:context:notifying:ifFail: evaluate:in:to: evaluate:in:to:notifying:ifFail: evaluate:in:to:notifying:ifFail:logged: format:in:notifying:contentsSymbol: format:in:notifying:decorated: from:class:classified:context:notifying: parser parserClass parserClass: parser: parse:in:notifying:) ('private' format:noPattern:ifFail: from:class:context:notifying: interactive translate:noPattern:ifFail:) ! CompiledMethod removeSelector: #abstract!