The problem is with #newTemp:
used for binding a temporary in a block argument -  [:foo <<< ]

which increments the total number of temps in encoder (nTemps)..

and as result, at the point where #fixTemp: is sent,
the nTemps = 2, while actually should be = 1.
resulting that error code temp having wrong index.
and if you look later, the total number of temps in compiled method
are not based on nTemps variable of encoder, but actually calculated
from scratch:

aCompiledMethodClass
                                newBytes: blkSize
                                trailerBytes: trailer
                                nArgs: arguments size
                                nTemps: (encoder supportsClosureOpcodes
                                                        ifTrue: [| locals |
                                                                        locals 
:= arguments,
                                                                                
          temporaries,
                                                                                
          (primErrNode
                                                                                
                ifNil: [#()]
                                                                                
                ifNotNil: [{primErrNode}]).
                                                                        encoder
                                                                                
noteBlockExtent: block blockExtent
                                                                                
hasLocals: locals.
                                                                        locals 
size]
                                                        ifFalse: [encoder 
maxTemp])

here, locals size = 2, not 3
which means, that (storeIntoTemp: 2) won't work, because it lies
outside of method's temps range.

Here's even more crazy... if we compile code like that:

badat: index
        <primitive: 60 error: x >
        [:foo | | xx y z | 5].
        ^ x

Bytecode:

<primitive: 60 error: x>
17 <81 45> storeIntoTemp: 5
19 <8F 01 00 05> closureNumCopied: 0 numArgs: 1 bytes 23 to 27
23      <73> pushConstant: nil
24      <73> pushConstant: nil
25      <73> pushConstant: nil
26      <20> pushConstant: 5
27      <7D> blockReturn
28 <87> pop
29 <15> pushTemp: 5
30 <7C> returnTop




-- 
Best regards,
Igor Stasenko.

Reply via email to