[z-machine] Replicating txd subroutine-finding functionality
Mark J Musante
olorin@world.std.com
Thu, 20 May 2004 08:49:22 -0400
On Wed, 19 May 2004, Amir Karger wrote:
> 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?
[snip]
>
> 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.
I haven't seen the txd source code, so I don't know whether its approach
is similar to yours, but I would tackle this a bit differently.
What I'd do would be a 'depth-first' search. You know where main is,
where the code starts, so begin there. Whenever you come across a call,
push your current location on the stack, and follow that call. Eventually
you'll hit a routine that doesn't make any calls whatsoever, and you can
pop your way back up the stack.
One tricky bit would be jumps, both conditional and unconditional.
There's nothing in the z-machine spec which prevents a user from jumping
from one routine to another, so it's something you'll have to be aware of.
The inform assembler does its best to prevent this, but I believe there
are ways around it.
I wouldn't count on the padding between routines being zeros. Instead I'd
create a bitmap of all the bytes in the code section of the z-file and use
that to determine what areas may have been missed.
Also bear in mind that some routines will only be called via object
properties - these won't be found using the depth-first search outlined
above. Instead you'll have to infer these by the gaps in the bitmap.
Finally, don't forget that the various 'call' opcodes are not the only
ones that call routines. There's also 'sread', 'aread', 'sound_effect',
and 'read_char'. Also, there's the indirect call, but there's not much
you can do about that.
This is an ambitious project. Good luck.
-markm