Hi all! :-)
Steps to reproduce:
Do it:
[true]
whileTrue;
whileFalse
Expected behavior:
The script is compiled and executed (and an infinite loop occurs).
Actual behavior:
[cid:60074202-9794-48ae-a5fd-57507c88211b]
Further investigations:
In #analyseTempsWithin:rootNode:assignmentPools:, the inner BlockNode [true] is not computed a blockExtent, because it is optimized.
This leads to a nil key in the ByteCodeEncoder's blockExtentsToLocals.
A fast solution would be to skip nil blockExtents in #noteBlockExtent:hasLocals:, but that's a dirty workaround.
Similar bug:
Try to do:
Object newSubclass compile: 'iWontCompile: foo
foo.
[true]
whileTrue;
whileFalse'
Fails with:
[cid:8ddf552d-c1a1-4498-9284-472389ef8208]
Again, the problem is that blockExtent isNil.
Workaround:
Send #yourself to the block before sending the cascade. This prevents the receiver from being optimized.
Please note that this problem does not only occur in case of special blocks. For example, [Sensor anyButtonPressed] whileTrue; whileFalse fails as well.
How to fix this appropriately? I'm not sure whether I understand the whole idea of blockExtent so far. According to the documentation comment, it should be okay to be nil; however, the #blockExtent comment does not mention this fact.
Please see the attached changeset for an approach to fix the issue. All tests from KernelTests-Methods and most tests from Test-Compiler pass it, except of the testAllNodePCs* which time out in my fresh image. It would be great to hear if this is the right way to solve the bug, or just extending a workaround :-)
Best,
Christoph