Skip to content

Commit 78f61f9

Browse files
committed
fix: pending promise shouldn't release by gc and should free after runtime shutdown
1 parent 2c6fbc9 commit 78f61f9

File tree

4 files changed

+25
-1
lines changed

4 files changed

+25
-1
lines changed

src/core/builtins/js-promise.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ void js_promise_mark(JSRuntime *rt, JSValueConst val,
353353
struct list_head *el;
354354
int i;
355355

356-
if (!s)
356+
if (!s || (rt->state != JS_RUNTIME_STATE_SHUTDOWN && s->promise_state == JS_PROMISE_PENDING))
357357
return;
358358
for(i = 0; i < 2; i++) {
359359
list_for_each(el, &s->promise_reactions[i]) {

src/core/runtime.c

+4
Original file line numberDiff line numberDiff line change
@@ -2601,6 +2601,9 @@ void JS_FreeRuntime(JSRuntime* rt) {
26012601
struct list_head *el, *el1;
26022602
int i;
26032603

2604+
if (rt->state == JS_RUNTIME_STATE_SHUTDOWN)
2605+
return;
2606+
rt->state = JS_RUNTIME_STATE_SHUTDOWN;
26042607
JS_FreeValueRT(rt, rt->current_exception);
26052608

26062609
list_for_each_safe(el, el1, &rt->job_list) {
@@ -3063,6 +3066,7 @@ JSRuntime* JS_NewRuntime2(const JSMallocFunctions* mf, void* opaque) {
30633066
JS_UpdateStackTop(rt);
30643067

30653068
rt->current_exception = JS_NULL;
3069+
rt->state = JS_RUNTIME_STATE_INIT;
30663070

30673071
return rt;
30683072
fail:

src/core/types.h

+6
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@ typedef struct {
158158
} JSNumericOperations;
159159
#endif
160160

161+
typedef enum {
162+
JS_RUNTIME_STATE_INIT,
163+
JS_RUNTIME_STATE_SHUTDOWN,
164+
} JSRuntimeState;
165+
161166
struct JSRuntime {
162167
JSMallocFunctions mf;
163168
JSMallocState malloc_state;
@@ -226,6 +231,7 @@ struct JSRuntime {
226231
uint32_t operator_count;
227232
#endif
228233
void *user_opaque;
234+
JSRuntimeState state;
229235
};
230236

231237
struct JSClass {

tests/test_promise_gc_crash.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
async function createTask() {
2+
return Promise.resolve().then(function () {
3+
new Uint8Array(1000000)
4+
})
5+
}
6+
7+
run()
8+
async function run() {
9+
let fn = (v) => { console.log(v.length); }
10+
let done = (v) => fn(v)
11+
createTask().then(done)
12+
const p = new Promise(() => { })
13+
await p
14+
}

0 commit comments

Comments
 (0)