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
squeak-dev@lists.squeakfoundation.org