1
0
mirror of https://github.com/roytam1/UXP.git synced 2026-05-26 13:58:49 +00:00

Fix WeakRef constructor realm prototype

This commit is contained in:
Basilisk-Dev
2026-05-10 19:17:00 -04:00
committed by roytam1
parent 890fb3f399
commit f3c6da5987
3 changed files with 85 additions and 1 deletions
+26 -1
View File
@@ -13,6 +13,7 @@
#include "vm/GlobalObject.h"
#include "vm/Symbol.h"
#include "jswrapper.h"
#include "jsobjinlines.h"
#include "vm/Interpreter-inl.h"
@@ -32,6 +33,30 @@ IsWeakRef(HandleValue v)
return v.isObject() && v.toObject().is<WeakRefObject>();
}
static bool
GetPrototypeFromWeakRefConstructor(JSContext* cx, HandleObject newTarget,
MutableHandleObject proto)
{
if (!GetPrototypeFromConstructor(cx, newTarget, proto))
return false;
if (proto)
return true;
RootedObject realmObject(cx, CheckedUnwrap(newTarget, /* stopAtWindowProxy = */ false));
if (!realmObject)
return false;
{
JSAutoCompartment ac(cx, realmObject);
Rooted<GlobalObject*> global(cx, &realmObject->global());
if (!GlobalObject::ensureConstructor(cx, global, JSProto_WeakRef))
return false;
proto.set(&global->getPrototype(JSProto_WeakRef).toObject());
}
return cx->compartment()->wrap(cx, proto);
}
static bool
WeakRef_deref_impl(JSContext* cx, const CallArgs& args)
{
@@ -155,7 +180,7 @@ WeakRefObject::construct(JSContext* cx, unsigned argc, Value* vp)
RootedObject proto(cx);
RootedObject newTarget(cx, &args.newTarget().toObject());
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
if (!GetPrototypeFromWeakRefConstructor(cx, newTarget, &proto))
return false;
Rooted<WeakRefObject*> obj(cx, WeakRefObject::create(cx, target, proto));
+58
View File
@@ -0,0 +1,58 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function assertThrowsTypeError(fn) {
try {
fn();
} catch (e) {
do_check_true(e instanceof TypeError);
return;
}
do_throw("expected TypeError");
}
add_task(function* test_weakref_api_surface() {
do_check_eq(typeof WeakRef, "function");
do_check_eq(WeakRef.name, "WeakRef");
do_check_eq(WeakRef.length, 1);
assertThrowsTypeError(() => WeakRef({}));
assertThrowsTypeError(() => new WeakRef(1));
assertThrowsTypeError(() => new WeakRef(Symbol.for("registered")));
let target = {};
let ref = new WeakRef(target);
do_check_eq(Object.prototype.toString.call(ref), "[object WeakRef]");
do_check_eq(ref.deref(), target);
do_check_eq(typeof WeakRef.prototype.deref, "function");
do_check_eq(WeakRef.prototype.deref.length, 0);
let desc = Object.getOwnPropertyDescriptor(WeakRef.prototype,
Symbol.toStringTag);
do_check_eq(desc.value, "WeakRef");
do_check_eq(desc.writable, false);
do_check_eq(desc.enumerable, false);
do_check_eq(desc.configurable, true);
});
add_task(function* test_newtarget_prototype_is_not_object() {
function newTarget() {}
for (let proto of [undefined, null, true, "", Symbol(), 1]) {
newTarget.prototype = proto;
let ref = Reflect.construct(WeakRef, [{}], newTarget);
do_check_true(Object.getPrototypeOf(ref) === WeakRef.prototype);
}
});
add_task(function* test_proto_from_constructor_realm() {
let other = new Components.utils.Sandbox("http://example.com", { freshZone: true });
Components.utils.evalInSandbox("var newTarget = new Function();", other);
for (let proto of [undefined, null, true, "", Symbol(), 1]) {
other.newTarget.prototype = proto;
let ref = Reflect.construct(WeakRef, [{}], other.newTarget);
do_check_true(Object.getPrototypeOf(ref) === other.WeakRef.prototype);
}
});
+1
View File
@@ -73,6 +73,7 @@ support-files =
[test_isModuleLoaded.js]
[test_finalization_registry.js]
[test_js_weak_references.js]
[test_weakref.js]
[test_onGarbageCollection-01.js]
head = head_ongc.js
[test_onGarbageCollection-02.js]