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