[squeak-dev] inlining repeat and the decompiler (Compiler-nice.186)

Levente Uzonyi leves at elte.hu
Fri Apr 1 23:34:28 UTC 2011


On Thu, 31 Mar 2011, Eliot Miranda wrote:

> Hi All,
>
>    just a note that once Compiler-nice.186 is installed, which inlines
> #repeat, one needs to recompile all senders of repeat to avoid having the
> decompiler crap out on you, e.g. in the debugger.  For example the

IMHO it's simply a decompiler bug. It should be able to decompile 
non-inlined #repeat sends, because it's possible in the current system to 
write code which yields such bytecodes. For example:

[ ] repeat; yourself.

Just tried the following which raises an interesting error:

[ [ ] repeat; yourself ] decompile

The error is:

'DecompilerConstructorForClosures(Object)>>error:
DecompilerConstructorForClosures(Object)>>primitiveFailed:
DecompilerConstructorForClosures(Object)>>primitiveFailed
DecompilerConstructorForClosures(Object)>>primitiveChangeClassTo:
Decompiler>>sawBlueBookBlock
Decompiler>>checkForBlockCopy:
Decompiler>>checkForBlock:selector:arguments:
Decompiler>>send:super:numArgs:
Decompiler(InstructionStream)>>interpretNextInstructionFor:
Decompiler>>interpretNextInstructionFor:
Decompiler>>statementsTo:
Decompiler>>blockTo:
Decompiler>>doClosureCopyCopiedValues:numArgs:blockSize:
Decompiler>>pushClosureCopyNumCopiedValues:numArgs:blockSize:
Decompiler(InstructionStream)>>interpretExtension:in:for:
Decompiler(InstructionStream)>>interpretNextInstructionFor:
Decompiler>>interpretNextInstructionFor:
Decompiler>>statementsTo:
Decompiler>>blockTo:
Decompiler>>decompile:in:method:using:
Decompiler>>decompile:in:method:
CompiledMethod>>getSourceFor:in:
CompiledMethod>>methodNode
CompiledMethod>>decompileWithTemps
Decompiler>>decompileBlock:
BlockClosure>>decompile
UndefinedObject>>DoIt
...

The source of the error is:

Decompiler >> sawBlueBookBlock
 	constructor isForClosures ifTrue:
 		[constructor primitiveChangeClassTo: DecompilerConstructor new]

I guess the decompiler should never see a blue book block, so it seems to 
be a compiler bug. The bytecodes for the CompiledMethod are:

25 <8F 00 00 0C> closureNumCopied: 0 numArgs: 0 bytes 29 to 40
29 	<89> pushThisContext:
30 	<75> pushConstant: 0
31 	<C8> send: blockCopy:
32 	<A4 02> jumpTo: 36
34 		<73> pushConstant: nil
35 		<7D> blockReturn
36 	<88> dup
37 	<D1> send: repeat
38 	<87> pop
39 	<D2> send: yourself
40 	<7D> blockReturn
41 <D0> send: decompile
42 <7C> returnTop

Evaluating the following is also funny, it brings you back to the world of 
BlockContexts:

[ self halt ] repeat; yourself


Levente

> compilation of
>
> GeneratorTest methods for generators
> fibonacciSequence
> "Yields an infinite sequence of fibonacci numbers."
> ^ Generator on: [ :generator |
> | a b |
> a := 0. b := 1.
> [ a := b + (b := a).
>  generator yield: a ]
> repeat ]
>
> with non-inlined repeat:
> pushLit: Generator
> closureNumCopied: 0 numArgs: 1 bytes 34 to 72
> pushConstant: nil
> push: (Array new: 2)
> popIntoTemp: 1
> pushConstant: 0
> popIntoTemp: 0 inVectorAt: 1
> pushConstant: 1
> popIntoTemp: 1 inVectorAt: 1
> pushTemp: 0
> pushTemp: 1
> closureNumCopied: 2 numArgs: 0 bytes 52 to 70
> pushTemp: 1 inVectorAt: 1
> pushTemp: 0 inVectorAt: 1
> storeIntoTemp: 1 inVectorAt: 1
> send: #+ (1 arg)
> popIntoTemp: 0 inVectorAt: 1
> pushTemp: 0
> pushTemp: 0 inVectorAt: 1
> send: #yield: (1 arg)
> blockReturn
> send: #repeat (0 args)
> blockReturn
> send: #on: (1 arg)
> returnTop
>
> with inlined repeat:
> pushLit: Generator
> closureNumCopied: 0 numArgs: 1 bytes 34 to 53
> pushConstant: nil
> pushConstant: nil
> pushConstant: 0
> popIntoTemp: 1
> pushConstant: 1
> popIntoTemp: 2
> L1:
> pushTemp: 2
> pushTemp: 1
> storeIntoTemp: 2
> send: #+ (1 arg)
> popIntoTemp: 1
> pushTemp: 0
> pushTemp: 1
> send: #yield: (1 arg)
> pop
> jumpTo: L1
> pushConstant: nil
> blockReturn
> send: #on: (1 arg)
> returnTop
>
>
> will cause the decompiler to fail horribly if the non-inlined result is
> decompiled with Compiler-nice.186 installed.  The fix is merely to recompile
> it (and other senders of #repeat).  The underlying problem is that if the is
> given temp names via a schematicTempNamesString then that string must match
> the temps in the method, and in the above if repeat is not inlined a and b
> are remote, and hence the schematicTempNamesString is [generator (a b)] but
> if repeat is inlined then they are local and the schematicTempNamesString is
> [generator a b].
>
> BTW, kudos to Nicholas for the newParser/newCompiler changes!
>
> best
> Eliot
>



More information about the Squeak-dev mailing list