Eliot Miranda uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-eem.354.mcz ==================== Summary ==================== Name: Compiler-eem.354 Author: eem Time: 5 May 2017, 12:11:34.451259 pm UUID: 79ec7453-8d66-471d-b7fa-2699146390c8 Ancestors: Compiler-eem.353 Provide a proper comment for BlockNode and eliminate an unused variable and an unused method; this in prelude to implementing full blocks. Eliminate obsolete binding machinery (literalScannedAs:notifying:). The current compiler deals with Undeclared in a more direct way earlier in compilation. Nuke the unnecessary identical override of generateMethodOfClass:trailer:from: in EncoderForSistaV1. Correct a spelling error. =============== Diff against Compiler-eem.353 =============== Item was changed: ParseNode subclass: #BlockNode + instanceVariableNames: 'arguments statements returns nArgsNode size temporaries optimized optimizedMessageNode actualScopeIfOptimized blockExtent remoteTempNode copiedValues closureCreationNode startOfLastStatement tempsMark' - instanceVariableNames: 'arguments statements returns nArgsNode size remoteCopyNode temporaries optimized optimizedMessageNode actualScopeIfOptimized blockExtent remoteTempNode copiedValues closureCreationNode startOfLastStatement tempsMark' classVariableNames: '' poolDictionaries: '' category: 'Compiler-ParseNodes'! + !BlockNode commentStamp: 'eem 5/4/2017 17:26' prior: 0! + I represent a bracketed block with 0 or more arguments and 1 or more statements. If I am initialized with no statements, I create one. I have a flag to tell whether my last statement returns a value from the enclosing method. I can emit for value in the usual way, in which case I create a BlockClosure to be evaluated by sending it value: at run time. Or I can emit code to be evaluated in line; this only happens at the top level of a method and in certain optimized control structures (see MessageNode class>>initialize MacroSelectors). + + Instance Variables + actualScopeIfOptimized: <nil | BlockNode> + arguments: <SequencableCollection of: TempVariableNode> + blockExtent: <nil | Interval> + closureCreationNode: <LeafNode> + copiedValues: <nil | (SequencableCollection of: TempVariableNode)> + nArgsNode: <nil | Integer> + optimized: <Boolean> + optimizedMessageNode: <nil | MessageNode> + remoteTempNode: <nil | RemoteTempVectorNode> + returns: <Boolean> + size: <nil | Integer> + startOfLastStatement: <nil | Integer> + statements: <SequencableCollection of: ParseNode> + temporaries: <SequencableCollection of: TempVariableNode> + tempsMark: <nil | Integer> + + actualScopeIfOptimized + - if the receiver has been inlined this is the non-optimized BlockNode the receiver is inlined into. + + arguments + - the sequence of arguments to the block (or method if a top-level block) + + blockExtent + - the interval defining the range of block scopes the receiver comprises, which is itself and any blokcs it may contain. See #analyseArguments:temporaries:rootNode: + + closureCreationNode + - a place-holder representing the body of the block. + + copiedValues + - blocks do not reference the temporary variables of their outer context they cose over directly; instead temporary variables which won't change value are collected and copied into the block, and temporary variables that are modified either within the block or after it has closed over the variales are allocated in a remote temp vector that again becomes one of the block's copied values. In this way, a block refers to the outer teporaries it closes over only throguh copiedValues. copiedValues is the sequence of these TempVariableNodes. + + nArgsNode + - a place holder for the encoder to allow it to number block temporaries + + optimized + - true if the receiver is inlined, false if a true block + + optimizedMessageNode + - the MessageNode in which the receiver is optimized, if it is optimized. + + remoteTempNode + - if any of the blocks nested into the receiver either modify a temp or access a temp that is modified after the block is created, then this temp is allocated remotely in a remote temp vector that allows the temp's location to be shared between blocks. This is the node that creates the remote temp vector. + + returns + - true if the receiver contains a method return. + + size + - the size of the block's bytecodes if it is generated by embedding its bytecodes within an enclosing CompiledMethod. + + startOfLastStatement + - the index in the source of the start of the last statement in the block. + + statements + - the sequence of statements comprising the receiver + + temporaries + - the sequence of temporaries (including the remoteTempNode if any) of block-local temporaries + + tempsMark + - the index in the source of the last block-local temporary, used to auto-insert temps declared during compilation! - !BlockNode commentStamp: '<historical>' prior: 0! - I represent a bracketed block with 0 or more arguments and 1 or more statements. If I am initialized with no statements, I create one. I have a flag to tell whether my last statement returns a value from the enclosing method. My last three fields remember data needed for code generation. I can emit for value in the usual way, in which case I create a literal method (actually a context remotely copied) to be evaluated by sending it value: at run time. Or I can emit code to be evaluated in line; this only happens at the top level of a method and in conditionals and while-loops, none of which have arguments.! Item was removed: - ----- Method: BlockNode>>closureCreationNode (in category 'accessing') ----- - closureCreationNode - closureCreationNode ifNil: - [closureCreationNode := LeafNode new - key: #closureCreationNode - code: nil]. - ^closureCreationNode! Item was removed: - ----- Method: CompilationCue>>literalScannedAs:notifying: (in category 'binding') ----- - literalScannedAs: anObject notifying: anEncoder - ^ class literalScannedAs: anObject environment: environment notifying: anEncoder! Item was changed: ----- Method: Encoder>>encodeLiteral: (in category 'encoding') ----- encodeLiteral: object - ^self name: object + key: object - key: (cue literalScannedAs: object notifying: self) class: LiteralNode type: LdLitType set: litSet! Item was removed: - ----- Method: EncoderForSistaV1>>generateMethodOfClass:trailer:from: (in category 'method encoding') ----- - generateMethodOfClass: aCompiledMethodClass trailer: trailer from: methodNode - "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. - The argument, trailer, is arbitrary but is typically either the reference to the source code - that is stored with every CompiledMethod, or an encoding of the method's temporary names." - - | primErrNode blkSize nLits locals literals header method stack | - primErrNode := methodNode primitiveErrorVariableName ifNotNil: - [self fixTemp: methodNode primitiveErrorVariableName]. - methodNode ensureClosureAnalysisDone. - self rootNode: methodNode. "this is for BlockNode>>sizeCodeForClosureValue:" - blkSize := (methodNode block sizeCodeForEvaluatedValue: self) - + (methodNode primitive > 0 - ifTrue: [self sizeCallPrimitive: methodNode primitive] - ifFalse: [0]) - + (primErrNode - ifNil: [0] - ifNotNil: - [primErrNode - index: methodNode arguments size + methodNode temporaries size; - sizeCodeForStore: self "The VM relies on storeIntoTemp: (129)"]). - locals := methodNode arguments, methodNode temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). - self noteBlockExtent: methodNode block blockExtent hasLocals: locals. - header := self computeMethodHeaderForNumArgs: methodNode arguments size - numTemps: locals size - numLits: (nLits := (literals := self allLiterals) size) - primitive: methodNode primitive. - method := trailer - createMethod: blkSize - class: aCompiledMethodClass - header: header. - 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. - self streamToMethod: method. - stack := ParseStack new init. - methodNode primitive > 0 ifTrue: - [self genCallPrimitive: methodNode primitive]. - primErrNode ifNotNil: - [primErrNode emitCodeForStore: stack encoder: self]. - stack position: method numTemps. - [methodNode block emitCodeForEvaluatedValue: stack encoder: self] - on: Error "If an attempt is made to write too much code the method will be asked" - do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" - ex signalerContext sender method = (CompiledMethod class>>#new:) - ifTrue: [^self error: 'Compiler code size discrepancy'] - ifFalse: [ex pass]]. - stack position ~= (method numTemps + 1) ifTrue: - [^self error: 'Compiler stack discrepancy']. - self methodStreamPosition ~= (method size - trailer size) ifTrue: - [^self error: 'Compiler code size discrepancy']. - method needsFrameSize: stack size - method numTemps. - ^method! Item was changed: ----- Method: MethodNode>>schematicTempNamesString (in category 'debugger support') ----- schematicTempNamesString "Answer the temp names for the current method node in a form that captures temp structure. The temps at each method and block scope level occur space-separated, with any indirect temps enclosed in parentheses. Each block level is enclosed in square brackets. e.g. 'method level temps (indirect temp)[block args and temps (indirect)]' This representation can be reconstituted into a blockExtentsToTempsMap by a CompiledMethod that has been copied with the schematicTempNamesString." encoder hasGeneratedMethod ifFalse: + ["create the encoder's blockExtentsToLocals map, except if the method is quick - ["create the encoder's blockExtentsToLoals map, except if the method is quick in which case it has no temps." + self generate isQuick ifTrue: - (self generate) isQuick ifTrue: [^'']]. ^encoder schematicTempNamesString! |
Free forum by Nabble | Edit this page |