From f7f70fc5799390983253adc2b8ad4d1afe4a3d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Mon, 25 Nov 2024 08:49:25 +0100 Subject: [PATCH] Fix leak when interpreter exits due to exception Fixes: https://github.com/quickjs-ng/quickjs/issues/720 --- gen/function_source.c | Bin 2749 -> 2892 bytes gen/hello.c | Bin 1416 -> 1559 bytes gen/hello_module.c | Bin 3818 -> 3961 bytes gen/test_fib.c | Bin 2697 -> 2840 bytes qjs.c | 2 ++ qjsc.c | 14 +++++++++++--- quickjs-libc.c | 7 +++++-- run-test262.c | 8 +++++++- 8 files changed, 25 insertions(+), 6 deletions(-) diff --git a/gen/function_source.c b/gen/function_source.c index 3c55b87642a5145c80d983924c158d5aec55dada..642e8285b4aad3c7fad526859cb8efec8bc34780 100644 GIT binary patch delta 181 zcmdlhdPZ!+dk)deyb^^XYc2%^ui&u6oYGWSk_t_brpz=24X@yM&tlh#LJ$ vYEe;sks(N@4#*C$b_InZpuvV9lWM_Eh<7VWO$ECHN#W#Fu3%Q68*8}$w3j$K delta 42 ycmX>jwpVn+dydKMoGP15I2{@Jvx?)3OH$%<^79Kcl1nNkf8q*dHL&KYSk_t_brpz=24X@yM&tlh#LJ$ vYEe;sks(N@4#*C$b_InZpuvV9lWM_Eh<7VWO$ECHN#SGz)?ikk8*8}$mjXBY delta 42 ycmbQv)4{#r9P{L7%qp9OS#%lsvx?)3OH$%<^79Kcl1nNk?_~{THL&KYnQ00dUcvF6#jX{}sRbpO`FR>ZNli_KYM==U3R%VR#U&~6DW$mu@u@{c`9+2r r$t4v!ATu>Vb|@$m0ZlaoF>AqA#=8}zrh@H-E1W!mFO(JNqFOEh`b05I delta 42 xcmew<_eyqy67OUyUX{)1yw;5TS;g_iB`NVa`S}GJ$t4w&<@rNd4Xn9pxd1=$4V(Y~ diff --git a/gen/test_fib.c b/gen/test_fib.c index 53293833c6e47c3e57f788e878f677fdf1f9425a..d33cff29e7dcea99b2c7254933f9db4529239b80 100644 GIT binary patch delta 163 zcmeAaogud2B!_5bUWr1HHJ5^dS8!NjPHCz_QEG|xCM7Q0p?rxuiC=I3buB{ek_s(~gbC}b7K7nh{Or #include "cutils.h" +#include "quickjs.h" #include "quickjs-libc.h" #ifdef QJS_USE_MIMALLOC @@ -556,6 +557,7 @@ int main(int argc, char **argv) ret = js_std_loop(ctx); if (!JS_IsUndefined(ret)) { js_std_dump_error1(ctx, ret); + JS_FreeValue(ctx, ret); goto fail; } } diff --git a/qjsc.c b/qjsc.c index 8e0b58b..5e2e8ae 100644 --- a/qjsc.c +++ b/qjsc.c @@ -314,19 +314,27 @@ static void compile_file(JSContext *ctx, FILE *fo, static const char main_c_template1[] = "int main(int argc, char **argv)\n" "{\n" + " int r;\n" + " JSValue ret;\n" " JSRuntime *rt;\n" " JSContext *ctx;\n" + " r = 0;\n" " rt = JS_NewRuntime();\n" " js_std_set_worker_new_context_func(JS_NewCustomContext);\n" " js_std_init_handlers(rt);\n" ; static const char main_c_template2[] = - " js_std_loop(ctx);\n" + " ret = js_std_loop(ctx);\n" + " if (JS_IsException(ret)) {\n" + " js_std_dump_error1(ctx, ret);\n" + " r = 1;\n" + " }\n" + " JS_FreeValue(ctx, ret);\n" " JS_FreeContext(ctx);\n" " js_std_free_handlers(rt);\n" " JS_FreeRuntime(rt);\n" - " return 0;\n" + " return r;\n" "}\n"; #define PROG_NAME "qjsc" @@ -375,7 +383,7 @@ int main(int argc, char **argv) stack_size = 0; memset(&dynamic_module_list, 0, sizeof(dynamic_module_list)); - + /* add system modules */ namelist_add(&cmodule_list, "qjs:std", "std", 0); namelist_add(&cmodule_list, "qjs:os", "os", 0); diff --git a/quickjs-libc.c b/quickjs-libc.c index a84c3b0..c1107de 100644 --- a/quickjs-libc.c +++ b/quickjs-libc.c @@ -3499,7 +3499,7 @@ static void *worker_func(void *opaque) js_std_dump_error(ctx); JS_FreeValue(ctx, val); - js_std_loop(ctx); + JS_FreeValue(ctx, js_std_loop(ctx)); JS_FreeContext(ctx); js_std_free_handlers(rt); @@ -4137,6 +4137,7 @@ JSValue js_std_loop(JSContext *ctx) JSRuntime *rt = JS_GetRuntime(ctx); JSThreadState *ts = js_get_thread_state(rt); JSContext *ctx1; + JSValue ret; int err; for(;;) { @@ -4156,7 +4157,9 @@ JSValue js_std_loop(JSContext *ctx) break; } done: - return ts->exc; + ret = ts->exc; + ts->exc = JS_UNDEFINED; + return ret; } /* Wait for a promise and execute pending jobs while waiting for diff --git a/run-test262.c b/run-test262.c index 5d42139..66ab898 100644 --- a/run-test262.c +++ b/run-test262.c @@ -45,6 +45,7 @@ typedef pthread_t js_thread_t; #include "cutils.h" #include "list.h" +#include "quickjs.h" #include "quickjs-c-atomics.h" #include "quickjs-libc.h" @@ -1554,7 +1555,12 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len, } if (local) { - js_std_loop(ctx); + JSValue val = js_std_loop(ctx); + if (JS_IsException(val)) { + js_std_dump_error1(ctx, val); + ret = -1; + } + JS_FreeValue(ctx, val); } JS_FreeCString(ctx, error_name);