Node:VM instruction table, Next:VM code generation, Previous:VM engine, Up:Using the generated code
For threaded code we also need to produce a table containing the labels
of all VM instructions. This is needed for VM code generation
(see VM code generation), and it has to be done in the engine
function, because the labels are not visible outside. It then has to be
passed outside the function (and assigned to vm_prim
), to be used
by the VM code generation functions.
This means that the engine function has to be called first to produce
the VM instruction table, and later, after generating VM code, it has to
be called again to execute the generated VM code (yes, this is ugly).
In our example program, these two modes of calling the engine function
are differentiated by the value of the parameter ip0 (if it equals 0,
then the table is passed out, otherwise the VM code is executed); in our
example, we pass the table out by assigning it to vm_prim
and
returning from engine
.
In our example (vmgen-ex/engine.c
), we also build such a table for
switch dispatch; this is mainly done for uniformity.
For switch dispatch, we also need to define the VM instruction opcodes
used as case labels in an enum
.
For both purposes (VM instruction table, and enum), the file
name-labels.i
is generated by Vmgen. You have to define
the following macro used in this file:
INST_ADDR(inst_name)
LABEL(inst_name)
), for both uses of
name-labels.i
. For threaded-code dispatch, this is the
address of the label defined in LABEL(inst_name)
); the
address is taken with &&
(see Labels as Values).