Matthew D Swank wrote:

If this were the only problem I could run my original example by picking unique variable names for the CPS style blocks:
|main sub|
sub :=
[:my_other_continuation |
Transcript show: '\n begin sub'.
Transcript show: '\n |-- Objective C --|'.
my_other_continuation value.
Transcript show: '\n end sub'.].


    main :=
         [:my_continuation|
         Transcript show: '\n begin main'.
         Transcript show: '\n |-- StepTalk --|'.
         sub
             valueWith:
                 [Transcript show: '\n |-- ANSI C --|'.
                     my_continuation value.].
         Transcript show: '\n end main'.].

    Transcript show: '\nbegin program'.
    main  valueWith: [Transcript show: '\nend program'.].

However this does not work.

I figured out problem two. When the Smalltalk compiler compiles a block, it allocates space for the parameters in the index of temp-variables names residing in the CompilerContext:'tempVars'. This mirrors the array of temps in the method context on the interpreter side
From STCompiler.m:


        argCount = [array count];
       for(index=0;index<argCount;index++)
       {
           [self addTempVariable:[array objectAtIndex:index]];
       }


When it is done compiling the block, it reclaims the space TempVars:

        [tempVars removeObjectsInRange:NSMakeRange(tempsSave,
                                              [tempVars count]-tempsSave)];


Lets look at one of the examples with the various blocks labeled:

       |main sub|
       sub :=
           [:my_other_continuation |
           Transcript  show: '\n   begin sub'.
           Transcript  show: '\n   |-- Objective C --|'.
           my_other_continuation value.
           Transcript  show: '\n   end sub'.]. "<---------------- BLOCK4"

       main :=
           [:my_continuation|
           Transcript show: '\n begin main'.
           Transcript show: '\n |-- StepTalk --|'.
           sub
                valueWith:
                    [Transcript show: '\n |-- ANSI C --|'.
                        my_continuation value.]. "<-------------- BLOCK3"
           Transcript show: '\n end main'.]. "<------------------ BLOCK2"

       Transcript show: '\nbegin program'.
       main  valueWith: [Transcript show: '\nend program'.]. "<-- BLOCK1"

In the CompilerContext we start out with (simplifying a bit):

tempVars <-> #('main' 'sub')
                 0     1

While BLOCK4 is compiled:

tempVars <-> #('main' 'sub' 'my_other_continuation')
                 0     1            2

after BLOCK4 is compiled:

tempVars <-> #('main' 'sub')
                 0     1


while BLOCK2 is compiled:

tempVars <-> #('main' 'sub' 'my_continuation')
                 0     1          2

after BLOCK2 is compiled:

tempVars <-> #('main' 'sub')
                 0     1

So, when 'my_continuation' or 'my_other_continuation' is accessed or assigned, it will push from or pop to index 2 in the MethodContext temp array.

When the code is interpreted, the last value in index 2 will be BLOCK3, so
when BLOCK3 actually runs :

        [Transcript show: '\n |-- ANSI C --|'. my_continuation value.].

'my_continuation' will point to BLOCK3, causing an infinite loop.

Consecutive blocks need to make sure they keep what are effectively activation records with-out the compiler complaining about redefinition.

Matt



_______________________________________________
Discuss-gnustep mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/discuss-gnustep

Reply via email to