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