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