summaryrefslogtreecommitdiffhomepage
path: root/mixlib/mix_vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'mixlib/mix_vm.c')
-rw-r--r--mixlib/mix_vm.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/mixlib/mix_vm.c b/mixlib/mix_vm.c
index d1ad6e7..2c41097 100644
--- a/mixlib/mix_vm.c
+++ b/mixlib/mix_vm.c
@@ -52,6 +52,11 @@ vm_reset_ (mix_vm_t *vm)
g_tree_destroy (vm->address_table);
vm->address_table = NULL;
}
+ if (vm->src_file != NULL)
+ {
+ mix_src_file_delete (vm->src_file);
+ vm->src_file = NULL;
+ }
bp_clear_all_ (vm);
}
@@ -83,6 +88,7 @@ mix_vm_delete (mix_vm_t * vm)
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);
+ if (vm->src_file != NULL) mix_src_file_delete (vm->src_file);
for (i = 0; i < BD_NO_; ++i)
mix_device_delete (vm->devices[i]);
g_free (vm);
@@ -244,6 +250,7 @@ mix_vm_load_file (mix_vm_t *vm, const gchar *name)
{
mix_code_file_t *file;
mix_ins_desc_t ins;
+ const gchar *sp;
g_return_val_if_fail (vm != NULL, FALSE);
file = mix_code_file_new_read (name);
@@ -255,6 +262,11 @@ mix_vm_load_file (mix_vm_t *vm, const gchar *name)
vm->line_table = g_tree_new (cmp_uint_);
vm->address_table = g_tree_new (cmp_uint_);
}
+
+ sp = mix_code_file_get_source_path (file);
+ if (sp != NULL)
+ vm->src_file = mix_src_file_new_for_read (sp);
+
while ( mix_code_file_get_ins (file, &ins) )
{
set_cell_ (vm, ins.address, ins.ins);
@@ -275,6 +287,13 @@ mix_vm_load_file (mix_vm_t *vm, const gchar *name)
return TRUE;
}
+const mix_src_file_t *
+mix_vm_get_src_file (const mix_vm_t *vm)
+{
+ g_return_val_if_fail (vm != NULL, NULL);
+ return vm->src_file;
+}
+
const mix_symbol_table_t *
mix_vm_get_symbol_table (const mix_vm_t *vm)
{
@@ -320,11 +339,17 @@ mix_vm_exec_next (mix_vm_t *vm)
{
mix_ins_t ins;
g_return_val_if_fail (vm != NULL, MIX_VM_ERROR);
- if ( is_halted_ (vm) ) return MIX_VM_HALT;
+ if (get_loc_ (vm) >= MIX_VM_CELL_NO) halt_ (vm, TRUE);
+ if (is_halted_ (vm))
+ {
+ reset_loc_ (vm); /* set current location to start address */
+ halt_ (vm, FALSE);
+ return MIX_VM_HALT;
+ }
mix_word_to_ins_uncheck (get_cell_ (vm, get_loc_ (vm)), ins);
if (!(*ins_handlers_[ins.opcode]) (vm, &ins))
return MIX_VM_ERROR;
- return MIX_VM_BREAK;
+ return bp_is_set_ (vm, get_loc_ (vm)) ? MIX_VM_BREAK : MIX_VM_OK;
}
/* Breakpoints */