diff options
Diffstat (limited to 'mixlib')
| -rw-r--r-- | mixlib/xmix_vm.c | 123 | ||||
| -rw-r--r-- | mixlib/xmix_vm.h | 7 | ||||
| -rw-r--r-- | mixlib/xmix_vm_handlers.c | 53 | 
3 files changed, 115 insertions, 68 deletions
| 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); diff --git a/mixlib/xmix_vm.h b/mixlib/xmix_vm.h index 45805e8..f4773eb 100644 --- a/mixlib/xmix_vm.h +++ b/mixlib/xmix_vm.h @@ -2,9 +2,9 @@   * This file contains internal declarations used in the implementation   * of the mix_vm_t type.   * ------------------------------------------------------------------ - *  $Id: xmix_vm.h,v 1.8 2003/01/12 21:05:01 jao Exp $ + *  $Id: xmix_vm.h,v 1.9 2004/06/06 19:53:13 jao Exp $   * ------------------------------------------------------------------ - * Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc.   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by @@ -50,6 +50,7 @@ struct mix_vm_t    mix_cmpflag_t cmpflag;    mix_short_t loc_count;    mix_vm_status_t status; +  mix_vm_error_t last_error;    mix_device_t * devices[BD_NO_];    mix_address_t start_addr;	/* start address of loaded file */    GTree *line_table;		/* source line no -> address  */ @@ -86,6 +87,8 @@ enum { A_ = 0, X_, J_, I1_, I2_, I3_, I4_, I5_, I6_ };  #define get_pred_list_(vm) (vm->pred_list)  #define get_address_list_(vm) (vm->address_list)  #define get_status_(vm) (vm->status) +#define get_last_error_(vm) (vm->last_error) +#define set_last_error_(vm,error) ((vm)->last_error = (error))  #define set_reg_(vm,r,x)			\  do {						\ diff --git a/mixlib/xmix_vm_handlers.c b/mixlib/xmix_vm_handlers.c index 4d0285f..a778750 100644 --- a/mixlib/xmix_vm_handlers.c +++ b/mixlib/xmix_vm_handlers.c @@ -1,9 +1,9 @@  /* -*-c-*- -------------- xmix_vm_handlers.c :   * Implementation of the functions declared in xmix_vm_handlers.h   * ------------------------------------------------------------------ - * $Id: xmix_vm_handlers.c,v 1.7 2003/01/11 22:43:13 jao Exp $ + * $Id: xmix_vm_handlers.c,v 1.8 2004/06/06 19:54:11 jao Exp $   * ------------------------------------------------------------------ - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by @@ -103,31 +103,42 @@ mix_vm_command_info_t commands_[] = {  /* trace current instruction */  static void -trace_ (mix_vm_cmd_dispatcher_t *dis) +do_trace_ (mix_vm_cmd_dispatcher_t *dis, gboolean error)  {    enum {BUFFER_LEN = 128};    static gchar STRINS[BUFFER_LEN]; -  if (wants_logs_ (dis)) +  const mix_src_file_t *file = mix_vm_get_src_file (dis->vm); +  const gchar *line = "\n"; +  mix_address_t loc = mix_vm_get_prog_count (dis->vm); +  mix_word_t ins = mix_vm_get_addr_contents (dis->vm, loc); +  mix_ins_t fins; +  mix_word_to_ins_uncheck (ins, fins); +  mix_ins_to_string_in_buffer (&fins, STRINS, BUFFER_LEN); + +  if (file != NULL)      { -      const mix_src_file_t *file = mix_vm_get_src_file (dis->vm); -      const gchar *line = "\n"; -      mix_address_t loc = mix_vm_get_prog_count (dis->vm); -      mix_word_t ins = mix_vm_get_addr_contents (dis->vm, loc); -      mix_ins_t fins; -      mix_word_to_ins_uncheck (ins, fins); -      mix_ins_to_string_in_buffer (&fins, STRINS, BUFFER_LEN); +      gulong b = mix_vm_get_break_lineno (dis->vm); +      if (b > 0) line = mix_src_file_get_line (file, b); +    } -      if (file != NULL) -	{ -	  gulong b = mix_vm_get_break_lineno (dis->vm); -	  if (b > 0) line = mix_src_file_get_line (file, b); -	} +  if (!error) +    log_message_ (dis, "%d: [%-15s]\t%s", (gint)loc, STRINS, line); +  else +    log_error_ (dis, "%d: [%-15s]\t%s", (gint)loc, STRINS, line); +} -      log_message_ (dis, "%d: [%-15s]\t%s", (gint)loc, STRINS, line); +static void +trace_ (mix_vm_cmd_dispatcher_t *dis) +{ +  if (wants_logs_ (dis)) +    { +      do_trace_ (dis, FALSE);      }  } +#define trace_error_(dis)  do_trace_ (dis, TRUE) +  /* run a program tracing executed instructions */  static int  run_and_trace_ (mix_vm_cmd_dispatcher_t *dis) @@ -328,12 +339,14 @@ cmd_run_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)  	}        break;      case MIX_VM_ERROR: -      log_error_ (dis, _("... error executing loaded file")); +      log_error_ (dis, _("%s:"), mix_vm_get_last_error_string (dis->vm)); +      trace_error_ (dis);        break;      default:        g_assert_not_reached ();        break;      } +    if (wants_logs_ (dis)) print_time_ (dis);    return TRUE; @@ -373,8 +386,8 @@ cmd_next_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)  	}        else if (k == MIX_VM_ERROR)  	{ -	  log_error_ (dis, _("Error at address %d"), -		      mix_vm_get_prog_count (dis->vm)); +	  log_error_ (dis, _("%s:"), mix_vm_get_last_error_string (dis->vm)); +          trace_error_ (dis);  	  break;  	}      } | 
