discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: StepTalk Segfaults


From: Matthew D Swank
Subject: Re: StepTalk Segfaults
Date: Wed, 23 Feb 2005 04:24:19 -0600
User-agent: Mozilla Thunderbird 1.0 (X11/20050209)

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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]