Node:VM instruction table, Next:, Previous:VM engine, Up:Using the generated code



VM instruction table

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)
For switch dispatch, this is just the name of the switch label (the same name as used in 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).