diff options
author | Jose Antonio Ortega Ruiz <jao@gnu.org> | 2001-07-22 21:08:38 +0000 |
---|---|---|
committer | Jose Antonio Ortega Ruiz <jao@gnu.org> | 2001-07-22 21:08:38 +0000 |
commit | da264d84bf8c3eca44f61adb63d0d6bac123f135 (patch) | |
tree | 7f34263839ddf45ae5a0ab1da222f8f8db8928e4 /mixlib | |
parent | df485d0fae4725d872bc6d7be0b1cc91227d88e1 (diff) | |
download | mdk-da264d84bf8c3eca44f61adb63d0d6bac123f135.tar.gz mdk-da264d84bf8c3eca44f61adb63d0d6bac123f135.tar.bz2 |
version 0.4
Diffstat (limited to 'mixlib')
-rw-r--r-- | mixlib/mix_vm.c | 41 | ||||
-rw-r--r-- | mixlib/mix_vm.h | 10 | ||||
-rw-r--r-- | mixlib/mix_vm_command.c | 37 | ||||
-rw-r--r-- | mixlib/mix_vm_command.h | 1 |
4 files changed, 63 insertions, 26 deletions
diff --git a/mixlib/mix_vm.c b/mixlib/mix_vm.c index 0e9f61b..692f84d 100644 --- a/mixlib/mix_vm.c +++ b/mixlib/mix_vm.c @@ -67,6 +67,12 @@ vm_reset_reload_ (mix_vm_t *vm, gboolean is_reload) } if (!is_reload) mix_vm_clear_all_breakpoints (vm); + + if (vm->address_list) + { + g_slist_free (vm->address_list); + vm->address_list = NULL; + } } @@ -82,6 +88,7 @@ mix_vm_new (void) vm->symbol_table = NULL; vm->src_file = NULL; vm->pred_list = mix_predicate_list_new (vm); + vm->address_list = NULL; for (i = 0; i < BD_NO_; ++i) vm->devices[i] = NULL; @@ -106,6 +113,8 @@ mix_vm_delete (mix_vm_t * vm) if (vm->address_table != NULL) g_tree_destroy (vm->address_table); if (vm->symbol_table != NULL) mix_symbol_table_delete (vm->symbol_table); if (vm->src_file != NULL) mix_src_file_delete (vm->src_file); + if (vm->pred_list != NULL) mix_predicate_list_delete (vm->pred_list); + if (vm->address_list != NULL) g_slist_free (vm->address_list); for (i = 0; i < BD_NO_; ++i) mix_device_delete (vm->devices[i]); mix_vm_clock_delete (vm->clock); @@ -418,25 +427,6 @@ mix_vm_get_lineno_address (const mix_vm_t *vm, guint lineno) } -/* Reposition program counter and reset state so that a loaded - program can be restarted. -*/ -void -mix_vm_reset_program (mix_vm_t *vm) -{ - guint k; - g_return_if_fail (vm != NULL); - reset_loc_ (vm); - halt_ (vm, FALSE); - set_rA_ (vm, MIX_WORD_ZERO); - set_rX_ (vm, MIX_WORD_ZERO); - set_rJ_ (vm, MIX_WORD_ZERO); - for ( k = 1; k < IREG_NO_+1; ++k ) - set_rI_ (vm, k, MIX_WORD_ZERO); - set_over_ (vm, FALSE); - set_cmp_ (vm, mix_EQ); -} - /* continue execution of instructions in memory */ int mix_vm_run (mix_vm_t *vm) @@ -447,6 +437,9 @@ mix_vm_run (mix_vm_t *vm) while ( !is_halted_ (vm) ) { mix_word_to_ins_uncheck (get_cell_ (vm, get_loc_ (vm)), ins); + vm->address_list = + g_slist_prepend (vm->address_list, + GINT_TO_POINTER ((gint)get_loc_ (vm))); if ( !(*ins_handlers_[ins.opcode]) (vm,&ins) ) return MIX_VM_ERROR; else @@ -468,6 +461,9 @@ mix_vm_exec_next (mix_vm_t *vm) g_return_val_if_fail (vm != NULL, MIX_VM_ERROR); if (get_loc_ (vm) >= MIX_VM_CELL_NO) halt_ (vm, TRUE); if (is_halted_ (vm)) return MIX_VM_HALT; + vm->address_list = + g_slist_prepend (vm->address_list, + GINT_TO_POINTER ((gint)get_loc_ (vm))); mix_word_to_ins_uncheck (get_cell_ (vm, get_loc_ (vm)), ins); if (!(*ins_handlers_[ins.opcode]) (vm, &ins)) return MIX_VM_ERROR; @@ -636,3 +632,10 @@ mix_vm_get_uptime (const mix_vm_t *vm) return mix_vm_clock_get_time (get_clock_ (vm)); } +/* Get the list of addresses for executed instructions */ +const GSList * +mix_vm_get_backtrace (const mix_vm_t *vm) +{ + g_return_val_if_fail (vm != NULL, NULL); + return get_address_list_ (vm); +} diff --git a/mixlib/mix_vm.h b/mixlib/mix_vm.h index d0403cc..d3f4e3f 100644 --- a/mixlib/mix_vm.h +++ b/mixlib/mix_vm.h @@ -151,12 +151,6 @@ mix_vm_get_address_lineno (const mix_vm_t *vm, mix_address_t addr); extern mix_address_t mix_vm_get_lineno_address (const mix_vm_t *vm, guint lineno); -/* Reposition program counter and reset state so that a loaded - program can be restarted. -*/ -extern void -mix_vm_reset_program (mix_vm_t *vm); - /* continue execution of instructions in memory */ /* Possible outcomes */ enum { @@ -220,6 +214,10 @@ mix_vm_get_last_breakpoint_message (const mix_vm_t *vm); extern mix_time_t mix_vm_get_uptime (const mix_vm_t *vm); +/* Get the list of addresses for executed instructions */ +extern const GSList * +mix_vm_get_backtrace (const mix_vm_t *vm); + #endif /* MIX_VM_H */ diff --git a/mixlib/mix_vm_command.c b/mixlib/mix_vm_command.c index 264c9ff..0ccfd7b 100644 --- a/mixlib/mix_vm_command.c +++ b/mixlib/mix_vm_command.c @@ -126,6 +126,7 @@ DEC_FUN (cbpr_); DEC_FUN (cbpm_); DEC_FUN (cbpc_); DEC_FUN (cbpo_); +DEC_FUN (pbt_); /* internal command info struct */ @@ -198,6 +199,8 @@ command_ commands_[] = { "w2d WORD"}, { "tracing", cmd_tracing_, N_("Turn on/off instruction tracing"), "tracing [on|off]"}, + { "pbt", cmd_pbt_, N_("Print backtrace of executed instructions"), + "pbt [INS_NO] (e.g pbt 5)"}, { "timing", cmd_timing_, N_("Turn on/off timing statistics"), "timing [on|off]"}, { "devdir", cmd_devdir_, N_("Print/set devices directory"), @@ -1699,4 +1702,36 @@ cmd_cbpc_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) return TRUE; } - +static gboolean +cmd_pbt_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) +{ + enum {SIZE = 256}; + static gchar BUFFER[SIZE]; + gint no = atoi (arg); + gint k = 0, address; + guint line; + const mix_src_file_t *file = mix_vm_get_src_file (dis->vm); + char *name = file ? g_basename (mix_src_file_get_path (file)) : NULL; + + const GSList *add = mix_vm_get_backtrace (dis->vm); + while (add && (no == 0 || k < no)) + { + BUFFER[0] = '\0'; + address = GPOINTER_TO_INT (add->data); + line = mix_vm_get_address_lineno (dis->vm, address); + if (line && file) + { + int j = 0; + snprintf (BUFFER, SIZE, "%s", mix_src_file_get_line (file, line)); + while (!isspace (BUFFER[j])) j++; + BUFFER[j] = '\0'; + } + if (strlen (BUFFER) == 0) snprintf (BUFFER, SIZE, "%d", address); + fprintf (dis->out, "#%d\t%s\tin %s%s:%d\n", k, BUFFER, name, + MIX_SRC_DEFEXT, line); + ++k; + add = add->next; + } + /* if (name) g_free (name); */ + return TRUE; +} diff --git a/mixlib/mix_vm_command.h b/mixlib/mix_vm_command.h index 6c60264..5d5ebca 100644 --- a/mixlib/mix_vm_command.h +++ b/mixlib/mix_vm_command.h @@ -75,6 +75,7 @@ typedef enum { MIX_CMD_WEVAL, /* evaluate a w-expression */ MIX_CMD_W2D, /* print word in decimal notation */ MIX_CMD_TRACING, /* enable/disable instruction traces */ + MIX_CMD_PBT, /* print backtrace */ MIX_CMD_TIMING, /* enable/disable timing statistics */ MIX_CMD_DEVDIR, /* print/set device directory */ MIX_CMD_INVALID, /* invalid command identifier */ |