diff --git a/oden-js-sys/quickjs/quickjs.c b/oden-js-sys/quickjs/quickjs.c index f7033f31..505f27dd 100644 --- a/oden-js-sys/quickjs/quickjs.c +++ b/oden-js-sys/quickjs/quickjs.c @@ -1018,6 +1018,11 @@ typedef struct JSBreakpoint { JS_BOOL enabled; } JSBreakpoint; +typedef struct JSDebugContext { + JSContext *ctx; + JSStackFrame *sf; +} JSDebugContext; + static int JS_InitAtoms(JSRuntime *rt); static JSAtom __JS_NewAtomInit(JSRuntime *rt, const char *str, int len, int atom_type); @@ -6503,6 +6508,7 @@ static void get_frame_debug_position(JSContext *ctx, JSStackFrame *sf, *backtrace_barrier = FALSE; *function = get_func_name(ctx, sf->cur_func); + p = JS_VALUE_GET_OBJ(sf->cur_func); if (js_class_has_bytecode(p->class_id)) { JSFunctionBytecode *b; @@ -6510,7 +6516,6 @@ static void get_frame_debug_position(JSContext *ctx, JSStackFrame *sf, b = p->u.func.function_bytecode; *backtrace_barrier = b->backtrace_barrier; - *function = JS_AtomToCString(ctx, b->func_name); if (b->has_debug) { line_num1 = find_line_num(ctx, b, sf->cur_pc - b->byte_code_buf - 1); @@ -33775,6 +33780,24 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, goto fail1; fun_obj = JS_DupValue(ctx, JS_MKPTR(JS_TAG_MODULE, m)); } + + if (ctx->rt->debug_callback) { + JSDebugContext dctx; + dctx.ctx = ctx; + dctx.sf = sf; + + JSDebugEvent evt; + evt.reason = JS_BREAK_CODE_LOADED; + evt.u.loaded.filename = filename; + + /* TODO: Handle the step/resume/what-have-you. Step from here will + be complicated because the function we need to step into will be + the one we just parsed, kinda- unless it's a module? Even then + it's not clear where the break will go if we're loading a + module... yikes. */ + /* resume = */ctx->rt->debug_callback(&dctx, &evt, ctx->rt->debug_opaque); + } + if (flags & JS_EVAL_FLAG_COMPILE_ONLY) { ret_val = fun_obj; } else { @@ -54147,6 +54170,12 @@ void JS_SetSourceMapFunc(JSRuntime *rt, JSMapSourceFunc *map_func, void *opaque) /* Debugger */ +void JS_SetDebugCallbackFunc(JSRuntime *rt, JSDebugCallbackFunc *func, void *opaque) +{ + rt->debug_callback = func; + rt->debug_opaque = opaque; +} + static BOOL find_pc_offset(JSFunctionBytecode *b, int target_line, int *break_pc, int *actual_line) { const uint8_t *p_end, *p; @@ -54199,7 +54228,8 @@ static BOOL find_pc_offset(JSFunctionBytecode *b, int target_line, int *break_pc return FALSE; } -static JSBreakpoint *find_existing_breakpoint(JSContext *ctx, JSFunctionBytecode *func, int pc) { +static JSBreakpoint *find_existing_breakpoint(JSContext *ctx, JSFunctionBytecode *func, int pc) +{ struct list_head *el; list_for_each(el, &ctx->rt->breakpoint_list) { JSBreakpoint *bp = list_entry(el, JSBreakpoint, link); @@ -54210,12 +54240,8 @@ static JSBreakpoint *find_existing_breakpoint(JSContext *ctx, JSFunctionBytecode return NULL; } -typedef struct JSDebugContext { - JSContext *ctx; - JSStackFrame *sf; -} JSDebugContext; - -static int js_handle_breakpoint(JSContext *ctx, JSFunctionBytecode *b, int code_offset) { +static int js_handle_breakpoint(JSContext *ctx, JSFunctionBytecode *b, int code_offset) +{ int next_op; /* JSResumeMode resume = JS_RESUME_MODE_CONTINUE; */ JSRuntime *rt = ctx->rt; @@ -54227,7 +54253,11 @@ static int js_handle_breakpoint(JSContext *ctx, JSFunctionBytecode *b, int code_ dctx.ctx = ctx; dctx.sf = ctx->rt->current_stack_frame; - /* resume = */rt->debug_callback(&dctx, JS_BREAK_BREAKPOINT, bp, rt->debug_opaque); + JSDebugEvent evt; + evt.reason = JS_BREAK_BREAKPOINT; + evt.u.breakpoint = bp; + + /* resume = */rt->debug_callback(&dctx, &evt, rt->debug_opaque); } } next_op = bp->replaced_byte; @@ -54241,8 +54271,11 @@ static int js_handle_breakpoint(JSContext *ctx, JSFunctionBytecode *b, int code_ JSDebugContext dctx; dctx.ctx = ctx; dctx.sf = ctx->rt->current_stack_frame; + + JSDebugEvent evt; + evt.reason = JS_BREAK_STEP; - /* resume = */rt->debug_callback(&dctx, JS_BREAK_STEP, NULL, rt->debug_opaque); + /* resume = */rt->debug_callback(&dctx, &evt, rt->debug_opaque); } } @@ -54271,7 +54304,7 @@ void JS_DebugGetFrameSourcePosition(JSDebugContext *dctx, JSDebugFrame *frame, JSStackFrame *sf = (JSStackFrame *)frame; JSContext *ctx = dctx->ctx; BOOL backtrace_barrier; - + get_frame_debug_position(ctx, sf, function, file, line, &backtrace_barrier); } diff --git a/oden-js-sys/quickjs/quickjs.h b/oden-js-sys/quickjs/quickjs.h index 6ca6cec7..7d9faf31 100644 --- a/oden-js-sys/quickjs/quickjs.h +++ b/oden-js-sys/quickjs/quickjs.h @@ -1070,15 +1070,25 @@ typedef enum JSResumeMode { } JSResumeMode; typedef enum JSBreakReason { + JS_BREAK_CODE_LOADED, JS_BREAK_BREAKPOINT, JS_BREAK_STEP, } JSBreakReason; typedef struct JSBreakpoint JSBreakpoint; +typedef struct JSDebugEvent { + JSBreakReason reason; + union { + struct { + const char *filename; + } loaded; + JSBreakpoint *breakpoint; + } u; +} JSDebugEvent; + typedef JSResumeMode JSDebugCallbackFunc(JSDebugContext *ctx, - JSBreakReason reason, - JSBreakpoint *breakpoint, + JSDebugEvent *event, void *opaque); void JS_SetDebugCallbackFunc(JSRuntime *rt, JSDebugCallbackFunc *bp_func, void *opqaue);