diff options
Diffstat (limited to 'byterun/interp.c')
-rw-r--r-- | byterun/interp.c | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/byterun/interp.c b/byterun/interp.c index 20c79add2..5729d9879 100644 --- a/byterun/interp.c +++ b/byterun/interp.c @@ -15,6 +15,7 @@ #include "alloc.h" #include "callback.h" +#include "debugger.h" #include "fail.h" #include "fix_code.h" #include "instrtrace.h" @@ -65,6 +66,24 @@ sp is a local copy of the global variable extern_sp. */ #define Setup_for_c_call { *--sp = env; extern_sp = sp; } #define Restore_after_c_call { sp = extern_sp; env = *sp++; } +/* Debugger interface */ + +#define Setup_for_debugger \ + { sp -= 4; \ + sp[0] = accu; sp[1] = (value)(pc - 1); \ + sp[2] = env; sp[3] = Val_long(extra_args); \ + extern_sp = sp; } +#define Restore_after_debugger { sp += 4; } + +#ifdef THREADED_CODE +#define Restart_curr_instr \ + goto *(jumptable[saved_code[pc - 1 - start_code]]) +#else +#define Restart_curr_instr \ + curr_instr = saved_code[pc - 1 - start_code]; \ + goto dispatch_instr +#endif + /* Register optimization. Many compilers underestimate the use of the local variables representing the abstract machine registers, and don't put them in hardware registers, @@ -133,6 +152,7 @@ value interprete(prog, prog_size) int initial_callback_depth; struct longjmp_buffer raise_buf; value * modify_dest, modify_newval; + opcode_t curr_instr; #ifdef THREADED_CODE static void * jumptable[] = { @@ -140,11 +160,15 @@ value interprete(prog, prog_size) }; #endif + if (prog == NULL) { /* Interpreter is initializing */ #ifdef THREADED_CODE - if (prog[0] <= STOP) { instr_table = jumptable; - thread_code(prog, prog_size); +#endif + return Val_unit; } + +#ifdef THREADED_CODE + if (prog[0] <= STOP) thread_code(prog, prog_size); #endif sp = extern_sp; @@ -160,6 +184,7 @@ value interprete(prog, prog_size) local_roots = initial_local_roots; callback_depth = initial_callback_depth; accu = exn_bucket; + sp = extern_sp; goto raise_exception; } external_raise = &raise_buf; @@ -182,7 +207,9 @@ value interprete(prog, prog_size) Assert(sp >= stack_low); Assert(sp <= stack_high); #endif - switch(*pc++) { + curr_instr = *pc++; + dispatch_instr: + switch(curr_instr) { #endif /* Basic stack operations */ @@ -657,8 +684,13 @@ value interprete(prog, prog_size) sp += 4; Next; - Instruct(RAISE): /* arg */ + Instruct(RAISE): raise_exception: + if (trapsp >= trap_barrier) { + Setup_for_debugger; + debugger(TRAP_BARRIER); + Restore_after_debugger; + } sp = trapsp; if (sp >= stack_high - initial_sp_offset) { exn_bucket = accu; @@ -863,13 +895,27 @@ value interprete(prog, prog_size) accu = Lookup(sp[0], accu); Next; -/* Machine control */ +/* Debugging and machine control */ Instruct(STOP): external_raise = initial_external_raise; extern_sp = sp; return accu; + Instruct(EVENT): + if (--event_count == 0) { + Setup_for_debugger; + debugger(EVENT_COUNT); + Restore_after_debugger; + } + Restart_curr_instr; + + Instruct(BREAK): + Setup_for_debugger; + debugger(BREAKPOINT); + Restore_after_debugger; + Restart_curr_instr; + #ifndef THREADED_CODE default: fatal_error_arg("Fatal error: bad opcode (%lx)\n", (char *) *(pc-1)); |