The purpose of this structure is to make VM as modular and as simple as
possible. It is especially important to be able to add/change individual
instructions by changing only the instruction module.
| File vm.h
C-functions:
-
Status make_instruction(INOUT unsigned char *buf,
INOUT int *instruction_size,
IN Vm_instruction instruction,
IN uint64 *args)
Description: | Create an encoded byte code instruction number 'instruction' to *
BUF and return the length of the instruction in bytes in
INSTRUCTION_SIZE. Instrument args are stored in the array ARGS in
the following way: register numbers are stored as uint64s, constant
table entries as uint64s (offsets to a constants table) and labels
in the same way. If BUF is NULL return length but do not write the
actual encoding anywhere. INSTRUCTION_SIZE may not be NULL. |
-
Status reverse_map_instruction(IN int instr_num,
OUT const char **nameptr,
OUT const char **argsptr)
Description: | Map instruction numbers to their names and arguments specification |
-
Status vm_execute(IN Heap heap,
IN Registerset *registers,
IN Bytecode *byte_code,
INOUT uint64 *instr_count,
OUT Vm_status *status)
Description: |
Execution of virtual machine instructions
int32 vm_execute(IN Heap heap,
IN Registerset *registers,
IN Bytecode *byte_code,
IN int64 code_offset,
INOUT int64 *instr_count,
OUT Vm_status *status);
PRECOND(NULL != registers);
PRECOND(NULL != byte_code);
PRECOND(NULL != status);
POSTCOND(IN(*instr_count) >= OUT(*instr_count));
The VM acts like a library; it has no internal state that persist
across calls to vm_execute() (or vm_message()).
Therefore the parameters specify the heap to be used, current
register set, instructions (bytecode) and the number of instructions
to be executed with this call. vm_execute() return the
number of instructions executed (it can (and in many cases will!) be
different from the number requested) and the status after the
current instruction. The status values include:
- VM_STATUS_OK VM state normal
- VM_STATUS_BLOCKING VM is blocking; this happens when waiting
for messages to arrive to the message queue
- VM_STATUS_FAIL VM state violation (illegal instruction, jump
out of code, invalid heap access, etc)
- VM_STATUS_HALT VM_INSTR_HALT exected (or similar condition)
|
-
Status vm_message(IN Heap heap,
IN Registerset *registers,
IN LinearizedHeap message,
OUT Vm_status *status)
Description: |
Messages to actors
Status vm_message(IN Heap heap,
IN Registerset *registers,
IN LinearizedHeap message,
OUT Vm_status *status);
PRECOND(NULL != registers);
PRECOND(NULL != message);
PRECOND(NULL != status);
The message delivery to the VM is handled here; the internal
exception mechanism is used to notify the bytecode program of the
arrival of a message. Incoming messages are serialized so that
the VM does not explicitly have to keep queues for incoming messages.
However, it is likely that the program running on the VM is using
a queue like mechanism if it does not handle the messages within
the exception handler.
The idea of the implementation is to place the message (linearized heap)
into the exception handler's parameter (delinearized heap), then the
exception mechanism is started by modifying the stack & PC to start the
exception handler iediately. It is assumed that the exceptions are enabled
when entering this function; if they are not, the function returns with
*status == VM_STATUS_BLOCKING.
|
-
Status vm_send_message_out(uchar *address,
LinearizedHeap heap,
uint64 data_length)
Description: | This function is NOT implemented in the library, but needs to
be implemented elsewhere in a program using the virtual machine
library. The virtual machine calls it when it wants to send
a message out. ADDRESS is the address where the message should
be sent; it will be a 256-bit actor address. DATA contains
the data (actually a linearized heap). DATA_LENGTH is the
length of the linearized heap.
Both ADDRESS and DATA are dynamically allocated. vm_send_message_out
or some other external procedure should free them when needed.
The function must return STATUS_OK. |
File vm_debug.h
C-functions:
File vm_encode.h
C-functions:
- Vm_status vm_encoder_const(IN Vm_instruction instr,
OUT unsigned char *buf,
OUT int *instr_size,
IN uint64 *args)
-
Vm_status vm_encoder_nop(IN Vm_instruction instr,
OUT unsigned char *buf,
OUT int *instr_size,
IN uint64 *args)
- Vm_status vm_encoder_reg1(IN Vm_instruction instr,
OUT unsigned char *buf,
OUT int *instr_size,
IN uint64 *args)
- Vm_status vm_encoder_reg12(IN Vm_instruction instr,
OUT unsigned char *buf,
OUT int *instr_size,
IN uint64 *args)
- Vm_status vm_encoder_reg123(IN Vm_instruction instr,
OUT unsigned char *buf,
OUT int *instr_size,
IN uint64 *args)
- Vm_status vm_encoder_reg1234(IN Vm_instruction instr,
OUT unsigned char *buf,
OUT int *instr_size,
IN uint64 *args)
- Vm_status vm_encoder_reg12const(IN Vm_instruction instr,
OUT unsigned char *buf,
OUT int *instr_size,
IN uint64 *args)
- Vm_status vm_encoder_reg12tag(IN Vm_instruction instr,
OUT unsigned char *buf,
OUT int *instr_size,
IN uint64 *args)
- Vm_status vm_encoder_reg1const(IN Vm_instruction instr,
OUT unsigned char *buf,
OUT int *instr_size,
IN uint64 *args)
- Vm_status vm_encoder_reg1tag(IN Vm_instruction instr,
OUT unsigned char *buf,
OUT int *instr_size,
IN uint64 *args)
File vm_instr.h
C-functions:
- _PLACE_INSTR(x)
-
Vm_status vm_decoder_const(IN uint32 instr,
IN Heap heap,
IN uint64 *imm_offset,
OUT Vm_decoded_instr *decoded)
Description: | Constant operand |
-
Vm_status vm_decoder_extend(IN uint32 instr,
IN Heap heap,
IN uint64 *imm_offset,
OUT Vm_decoded_instr *decoded)
Description: | i_offset extend operand |
-
Vm_status vm_decoder_nop(IN uint32 instr,
IN Heap heap,
IN uint64 *imm_offset,
OUT Vm_decoded_instr *decoded)
Description: | No operand decoding |
-
Vm_status vm_decoder_reg1(IN uint32 instr,
IN Heap heap,
IN uint64 *imm_offset,
OUT Vm_decoded_instr *decoded)
Description: | One register operand |
-
Vm_status vm_decoder_reg12(IN uint32 instr,
IN Heap heap,
IN uint64 *imm_offset,
OUT Vm_decoded_instr *decoded)
Description: | Two register operands |
-
Vm_status vm_decoder_reg123(IN uint32 instr,
IN Heap heap,
IN uint64 *imm_offset,
OUT Vm_decoded_instr *decoded)
Description: | Three register operands |
-
Vm_status vm_decoder_reg1234(IN uint32 instr,
IN Heap heap,
IN uint64 *imm_offset,
OUT Vm_decoded_instr *decoded)
Description: | Four register operands |
-
Vm_status vm_decoder_reg12const(IN uint32 instr,
IN Heap heap,
IN uint64 *imm_offset,
OUT Vm_decoded_instr *decoded)
Description: | Two registers and constant operand |
-
Vm_status vm_decoder_reg12tag(IN uint32 instr,
IN Heap heap,
IN uint64 *imm_offset,
OUT Vm_decoded_instr *decoded)
Description: | Two registers + type tag operands |
-
Vm_status vm_decoder_reg1const(IN uint32 instr,
IN Heap heap,
IN uint64 *imm_offset,
OUT Vm_decoded_instr *decoded)
Description: | Register and constant operand |
-
Vm_status vm_decoder_reg1tag(IN uint32 instr,
IN Heap heap,
IN uint64 *imm_offset,
OUT Vm_decoded_instr *decoded)
Description: | One register + type tag operands |
- Vm_status vm_operator_alloc_boolean(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_alloc_float(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_alloc_integer(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_alloc_pair(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_alloc_pair_tagged(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_alloc_private_bit_string(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_alloc_private_bit_string_tagged(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_alloc_shared_bit_string(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_alloc_shared_bit_string_tagged(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_alloc_vector(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_alloc_vector_immediate(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_alloc_vector_tagged(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_and(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_bit_string_cmp(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_bit_string_debug_dump(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_bit_string_ge(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_bit_string_len(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_bit_string_to_int(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_boolean_get(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_boolean_not(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_boolean_set(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_branch(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_branch_immediate(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_cons(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_copy_bit_string(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_copy_pair(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_copy_vector(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_create_procedure(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_create_procedure_immediate(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_disable_exceptions(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_enable_exceptions(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_eq(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_float_add(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_float_cmp(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_float_div(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_float_exp(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_float_ge(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_float_get(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_float_log(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_float_log10(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_float_mod(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_float_mul(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_float_rem(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_float_set(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_float_sqrt(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_float_sub(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_float_to_int(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_get_message(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_get_procedure_address(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_get_procedure_env(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_get_substring(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_halt(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_int_add(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_int_cmp(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_int_div(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_int_ge(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_int_mod(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_int_mul(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_int_rem(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_int_sub(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_int_to_bit_string(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_int_to_float(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_integer_get(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_integer_set(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_is_of_actor_address(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_is_of_boolean(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_is_of_byte_code(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_is_of_float(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_is_of_integer(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_is_of_pair(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_is_of_pair_tagged(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_is_of_private_bit_string(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_is_of_private_bit_string_tagged(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_is_of_procedure(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_is_of_shared_bit_string(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_is_of_shared_bit_string_tagged(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_is_of_vector(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_is_of_vector_tagged(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_jump(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_jump_immediate(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_land(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_load(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_load_null(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_lor(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_move(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_neg(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
-
Vm_status vm_operator_nop(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
Description: | Instruction operator prototypes |
- Vm_status vm_operator_not(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_or(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_pair_get_car(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_pair_get_car_or_block(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_pair_get_cdr(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_pair_set_car(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_pair_set_cdr(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_pop(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_push(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_put_message(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_restore(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_restore_immediate(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_rol(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_ror(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_save(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_save_immediate(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_send_message(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_set_exception_handler(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_set_substring(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_shl(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_shr(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_tag_cmp(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_vector_get(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_vector_get_index(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_vector_len(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_vector_set(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_vector_set_index(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
- Vm_status vm_operator_xor(IN Heap heap,
IN Registerset *registers,
IN Vm_decoded_instr *instr)
3 Internal interfaces
This internal interface definition specifies the current
implementation decisions of the SCHEMESTATION VM.
3.1 Instruction encoding & decoding
With each instruction (VM_INSTR_*) there is an association
to instruction encoder and decoder functions.
The purpose of the instruction decoding
phase is to pick out the operands of the instruction and place them
to a structure that holds all possible operand combinations. This
structure can then be passed to individual instruction function.
The encoder is placed here for convenience; the assembler uses the
encoder to produce the binary from instructions and their operands.
Each decoder instruction is implemented as a function that has the following
fingerprint:
Vm_status vm_decoder_*(IN uint32 instr, /* Instruction item to be decoded */
IN Heap heap, /* Constants are located here */
IN uint64 *imm_offset, /* IMM_EXTEND support */
OUT Vm_decoded_instr *decoded); /* The final result */
Encoder function fingerprint:
Vm_status vm_encoder_*(IN Vm_instruction instr, /* The instruction */
OUT unsigned char *buf, /* Output buffer */
OUT int *instr_size, /* Size of the encoded instruction */
IN uint64 *args); /* Operand vector */
3.2 Instruction selection and individual instructions
Instructions are associated to an instruction function and using
a table of associations, the particular instruction function for an
instruction is selected.
Each instruction is implemented as a function that has the following
fingerprint:
Vm_status vm_operator_*(INOUT Heap heap,
INOUT Registerset *registers,
IN Vm_decoded_instr *instr);
If instruction return status is different from VM_STATUS_OK,
some decisions has to be made: either the VM exception mechanism can
handle the situation and continue execution or the status value will be
passed to the external interface of the VM and the instruction scheduling
discontinued.
3.3 Exceptions
The exception mechanism is based on the register VM_REG_EXCEPTION
which contains the address of the user-defined exception handler. If this
register contains NIL, it means that the exceptions are disabled;
if an exception should occur whenever exceptions are disabled, the VM
acts like VM_INSTR_HALT would have been executed (the program dies).
When an exception is raised, the following instructions are executed
internally:
VM_INSTR_SAVE_IMMEDIATE VM_REG_STACK, B1111111111110111 ; save registers except VM_REG_MSG_QUEUE
VM_INSTR_JUMP VM_REG_EXCEPTION ; jump to the exception handler
VM_INSTR_LOAD_NULL VM_REG_EXCEPTION ; set the exception handler to NIL -> exceptions disabled
After that, the parameter is placed to VM_REG_R2 and the
execution can continue. This implies that whenever the instruction
VM_INSTR_RESTORE_IMMEDIATE, VM_REG_STACK, B11111111111111
is executed, it has the effect of returning from the exception handler
and continuing the execution from the point where the exception occurred.
Note that the register VM_REG_MSG_QUEUE is not saved or
restored.
NOTE: Current implementation does not generate fatal exceptions, as there
are no defined semantics to handle them - instead, the program that generated
the exception is terminated.
3.4 VM and asynchronous messages
vm_message() interface invokes the exception handling facility
which passes the message to the exception handler of this particular
bytecode instance. This message delinearizes the message (a linearized
heap, formed as a list of parameters, where the first parameter is a
bitstring identifying the message) and passes it to the program as the
parameter of the exception handler.
NOTE: It is assumed that the exception mechanism (once defined) will be
using this kind of parameter passing - that is, exceptions behave like
"out of band" messages, and they can be recognized just like normal
messages.
|