Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
5398b54
Update quickjs.c
G-Yong Dec 12, 2025
c1f2e00
Add operation changed handler and emit source locations
G-Yong Dec 12, 2025
9ed51a9
格式对其
G-Yong Dec 13, 2025
c0141e7
Fix comment formatting in quickjs.c
G-Yong Dec 13, 2025
acd4535
Fix comment formatting in quickjs.h
G-Yong Dec 13, 2025
39b5ce8
add `emit_source_loc(s) ` for `for` and `if`
G-Yong Dec 14, 2025
442ab63
remove `emit_source_loc` from `case` `default`; add it for `break`
G-Yong Dec 14, 2025
22d98ce
remove file's UTF8-BOM
G-Yong Dec 14, 2025
e449357
增加try catch finally 语句的位置跟踪语句
G-Yong Dec 15, 2025
942e9dd
Fix number literal parsing error handling (#1)
G-Yong Jan 27, 2026
2fd8274
Merge remote-tracking branch 'upstream/master'
G-Yong Jan 27, 2026
b644d17
Add debug API for stack frames and local variables
G-Yong Jan 31, 2026
564675e
Merge remote-tracking branch 'upstream/master'
G-Yong Jan 31, 2026
9948ffc
Merge branch 'quickjs-ng:master' into master
G-Yong Feb 2, 2026
c185571
fix TailCall's line and column number error.
G-Yong Feb 4, 2026
a009be9
Merge branch 'quickjs-ng:master' into master
G-Yong Feb 10, 2026
eb8981e
Merge branch 'quickjs-ng:master' into master
G-Yong Feb 12, 2026
b2531c8
Merge branch 'quickjs-ng:master' into master
G-Yong Feb 24, 2026
2227626
解决函数return语句后假如跟着while会导致得到错误的return行号的问题
G-Yong Mar 3, 2026
5faa3aa
Merge remote-tracking branch 'upstream/master'
G-Yong Mar 3, 2026
afc287f
Merge branch 'quickjs-ng:master' into master
G-Yong Mar 26, 2026
76aec02
Added a compile-time macro QJS_ENABLE_DEBUGGER to gate all the debug…
G-Yong Mar 28, 2026
fc71cbd
Merge remote-tracking branch 'upstream/master'
G-Yong Mar 28, 2026
6d4c96b
Refactor bytecode trace API and debug guards
G-Yong Mar 30, 2026
e1fc1be
Merge branch 'quickjs-ng:master' into master
G-Yong Mar 30, 2026
d98951d
Restore unexpected changes
G-Yong Mar 30, 2026
59e0422
Merge branch 'master' of https://github.com/G-Yong/quickjs
G-Yong Mar 30, 2026
9894306
Remove unnecessary macro definitions
G-Yong Mar 30, 2026
1e05bd7
Add per-context debugger with OP_debug
G-Yong Apr 1, 2026
abdf36c
Merge branch 'quickjs-ng:master' into master
G-Yong Apr 1, 2026
793ced2
Move DEF(debug) to end of opcode list to preserve opcode numbering (#2)
Copilot Apr 1, 2026
765fbf3
Use JS_AtomGetStr for debug break
G-Yong Apr 1, 2026
71b7ddf
Remove some modifications that are unnecessary under the current arch…
G-Yong Apr 1, 2026
6190ff1
Restore the things that were accidentally deleted earlier.
G-Yong Apr 1, 2026
9985cf7
Remove commented-out debug_break code
G-Yong Apr 1, 2026
219046a
Use unlikely() for debug_break check
G-Yong Apr 2, 2026
7e0a42d
Add JS_SetDebugBreakHandler and emit OP_debug
G-Yong Apr 2, 2026
4d34848
fix: do not update last_opcode_pos when emitting OP_debug (#3)
G-Yong Apr 2, 2026
16bb4d7
Rename debug break API to trace and bump BC
G-Yong Apr 2, 2026
87c3115
Merge branch 'quickjs-ng:master' into master
G-Yong Apr 2, 2026
c5a673a
Update api-test.c
G-Yong Apr 2, 2026
5d32778
Regenerate pre-compiled bytecode files (make codegen) to fix version …
Copilot Apr 3, 2026
b23207e
Merge branch 'quickjs-ng:master' into master
G-Yong Apr 3, 2026
1110f2c
Update quickjs-opcode.h
G-Yong Apr 3, 2026
ef48f55
Merge branch 'master' into master
G-Yong Apr 13, 2026
ba4bc03
fix: add missing closing brace for debug_trace() in api-test.c (#5)
Copilot Apr 13, 2026
f3904a4
fix: emit correct source location for return statement with ASI
G-Yong Apr 13, 2026
0a19469
chore: regenerate pre-compiled bytecode files (make codegen) (#6)
Copilot Apr 13, 2026
cade8c9
Add QJS_ENABLE_DEBUGGER build option
G-Yong Apr 15, 2026
bac8c1c
Regenerate pre-compiled bytecode files for BC_VERSION=25 (#7)
Copilot Apr 15, 2026
c581c50
Merge branch 'quickjs-ng:master' into master
G-Yong Apr 15, 2026
c94347a
Guard return parsing with QJS_ENABLE_DEBUGGER
G-Yong Apr 15, 2026
cce8fbc
Regenerate bytecode files via make codegen (#8)
Copilot Apr 15, 2026
f528674
Wrap emit_source_loc with QJS_ENABLE_DEBUGGER
G-Yong Apr 15, 2026
6c7c3c3
make codegen
G-Yong Apr 15, 2026
664577d
fix: regenerate hello_module.c with LF line endings
G-Yong Apr 15, 2026
503964b
emit_source_loc_debug
G-Yong Apr 15, 2026
c2a52b6
fix: guard debug_trace test with QJS_ENABLE_DEBUGGER (#9)
Copilot Apr 15, 2026
d8b5b3f
refactored the implementation to make the debugger a runtime option i…
G-Yong Apr 16, 2026
d25e013
remove unnecessary modification
G-Yong Apr 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions api-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,130 @@ static void get_uint8array(void)
JS_FreeRuntime(rt);
}

static struct {
int call_count;
int last_line;
int last_col;
char last_filename[256];
char last_funcname[256];
int stack_depth;
int max_local_count;
int abort_at; /* abort (return -1) on this call, 0 = never */
} trace_state;

static int debug_trace_cb(JSContext *ctx,
const char *filename,
const char *funcname,
int line,
int col)
{
trace_state.call_count++;
trace_state.last_line = line;
trace_state.last_col = col;
snprintf(trace_state.last_filename, sizeof(trace_state.last_filename),
"%s", filename);
snprintf(trace_state.last_funcname, sizeof(trace_state.last_funcname),
"%s", funcname);
trace_state.stack_depth = JS_GetStackDepth(ctx);
int count = 0;
JSDebugLocalVar *vars = JS_GetLocalVariablesAtLevel(ctx, 0, &count);
if (count > trace_state.max_local_count)
trace_state.max_local_count = count;
if (vars)
JS_FreeLocalVariables(ctx, vars, count);
if (trace_state.abort_at > 0 &&
trace_state.call_count >= trace_state.abort_at)
return -1;
return 0;
}

static void debug_trace(void)
{
JSRuntime *rt = JS_NewRuntime();
JSContext *ctx = JS_NewContext(rt);

/* no handler set: eval should work and call_count stays 0 */
memset(&trace_state, 0, sizeof(trace_state));
{
JSValue ret = eval(ctx, "1+2");
assert(!JS_IsException(ret));
JS_FreeValue(ctx, ret);
assert(trace_state.call_count == 0);
}

/* set handler: callback fires for each statement */
JS_SetDebugTraceHandler(ctx, debug_trace_cb);
memset(&trace_state, 0, sizeof(trace_state));
{
JSValue ret = eval(ctx, "var x = 1; x + 2");
assert(!JS_IsException(ret));
JS_FreeValue(ctx, ret);
assert(trace_state.call_count > 0);
assert(!strcmp(trace_state.last_filename, "<input>"));
}

/* stack depth inside a nested call */
memset(&trace_state, 0, sizeof(trace_state));
{
static const char code[] =
"function outer() {\n"
" function inner() {\n"
" return 42;\n"
" }\n"
" return inner();\n"
"}\n"
"outer();\n";
JSValue ret = eval(ctx, code);
assert(!JS_IsException(ret));
JS_FreeValue(ctx, ret);
assert(trace_state.call_count > 0);
/* the deepest invocation should have a stack depth > 1 */
/* (just verify we got a sane value; exact depth depends on internals) */
assert(trace_state.stack_depth >= 1);
}

/* local variables are visible inside the callback */
memset(&trace_state, 0, sizeof(trace_state));
{
static const char code[] =
"function f(a, b) {\n"
" var c = a + b;\n"
" return c;\n"
"}\n"
"f(10, 20);\n";
JSValue ret = eval(ctx, code);
assert(!JS_IsException(ret));
JS_FreeValue(ctx, ret);
assert(trace_state.call_count > 0);
/* inside f() we should see locals (a, b, c) at some point */
assert(trace_state.max_local_count >= 2);
}

/* returning non-zero aborts execution */
memset(&trace_state, 0, sizeof(trace_state));
trace_state.abort_at = 1; /* abort on first callback */
{
JSValue ret = eval(ctx, "1+2; 3+4");
assert(JS_IsException(ret));
JS_FreeValue(ctx, ret);
JSValue exc = JS_GetException(ctx);
JS_FreeValue(ctx, exc);
}

/* clear handler: callbacks no longer fire */
JS_SetDebugTraceHandler(ctx, NULL);
memset(&trace_state, 0, sizeof(trace_state));
{
JSValue ret = eval(ctx, "1+2");
assert(!JS_IsException(ret));
JS_FreeValue(ctx, ret);
assert(trace_state.call_count == 0);
}

JS_FreeContext(ctx);
JS_FreeRuntime(rt);
}

static void new_symbol(void)
{
JSRuntime *rt = JS_NewRuntime();
Expand Down Expand Up @@ -1037,6 +1161,7 @@ int main(void)
slice_string_tocstring();
immutable_array_buffer();
get_uint8array();
debug_trace();
new_symbol();
return 0;
}
2 changes: 2 additions & 0 deletions quickjs-opcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,8 @@ DEF( is_null, 1, 1, 1, none)
DEF(typeof_is_undefined, 1, 1, 1, none)
DEF( typeof_is_function, 1, 1, 1, none)

DEF( debug, 1, 0, 0, none) /* debugger trace point */

#undef DEF
#undef def
#endif /* DEF */
Loading