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.