Amir Karger writes:
> Still working on the prelude to the preface to the "Z-machine running
> natively on Parrot" project, namely translating Z-code into a Perl
> executable. (My brother, who's a CS professor so he should know, says
> I'm actually *compiling* it. Compiling bytecode to an interpreted
> language? Weird!)

Yeah.  Actually, Perl 5 is even compiling itself, into bytecode, which
is then interpreted.  An example of a language that isn't compiled is,
say, Bourne Shell, which is executed based on repeated text
substitutions.

> I'm making some progress, but now I have to deal with
> the harder opcodes I'd ignored, like I/O and save/restore. (Interesting
> to hear about Parrot curses, wrt Z-code I/O, btw.)
> 
> I figured I could just use the Perl subroutine mechanism to emulate
> Z-machine calls. So I just translate Z-code's "call routine arg0
> arg1..." to "&routine(arg0, arg1, ...)" and "ret value" becomes "return
> $value". 
> 
> I realized that I get in trouble when we get to the save/restore
> commands. Those are supposed to save and restore the call stack, which
> includes the subroutine addresses & all the local variables in the
> various routines. Am I right in thinking I don't actually have access
> to that in Perl? (That is, I can't change the call stack at runtime,
> such that when I "return" it'll return to a different subroutine than
> the one that actually called the current routine.)

You mean.. in Parrot?  In Perl 5, using just the language, no you don't.
In parrot, however, you do.  There is actually no call stack; it's
implicit in the cascade of P1 registers.  That's why we call it the
'call chain'.

> In Perl, I can fake it by making my entire program have no subroutines
> (yuck!) and using gotos and manually storing the call stack. Then I
> thought, "but what do I do about Parrot?", which is supposed to be the
> whole point of this project. Then I thought that maybe I *do* have
> access to Parrot's stack!
>
> So the question is, will I be able to write a Parrot opcode that resets
> the Parrot call stack? And I guess to reset the register stacks too?
> Otherwise, I won't be able to save/restore games.

>From disk, right?  No, I don't think that's possible using the basic
Parrot mechanisms.  That is, in general, a fairly hard thing to do
(although, it might be done, considering how people have been talking
about serialization recently.  In any case, it's not available at the
moment).

So you could wait until it might be implemented.  But I don't recommend
that, because then you're counting on the timelyness of open source,
which doesn't exist :-).  

Then let's think of some other solutions to the problem.  This will be
pretty abstract, mind you.

My first thought is that you can create a "call frame" object.  This
object then holds a reference to the current lexical pad, the bytecode
address, and a reference to the caller's call frame object.  This object 
would be passed into new functions much in the manner of the return
continuations we now pass.  To save, you walk up these frames,
serializing whatever is there (presuming you know the exact set of
possible data types that might be in your lexical pads).

Because of the explicitness of the bytecode format, it's possible to
take this data and re-create the stack out-of-band, and then jump to the
proper address.  It'd be a lot of work, but possible nonetheless.

There are problems with that, however.  The biggest one is that it
places a lot of restrictions on what kinds of data you're allowed to
have in your program.  I don't know Z-code well enough to say whether
this will be too limiting.

Maybe continuations aren't so hard to serialize after all (well,
excluding things like open filehandles and such).  What's the status on
the serialization subsystem?

Luke

Reply via email to