mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 20:07:30 +09:00
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:
parent
2a6ec52f2f
commit
3cf82e2ca1
7 changed files with 32 additions and 8 deletions
|
|
@ -301,6 +301,7 @@ LoadContextOptions(const char* aPrefName, void* /* aClosure */)
|
|||
.setAsyncStack(GetWorkerPref<bool>(NS_LITERAL_CSTRING("asyncstack")))
|
||||
.setWerror(GetWorkerPref<bool>(NS_LITERAL_CSTRING("werror")))
|
||||
.setStreams(GetWorkerPref<bool>(NS_LITERAL_CSTRING("streams")))
|
||||
.setWeakRefs(GetWorkerPref<bool>(NS_LITERAL_CSTRING("weakrefs")))
|
||||
.setExtraWarnings(GetWorkerPref<bool>(NS_LITERAL_CSTRING("strict")))
|
||||
.setArrayProtoValues(GetWorkerPref<bool>(
|
||||
NS_LITERAL_CSTRING("array_prototype_values")));
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ WORKER_SIMPLE_PREF("dom.serviceWorkers.openWindow.enabled", OpenWindowEnabled, O
|
|||
WORKER_SIMPLE_PREF("dom.storageManager.enabled", StorageManagerEnabled, STORAGEMANAGER_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.push.enabled", PushEnabled, PUSH_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.streams.enabled", StreamsEnabled, STREAMS_ENABLED)
|
||||
WORKER_SIMPLE_PREF("javascript.options.weakrefs", WeakRefsEnabled, WEAKREFS_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.requestcontext.enabled", RequestContextEnabled, REQUESTCONTEXT_ENABLED)
|
||||
WORKER_SIMPLE_PREF("gfx.offscreencanvas.enabled", OffscreenCanvasEnabled, OFFSCREENCANVAS_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.webkitBlink.dirPicker.enabled", WebkitBlinkDirectoryPickerEnabled, DOM_WEBKITBLINK_DIRPICKER_WEBKITBLINK)
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,8 +15,10 @@ class WeakRefObject : public NativeObject
|
|||
{
|
||||
public:
|
||||
struct Referent {
|
||||
explicit Referent(JSObject* obj) : target(obj) {}
|
||||
explicit Referent(JSObject* obj, bool enabled)
|
||||
: target(obj), enabled(enabled) {}
|
||||
WeakRef<JSObject*> target;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
static const Class class_;
|
||||
|
|
|
|||
|
|
@ -998,7 +998,9 @@ class JS_PUBLIC_API(ContextOptions) {
|
|||
werror_(false),
|
||||
strictMode_(false),
|
||||
extraWarnings_(false),
|
||||
arrayProtoValues_(true)
|
||||
arrayProtoValues_(true),
|
||||
streams_(true),
|
||||
weakRefs_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -1138,6 +1140,16 @@ class JS_PUBLIC_API(ContextOptions) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool weakRefs() const { return weakRefs_; }
|
||||
ContextOptions& setWeakRefs(bool flag) {
|
||||
weakRefs_ = flag;
|
||||
return *this;
|
||||
}
|
||||
ContextOptions& toggleWeakRefs() {
|
||||
weakRefs_ = !weakRefs_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
bool baseline_ : 1;
|
||||
bool ion_ : 1;
|
||||
|
|
@ -1155,6 +1167,7 @@ class JS_PUBLIC_API(ContextOptions) {
|
|||
bool extraWarnings_ : 1;
|
||||
bool arrayProtoValues_ : 1;
|
||||
bool streams_ : 1;
|
||||
bool weakRefs_ : 1;
|
||||
};
|
||||
|
||||
JS_PUBLIC_API(ContextOptions&)
|
||||
|
|
|
|||
|
|
@ -1446,6 +1446,7 @@ ReloadPrefsCallback(const char* pref, void* data)
|
|||
bool extraWarnings = Preferences::GetBool(JS_OPTIONS_DOT_STR "strict");
|
||||
|
||||
bool streams = Preferences::GetBool(JS_OPTIONS_DOT_STR "streams");
|
||||
bool weakRefs = Preferences::GetBool(JS_OPTIONS_DOT_STR "weakrefs");
|
||||
|
||||
bool unboxedObjects = Preferences::GetBool(JS_OPTIONS_DOT_STR "unboxed_objects");
|
||||
|
||||
|
|
@ -1472,7 +1473,8 @@ ReloadPrefsCallback(const char* pref, void* data)
|
|||
.setWerror(werror)
|
||||
.setExtraWarnings(extraWarnings)
|
||||
.setArrayProtoValues(arrayProtoValues)
|
||||
.setStreams(streams);
|
||||
.setStreams(streams)
|
||||
.setWeakRefs(weakRefs);
|
||||
|
||||
JS_SetParallelParsingEnabled(cx, parallelParsing);
|
||||
JS_SetOffthreadIonCompilationEnabled(cx, offthreadIonCompilation);
|
||||
|
|
|
|||
|
|
@ -1347,6 +1347,7 @@ pref("javascript.options.dynamicImport", true);
|
|||
|
||||
// Streams API
|
||||
pref("javascript.options.streams", true);
|
||||
pref("javascript.options.weakrefs", false);
|
||||
|
||||
// advanced prefs
|
||||
pref("advanced.mailftp", false);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue