diff options
| -rw-r--r-- | mixlib/mix_vm.c | 59 | 
1 files changed, 27 insertions, 32 deletions
| diff --git a/mixlib/mix_vm.c b/mixlib/mix_vm.c index 37a0c6d..d1ad6e7 100644 --- a/mixlib/mix_vm.c +++ b/mixlib/mix_vm.c @@ -47,6 +47,11 @@ vm_reset_ (mix_vm_t *vm)        g_tree_destroy (vm->line_table);        vm->line_table = NULL;      } +  if (vm->address_table != NULL) +    { +      g_tree_destroy (vm->address_table); +      vm->address_table = NULL; +    }    bp_clear_all_ (vm);  } @@ -59,6 +64,7 @@ mix_vm_new (void)    mix_vm_t *vm = g_new (struct mix_vm_t,1);    vm->line_table = NULL; +  vm->address_table = NULL;    vm->symbol_table = NULL;    for (i = 0; i < BD_NO_; ++i) @@ -68,12 +74,14 @@ mix_vm_new (void)    return vm;  } +  void  mix_vm_delete (mix_vm_t * vm)  {    int i;    if (vm->line_table != NULL) g_tree_destroy (vm->line_table); +  if (vm->address_table != NULL) g_tree_destroy (vm->address_table);    if (vm->symbol_table != NULL) mix_symbol_table_delete (vm->symbol_table);    for (i = 0; i < BD_NO_; ++i)      mix_device_delete (vm->devices[i]); @@ -224,9 +232,9 @@ mix_vm_exec_ins (mix_vm_t *vm, const mix_ins_t *ins)    return (*ins_handlers_[ins->opcode]) (vm,ins);  } -/* comparison function for the line table tree */ +/* comparison function for the line and address tables tree */  static gint -cmp_lineno_ (gconstpointer a, gconstpointer b) +cmp_uint_ (gconstpointer a, gconstpointer b)  {    return GPOINTER_TO_UINT (a) - GPOINTER_TO_UINT (b);  } @@ -244,15 +252,21 @@ mix_vm_load_file (mix_vm_t *vm, const gchar *name)    if ( mix_code_file_is_debug (file) )      {        vm->symbol_table = mix_code_file_get_symbol_table (file); -      vm->line_table = g_tree_new (cmp_lineno_); +      vm->line_table = g_tree_new (cmp_uint_); +      vm->address_table = g_tree_new (cmp_uint_);      }    while ( mix_code_file_get_ins (file, &ins) )       {        set_cell_ (vm, ins.address, ins.ins);        if ( vm->line_table != NULL ) -	g_tree_insert (vm->line_table,  -		       GUINT_TO_POINTER (ins.lineno), -		       GUINT_TO_POINTER ((guint)ins.address)); +	{ +	  g_tree_insert (vm->line_table,  +			 GUINT_TO_POINTER (ins.lineno), +			 GUINT_TO_POINTER ((guint)ins.address)); +	  g_tree_insert (vm->address_table,  +			 GUINT_TO_POINTER ((guint)ins.address), +			 GUINT_TO_POINTER (ins.lineno)); +	}      }    set_loc_ (vm, mix_code_file_get_start_addr (file));    set_start_ (vm, get_loc_ (vm)); @@ -314,36 +328,17 @@ mix_vm_exec_next (mix_vm_t *vm)  }  /* Breakpoints */ -typedef struct -{ -  mix_address_t address; -  gulong lineno; -} fline_t; - -static int -find_break_ (gpointer key, gpointer value, gpointer data) -{ -  fline_t *fl = (fline_t *)data; -   -  if ( mix_short_new (GPOINTER_TO_UINT (value)) == fl->address ) -    { -      fl->lineno = GPOINTER_TO_UINT (key); -      return TRUE; -    } -  return FALSE; -} -  gulong  mix_vm_get_break_lineno (const mix_vm_t *vm)  { -  fline_t fl; -      g_return_val_if_fail (vm != NULL, 0); -  if (vm->line_table == NULL) return 0; -  fl.lineno = 0; -  fl.address = get_loc_ (vm); -  g_tree_traverse (vm->line_table, find_break_, G_IN_ORDER, (gpointer) &fl); -  return fl.lineno; +  if (vm->address_table == NULL) +    return 0; +  else +    { +      gpointer loc = GUINT_TO_POINTER ((guint)get_loc_ (vm)); +      return GPOINTER_TO_UINT (g_tree_lookup (vm->address_table,loc)); +    }  }  typedef struct  | 
