The Trunk: Compiler-eem.373.mcz

Previous Topic Next Topic
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

The Trunk: Compiler-eem.373.mcz

Eliot Miranda uploaded a new version of Compiler to project The Trunk:

==================== 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') -----
  "Answer the pc to store in a node for source range identification."
  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])
+ [tempVars := blockStartsToTempVars at: aCompiledBlock]
- [tempVars := blockStartsToTempVars at: pc]
  [blockArgs := (1 to: aCompiledBlock numArgs) collect:
  [:i| (constructor
  codeTemp: i - 1
  named: 't', (tempVarCount + i) printString)
  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;
  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 last isArray
  [subMap at: tuple last first put: tuple last last.
  numTemps := tuple last first]
  [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
  [itv := tempVector at: tuple last first.
  itv at: tuple last last
  put: (aDecompilerConstructor
  codeTemp: tuple last last - 1
  named: tuple first)]
  at: tuple last
  put: (aDecompilerConstructor
  codeTemp: tuple last - 1
  named: tuple first)]].
  "replace any indirect temp vectors with proper RemoteTempVectorNodes"
  subMap keysAndValuesDo:
  [:index :size|
  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
  [start := 2.
  tempVector at: 1 put: (tempVars at: offset + 1)]
  [tempVars := (Array new: offset + 1)
  replaceFrom: 1
  to: tempVars size
  with: tempVars.
  start := 1].
  start to: tempVector size do:
  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.
  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!