Re: Lexical variables, scratchpads, closures, ...
by Jerome Vouillon other posts by this author
Aug 2 2002 4:43PM messages near this date
Re: Lexical variables, scratchpads, closures, ...
|
Re: Lexical variables, scratchpads, closures, ...
On Fri, Aug 02, 2002 at 08:50:27AM -0700, Sean O'Rourke wrote:
> On Fri, 2 Aug 2002, Jerome Vouillon wrote:
>
> > On Thu, Aug 01, 2002 at 10:57:34AM -0700, Sean O'Rourke wrote:
> > > My naive implementation would have an array of hashes for each sub, with
> > > one entry for each level of scope within.
> >
> > I would use an array of arrays or a linked-list of arrays. This is
> > hardly more difficult to implement (you just need to keep track of the
> > variable indices during compilation) and the generated code will be a
> > lot more efficient.
>
> I don't see how you can cope with '%MY' unless you have a hash. You could
> have a hash in addition to the array, I suppose.
Sure, you need a hash. But this can be a statically allocated hash,
mapping variable names to indices.
> In any case, Dan has
> promised us some sort of indexed "back-door" access to our hashes, so I
> get the feeling the point is moot -- hashes will be arrays in some sense.
Allocating a hash will certainly remain a lot more expensive than
allocating an array. And we are going to allocate pads pretty
often...
> > > This is just like the
> > > pad_stack, but implemented using only language features. (Dynamic)
> > > lexical lookup works its way through this stack. Static lookups can
> > > probably be resolved to registers, with code inserted to fetch values out
> > > of the pad the first time they are used, and store them back when a scope
> > > is exited.
>
> > I think it is good enough for the moment to always go through the
> > stack.
>
> Without performance numbers, this is hard to test, but it can potentially
> turn a single "a = b + c", which is just "add P0, P1, P2" if a, b, and c
> have been referenced, into a hideous five instructions:
>
> fetch_lex P0, 'a' # Because how we store result depends on a's type
> fetch_lex P1, 'b'
> fetch_lex P2, 'c'
> add P0, P1, P2
> store_lex P0, 'a'
Sure, but this seems to be a non-trivial optimization (I may be
wrong). I think we should implement a larger part of the language
first.
By the way, the code should probably be:
fetch_lex P0, 'a' # Get the PMC of variable 'a'
fetch_lex P1, 'b' # Get the PMC of variable 'b'
fetch_lex P2, 'c' # Get the PMC of variable 'c'
add P0, P1, P2 # Add the values contained in the PMC of 'b' and 'c'
and store them in the PMC of 'a'
The opcode store_lex is only needed for the operator := (and maybe for
variable initialization).
> > > Returning a closure would make a copy of the scope array, containing
> > > references to the pad hashes (here's where GC makes me happy, and where I
> > > may make the GC unhappy).
> >
> > You don't need to make a copy at this point. Instead, the copy should
> > happen each time you enter a block containing lexical variables. (You
> > should also allocate and fill a new pad at this time.)
>
> Making a copy on every scope entry would solve the problem (the Befunge
> stack-stack metaphor grows stronger!), but I was hoping we could do
> better, since most lexical scopes won't be creating closures. The more I
> think about it, though, the more complicated that gets.
Note that when you have a loop you need to allocate some fresh lexical
variables at each iteration (so, you need to create a new pad each
time). Furthermore, you can create loops with callcc, so the piece of
code below could be a loop, if the function foo captures the current
continuation and the function bar resumes it.
foo();
do { my $x = ... }
bar();
> And actually, thanks to %MY and caller.MY, we need a new pad even
> for scopes without lexicals, since they can be inserted later.
I really hope %MY and caller.MY will not be able to extend the lexical
scope: we would get a really huge speed penalty for a feature which
would hardly ever be used.
-- Jerome
Thread:
Jerome Vouillon
Melvin Smith
Jerome Vouillon
Sean O'Rourke
Jerome Vouillon
Dan Sugalski
Dan Sugalski
Simon Cozens
Nicholas Clark
Sean O'Rourke
Jerome Vouillon
Nicholas Clark
Jerome Vouillon
Jonathan Sillito
Dave Mitchell
Melvin Smith
Sean O'Rourke
Dan Sugalski
Dan Sugalski
Jonathan Sillito
Jerome Vouillon
Melvin Smith
Jerome Vouillon
Melvin Smith
Jerome Vouillon
Jonathan Sillito
Sean O'Rourke
|