This, and the other decompiler test failure, happens because of the
recent chained assignment work: original snippet: ActiveWorld := ActiveHand := ActiveEvent := nil. decompiled version of sameL ActiveEvent := nil. ActiveHand := nil. ActiveWorld := nil. How to fix? frank |
On Fri, 12 Apr 2013, Frank Shearar wrote:
> This, and the other decompiler test failure, happens because of the > recent chained assignment work: > > original snippet: > > ActiveWorld := ActiveHand := ActiveEvent := nil. > > decompiled version of sameL > > ActiveEvent := nil. > ActiveHand := nil. > ActiveWorld := nil. > > How to fix? The only method with this assignment chain in my image is MorphicProject >> #saveState . The bytecodes for this line are: 73 <73> pushConstant: nil 74 <81 C5> storeIntoLit: ActiveEvent 76 <81 C6> storeIntoLit: ActiveHand 78 <82 C7> popIntoLit: ActiveWorld And the decompiler can reproduce the original code. If I recompile this method (which should have been done due to the Environments changes, but for some reason it hasn't happened yet), then there's a bug in the compiler. The bytecodes will be: 78 <25> pushConstant: ##ActiveWorld 79 <73> pushConstant: nil 80 <27> pushConstant: ##ActiveEvent 81 <80 41> pushTemp: 1 83 <CA> send: value: 84 <87> pop 85 <26> pushConstant: ##ActiveHand 86 <80 41> pushTemp: 1 88 <CA> send: value: 89 <87> pop 90 <CA> send: value: 91 <87> pop Which are obviously wrong. Creating a new method with just a simple assignment chain: foo GlobalA := GlobalB := $a generetes: 25 <20> pushConstant: ##GlobalA 26 <22> pushConstant: $a 27 <21> pushConstant: ##GlobalB 28 <80 41> pushTemp: 1 30 <CA> send: value: 31 <87> pop 32 <CA> send: value: 33 <87> pop 34 <78> returnSelf Which still has the pushTemp: 1. But this method has 0 temporaries, so it's a compiler bug. I wonder how the decompiler can decompile anything meaningful from this, and how the VM doesn't crash. Levente > > frank > > |
Once you recompileAll, they do not fail anymore. Still the same problem, Compiler recompileAll will leave unbound CompiledMethod here and there.
2013/4/12 Levente Uzonyi <[hidden email]>
|
On Fri, 12 Apr 2013, Nicolas Cellier wrote:
> Once you recompileAll, they do not fail anymore. Digging into the code a bit I found out that the pushTemp: bytecode is a hack to duplicate the value which will be assigned. The generated code could be improved if Binding >> #value: would always return its argument. In that case the bytecode could follow the assignment chain directly: 78 <25> pushConstant: ##ActiveWorld 79 <26> pushConstant: ##ActiveHand 80 <27> pushConstant: ##ActiveEvent 81 <73> pushConstant: nil 82 <CA> send: value: 83 <CA> send: value: 84 <CA> send: value: 85 <87> pop It doesn't seem to be a simple change though. Levente > Still the same problem, Compiler recompileAll will leave unbound CompiledMethod here and there. > > > 2013/4/12 Levente Uzonyi <[hidden email]> > On Fri, 12 Apr 2013, Frank Shearar wrote: > > This, and the other decompiler test failure, happens because of the > recent chained assignment work: > > original snippet: > > ActiveWorld := ActiveHand := ActiveEvent := nil. > > decompiled version of sameL > > ActiveEvent := nil. > ActiveHand := nil. > ActiveWorld := nil. > > How to fix? > > > The only method with this assignment chain in my image is MorphicProject > #saveState . The bytecodes for this line are: > > > 73 <73> pushConstant: nil > 74 <81 C5> storeIntoLit: ActiveEvent > 76 <81 C6> storeIntoLit: ActiveHand > 78 <82 C7> popIntoLit: ActiveWorld > > And the decompiler can reproduce the original code. > > If I recompile this method (which should have been done due to the Environments changes, but for some reason it hasn't happened yet), then there's a bug in the compiler. The bytecodes will be: > > 78 <25> pushConstant: ##ActiveWorld > 79 <73> pushConstant: nil > 80 <27> pushConstant: ##ActiveEvent > 81 <80 41> pushTemp: 1 > 83 <CA> send: value: > 84 <87> pop > 85 <26> pushConstant: ##ActiveHand > 86 <80 41> pushTemp: 1 > 88 <CA> send: value: > 89 <87> pop > 90 <CA> send: value: > 91 <87> pop > > Which are obviously wrong. > > Creating a new method with just a simple assignment chain: > > foo > > GlobalA := GlobalB := $a > > generetes: > > 25 <20> pushConstant: ##GlobalA > 26 <22> pushConstant: $a > 27 <21> pushConstant: ##GlobalB > 28 <80 41> pushTemp: 1 > 30 <CA> send: value: > 31 <87> pop > 32 <CA> send: value: > 33 <87> pop > 34 <78> returnSelf > > Which still has the pushTemp: 1. But this method has 0 temporaries, so it's a compiler bug. I wonder how the decompiler can decompile anything > meaningful from this, and how the VM doesn't crash. > > > Levente > > > frank > > > > > > |
Changing #value: would be simple, but we preferred to not depend on this. Current bytecode does completely ignore the returned value, which is a bit more robust.2013/4/12 Levente Uzonyi <[hidden email]>
|
Free forum by Nabble | Edit this page |