Skip to content

Commit 1232d2e

Browse files
committed
Add debugger interface
1 parent bcac5c2 commit 1232d2e

4 files changed

Lines changed: 397 additions & 0 deletions

File tree

api-test.c

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,131 @@ static void get_uint8array(void)
971971
JS_FreeRuntime(rt);
972972
}
973973

974+
static struct {
975+
int call_count;
976+
int last_line;
977+
int last_col;
978+
char last_filename[256];
979+
char last_funcname[256];
980+
int stack_depth;
981+
int max_local_count;
982+
int abort_at; /* abort (return -1) on this call, 0 = never */
983+
} trace_state;
984+
985+
static int debug_trace_cb(JSContext *ctx,
986+
const char *filename,
987+
const char *funcname,
988+
int line,
989+
int col,
990+
void *opaque)
991+
{
992+
trace_state.call_count++;
993+
trace_state.last_line = line;
994+
trace_state.last_col = col;
995+
snprintf(trace_state.last_filename, sizeof(trace_state.last_filename),
996+
"%s", filename);
997+
snprintf(trace_state.last_funcname, sizeof(trace_state.last_funcname),
998+
"%s", funcname);
999+
trace_state.stack_depth = JS_GetStackDepth(ctx);
1000+
int count = 0;
1001+
JSDebugLocalVar *vars = NULL;
1002+
assert(JS_GetLocalVariablesAtLevel(ctx, 0, &vars, &count) == 0);
1003+
if (count > trace_state.max_local_count)
1004+
trace_state.max_local_count = count;
1005+
if (vars)
1006+
JS_FreeLocalVariables(ctx, vars, count);
1007+
if (trace_state.abort_at > 0 &&
1008+
trace_state.call_count >= trace_state.abort_at)
1009+
return -1;
1010+
return 0;
1011+
}
1012+
1013+
static void debug_trace(void)
1014+
{
1015+
JSRuntime *rt = JS_NewRuntime();
1016+
JSContext *ctx = JS_NewContext(rt);
1017+
1018+
memset(&trace_state, 0, sizeof(trace_state));
1019+
{
1020+
JSValue ret = eval(ctx, "1+2");
1021+
assert(!JS_IsException(ret));
1022+
JS_FreeValue(ctx, ret);
1023+
assert(trace_state.call_count == 0);
1024+
}
1025+
1026+
JS_SetDebugTraceHandler(ctx, debug_trace_cb, NULL);
1027+
memset(&trace_state, 0, sizeof(trace_state));
1028+
{
1029+
JSValue ret = eval(ctx, "var x = 1; x + 2");
1030+
assert(!JS_IsException(ret));
1031+
JS_FreeValue(ctx, ret);
1032+
assert(trace_state.call_count > 0);
1033+
assert(!strcmp(trace_state.last_filename, "<input>"));
1034+
}
1035+
1036+
{
1037+
JSDebugLocalVar *vars = NULL;
1038+
int count = -1;
1039+
assert(JS_GetLocalVariablesAtLevel(ctx, 0, &vars, &count) == 0);
1040+
assert(vars == NULL);
1041+
assert(count == 0);
1042+
}
1043+
1044+
memset(&trace_state, 0, sizeof(trace_state));
1045+
{
1046+
static const char code[] =
1047+
"function outer() {\n"
1048+
" function inner() {\n"
1049+
" return 42;\n"
1050+
" }\n"
1051+
" return inner();\n"
1052+
"}\n"
1053+
"outer();\n";
1054+
JSValue ret = eval(ctx, code);
1055+
assert(!JS_IsException(ret));
1056+
JS_FreeValue(ctx, ret);
1057+
assert(trace_state.call_count > 0);
1058+
assert(trace_state.stack_depth >= 1);
1059+
}
1060+
1061+
memset(&trace_state, 0, sizeof(trace_state));
1062+
{
1063+
static const char code[] =
1064+
"function f(a, b) {\n"
1065+
" var c = a + b;\n"
1066+
" return c;\n"
1067+
"}\n"
1068+
"f(10, 20);\n";
1069+
JSValue ret = eval(ctx, code);
1070+
assert(!JS_IsException(ret));
1071+
JS_FreeValue(ctx, ret);
1072+
assert(trace_state.call_count > 0);
1073+
assert(trace_state.max_local_count >= 2);
1074+
}
1075+
1076+
memset(&trace_state, 0, sizeof(trace_state));
1077+
trace_state.abort_at = 1;
1078+
{
1079+
JSValue ret = eval(ctx, "1+2; 3+4");
1080+
assert(JS_IsException(ret));
1081+
JS_FreeValue(ctx, ret);
1082+
JSValue exc = JS_GetException(ctx);
1083+
JS_FreeValue(ctx, exc);
1084+
}
1085+
1086+
JS_SetDebugTraceHandler(ctx, NULL, NULL);
1087+
memset(&trace_state, 0, sizeof(trace_state));
1088+
{
1089+
JSValue ret = eval(ctx, "1+2");
1090+
assert(!JS_IsException(ret));
1091+
JS_FreeValue(ctx, ret);
1092+
assert(trace_state.call_count == 0);
1093+
}
1094+
1095+
JS_FreeContext(ctx);
1096+
JS_FreeRuntime(rt);
1097+
}
1098+
9741099
static void new_symbol(void)
9751100
{
9761101
JSRuntime *rt = new_runtime();
@@ -1046,6 +1171,7 @@ int main(void)
10461171
slice_string_tocstring();
10471172
immutable_array_buffer();
10481173
get_uint8array();
1174+
debug_trace();
10491175
new_symbol();
10501176
return 0;
10511177
}

quickjs-opcode.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,8 @@ DEF( is_null, 1, 1, 1, none)
372372
DEF(typeof_is_undefined, 1, 1, 1, none)
373373
DEF( typeof_is_function, 1, 1, 1, none)
374374

375+
DEF( debug, 1, 0, 0, none)
376+
375377
#undef DEF
376378
#undef def
377379
#endif /* DEF */

0 commit comments

Comments
 (0)