summaryrefslogtreecommitdiffhomepage
path: root/mixlib
diff options
context:
space:
mode:
Diffstat (limited to 'mixlib')
-rw-r--r--mixlib/mix_vm.c50
-rw-r--r--mixlib/mix_vm.h31
2 files changed, 57 insertions, 24 deletions
diff --git a/mixlib/mix_vm.c b/mixlib/mix_vm.c
index 692f84d..4bbc976 100644
--- a/mixlib/mix_vm.c
+++ b/mixlib/mix_vm.c
@@ -28,6 +28,7 @@ static void
vm_reset_reload_ (mix_vm_t *vm, gboolean is_reload)
{
guint k;
+ set_status_ (vm, MIX_VM_EMPTY);
set_rA_ (vm, MIX_WORD_ZERO);
set_rX_ (vm, MIX_WORD_ZERO);
set_rJ_ (vm, MIX_WORD_ZERO);
@@ -38,7 +39,6 @@ vm_reset_reload_ (mix_vm_t *vm, gboolean is_reload)
set_loc_ (vm, MIX_WORD_ZERO);
for ( k = 0; k < MEM_CELLS_NO_; ++k)
set_cell_ (vm, k, MIX_WORD_ZERO);
- halt_ (vm, FALSE);
if (vm->symbol_table != NULL )
{
mix_symbol_table_delete (vm->symbol_table);
@@ -318,7 +318,11 @@ mix_vm_load_file (mix_vm_t *vm, const gchar *name)
g_return_val_if_fail (vm != NULL, FALSE);
file = mix_code_file_new_read (name);
- if (file == NULL) return FALSE;
+ if (file == NULL)
+ {
+ set_status_ (vm, MIX_VM_ERROR);
+ return FALSE;
+ }
sp = mix_code_file_get_source_path (file);
if (sp != NULL)
@@ -357,6 +361,7 @@ mix_vm_load_file (mix_vm_t *vm, const gchar *name)
set_start_ (vm, get_loc_ (vm));
mix_code_file_delete (file);
+ set_status_ (vm, MIX_VM_LOADED);
return TRUE;
}
@@ -428,7 +433,7 @@ mix_vm_get_lineno_address (const mix_vm_t *vm, guint lineno)
/* continue execution of instructions in memory */
-int
+mix_vm_status_t
mix_vm_run (mix_vm_t *vm)
{
mix_ins_t ins;
@@ -441,39 +446,47 @@ mix_vm_run (mix_vm_t *vm)
g_slist_prepend (vm->address_list,
GINT_TO_POINTER ((gint)get_loc_ (vm)));
if ( !(*ins_handlers_[ins.opcode]) (vm,&ins) )
- return MIX_VM_ERROR;
+ return set_status_ (vm, MIX_VM_ERROR);
else
update_time_ (vm, &ins);
if (bp_is_set_ (vm, get_loc_ (vm)))
- return MIX_VM_BREAK;
+ return set_status_ (vm, MIX_VM_BREAK);
if (mix_predicate_list_eval (get_pred_list_ (vm)))
- return MIX_VM_COND_BREAK;
+ return set_status_ (vm, MIX_VM_COND_BREAK);
if (get_loc_ (vm) >= MIX_VM_CELL_NO) halt_ (vm, TRUE);
}
- return MIX_VM_HALT;
+ return set_status_ (vm, MIX_VM_HALT);
}
/* execute next memory instruction */
-int
+mix_vm_status_t
mix_vm_exec_next (mix_vm_t *vm)
{
mix_ins_t ins;
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;
+ if (is_halted_ (vm)) return set_status_ (vm, 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;
+ return set_status_ (vm, MIX_VM_ERROR);
else
update_time_ (vm, &ins);
- if (is_halted_ (vm)) return MIX_VM_HALT;
- if (bp_is_set_ (vm, get_loc_ (vm))) return MIX_VM_BREAK;
+ if (is_halted_ (vm)) return set_status_ (vm, MIX_VM_HALT);
+ if (bp_is_set_ (vm, get_loc_ (vm))) return set_status_ (vm, MIX_VM_BREAK);
if (mix_predicate_list_eval (get_pred_list_ (vm)))
- return MIX_VM_COND_BREAK;
- return MIX_VM_OK;
+ return set_status_ (vm, MIX_VM_COND_BREAK);
+ return set_status_ (vm, MIX_VM_RUNNING);
+}
+
+/* get the current execution status */
+mix_vm_status_t
+mix_vm_get_run_status (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, MIX_VM_ERROR);
+ return get_status_ (vm);
}
/* Breakpoints */
@@ -624,6 +637,15 @@ mix_vm_get_last_breakpoint_message (const mix_vm_t *vm)
return NULL;
}
+mix_predicate_type_t
+mix_vm_get_last_conditional_breakpoint_type (const mix_vm_t *vm)
+{
+ const mix_predicate_t *last = NULL;
+ g_return_val_if_fail (vm != NULL, MIX_PRED_INVALID);
+ last = mix_predicate_list_last_true_eval (get_pred_list_ (vm));
+ return last? mix_predicate_get_type (last) : MIX_PRED_INVALID;
+}
+
/* Get the vm uptime, defined as the time spent executing instructions */
mix_time_t
mix_vm_get_uptime (const mix_vm_t *vm)
diff --git a/mixlib/mix_vm.h b/mixlib/mix_vm.h
index d3f4e3f..b7412bf 100644
--- a/mixlib/mix_vm.h
+++ b/mixlib/mix_vm.h
@@ -153,25 +153,33 @@ mix_vm_get_lineno_address (const mix_vm_t *vm, guint lineno);
/* continue execution of instructions in memory */
/* Possible outcomes */
-enum {
- MIX_VM_ERROR, /* error executing instructions */
- MIX_VM_BREAK, /* breakpoint found */
- MIX_VM_COND_BREAK, /* conditional breakpoint found */
- MIX_VM_HALT, /* end of execution */
- MIX_VM_OK /* successful instruction execution */
-};
-
-extern int
+typedef enum {
+ MIX_VM_ERROR, /* error executing instructions */
+ MIX_VM_BREAK, /* breakpoint found */
+ MIX_VM_COND_BREAK, /* conditional breakpoint found */
+ MIX_VM_HALT, /* end of execution */
+ MIX_VM_RUNNING, /* successful instruction execution */
+ MIX_VM_LOADED, /* program loaded */
+ MIX_VM_EMPTY /* no program loaded */
+} mix_vm_status_t;
+
+/* run until next breakpoint or end of execution */
+extern mix_vm_status_t
mix_vm_run (mix_vm_t *vm);
/* execute next memory instruction */
-extern int
+extern mix_vm_status_t
mix_vm_exec_next (mix_vm_t *vm);
+/* get the current execution status */
+extern mix_vm_status_t
+mix_vm_get_run_status (const mix_vm_t *vm);
+
/* get the line no. of the last break or 0 if not found */
extern gulong
mix_vm_get_break_lineno (const mix_vm_t *vm);
+
/* Breakpoints */
/* possible error outcomes */
enum {
@@ -210,6 +218,9 @@ mix_vm_clear_conditional_breakpoint (mix_vm_t *vm, mix_predicate_t *pred);
extern const gchar *
mix_vm_get_last_breakpoint_message (const mix_vm_t *vm);
+extern mix_predicate_type_t
+mix_vm_get_last_conditional_breakpoint_type (const mix_vm_t *vm);
+
/* Get the vm uptime, defined as the time spent executing instructions */
extern mix_time_t
mix_vm_get_uptime (const mix_vm_t *vm);