On Thu, 1 Aug 2002, Jerome Vouillon wrote:

> On Wed, Jul 31, 2002 at 11:22:56PM -0400, Melvin Smith wrote:
> > We chose to implement
> > the access as ops, and you prefer using a PMC Array directly. I can
> > at least see one advantage to the explicit ops: they don't require
> > a register to use them in the general case.
>
> [snip]
>
> But I'm especially frightened by opcodes such as new_pad.  The Perl
> compiler may well be able to perform more optimizations if it does not
> use this opcode but rather generate specialized code.

Putting my "amateur compiler writer" hat on for a moment, I'll have to
agree for a couple of reasons.  First, supporting Perl 6's introspective
features (e.g. %MY) is much easier if the internals and language
implementation use the same data structures where practical.  Sure, it's
possible to write some glue code to make a stack act like a PerlArray, but
it's more work, and in this case I'm not sure it's necessary.  There is
the unfortunate fact that all of a sudden the lexical implementation will
be tied to a particular language's PMC's, but this seems like another
reason to push lexicals out of the interpreter core.

Second, I've been playing with implementing lexicals "the right way" in
P6C, and haven't really found new_pad and pop_pad all that useful.  Of
course, I don't have a working implementation yet, and I may be completely
misunderstanding how the ops should be used.  I suspect that getting them
to "do the right thing" would involve adding lex-playing-with code to bsr
and ret, plus maybe a couple more ops.  Plus adding more ops to push
lexical stacks onto the lexical stack-stack (for your Befunge fans ;).

> So, I would feel more comfortable trying to reuse existing opcodes for
> the moment, especially as I don't think we have a clear view of the
> "right" way to implement lexical variables yet.

My naive implementation would have an array of hashes for each sub, with
one entry for each level of scope within.  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.

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).  So the Sub PMC has a code pointer and a scope
stack pointer, which is either set up automatically when creating a new
Sub, or is accessible as a method.

Another alternative would be single-level pads for each scope containing
all accessible lexicals.  Unfortunately, I think %OUTER and %MY make this
very complicated (or impossible) to get right.

Waving my hands somewhat more quickly, as an optimization, lexicals can
just live in registers when the compiler sees no references to %MY or
closures.  Nastiness like eval and caller.MY can be handled by inserting
fixup code to reconstruct the lexical array on demand.

Hopefully I can get some of this working soon, and put it up on the list
for people to play with and improve.

/s

Reply via email to