fix debug stack getting
This commit is contained in:
@@ -14,11 +14,6 @@ if get_option('bignum')
|
|||||||
add_project_arguments('-DCONFIG_BIGNUM', language : 'c')
|
add_project_arguments('-DCONFIG_BIGNUM', language : 'c')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if get_option('trace')
|
|
||||||
add_project_arguments('-DTRACY_ENABLE', language:'c')
|
|
||||||
deps += dependency('tracy', static:true)
|
|
||||||
endif
|
|
||||||
|
|
||||||
lib_sources = ['libbf.c', 'libregexp.c', 'quickjs.c', 'libunicode.c', 'cutils.c']
|
lib_sources = ['libbf.c', 'libregexp.c', 'quickjs.c', 'libunicode.c', 'cutils.c']
|
||||||
|
|
||||||
libquickjs = library('quickjs',
|
libquickjs = library('quickjs',
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
option('bignum', type:'boolean', value:true)
|
option('bignum', type:'boolean', value:true)
|
||||||
option('trace', type:'boolean', value:false)
|
|
||||||
111
quickjs.c
111
quickjs.c
@@ -429,8 +429,11 @@ struct JSContext {
|
|||||||
JSAtom doc_sym;
|
JSAtom doc_sym;
|
||||||
JSAtom typeof_sym;
|
JSAtom typeof_sym;
|
||||||
|
|
||||||
void (*fn_start_hook)(JSContext*, JSValue);
|
js_hook fn_start_hook;
|
||||||
void (*fn_end_hook)(JSContext*, JSValue);
|
js_hook fn_end_hook;
|
||||||
|
js_hook fn_cycle_hook;
|
||||||
|
js_hook fn_gc_hook;
|
||||||
|
int hook_disabled;
|
||||||
|
|
||||||
uint64_t random_state;
|
uint64_t random_state;
|
||||||
|
|
||||||
@@ -1629,9 +1632,6 @@ static void *js_def_malloc(JSMallocState *s, size_t size)
|
|||||||
|
|
||||||
s->malloc_count++;
|
s->malloc_count++;
|
||||||
s->malloc_size += js_def_malloc_usable_size(ptr) + MALLOC_OVERHEAD;
|
s->malloc_size += js_def_malloc_usable_size(ptr) + MALLOC_OVERHEAD;
|
||||||
#ifdef TRACY_ENABLE
|
|
||||||
TracyCAllocN(ptr,js_def_malloc_usable_size(ptr) + MALLOC_OVERHEAD, "quickjs");
|
|
||||||
#endif
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1642,9 +1642,6 @@ static void js_def_free(JSMallocState *s, void *ptr)
|
|||||||
|
|
||||||
s->malloc_count--;
|
s->malloc_count--;
|
||||||
s->malloc_size -= js_def_malloc_usable_size(ptr) + MALLOC_OVERHEAD;
|
s->malloc_size -= js_def_malloc_usable_size(ptr) + MALLOC_OVERHEAD;
|
||||||
#ifdef TRACY_ENABLE
|
|
||||||
TracyCFreeN(ptr, "quickjs");
|
|
||||||
#endif
|
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1661,26 +1658,17 @@ static void *js_def_realloc(JSMallocState *s, void *ptr, size_t size)
|
|||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
s->malloc_count--;
|
s->malloc_count--;
|
||||||
s->malloc_size -= old_size + MALLOC_OVERHEAD;
|
s->malloc_size -= old_size + MALLOC_OVERHEAD;
|
||||||
#ifdef TRACY_ENABLE
|
|
||||||
TracyCFreeN(ptr, "quickjs");
|
|
||||||
#endif
|
|
||||||
free(ptr);
|
free(ptr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (s->malloc_size + size - old_size > s->malloc_limit)
|
if (s->malloc_size + size - old_size > s->malloc_limit)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#ifdef TRACY_ENABLE
|
|
||||||
TracyCFreeN(ptr, "quickjs");
|
|
||||||
#endif
|
|
||||||
ptr = realloc(ptr, size);
|
ptr = realloc(ptr, size);
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
s->malloc_size += js_def_malloc_usable_size(ptr) - old_size;
|
s->malloc_size += js_def_malloc_usable_size(ptr) - old_size;
|
||||||
#ifdef TRACY_ENABLE
|
|
||||||
TracyCAllocN(ptr,js_def_malloc_usable_size(ptr) + MALLOC_OVERHEAD, "quickjs");
|
|
||||||
#endif
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2090,6 +2078,7 @@ JSContext *JS_NewContextRaw(JSRuntime *rt)
|
|||||||
|
|
||||||
ctx->fn_start_hook = NULL;
|
ctx->fn_start_hook = NULL;
|
||||||
ctx->fn_end_hook = NULL;
|
ctx->fn_end_hook = NULL;
|
||||||
|
ctx->hook_disabled = 0;
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
@@ -16245,8 +16234,11 @@ static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj,
|
|||||||
|
|
||||||
func = p->u.cfunc.c_function;
|
func = p->u.cfunc.c_function;
|
||||||
|
|
||||||
// if (unlikely(ctx->fn_start_hook))
|
if (unlikely(ctx->fn_start_hook) && !ctx->hook_disabled) {
|
||||||
// ctx->fn_start_hook(ctx,func_obj);
|
ctx->hook_disabled = 1;
|
||||||
|
ctx->fn_start_hook(ctx,func_obj);
|
||||||
|
ctx->hook_disabled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
switch(cproto) {
|
switch(cproto) {
|
||||||
case JS_CFUNC_constructor:
|
case JS_CFUNC_constructor:
|
||||||
@@ -16333,9 +16325,11 @@ static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj,
|
|||||||
|
|
||||||
rt->current_stack_frame = sf->prev_frame;
|
rt->current_stack_frame = sf->prev_frame;
|
||||||
|
|
||||||
|
if (unlikely(ctx->fn_end_hook) && !ctx->hook_disabled) {
|
||||||
// if (unlikely(ctx->fn_end_hook))
|
ctx->hook_disabled = 1;
|
||||||
// ctx->fn_end_hook(ctx, func_obj);
|
ctx->fn_end_hook(ctx, func_obj);
|
||||||
|
ctx->hook_disabled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
@@ -16468,8 +16462,11 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
|
|||||||
}
|
}
|
||||||
b = p->u.func.function_bytecode;
|
b = p->u.func.function_bytecode;
|
||||||
|
|
||||||
if (unlikely(caller_ctx->fn_start_hook))
|
if (unlikely(caller_ctx->fn_start_hook) && !caller_ctx->hook_disabled) {
|
||||||
|
caller_ctx->hook_disabled = 1;
|
||||||
caller_ctx->fn_start_hook(caller_ctx,func_obj);
|
caller_ctx->fn_start_hook(caller_ctx,func_obj);
|
||||||
|
caller_ctx->hook_disabled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely(argc < b->arg_count || (flags & JS_CALL_FLAG_COPY_ARGV))) {
|
if (unlikely(argc < b->arg_count || (flags & JS_CALL_FLAG_COPY_ARGV))) {
|
||||||
arg_allocated_size = b->arg_count;
|
arg_allocated_size = b->arg_count;
|
||||||
@@ -19025,9 +19022,11 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
|
|||||||
}
|
}
|
||||||
rt->current_stack_frame = sf->prev_frame;
|
rt->current_stack_frame = sf->prev_frame;
|
||||||
|
|
||||||
// if (unlikely(ctx->fn_end_hook))
|
if (unlikely(caller_ctx->fn_end_hook) && !caller_ctx->hook_disabled) {
|
||||||
// ctx->fn_end_hook(ctx,func_obj);
|
caller_ctx->hook_disabled = 1;
|
||||||
|
caller_ctx->fn_end_hook(caller_ctx,func_obj);
|
||||||
|
caller_ctx->hook_disabled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
@@ -54977,6 +54976,66 @@ JSValue js_debugger_backtrace_fns(JSContext *ctx, const uint8_t *cur_pc)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define STRLEN(s) (sizeof(s)/sizeof(s[0]))
|
||||||
|
#define CSTR "<native C>"
|
||||||
|
|
||||||
|
void js_debug_info(JSContext *js, JSValue fn, js_debug *dbg)
|
||||||
|
{
|
||||||
|
memset(dbg, 0, sizeof(*dbg));
|
||||||
|
|
||||||
|
if (!JS_IsObject(fn)) return;
|
||||||
|
JSObject *p = JS_VALUE_GET_OBJ(fn);
|
||||||
|
|
||||||
|
char *fn_name = get_func_name(js,fn);
|
||||||
|
|
||||||
|
if (!fn_name || fn_name[0] == 0)
|
||||||
|
dbg->name = js_strdup(js, "<anonymous>");
|
||||||
|
else {
|
||||||
|
dbg->name = js_strdup(js, fn_name);
|
||||||
|
JS_FreeCString(js,fn_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg->unique = (int)p;
|
||||||
|
|
||||||
|
switch(p->class_id) {
|
||||||
|
case JS_CLASS_BYTECODE_FUNCTION: {
|
||||||
|
JSFunctionBytecode *b = p->u.func.function_bytecode;
|
||||||
|
// get filename
|
||||||
|
char *filename = JS_AtomToCString(js, b->debug.filename);
|
||||||
|
if (!filename || filename[0] == 0)
|
||||||
|
dbg->filename = js_strdup(js, "unknown");
|
||||||
|
else {
|
||||||
|
dbg->filename = js_strdup(js, filename);
|
||||||
|
JS_FreeCString(js,filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg->what = "JS";
|
||||||
|
dbg->closure_n = b->closure_var_count;
|
||||||
|
dbg->param_n = b->arg_count;
|
||||||
|
dbg->vararg = 1;
|
||||||
|
dbg->line = b->debug.line_num;
|
||||||
|
dbg->source = b->debug.source;
|
||||||
|
dbg->srclen = b->debug.source_len;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case JS_CLASS_C_FUNCTION:
|
||||||
|
dbg->filename = js_strdup(js, "<native C>");
|
||||||
|
dbg->what = "C";
|
||||||
|
dbg->nparams = 0;
|
||||||
|
dbg->vararg = 1;
|
||||||
|
dbg->line = 0;
|
||||||
|
dbg->source = CSTR;
|
||||||
|
dbg->srclen = STRLEN(CSTR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_js_debug_info(JSContext *js, js_debug *dbg)
|
||||||
|
{
|
||||||
|
js_free(js, dbg->filename);
|
||||||
|
js_free(js, dbg->name);
|
||||||
|
}
|
||||||
|
|
||||||
JSValue js_debugger_build_backtrace(JSContext *ctx, const uint8_t *cur_pc)
|
JSValue js_debugger_build_backtrace(JSContext *ctx, const uint8_t *cur_pc)
|
||||||
{
|
{
|
||||||
JSStackFrame *sf;
|
JSStackFrame *sf;
|
||||||
|
|||||||
17
quickjs.h
17
quickjs.h
@@ -1202,6 +1202,23 @@ int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *export_name,
|
|||||||
int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
|
int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
|
||||||
const JSCFunctionListEntry *tab, int len);
|
const JSCFunctionListEntry *tab, int len);
|
||||||
|
|
||||||
|
typedef struct js_debug {
|
||||||
|
const char *name; // nameof function
|
||||||
|
const char *what;
|
||||||
|
const char *source; // source code of function
|
||||||
|
size_t srclen;
|
||||||
|
const char *filename; // name of file function is in
|
||||||
|
int nparams;
|
||||||
|
int vararg;
|
||||||
|
int line; // line the function is on
|
||||||
|
int param_n;
|
||||||
|
int closure_n;
|
||||||
|
uint32_t unique; // a unique identifier for this function
|
||||||
|
} js_debug;
|
||||||
|
|
||||||
|
void js_debug_info(JSContext *js, JSValue fn, js_debug *dbg);
|
||||||
|
void free_js_debug_info(JSContext *js, js_debug *dbg);
|
||||||
|
|
||||||
JSValue js_debugger_closure_variables(JSContext *js, JSValue fn);
|
JSValue js_debugger_closure_variables(JSContext *js, JSValue fn);
|
||||||
JSValue js_debugger_local_variables(JSContext *ctx, int stack_index);
|
JSValue js_debugger_local_variables(JSContext *ctx, int stack_index);
|
||||||
JSValue js_debugger_build_backtrace(JSContext *ctx, const uint8_t *cur_pc);
|
JSValue js_debugger_build_backtrace(JSContext *ctx, const uint8_t *cur_pc);
|
||||||
|
|||||||
Reference in New Issue
Block a user