<div dir="ltr">Hi Nicolas,<br><div><br></div><div>    nice, thank you!</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Mar 11, 2020 at 2:18 PM <<a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Nicolas Cellier uploaded a new version of Compiler to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Compiler-nice.417.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/trunk/Compiler-nice.417.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Compiler-nice.417<br>
Author: nice<br>
Time: 11 March 2020, 10:18:30.802676 pm<br>
UUID: dabc222a-b8c1-4a9e-9495-938c11b4f17b<br>
Ancestors: Compiler-eem.416<br>
<br>
Fix decompilation of FullBlockClosure<br>
<br>
Some Closure with complex jump flow (optimized ifTrue: etc...) will alter some of the states required to decompile the method and fool the backward return detection logic.<br>
<br>
There are so many states to be saved, that the most reasonable thing to do is to decompile the block in a shallowCopy, and simply re-initialize the states that should not be shared. Note that this is un-necessary for all the immediate or immutable values, which are not shared states with the shallowCopy, so we don't have to care for most of them.<br>
<br>
Same changes could eventually apply to V3 closure, but if it ain't broken don't fix it: it's touchy and it would be necessary to test that in a non SistaV1 which is superfluous...<br>
<br>
Last little detail: don't invoke super method:pc: there is a single implementation and self will do the work.<br>
<br>
=============== Diff against Compiler-eem.416 ===============<br>
<br>
Item was changed:<br>
  ----- Method: Decompiler>>decompile:in:method:using: (in category 'public access') -----<br>
  decompile: aSelector in: aClass method: aMethod using: aConstructor<br>
<br>
        | block node |<br>
        constructor := aConstructor.<br>
        method := aMethod.<br>
        self initSymbols: aClass.  "create symbol tables"<br>
        method isQuick<br>
                ifTrue: [block := self quickMethod]<br>
                ifFalse: <br>
                        [stack := OrderedCollection new: method frameSize.<br>
                        lastJumpIfPcStack := OrderedCollection new.<br>
                        caseExits := OrderedCollection new.<br>
                        statements := OrderedCollection new: 20.<br>
                        numLocalTemps := 0.<br>
+                       self method: method pc: method initialPC.<br>
-                       super method: method pc: method initialPC.<br>
                        "skip primitive error code store if necessary"<br>
                        (method primitive ~= 0 and: [self skipCallPrimitive; willStore]) ifTrue:<br>
                                [pc := pc + (method encoderClass bytecodeSize: self firstByte).<br>
                                 tempVars := tempVars asOrderedCollection].<br>
                        block := self blockTo: method endPC + 1.<br>
                        stack isEmpty ifFalse: [self error: 'stack not empty']].<br>
        node := constructor<br>
                                codeMethod: aSelector<br>
                                block: block<br>
                                tempVars: tempVars<br>
                                primitive: method primitive<br>
                                class: aClass.<br>
        method primitive > 0 ifTrue:<br>
                [node removeAndRenameLastTempIfErrorCode].<br>
        ^node preen!<br>
<br>
Item was changed:<br>
  ----- Method: Decompiler>>doClosureCopy:copiedValues: (in category 'control') -----<br>
  doClosureCopy: aCompiledBlock copiedValues: blockCopiedValues<br>
+       "implementation note: must be invoked on a copy because it modifies states"<br>
+       | savedPC blockArgs blockTemps blockTempsOffset block mark |<br>
-       | savedTemps savedTempVarCount savedNumLocalTemps savedMethod savedPC<br>
-         blockArgs blockTemps blockTempsOffset block |<br>
-       savedTemps := tempVars.<br>
-       savedTempVarCount := tempVarCount.<br>
-       savedNumLocalTemps := numLocalTemps.<br>
        numLocalTemps := aCompiledBlock numTemps - aCompiledBlock numArgs - blockCopiedValues size.<br>
        blockTempsOffset := aCompiledBlock numArgs + blockCopiedValues size.<br>
        (blockStartsToTempVars notNil "implies we were intialized with temp names."<br>
         and: [blockStartsToTempVars includesKey: aCompiledBlock])<br>
                ifTrue:<br>
                        [tempVars := blockStartsToTempVars at: aCompiledBlock]<br>
                ifFalse:<br>
                        [blockArgs := (1 to: aCompiledBlock numArgs) collect:<br>
                                                        [:i| (constructor<br>
                                                                        codeTemp: i - 1<br>
                                                                        named: 't', (tempVarCount + i) printString)<br>
                                                                  beBlockArg].<br>
                        blockTemps := (1 to: numLocalTemps) collect:<br>
                                                        [:i| constructor<br>
                                                                        codeTemp: i + blockTempsOffset - 1<br>
                                                                        named: 't', (tempVarCount + i + aCompiledBlock numArgs) printString].<br>
                        tempVars := blockArgs, blockCopiedValues, blockTemps].<br>
        tempVarCount := tempVarCount + aCompiledBlock numArgs + numLocalTemps.<br>
+       lastJumpIfPcStack := OrderedCollection new.<br>
+       caseExits := OrderedCollection new.<br>
+       statements := OrderedCollection new: 20.<br>
+       savedPC := pc.<br>
+       self method: (method := aCompiledBlock) pc: aCompiledBlock initialPC.<br>
+       mark := stack size.<br>
+       block := self blockTo: aCompiledBlock endPC.<br>
+       mark = stack size ifFalse: [self error: 'block did alter the stack'].<br>
+       ^((constructor<br>
+                       codeArguments: (tempVars copyFrom: 1 to: aCompiledBlock numArgs)<br>
+                       temps: (tempVars copyFrom: blockTempsOffset + 1 to: blockTempsOffset + numLocalTemps)<br>
+                       block: block)<br>
+                               pc: aCompiledBlock -> savedPC; "c.f. BytecodeEncoder>>pc"<br>
+                               yourself).!<br>
-       savedMethod := self method. savedPC := pc.<br>
-       super method: (method := aCompiledBlock) pc: aCompiledBlock initialPC.<br>
-       block := [self blockTo: aCompiledBlock endPC]<br>
-                               ensure: [super method: (method := savedMethod) pc: savedPC].<br>
-       stack addLast: ((constructor<br>
-                                               codeArguments: (tempVars copyFrom: 1 to: aCompiledBlock numArgs)<br>
-                                               temps: (tempVars copyFrom: blockTempsOffset + 1 to: blockTempsOffset + numLocalTemps)<br>
-                                               block: block)<br>
-                                                       pc: aCompiledBlock -> pc; "c.f. BytecodeEncoder>>pc"<br>
-                                                       yourself).<br>
-       tempVars := savedTemps.<br>
-       tempVarCount := savedTempVarCount.<br>
-       numLocalTemps := savedNumLocalTemps!<br>
<br>
Item was changed:<br>
  ----- Method: Decompiler>>pushFullClosure:numCopied: (in category 'instruction decoding') -----<br>
  pushFullClosure: aCompiledBlock numCopied: numCopied<br>
        | copiedValues |<br>
        copiedValues := ((1 to: numCopied) collect: [:ign| stack removeLast]) reversed.<br>
+       stack addLast: (self shallowCopy doClosureCopy: aCompiledBlock copiedValues: copiedValues)!<br>
-       self doClosureCopy: aCompiledBlock copiedValues: copiedValues!<br>
<br>
<br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>