diff options
Diffstat (limited to 'mixlib')
-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 |