On Wed, 2002-07-31 at 10:25, Jerome Vouillon wrote:
>
> Let us think a bit about the implementation of lexical variables.
Thanks for spelling this out in such detail.
Here is a variation based on the lexical ops (new_pad, pop_pad,
store_lex, find_lex) committed yesterday. Note that lexical pads are
stored in the Parrot_Context struct's pad_stack field (see
include/parrot/interpreter.h).
In what follows I assume that all lexicals are stored as pointers
(instance of classes/pointer.pmc?) in the pad and that each scope will
have a reference to all of the pointers it needs to know about. In other
words a each pad has a pointer to all lexical variables declared or
referenced in the scope associated with the pad. A given pointer object
may live in multiple pads.
So:
- store_lex does not change the object that is in the hash, it just
changes what the object points to,
- and find_lex does not return the (pointer) object in the hash, it
returns the object pointed to by the object in the hash.
So here is my take on a slightly simpler example:
sub foo {
my $x = 13;
return sub { print "$x\n"; };
}
$foo()
main:
new_pad # push this on the lexical stack
# some constant descriptor should also be passed
# to the new_pad op which would then know about
# the lexical variable 'x', and would create an
# associated pointer object
new P0, .Sub # gets current lexicals from interp's context
set_addr I0, foo
set P0, I0 # current hack to get the correct address in sub
pop_pad
invoke # assumes sub is in P0
# on invoke the sub pmc fixes the current
# context to have the correct lexicals
end
foo: # We assume the closure is in P0
new P1, .Int
store_lex P1, "x" # probably by number not by name but ...
# the store would then store the new int in a
# the pointer object already allocated
set P1, 13
new_pad # again a constant descriptor should be passed
# to the new_pad op which would then know about
# the lexical variable 'x', and would get a pointer
# object from the parent scope (ie would not
# allocated a new pointer)
new P0, .Sub # this would then get the correct lexical
# info from interp's context so no need for a
# set_pad op
set_addr I0, sub
set P0, I0 # current hack to get the correct address in sub
pop_pad
ret # return the sub object
sub:
# on invoke the correct lexicals are in the current scope
find_lex P1, "x" # again probably by index not name
# after this P1 holds the int pmc
# print
ret
Does that make sense?
--
Jonathan Sillito