[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