Issue MoonchildProductions/UXP#2306: Add pref-gated WeakRef with safe stub when disabled

* Add javascript.options.weakrefs and plumb it through context options, XPConnect, and workers
* Keep referents alive via strong tracing when the pref is off so deref() still returns the target
* Retain weak-edge semantics when the pref is enabled
This commit is contained in:
Basilisk-Dev 2025-12-17 16:35:41 -05:00 committed by wuggy
commit 3cf82e2ca1
7 changed files with 32 additions and 8 deletions

View file

@ -89,7 +89,7 @@ WeakRefObject::create(JSContext* cx, HandleObject target, HandleObject proto /*
if (!obj)
return nullptr;
Referent* data = cx->new_<Referent>(target);
Referent* data = cx->new_<Referent>(target, cx->options().weakRefs());
if (!data)
return nullptr;
@ -146,12 +146,16 @@ WeakRefObject::trace(JSTracer* trc, JSObject* obj)
if (!target)
return;
// Weak edges must be tenured; fall back to a strong trace while the
// referent is still in the nursery to avoid crashing the GC.
if (IsInsideNursery(target))
// When pref-disabled, keep referent alive via strong trace so deref()
// stays usable as a stub without touching GC internals.
if (!data->enabled) {
TraceManuallyBarrieredEdge(trc, data->target.unsafeGet(), "WeakRef stub referent");
} else if (IsInsideNursery(target)) {
// Weak edges must be tenured; trace strongly while referent is in the nursery.
TraceManuallyBarrieredEdge(trc, data->target.unsafeGet(), "WeakRef nursery referent");
else
} else {
TraceWeakEdge(trc, &data->target, "WeakRef referent");
}
}
}