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


Reply via email to