Eliot Miranda uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-eem.373.mcz ==================== Summary ==================== Name: Compiler-eem.373 Author: eem Time: 12 January 2018, 3:37:48.690536 pm UUID: 47f067a5-1d56-4b81-824c-e48560584230 Ancestors: Compiler-eem.372 Decompiler support for full blocks. Also fix bug in doClosureCopy:copiedValues: so as to create a block node with the expected pc association. =============== Diff against Compiler-eem.372 =============== Item was changed: ----- Method: BytecodeEncoder>>pc (in category 'accessing') ----- pc "Answer the pc to store in a node for source range identification." ^blockMethod ifNil: [stream position] + ifNotNil: [:aCompiledBlock| aCompiledBlock -> stream position]! - ifNotNil: [:proxy| proxy -> (stream position)]! Item was changed: ----- Method: Decompiler>>decompileBlock: (in category 'public access') ----- decompileBlock: aBlock "Decompile aBlock, returning the result as a BlockNode. Show temp names from source if available." "Decompiler new decompileBlock: [3 + 4]" + aBlock method decompileWithTemps + ifNil: [^nil] + ifNotNil: + [:methodNode| + methodNode nodesDo: + (aBlock isFullBlock + ifTrue: [[:node| (node pc isVariableBinding and: [node pc key = aBlock method]) ifTrue: [^node]]] + ifFalse: [[:node| node pc = aBlock startpc ifTrue: [^node]]])]. + ^self error: 'cannot find block node matching aBlock'! - | startpc end homeClass blockNode methodNode home | - (home := aBlock home) ifNil: [^nil]. - (homeClass := home methodClass) == #unknown ifTrue: [^nil]. - method := aBlock method. - aBlock isClosure ifTrue: - [(methodNode := method decompileWithTemps) - ifNil: [^nil] - ifNotNil: [methodNode nodesDo: [:node| node pc = aBlock startpc ifTrue: [^node]]]. - ^self error: 'cannot find block node matching aBlock']. - constructor := self constructorForMethod: aBlock method. - - self withTempNames: method methodNode tempNames. - - self initSymbols: homeClass. - startpc := aBlock startpc. - end := aBlock endPC. - stack := OrderedCollection new: method frameSize. - lastJumpIfPcStack := OrderedCollection new. - caseExits := OrderedCollection new. - statements := OrderedCollection new: 20. - super method: method pc: startpc - 5. - blockNode := self blockTo: end. - stack isEmpty ifFalse: [self error: 'stack not empty']. - ^blockNode statements first! Item was changed: ----- Method: Decompiler>>doClosureCopy:copiedValues: (in category 'control') ----- doClosureCopy: aCompiledBlock copiedValues: blockCopiedValues | savedTemps savedTempVarCount savedNumLocalTemps savedMethod savedPC blockArgs blockTemps blockTempsOffset block | savedTemps := tempVars. savedTempVarCount := tempVarCount. savedNumLocalTemps := numLocalTemps. numLocalTemps := aCompiledBlock numTemps - aCompiledBlock numArgs - blockCopiedValues size. blockTempsOffset := aCompiledBlock numArgs + blockCopiedValues size. (blockStartsToTempVars notNil "implies we were intialized with temp names." + and: [blockStartsToTempVars includesKey: aCompiledBlock]) - and: [blockStartsToTempVars includesKey: pc]) ifTrue: + [tempVars := blockStartsToTempVars at: aCompiledBlock] - [tempVars := blockStartsToTempVars at: pc] ifFalse: [blockArgs := (1 to: aCompiledBlock numArgs) collect: [:i| (constructor codeTemp: i - 1 named: 't', (tempVarCount + i) printString) beBlockArg]. blockTemps := (1 to: numLocalTemps) collect: [:i| constructor codeTemp: i + blockTempsOffset - 1 named: 't', (tempVarCount + i + aCompiledBlock numArgs) printString]. tempVars := blockArgs, blockCopiedValues, blockTemps]. tempVarCount := tempVarCount + aCompiledBlock numArgs + numLocalTemps. savedMethod := self method. savedPC := pc. super method: aCompiledBlock pc: aCompiledBlock initialPC. block := [self blockTo: aCompiledBlock endPC] ensure: [super method: savedMethod pc: savedPC]. stack addLast: ((constructor codeArguments: (tempVars copyFrom: 1 to: aCompiledBlock numArgs) temps: (tempVars copyFrom: blockTempsOffset + 1 to: blockTempsOffset + numLocalTemps) block: block) + pc: aCompiledBlock -> pc; "c.f. BytecodeEncoder>>pc" - pc: pc; yourself). tempVars := savedTemps. tempVarCount := savedTempVarCount. numLocalTemps := savedNumLocalTemps! Item was changed: ----- Method: Decompiler>>mapFromBlockKeysIn:toTempVarsFrom:constructor: (in category 'initialize-release') ----- mapFromBlockKeysIn: aMethod toTempVarsFrom: schematicTempNamesString constructor: aDecompilerConstructor + | startMap tempMap | + startMap := aMethod startKeysToBlockExtents. + tempMap := aMethod + mapFromBlockKeys: (startMap keys asArray sort: [:a :b| (startMap at: a) first <= (startMap at: b) first]) + toSchematicTemps: schematicTempNamesString. + tempMap keysAndValuesDo: - | map | - map := aMethod - mapFromBlockKeys: aMethod startKeysToBlockExtents keys asArray sort - toSchematicTemps: schematicTempNamesString. - map keysAndValuesDo: [:startKey :tempNameTupleVector| tempNameTupleVector isEmpty ifFalse: [| subMap numTemps tempVector | subMap := Dictionary new. "Find how many temp slots there are (direct & indirect temp vectors) and for each indirect temp vector find how big it is." tempNameTupleVector do: [:tuple| tuple last isArray ifTrue: [subMap at: tuple last first put: tuple last last. numTemps := tuple last first] ifFalse: [numTemps := tuple last]]. "create the temp vector for this scope level." tempVector := Array new: numTemps. "fill it in with any indirect temp vectors" subMap keysAndValuesDo: [:index :size| tempVector at: index put: (Array new: size)]. "fill it in with temp nodes." tempNameTupleVector do: [:tuple| | itv | tuple last isArray ifTrue: [itv := tempVector at: tuple last first. itv at: tuple last last put: (aDecompilerConstructor codeTemp: tuple last last - 1 named: tuple first)] ifFalse: [tempVector at: tuple last put: (aDecompilerConstructor codeTemp: tuple last - 1 named: tuple first)]]. "replace any indirect temp vectors with proper RemoteTempVectorNodes" subMap keysAndValuesDo: [:index :size| tempVector at: index put: (aDecompilerConstructor codeRemoteTemp: index remoteTemps: (tempVector at: index))]. "and update the entry in the map" + tempMap at: startKey put: tempVector]]. + ^tempMap! - map at: startKey put: tempVector]]. - ^map! Item was changed: ----- Method: Decompiler>>popIntoTemporaryVariable: (in category 'instruction decoding') ----- popIntoTemporaryVariable: offset | maybeTVTag tempVector start | maybeTVTag := stack last. ((maybeTVTag isMemberOf: Association) and: [maybeTVTag key == #pushNewArray]) ifTrue: + [blockStartsToTempVars "implies we were intialized with temp names." + ifNotNil: "Use the provided temps" - [blockStartsToTempVars notNil "implies we were intialized with temp names." - ifTrue: "Use the provided temps" [self assert: ((tempVector := tempVars at: offset + 1 ifAbsent: [ParseNode basicNew]) isTemp and: [tempVector isIndirectTempVector and: [tempVector remoteTemps size = maybeTVTag value size]])] + ifNil: "Synthesize some remote temps" - ifFalse: "Synthesize some remote temps" [tempVector := maybeTVTag value. offset + 1 <= tempVars size ifTrue: [start := 2. tempVector at: 1 put: (tempVars at: offset + 1)] ifFalse: [tempVars := (Array new: offset + 1) replaceFrom: 1 to: tempVars size with: tempVars. start := 1]. start to: tempVector size do: [:i| tempVector at: i put: (constructor codeTemp: numLocalTemps + offset + i - 1 named: 't', (tempVarCount + i) printString)]. tempVars at: offset + 1 put: (constructor codeRemoteTemp: offset + 1 remoteTemps: tempVector)]. tempVarCount := tempVarCount + maybeTVTag value size. stack removeLast. ^self]. stack addLast: (offset >= tempVars size ifTrue: "Handle the case of chained LiteralVariableBinding assigments" [stack at: (offset + 1 - tempVars size)] ifFalse: "A regular argument or temporary" [tempVars at: offset + 1]). self doStore: statements! |
Free forum by Nabble | Edit this page |