From e4ea0f415121795b552134254dccf76999f70d40 Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Sun, 6 Jun 2004 19:53:13 +0000 Subject: keep track of runtime errors and correctly report them. --- mixlib/xmix_vm.c | 123 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 46 deletions(-) (limited to 'mixlib/xmix_vm.c') diff --git a/mixlib/xmix_vm.c b/mixlib/xmix_vm.c index 718a9d3..ecb67c9 100644 --- a/mixlib/xmix_vm.c +++ b/mixlib/xmix_vm.c @@ -56,6 +56,20 @@ get_dev_ (mix_vm_t *vm, mix_fspec_t type) return vm->devices[type]; } +/* error macro */ +#define fail_if_not_(vm,cond,error) \ +do { \ + if (!(cond)) \ + { \ + set_last_error_ (vm, error); \ + return FALSE; \ + } \ +} while (FALSE) + +#define fail_(vm,error) fail_if_not_ (vm, FALSE, error) + +#define fail_unexpected_(vm) fail_ (vm, MIX_VM_ERROR_UNEXPECTED) + /* Instruction handlers */ static gboolean @@ -136,7 +150,7 @@ spc_handler_ (mix_vm_t *vm, const mix_ins_t *ins) mix_word_negative (num) : num); break; } - default: return FALSE; + default: fail_ (vm, MIX_VM_ERROR_BAD_FSPEC); } inc_loc_ (vm); return TRUE; @@ -148,7 +162,8 @@ sla_handler_ (mix_vm_t *vm, const mix_ins_t *ins) mix_short_t n = get_M_ (vm,ins); g_assert (ins->opcode == mix_opSLx); - g_return_val_if_fail (mix_short_is_positive (n), FALSE); + + fail_if_not_ (vm, mix_short_is_positive (n), MIX_VM_ERROR_BAD_M); switch ( mix_ins_id_from_ins (*ins) ) { case mix_SLA: @@ -174,7 +189,7 @@ sla_handler_ (mix_vm_t *vm, const mix_ins_t *ins) &get_rA_ (vm), &get_rX_ (vm)); break; default: - return FALSE; + fail_unexpected_ (vm); } inc_loc_ (vm); @@ -189,16 +204,19 @@ mov_handler_ (mix_vm_t *vm, const mix_ins_t *ins) guint k, delta = ins->fspec; g_assert (ins->opcode == mix_opMOVE); - g_return_val_if_fail (mix_short_is_positive (from), FALSE); - g_return_val_if_fail (mix_short_is_positive (to), FALSE); - g_return_val_if_fail (MEMOK_ (from + delta -1), FALSE); - g_return_val_if_fail (MEMOK_ (to + delta - 1), FALSE); - - for (k = 0; k < delta; ++k) - set_cell_ (vm, to+k, get_cell_ (vm, from+k)); - set_rI_ (vm, 1, to+delta); - inc_loc_ (vm); - return TRUE; + if (mix_short_is_positive (from) + && mix_short_is_positive (to) + && MEMOK_ (from + delta -1) + && MEMOK_ (to + delta - 1)) + { + for (k = 0; k < delta; ++k) + set_cell_ (vm, to+k, get_cell_ (vm, from+k)); + set_rI_ (vm, 1, to+delta); + inc_loc_ (vm); + return TRUE; + } + else + return FALSE; } static gboolean @@ -258,8 +276,10 @@ static gboolean jbs_handler_ (mix_vm_t *vm, const mix_ins_t *ins) { g_assert (ins->opcode == mix_opJBUS); - g_return_val_if_fail (ins->fspec < BD_NO_, TRUE); - g_return_val_if_fail (get_dev_ (vm, ins->fspec) != NULL, TRUE); + fail_if_not_ (vm, ins->fspec < BD_NO_, MIX_VM_ERROR_BAD_DEVICE_NO); + fail_if_not_ (vm, get_dev_ (vm, ins->fspec) != NULL, + MIX_VM_ERROR_BAD_DEVICE_NO); + if ( mix_device_busy (get_dev_ (vm, ins->fspec)) ) { set_rJ_ (vm, get_loc_ (vm)); set_loc_ (vm, get_M_ (vm, ins)); @@ -272,18 +292,19 @@ ioc_handler_ (mix_vm_t *vm, const mix_ins_t *ins) { mix_address_t addr; mix_device_t *dev; - gboolean result; g_assert (ins->opcode == mix_opIOC); + addr = get_M_ (vm, ins); - g_return_val_if_fail (ins->fspec < BD_NO_, TRUE); + fail_if_not_ (vm, ins->fspec < BD_NO_, MIX_VM_ERROR_BAD_DEVICE_NO); + dev = get_dev_ (vm, ins->fspec); - g_return_val_if_fail (dev != NULL, TRUE); - result = - mix_device_ioc (dev, addr); + fail_if_not_ (vm, dev != NULL, MIX_VM_ERROR_BAD_DEVICE_NO); + + fail_if_not_ (vm, mix_device_ioc (dev, addr), MIX_VM_ERROR_DEV_CTL); inc_loc_ (vm); - return result; + return TRUE; } static gboolean @@ -291,21 +312,24 @@ inp_handler_ (mix_vm_t *vm, const mix_ins_t *ins) { mix_address_t addr; mix_device_t *dev; - gboolean result; g_assert (ins->opcode == mix_opIN); + fail_if_not_ (vm, ins->fspec < BD_NO_, MIX_VM_ERROR_BAD_DEVICE_NO); + addr = get_M_ (vm, ins); - g_return_val_if_fail (ins->fspec < BD_NO_, TRUE); - g_return_val_if_fail (MEMOK_ (addr), TRUE); + fail_if_not_ (vm, MEMOK_ (addr), MIX_VM_ERROR_BAD_ACCESS); + dev = get_dev_ (vm, ins->fspec); - g_return_val_if_fail ( dev != NULL, TRUE); - g_return_val_if_fail (MEM_CELLS_NO_ - addr > mix_device_block_size (dev), - TRUE); - result = - mix_device_read (dev, get_cell_ptr_ (vm, addr)); + fail_if_not_ (vm, dev != NULL, MIX_VM_ERROR_BAD_DEVICE_NO); + + fail_if_not_ (vm, MEM_CELLS_NO_ - addr > mix_device_block_size (dev), + MIX_VM_ERROR_BAD_ACCESS); + + fail_if_not_ (vm, mix_device_read (dev, get_cell_ptr_ (vm, addr)), + MIX_VM_ERROR_DEV_READ); inc_loc_ (vm); - return result; + return TRUE; } static gboolean @@ -313,29 +337,35 @@ out_handler_ (mix_vm_t *vm, const mix_ins_t *ins) { mix_address_t addr; mix_device_t *dev; - gboolean result; g_assert (ins->opcode == mix_opOUT); + + fail_if_not_ (vm, ins->fspec < BD_NO_, MIX_VM_ERROR_BAD_DEVICE_NO); + addr = get_M_ (vm, ins); - g_return_val_if_fail (ins->fspec < BD_NO_, TRUE); - g_return_val_if_fail (MEMOK_ (addr), TRUE); + fail_if_not_ (vm, MEMOK_ (addr), MIX_VM_ERROR_BAD_ACCESS); + dev = get_dev_ (vm, ins->fspec); - g_return_val_if_fail ( dev != NULL, TRUE); - g_return_val_if_fail (MEM_CELLS_NO_ - addr > mix_device_block_size (dev), - TRUE); - result = - mix_device_write (dev, get_cell_ptr_ (vm, addr)); + fail_if_not_ (vm, dev != NULL, MIX_VM_ERROR_BAD_DEVICE_NO); + + fail_if_not_ (vm, MEM_CELLS_NO_ - addr > mix_device_block_size (dev), + MIX_VM_ERROR_BAD_ACCESS); + + fail_if_not_ (vm, mix_device_write (dev, get_cell_ptr_ (vm, addr)), + MIX_VM_ERROR_DEV_WRITE); inc_loc_ (vm); - return result; + return TRUE; } static gboolean jrd_handler_ (mix_vm_t *vm, const mix_ins_t *ins) { g_assert (ins->opcode == mix_opJRED); - g_return_val_if_fail (ins->fspec < BD_NO_, TRUE); - g_return_val_if_fail (get_dev_ (vm, ins->fspec) != NULL, TRUE); + fail_if_not_ (vm, ins->fspec < BD_NO_, MIX_VM_ERROR_BAD_DEVICE_NO); + fail_if_not_ (vm, get_dev_ (vm, ins->fspec) != NULL, + MIX_VM_ERROR_BAD_DEVICE_NO); + inc_loc_ (vm); if ( !mix_device_busy (get_dev_ (vm, ins->fspec)) ) { @@ -353,7 +383,8 @@ jmp_handler_ (mix_vm_t *vm, const mix_ins_t *ins) mix_ins_id_t id = mix_ins_id_from_ins (*ins); g_assert (ins->opcode == mix_opJMP); - g_return_val_if_fail (MEMOK_ (addr), FALSE); + fail_if_not_ (vm, MEMOK_ (addr), MIX_VM_ERROR_BAD_ACCESS); + switch ( id ) { case mix_JMP: case mix_JSJ: @@ -386,7 +417,7 @@ jmp_handler_ (mix_vm_t *vm, const mix_ins_t *ins) jump = ( get_cmp_ (vm) != mix_GREAT ); break; default: - return FALSE; + fail_unexpected_ (vm); } inc_loc_ (vm); @@ -406,7 +437,7 @@ jpx_handler_ (mix_vm_t *vm, const mix_ins_t *ins) mix_word_t val; g_assert (ins->opcode >= mix_opJAx || ins->opcode <= mix_opJXx); - g_return_val_if_fail (MEMOK_ (addr), FALSE); + fail_if_not_ (vm, MEMOK_ (addr), MIX_VM_ERROR_BAD_ACCESS); switch (ins->opcode) { case mix_opJAx: val = get_rA_ (vm); break; @@ -448,7 +479,7 @@ jpx_handler_ (mix_vm_t *vm, const mix_ins_t *ins) || mix_word_is_negative (val); break; default: - return FALSE; + fail_unexpected_ (vm); } inc_loc_ (vm); @@ -509,7 +540,7 @@ ina_handler_ (mix_vm_t *vm, const mix_ins_t *ins) mix_word_reverse_sign (val); break; default: - return FALSE; + fail_unexpected_ (vm); } set_reg_ (vm, r, val); inc_loc_ (vm); -- cgit v1.2.3