diff --git a/src/core/builtins/js-promise.c b/src/core/builtins/js-promise.c index 0f6d87d5c..324530ecc 100644 --- a/src/core/builtins/js-promise.c +++ b/src/core/builtins/js-promise.c @@ -353,7 +353,7 @@ void js_promise_mark(JSRuntime *rt, JSValueConst val, struct list_head *el; int i; - if (!s) + if (!s || (rt->state != JS_RUNTIME_STATE_SHUTDOWN && s->promise_state == JS_PROMISE_PENDING)) return; for(i = 0; i < 2; i++) { list_for_each(el, &s->promise_reactions[i]) { diff --git a/src/core/runtime.c b/src/core/runtime.c index 3d03c2c4b..04a89625d 100644 --- a/src/core/runtime.c +++ b/src/core/runtime.c @@ -2601,6 +2601,9 @@ void JS_FreeRuntime(JSRuntime* rt) { struct list_head *el, *el1; int i; + if (rt->state == JS_RUNTIME_STATE_SHUTDOWN) + return; + rt->state = JS_RUNTIME_STATE_SHUTDOWN; JS_FreeValueRT(rt, rt->current_exception); list_for_each_safe(el, el1, &rt->job_list) { @@ -3063,6 +3066,7 @@ JSRuntime* JS_NewRuntime2(const JSMallocFunctions* mf, void* opaque) { JS_UpdateStackTop(rt); rt->current_exception = JS_NULL; + rt->state = JS_RUNTIME_STATE_INIT; return rt; fail: diff --git a/src/core/types.h b/src/core/types.h index 43afa1e7e..db5e89018 100644 --- a/src/core/types.h +++ b/src/core/types.h @@ -158,6 +158,11 @@ typedef struct { } JSNumericOperations; #endif +typedef enum { + JS_RUNTIME_STATE_INIT, + JS_RUNTIME_STATE_SHUTDOWN, +} JSRuntimeState; + struct JSRuntime { JSMallocFunctions mf; JSMallocState malloc_state; @@ -226,6 +231,7 @@ struct JSRuntime { uint32_t operator_count; #endif void *user_opaque; + JSRuntimeState state; }; struct JSClass { diff --git a/tests/test_promise_gc_crash.js b/tests/test_promise_gc_crash.js new file mode 100644 index 000000000..6549eebda --- /dev/null +++ b/tests/test_promise_gc_crash.js @@ -0,0 +1,14 @@ +async function createTask() { + return Promise.resolve().then(function () { + new Uint8Array(1000000) + }) +} + +run() +async function run() { + let fn = (v) => { console.log(v.length); } + let done = (v) => fn(v) + createTask().then(done) + const p = new Promise(() => { }) + await p +} \ No newline at end of file