summaryrefslogtreecommitdiffhomepage
path: root/mixlib
diff options
context:
space:
mode:
authorJose Antonio Ortega Ruiz <jao@gnu.org>2001-07-22 21:08:38 +0000
committerJose Antonio Ortega Ruiz <jao@gnu.org>2001-07-22 21:08:38 +0000
commitdd2730739c3c1204ecee97aa936e84ad0f7c5b08 (patch)
tree8ae0e030e9884c144ed396f28f1b8acdd0a00c99 /mixlib
parent4b003474d25aa79508f392ea16533b738896856d (diff)
downloadmdk-dd2730739c3c1204ecee97aa936e84ad0f7c5b08.tar.gz
mdk-dd2730739c3c1204ecee97aa936e84ad0f7c5b08.tar.bz2
version 0.4
Diffstat (limited to 'mixlib')
-rw-r--r--mixlib/mix_vm.c41
-rw-r--r--mixlib/mix_vm.h10
-rw-r--r--mixlib/mix_vm_command.c37
-rw-r--r--mixlib/mix_vm_command.h1
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 */