[z-machine] Replicating txd subroutine-finding functionality
Amir Karger
amirkargerweb@yahoo.com
Thu, 20 May 2004 20:18:19 -0700 (PDT)
Sorry about replying to myself.
I've been thinking, and I'm a bit more confident about things.
--- Amir Karger <amirkargerweb@yahoo.com> wrote:
> So I've decided to try replicating [txd], at least for easy cases
(e.g.,
> Inform, which seems to be better behaved about where it puts things).
Since we last spoke, I figured out some things:
1. 0 is not a legal opcode (almost every other 1-byte number is,
depending on version)
2a. subs must start at packed addresses
2b. subs must start with a byte 0-15
So let's work by induction. Assume I've just read a command, and my PC
is about to read the next byte.
if next byte is a known start of sub {
we finished this sub! Celebrate
} else if next byte is a 0 { # there must be a sub next
if there's more than one 0 {
skip to the last 0 in the series
again, if we get to known start of sub, we're done
}
if last 0 is on packed address {
start a sub here
} else if next byte is on packed address and is 1-15 {
start a sub at that byte
} else error!
} else if not on packed address OR next byte is not 1-15 { # must be a
command
read next command
} else { # start doing things I'm less sure about
# During this less sure part, if I get a parsing error, try
# the other possibility
if previous command was not a ret, rfalse etc. {
read command
} else {
read sub
}
}
Note that I didn't even have to use my "if we jump ahead to an
address, then this sub goes at least to that address". I could
probably use that within the "less sure" piece to make it more sure.
My plan below stays the same, but I'm more sure about it.
Answers to the below questions would still be helpful.
Right. Also stop if we get to a known string address or end of the
file. It's a slight worry that the first string will be referenced in
a sub we don't see, so we'll run past the end of the last sub and into
the strings. Let's just hope that doesn't happen.
> The basic plan is this:
> -start at the "main" sub, and translate commands one at a time.
> -If I get to a call of any kind (except "call sp" or the like), put
> the called address onto my list of subs to look at.
> -If I find that I've translated addresses 1000-1100 and 1120-1200,
> assume there's a sub at 1101, and try to parse it that way.
Actually, don't assume there's a sub at 1101. Use the rules above to
figure out if we should continue the 1000-1100 sub or start working on
a new one.
> 1. will all subs (compiled with "all" compilers) have as their last
> opcode one of: ret, ret_popped, rfalse, rtrue, print_ret, jump (only
> true jump, and must jump backwards), throw, restart, restore, quit?
>
> 2. Will space between end of one sub and beginning of the next (at a
> packed address) always be zeroes? This will also help determine
> whether I've finished a sub.
If not, my pretty rules above don't work nearly as well.
> 4. are we guaranteed to find action etc. routine addresses in a
> certain place? I can't seem to find info on the web describing how
> the addresses for these guys are chosen or how I can figure them
> out.
Definitely would still be good to know this. Otherwise we'll miss a
huge swath of subs.
> (If I were REALLY crazy, I'd actually start executing the code, and
> whenever I found a sub I hadn't yet translated, I'd translate it.
> But of course I can't guarantee code coverage.)
By the way, this got me thinking. Why not have the translated Perl
program I write set up so that if it tries to call a sub it doesn't
know about, then it re-calls the the translator to write a new version
of the Perl program that includes the new sub! (In fact, you wouldn't
need to run the translator in the first place - just start the Perl
program off with a "call first_address" and let it run!)
Perl lets you generate code and subroutines on the fly, so we could
generate the new subs, AND we could output the text to a file that
would make up a new version of the program containing the new sub.
Neat!
> If anyone has better ideas for how to find subroutine starts and ends
> in a Zcode game, feel free to speak up.
I hope you don't mind the long emails - I always think better when I
force someone else to listen.
-Amir
__________________________________
Do you Yahoo!?
Yahoo! Domains – Claim yours for only $14.70/year
http://smallbusiness.promotions.yahoo.com/offer