Serious Compiler Bug when using to:do:

Tim Olson tim at jumpnet.com
Mon Jan 26 14:54:20 UTC 1998


>Curiouser and curiouser!
>
>The following code will recreate the scenario I mentioned earlier, but it 
>does
>not always generate improper temp var values as earlier observed.
>The first time I tried this code the value of "fred" was 5!  I then filed out
>the class, removed it, filed it in and reran the test, and all was well!  Go
>figure.

I've tried this, but can't recreate the "swapping" of temp values that 
you have seen.


>DoIt
> | t1 t2 t4 |
> t1 _ #(1 2 3 4 ).
> t2 _ 0.
> t4 _ t1 size.
> 1 to: t4 do: [:t3 | t2 _ t2 + 1].
> ^ t2 foo
>
>Interestingly,  in the tempVar inspector in the Debugger, the variables are:
>
>t1:  #(1 2 3 4 )
>t2:  4
>t4:  5
>t3:  4
>
>Note that t4 is 5 but the array's size is only 4!

What you are seeing here is simply the effect of how to:do: messages are 
inlined by the compiler; known intervals are open-coded into a loop that 
looks like:

     push index
     push limit
     send <=
     jumpFalse <end of loop>
     <loop body>
     push index
     pushConst 1
     send +
     popInto index
     jump <begin of loop>

This will leave the limit temp variable exceeding the limit after the 
loop has terminated.  This is different from what the value would be if a 
real interval (1 to: 10) was the receiver of do:, but shouldn't cause any 
problems, because you shouldn't rely upon the value of the block temp 
outside of the block itself.

(actually, looking at this the inlining could be cleaned up to put the 
test at the end of the loop and dynamically remove one of the jumps).


You would see the strange "temp value swaps" if you change the method by 
adding or removing a temp variable while debugging the method (or a call 
chain that contains the method); might this be what is happening?



     -- tim





More information about the Squeak-dev mailing list