Fix crash in FinalizationRegistry when the observed object is GC'd
In the pathological case shown in https://github.com/quickjs-ng/quickjs/issues/367 both the object and the registry will be destroyed as part of the GC phase of JS_FreeRuntime. When the GC sweep happens it's possible we are holding on to a corpse so avoid calling the registry callback in that case. This is similar to how Weak{Map,Set} deal with iterators being freed as part of a cycle. Fixes: https://github.com/quickjs-ng/quickjs/issues/367
This commit is contained in:
parent
325ce95c5e
commit
38fa7d7cf6
1 changed files with 10 additions and 5 deletions
|
@ -52141,11 +52141,16 @@ static void reset_weak_ref(JSRuntime *rt, JSWeakRefRecord **first_weak_ref)
|
||||||
fre = wr->u.fin_rec_entry;
|
fre = wr->u.fin_rec_entry;
|
||||||
JSFinalizationRegistryData *frd = JS_GetOpaque(fre->obj, JS_CLASS_FINALIZATION_REGISTRY);
|
JSFinalizationRegistryData *frd = JS_GetOpaque(fre->obj, JS_CLASS_FINALIZATION_REGISTRY);
|
||||||
assert(frd != NULL);
|
assert(frd != NULL);
|
||||||
|
/**
|
||||||
|
* During the GC sweep phase the held object might be collected first.
|
||||||
|
*/
|
||||||
|
if (JS_IsLiveObject(frd->ctx->rt, fre->held_val)) {
|
||||||
JSValue func = js_dup(frd->cb);
|
JSValue func = js_dup(frd->cb);
|
||||||
JSValue ret = JS_Call(frd->ctx, func, JS_UNDEFINED, 1, &fre->held_val);
|
JSValue ret = JS_Call(frd->ctx, func, JS_UNDEFINED, 1, &fre->held_val);
|
||||||
JS_FreeValueRT(rt, func);
|
JS_FreeValueRT(rt, func);
|
||||||
JS_FreeValueRT(rt, ret);
|
JS_FreeValueRT(rt, ret);
|
||||||
JS_FreeValueRT(rt, fre->held_val);
|
JS_FreeValueRT(rt, fre->held_val);
|
||||||
|
}
|
||||||
JS_FreeValueRT(rt, fre->token);
|
JS_FreeValueRT(rt, fre->token);
|
||||||
js_free_rt(rt, fre);
|
js_free_rt(rt, fre);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue