Here's a quick sketch of what I'm thinking we'll do for subs. No, it 
doesn't address stack stuff yet. That's next.

There are four flavors of subs:

1) Normal subs
2) Closures (which most normal subs really are)
3) Coroutines
4) Continuations

Additionally each of these subs may be either native (either as an
extention or JITted) or bytecode.

Normal subs may need to switch in:

*) Opcode table
*) Global namespace chain

Closures may additionally need to switch in:

*) Existing Lexical scope

Coroutines may also need to:

*) Track the current entry point

And Continuations may need to switch in:

*) All four register sets
*) All the stack frames

So, in total, we need:

*) Original routine entry point
*) Current routine entry point
*) Native/bytecode flag
*) Opcode table
*) Global namespace chain
*) "default" lexical scope
*) All the register sets
*) All the stack frames

Needless to say, we don't want all subs to switch this in--we want
perl 6 *faster* than perl 5, not slower. Because of this, it seems to
make sense to have multiple PMCs that have specialized knowledge of
how to invoke themselves, as well as a vtable entry for invocation.

So, we're adding an invoke vtable method, and we'll have four sub PMC
types: ParrotSub, ParrotClosure, ParrotCoroutine, and
ParrotContinuation. We ought to be able to create them with limited
trouble, and it's OK if they've got evil knowledge of Parrot's
internals.

We could, I suppose, make some sort of special interface to set things
up, but that seems to be a waste of time. Instead, we can treat them
as hashes and/or arrays, for each of the 'interesting' bits. (And we
can cheat a lot, by having the new method for ParrotClosure and
ParrotContinuation snapshot what they find interesting about the
current environment and fill in the destination blanks as need be)
Both array and hash lookup should work (introspection!), but the
interpreter should always use the array form for speed.

The invoke method is straightforward. It should set up the environment
for the sub and return the address (absolute) that the interpreter
should jump to. If it returns 0, then the interpreter should just take
up with the next instruction. (If the sub just goes and does its thing
and returns, which most C subs will do at the moment) At some point
we'll probably do Odd Things With Exceptions to avoid diving too deep
down the C stack, but for now it's OK (though it shouldn't be
expected) that we recurse.
-- 
                                         Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski                          even samurai
[EMAIL PROTECTED]                         have teddy bears and even
                                       teddy bears get drunk

Reply via email to