mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Bug 1379222 - Avoid [[Get]] for "prototype" property when calling builtin constructors. r=jandem
--HG-- extra : rebase_source : f2a369851a66b880eb693bdea8b53aafb0c1f00b
This commit is contained in:
parent
adabab920b
commit
b6817f5d89
@ -212,8 +212,7 @@ DataViewObject::constructSameCompartment(JSContext* cx, HandleObject bufobj, con
|
||||
return false;
|
||||
|
||||
RootedObject proto(cx);
|
||||
RootedObject newTarget(cx, &args.newTarget().toObject());
|
||||
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
Rooted<ArrayBufferObjectMaybeShared*> buffer(cx, &AsArrayBufferMaybeShared(bufobj));
|
||||
@ -257,8 +256,7 @@ DataViewObject::constructWrapped(JSContext* cx, HandleObject bufobj, const CallA
|
||||
// Make sure to get the [[Prototype]] for the created view from this
|
||||
// compartment.
|
||||
RootedObject proto(cx);
|
||||
RootedObject newTarget(cx, &args.newTarget().toObject());
|
||||
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
Rooted<GlobalObject*> global(cx, cx->compartment()->maybeGlobal());
|
||||
|
@ -989,7 +989,7 @@ Collator(JSContext* cx, const CallArgs& args)
|
||||
|
||||
// Steps 2-5 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
|
||||
RootedObject proto(cx);
|
||||
if (args.isConstructing() && !GetPrototypeFromCallableConstructor(cx, args, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
if (!proto) {
|
||||
@ -1557,7 +1557,7 @@ NumberFormat(JSContext* cx, const CallArgs& args, bool construct)
|
||||
|
||||
// Step 2 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
|
||||
RootedObject proto(cx);
|
||||
if (args.isConstructing() && !GetPrototypeFromCallableConstructor(cx, args, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
if (!proto) {
|
||||
@ -2432,7 +2432,7 @@ DateTimeFormat(JSContext* cx, const CallArgs& args, bool construct, DateTimeForm
|
||||
|
||||
// Step 2 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
|
||||
RootedObject proto(cx);
|
||||
if (args.isConstructing() && !GetPrototypeFromCallableConstructor(cx, args, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
if (!proto) {
|
||||
@ -3540,7 +3540,7 @@ PluralRules(JSContext* cx, unsigned argc, Value* vp)
|
||||
|
||||
// Step 2 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
|
||||
RootedObject proto(cx);
|
||||
if (!GetPrototypeFromCallableConstructor(cx, args, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
if (!proto) {
|
||||
|
@ -564,8 +564,7 @@ MapObject::construct(JSContext* cx, unsigned argc, Value* vp)
|
||||
return false;
|
||||
|
||||
RootedObject proto(cx);
|
||||
RootedObject newTarget(cx, &args.newTarget().toObject());
|
||||
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
Rooted<MapObject*> obj(cx, MapObject::create(cx, proto));
|
||||
@ -1168,8 +1167,7 @@ SetObject::construct(JSContext* cx, unsigned argc, Value* vp)
|
||||
return false;
|
||||
|
||||
RootedObject proto(cx);
|
||||
RootedObject newTarget(cx, &args.newTarget().toObject());
|
||||
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
Rooted<SetObject*> obj(cx, SetObject::create(cx, proto));
|
||||
|
@ -1291,7 +1291,6 @@ PromiseConstructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
|
||||
// Steps 3-10.
|
||||
RootedObject newTarget(cx, &args.newTarget().toObject());
|
||||
RootedObject originalNewTarget(cx, newTarget);
|
||||
bool needsWrapping = false;
|
||||
|
||||
// If the constructor is called via an Xray wrapper, then the newTarget
|
||||
@ -1322,9 +1321,11 @@ PromiseConstructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
// Promises, with the unprivileged one resolved with the resolution of the
|
||||
// privileged one.
|
||||
if (IsWrapper(newTarget)) {
|
||||
newTarget = CheckedUnwrap(newTarget);
|
||||
MOZ_ASSERT(newTarget);
|
||||
MOZ_ASSERT(newTarget != originalNewTarget);
|
||||
JSObject* unwrappedNewTarget = CheckedUnwrap(newTarget);
|
||||
MOZ_ASSERT(unwrappedNewTarget);
|
||||
MOZ_ASSERT(unwrappedNewTarget != newTarget);
|
||||
|
||||
newTarget = unwrappedNewTarget;
|
||||
{
|
||||
AutoCompartment ac(cx, newTarget);
|
||||
RootedObject promiseCtor(cx);
|
||||
@ -1340,10 +1341,15 @@ PromiseConstructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
}
|
||||
|
||||
RootedObject proto(cx);
|
||||
if (!GetPrototypeFromConstructor(cx, needsWrapping ? newTarget : originalNewTarget, &proto))
|
||||
return false;
|
||||
if (needsWrapping && !cx->compartment()->wrap(cx, &proto))
|
||||
return false;
|
||||
if (needsWrapping) {
|
||||
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
|
||||
return false;
|
||||
if (!cx->compartment()->wrap(cx, &proto))
|
||||
return false;
|
||||
} else {
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
}
|
||||
Rooted<PromiseObject*> promise(cx, PromiseObject::create(cx, executor, proto, needsWrapping));
|
||||
if (!promise)
|
||||
return false;
|
||||
|
@ -399,7 +399,7 @@ js::regexp_construct(JSContext* cx, unsigned argc, Value* vp)
|
||||
return false;
|
||||
|
||||
// We can delay step 3 and step 4a until later, during
|
||||
// GetPrototypeFromCallableConstructor calls. Accessing the new.target
|
||||
// GetPrototypeFromBuiltinConstructor calls. Accessing the new.target
|
||||
// and the callee from the stack is unobservable.
|
||||
if (!args.isConstructing()) {
|
||||
// Step 3.b.
|
||||
@ -447,7 +447,7 @@ js::regexp_construct(JSContext* cx, unsigned argc, Value* vp)
|
||||
|
||||
// Step 7.
|
||||
RootedObject proto(cx);
|
||||
if (!GetPrototypeFromCallableConstructor(cx, args, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, GenericObject, proto));
|
||||
@ -506,7 +506,7 @@ js::regexp_construct(JSContext* cx, unsigned argc, Value* vp)
|
||||
|
||||
// Step 7.
|
||||
RootedObject proto(cx);
|
||||
if (!GetPrototypeFromCallableConstructor(cx, args, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, GenericObject, proto));
|
||||
|
@ -291,8 +291,11 @@ WeakMap_construct(JSContext* cx, unsigned argc, Value* vp)
|
||||
if (!ThrowIfNotConstructing(cx, args, "WeakMap"))
|
||||
return false;
|
||||
|
||||
RootedObject newTarget(cx, &args.newTarget().toObject());
|
||||
RootedObject obj(cx, CreateThis(cx, &WeakMapObject::class_, newTarget));
|
||||
RootedObject proto(cx);
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
RootedObject obj(cx, NewObjectWithClassProto<WeakMapObject>(cx, proto));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
|
@ -93,8 +93,7 @@ WeakSetObject::construct(JSContext* cx, unsigned argc, Value* vp)
|
||||
return false;
|
||||
|
||||
RootedObject proto(cx);
|
||||
RootedObject newTarget(cx, &args.newTarget().toObject());
|
||||
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
Rooted<WeakSetObject*> obj(cx, WeakSetObject::create(cx, proto));
|
||||
|
@ -3515,7 +3515,7 @@ ArrayConstructorImpl(JSContext* cx, CallArgs& args, bool isConstructor)
|
||||
{
|
||||
RootedObject proto(cx);
|
||||
if (isConstructor) {
|
||||
if (!GetPrototypeFromCallableConstructor(cx, args, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
} else {
|
||||
// We're emulating |new Array(n)| with |std_Array(n)| in self-hosted JS,
|
||||
|
@ -117,10 +117,8 @@ Boolean(JSContext* cx, unsigned argc, Value* vp)
|
||||
bool b = args.length() != 0 ? JS::ToBoolean(args[0]) : false;
|
||||
|
||||
if (args.isConstructing()) {
|
||||
RootedObject newTarget (cx, &args.newTarget().toObject());
|
||||
RootedObject proto(cx);
|
||||
|
||||
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
JSObject* obj = BooleanObject::create(cx, b, proto);
|
||||
|
@ -3095,8 +3095,7 @@ NewDateObject(JSContext* cx, const CallArgs& args, ClippedTime t)
|
||||
MOZ_ASSERT(args.isConstructing());
|
||||
|
||||
RootedObject proto(cx);
|
||||
RootedObject newTarget(cx, &args.newTarget().toObject());
|
||||
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
JSObject* obj = NewDateObjectMsec(cx, t, proto);
|
||||
|
@ -442,7 +442,7 @@ Error(JSContext* cx, unsigned argc, Value* vp)
|
||||
|
||||
// ES6 19.5.1.1 mandates the .prototype lookup happens before the toString
|
||||
RootedObject proto(cx);
|
||||
if (!GetPrototypeFromCallableConstructor(cx, args, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
/* Compute the error message, if any. */
|
||||
|
@ -1884,7 +1884,7 @@ FunctionConstructor(JSContext* cx, const CallArgs& args, GeneratorKind generator
|
||||
// Step 24.
|
||||
RootedObject proto(cx);
|
||||
if (!isAsync) {
|
||||
if (!GetPrototypeFromCallableConstructor(cx, args, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -496,25 +496,25 @@ Number(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
/* Sample JS_CALLEE before clobbering. */
|
||||
bool isConstructing = args.isConstructing();
|
||||
|
||||
if (args.length() > 0) {
|
||||
if (!ToNumber(cx, args[0]))
|
||||
return false;
|
||||
args.rval().set(args[0]);
|
||||
} else {
|
||||
args.rval().setInt32(0);
|
||||
}
|
||||
|
||||
if (!isConstructing)
|
||||
if (!args.isConstructing()) {
|
||||
if (args.length() > 0)
|
||||
args.rval().set(args[0]);
|
||||
else
|
||||
args.rval().setInt32(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
RootedObject newTarget(cx, &args.newTarget().toObject());
|
||||
RootedObject proto(cx);
|
||||
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
JSObject* obj = NumberObject::create(cx, args.rval().toNumber(), proto);
|
||||
|
||||
double d = args.length() > 0 ? args[0].toNumber() : 0;
|
||||
JSObject* obj = NumberObject::create(cx, d, proto);
|
||||
if (!obj)
|
||||
return false;
|
||||
args.rval().setObject(*obj);
|
||||
|
@ -1002,17 +1002,6 @@ js::GetPrototypeFromConstructor(JSContext* cx, HandleObject newTarget, MutableHa
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::GetPrototypeFromCallableConstructor(JSContext* cx, const CallArgs& args, MutableHandleObject proto)
|
||||
{
|
||||
RootedObject newTarget(cx);
|
||||
if (args.isConstructing())
|
||||
newTarget = &args.newTarget().toObject();
|
||||
else
|
||||
newTarget = &args.callee();
|
||||
return GetPrototypeFromConstructor(cx, newTarget, proto);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
js::CreateThisForFunction(JSContext* cx, HandleObject callee, HandleObject newTarget,
|
||||
NewObjectKind newKind)
|
||||
|
@ -1152,8 +1152,21 @@ NewObjectWithTaggedProtoIsCachable(JSContext* cx, Handle<TaggedProto> proto,
|
||||
extern bool
|
||||
GetPrototypeFromConstructor(JSContext* cx, js::HandleObject newTarget, js::MutableHandleObject proto);
|
||||
|
||||
extern bool
|
||||
GetPrototypeFromCallableConstructor(JSContext* cx, const CallArgs& args, js::MutableHandleObject proto);
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
GetPrototypeFromBuiltinConstructor(JSContext* cx, const CallArgs& args, js::MutableHandleObject proto)
|
||||
{
|
||||
// When proto is set to nullptr, the caller is expected to select the
|
||||
// correct default built-in prototype for this constructor.
|
||||
if (!args.isConstructing() || &args.newTarget().toObject() == &args.callee()) {
|
||||
proto.set(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
// We're calling this constructor from a derived class, retrieve the
|
||||
// actual prototype from newTarget.
|
||||
RootedObject newTarget(cx, &args.newTarget().toObject());
|
||||
return GetPrototypeFromConstructor(cx, newTarget, proto);
|
||||
}
|
||||
|
||||
// Specialized call for constructing |this| with a known function callee,
|
||||
// and a known prototype.
|
||||
|
@ -3209,8 +3209,7 @@ js::StringConstructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
|
||||
if (args.isConstructing()) {
|
||||
RootedObject proto(cx);
|
||||
RootedObject newTarget(cx, &args.newTarget().toObject());
|
||||
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
StringObject* strobj = StringObject::create(cx, str, proto);
|
||||
|
@ -285,8 +285,7 @@ ArrayBufferObject::class_constructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
// Step 3 (Inlined 24.1.1.1 AllocateArrayBuffer).
|
||||
// 24.1.1.1, step 1 (Inlined 9.1.14 OrdinaryCreateFromConstructor).
|
||||
RootedObject proto(cx);
|
||||
RootedObject newTarget(cx, &args.newTarget().toObject());
|
||||
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
// 24.1.1.1, step 3 (Inlined 6.2.6.1 CreateByteDataBlock, step 2).
|
||||
|
@ -273,8 +273,7 @@ SharedArrayBufferObject::class_constructor(JSContext* cx, unsigned argc, Value*
|
||||
// Step 3 (Inlined 24.2.1.1 AllocateSharedArrayBuffer).
|
||||
// 24.2.1.1, step 1 (Inlined 9.1.14 OrdinaryCreateFromConstructor).
|
||||
RootedObject proto(cx);
|
||||
RootedObject newTarget(cx, &args.newTarget().toObject());
|
||||
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
// 24.2.1.1, step 3 (Inlined 6.2.7.2 CreateSharedByteDataBlock, step 2).
|
||||
|
@ -321,20 +321,6 @@ NewArray(JSContext* cx, uint32_t nelements);
|
||||
|
||||
namespace {
|
||||
|
||||
// We allow nullptr for newTarget for all the creation methods, to allow for
|
||||
// JSFriendAPI functions that don't care about subclassing
|
||||
static bool
|
||||
GetPrototypeForInstance(JSContext* cx, HandleObject newTarget, MutableHandleObject proto)
|
||||
{
|
||||
if (newTarget) {
|
||||
if (!GetPrototypeFromConstructor(cx, newTarget, proto))
|
||||
return false;
|
||||
} else {
|
||||
proto.set(nullptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
enum class SpeciesConstructorOverride {
|
||||
None,
|
||||
ArrayBuffer
|
||||
@ -472,7 +458,7 @@ class TypedArrayObjectTemplate : public TypedArrayObject
|
||||
// the time, though, that [[Prototype]] will not be interesting. If
|
||||
// it isn't, we can do some more TI optimizations.
|
||||
RootedObject checkProto(cx);
|
||||
if (!GetBuiltinPrototype(cx, JSCLASS_CACHED_PROTO_KEY(instanceClass()), &checkProto))
|
||||
if (proto && !GetBuiltinPrototype(cx, JSCLASS_CACHED_PROTO_KEY(instanceClass()), &checkProto))
|
||||
return nullptr;
|
||||
|
||||
AutoSetNewObjectMetadata metadata(cx);
|
||||
@ -724,24 +710,30 @@ class TypedArrayObjectTemplate : public TypedArrayObject
|
||||
if (!ToIndex(cx, args.get(0), JSMSG_BAD_ARRAY_LENGTH, &len))
|
||||
return nullptr;
|
||||
|
||||
return fromLength(cx, len, newTarget);
|
||||
// 22.2.4.1, step 3 and 22.2.4.2, step 5.
|
||||
// 22.2.4.2.1 AllocateTypedArray, step 1.
|
||||
RootedObject proto(cx);
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return nullptr;
|
||||
|
||||
return fromLength(cx, len, proto);
|
||||
}
|
||||
|
||||
RootedObject dataObj(cx, &args[0].toObject());
|
||||
|
||||
// 22.2.4.{3,4,5}, step 4.
|
||||
// 22.2.4.2.1 AllocateTypedArray, step 1.
|
||||
RootedObject proto(cx);
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
|
||||
return nullptr;
|
||||
|
||||
// 22.2.4.3 TypedArray ( typedArray )
|
||||
// 22.2.4.4 TypedArray ( object )
|
||||
if (!UncheckedUnwrap(dataObj)->is<ArrayBufferObjectMaybeShared>())
|
||||
return fromArray(cx, dataObj, newTarget);
|
||||
return fromArray(cx, dataObj, proto);
|
||||
|
||||
// 22.2.4.5 TypedArray ( buffer [ , byteOffset [ , length ] ] )
|
||||
|
||||
// Step 4.
|
||||
// 22.2.4.2.1 AllocateTypedArray, step 1.
|
||||
RootedObject proto(cx);
|
||||
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
|
||||
return nullptr;
|
||||
|
||||
uint64_t byteOffset = 0;
|
||||
if (args.hasDefined(1)) {
|
||||
// Step 6.
|
||||
@ -966,16 +958,11 @@ class TypedArrayObjectTemplate : public TypedArrayObject
|
||||
// 22.2.4.1 TypedArray ( )
|
||||
// 22.2.4.2 TypedArray ( length )
|
||||
static JSObject*
|
||||
fromLength(JSContext* cx, uint64_t nelements, HandleObject newTarget = nullptr)
|
||||
fromLength(JSContext* cx, uint64_t nelements, HandleObject proto = nullptr)
|
||||
{
|
||||
// 22.2.4.1, step 1 and 22.2.4.2, steps 1-3 (performed in caller).
|
||||
// 22.2.4.1, step 2 and 22.2.4.2, step 4 (implicit).
|
||||
|
||||
// 22.2.4.1, step 3 and 22.2.4.2, step 5.
|
||||
// 22.2.4.2.1 AllocateTypedArray, step 1.
|
||||
RootedObject proto(cx);
|
||||
if (!GetPrototypeForInstance(cx, newTarget, &proto))
|
||||
return nullptr;
|
||||
// 22.2.4.1, step 3 and 22.2.4.2, step 5 (call AllocateTypedArray).
|
||||
|
||||
if (nelements > UINT32_MAX) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_ARRAY_LENGTH);
|
||||
@ -1001,13 +988,13 @@ class TypedArrayObjectTemplate : public TypedArrayObject
|
||||
MutableHandle<ArrayBufferObject*> buffer);
|
||||
|
||||
static JSObject*
|
||||
fromArray(JSContext* cx, HandleObject other, HandleObject newTarget = nullptr);
|
||||
fromArray(JSContext* cx, HandleObject other, HandleObject proto = nullptr);
|
||||
|
||||
static JSObject*
|
||||
fromTypedArray(JSContext* cx, HandleObject other, bool isWrapped, HandleObject newTarget);
|
||||
fromTypedArray(JSContext* cx, HandleObject other, bool isWrapped, HandleObject proto);
|
||||
|
||||
static JSObject*
|
||||
fromObject(JSContext* cx, HandleObject other, HandleObject newTarget);
|
||||
fromObject(JSContext* cx, HandleObject other, HandleObject proto);
|
||||
|
||||
static const NativeType
|
||||
getIndex(JSObject* obj, uint32_t index)
|
||||
@ -1190,17 +1177,17 @@ TypedArrayObjectTemplate<T>::CloneArrayBufferNoCopy(JSContext* cx,
|
||||
template<typename T>
|
||||
/* static */ JSObject*
|
||||
TypedArrayObjectTemplate<T>::fromArray(JSContext* cx, HandleObject other,
|
||||
HandleObject newTarget /* = nullptr */)
|
||||
HandleObject proto /* = nullptr */)
|
||||
{
|
||||
// Allow nullptr newTarget for FriendAPI methods, which don't care about
|
||||
// Allow nullptr proto for FriendAPI methods, which don't care about
|
||||
// subclassing.
|
||||
if (other->is<TypedArrayObject>())
|
||||
return fromTypedArray(cx, other, /* wrapped= */ false, newTarget);
|
||||
return fromTypedArray(cx, other, /* wrapped= */ false, proto);
|
||||
|
||||
if (other->is<WrapperObject>() && UncheckedUnwrap(other)->is<TypedArrayObject>())
|
||||
return fromTypedArray(cx, other, /* wrapped= */ true, newTarget);
|
||||
return fromTypedArray(cx, other, /* wrapped= */ true, proto);
|
||||
|
||||
return fromObject(cx, other, newTarget);
|
||||
return fromObject(cx, other, proto);
|
||||
}
|
||||
|
||||
// ES2017 draft rev 6390c2f1b34b309895d31d8c0512eac8660a0210
|
||||
@ -1208,7 +1195,7 @@ TypedArrayObjectTemplate<T>::fromArray(JSContext* cx, HandleObject other,
|
||||
template<typename T>
|
||||
/* static */ JSObject*
|
||||
TypedArrayObjectTemplate<T>::fromTypedArray(JSContext* cx, HandleObject other, bool isWrapped,
|
||||
HandleObject newTarget)
|
||||
HandleObject proto)
|
||||
{
|
||||
// Step 1.
|
||||
MOZ_ASSERT_IF(!isWrapped, other->is<TypedArrayObject>());
|
||||
@ -1216,12 +1203,9 @@ TypedArrayObjectTemplate<T>::fromTypedArray(JSContext* cx, HandleObject other, b
|
||||
other->is<WrapperObject>() &&
|
||||
UncheckedUnwrap(other)->is<TypedArrayObject>());
|
||||
|
||||
// Step 2 (done in caller).
|
||||
// Step 2 (Already performed in caller).
|
||||
|
||||
// Step 4 (partially).
|
||||
RootedObject proto(cx);
|
||||
if (!GetPrototypeForInstance(cx, newTarget, &proto))
|
||||
return nullptr;
|
||||
// Step 4 (Allocation deferred until later).
|
||||
|
||||
// Step 5.
|
||||
Rooted<TypedArrayObject*> srcArray(cx);
|
||||
@ -1335,14 +1319,11 @@ IsOptimizableInit(JSContext* cx, HandleObject iterable, bool* optimized)
|
||||
// 22.2.4.4 TypedArray ( object )
|
||||
template<typename T>
|
||||
/* static */ JSObject*
|
||||
TypedArrayObjectTemplate<T>::fromObject(JSContext* cx, HandleObject other, HandleObject newTarget)
|
||||
TypedArrayObjectTemplate<T>::fromObject(JSContext* cx, HandleObject other, HandleObject proto)
|
||||
{
|
||||
// Steps 1-2 (Already performed in caller).
|
||||
|
||||
// Steps 3-4 (Allocation deferred until later).
|
||||
RootedObject proto(cx);
|
||||
if (!GetPrototypeForInstance(cx, newTarget, &proto))
|
||||
return nullptr;
|
||||
|
||||
bool optimized = false;
|
||||
if (!IsOptimizableInit(cx, other, &optimized))
|
||||
|
Loading…
Reference in New Issue
Block a user