Skip to content

Commit 83fe8f1

Browse files
authored
Fix exception in WeakRef.prototype.deref (#653)
Set the object's opaque to a sentinel value instead of NULL, to stop JS_GetOpaque2 from raising an "illegal class" exception. Fixes: #651
1 parent 0a70623 commit 83fe8f1

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

quickjs.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54737,10 +54737,12 @@ typedef struct JSWeakRefData {
5473754737
JSValue obj;
5473854738
} JSWeakRefData;
5473954739

54740+
static JSWeakRefData js_weakref_sentinel;
54741+
5474054742
static void js_weakref_finalizer(JSRuntime *rt, JSValue val)
5474154743
{
5474254744
JSWeakRefData *wrd = JS_GetOpaque(val, JS_CLASS_WEAK_REF);
54743-
if (!wrd)
54745+
if (!wrd || wrd == &js_weakref_sentinel)
5474454746
return;
5474554747

5474654748
/* Delete weak ref */
@@ -54796,6 +54798,8 @@ static JSValue js_weakref_deref(JSContext *ctx, JSValue this_val, int argc, JSVa
5479654798
JSWeakRefData *wrd = JS_GetOpaque2(ctx, this_val, JS_CLASS_WEAK_REF);
5479754799
if (!wrd)
5479854800
return JS_EXCEPTION;
54801+
if (wrd == &js_weakref_sentinel)
54802+
return JS_UNDEFINED;
5479954803
return js_dup(wrd->target);
5480054804
}
5480154805

@@ -55055,7 +55059,7 @@ static void reset_weak_ref(JSRuntime *rt, JSWeakRefRecord **first_weak_ref)
5505555059
break;
5505655060
case JS_WEAK_REF_KIND_WEAK_REF:
5505755061
wrd = wr->u.weak_ref_data;
55058-
JS_SetOpaque(wrd->obj, NULL);
55062+
JS_SetOpaque(wrd->obj, &js_weakref_sentinel);
5505955063
js_free_rt(rt, wrd);
5506055064
break;
5506155065
case JS_WEAK_REF_KIND_FINALIZATION_REGISTRY_ENTRY: {

tests/bug652.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { assert } from "./assert.js"
2+
const ref = new WeakRef({})
3+
const val = ref.deref() // should not throw
4+
assert(val, undefined)

0 commit comments

Comments
 (0)