mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 22:32:51 +00:00
Bug 1723715 part 13 - Move builtin constructors to GlobalObjectData. r=jonco
This replaces the JS_OFF_THREAD_CONSTRUCTOR MagicValue for off-thread constructors with the same placeholder object we use for the prototype. These constructors aren't used by off-thread parsing and handling this another way requires a lot of complexity. With Stencil work the off-thread global will hopefully be removed eventually. Differential Revision: https://phabricator.services.mozilla.com/D121993
This commit is contained in:
parent
12961aecf7
commit
6ad790bd22
@ -572,7 +572,7 @@ static const uint32_t JSCLASS_FOREGROUND_FINALIZE =
|
||||
// application.
|
||||
static const uint32_t JSCLASS_GLOBAL_APPLICATION_SLOTS = 5;
|
||||
static const uint32_t JSCLASS_GLOBAL_SLOT_COUNT =
|
||||
JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 2;
|
||||
JSCLASS_GLOBAL_APPLICATION_SLOTS + 2;
|
||||
|
||||
static constexpr uint32_t JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(uint32_t n) {
|
||||
return JSCLASS_IS_GLOBAL |
|
||||
|
@ -241,9 +241,6 @@ enum JSWhyMagic {
|
||||
/** arguments object can't be created because environment is dead. */
|
||||
JS_MISSING_ARGUMENTS,
|
||||
|
||||
/** standard constructors are not created for off-thread parsing. */
|
||||
JS_OFF_THREAD_CONSTRUCTOR,
|
||||
|
||||
/** for local use */
|
||||
JS_GENERIC_MAGIC,
|
||||
|
||||
|
@ -4044,12 +4044,10 @@ void js::ArraySpeciesLookup::initialize(JSContext* cx) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the canonical Array constructor.
|
||||
const Value& arrayCtorValue = cx->global()->getConstructor(JSProto_Array);
|
||||
MOZ_ASSERT(arrayCtorValue.isObject(),
|
||||
"The Array constructor is initialized iff Array.prototype is "
|
||||
"initialized");
|
||||
JSFunction* arrayCtor = &arrayCtorValue.toObject().as<JSFunction>();
|
||||
// Get the canonical Array constructor. The Array constructor must be
|
||||
// initialized if Array.prototype is initialized.
|
||||
JSObject& arrayCtorObject = cx->global()->getConstructor(JSProto_Array);
|
||||
JSFunction* arrayCtor = &arrayCtorObject.as<JSFunction>();
|
||||
|
||||
// Shortcut returns below means Array[@@species] will never be
|
||||
// optimizable, set to disabled now, and clear it later when we succeed.
|
||||
|
@ -6730,7 +6730,8 @@ extern JS_PUBLIC_API bool JS_DefineDebuggerObject(JSContext* cx,
|
||||
if (!debuggeeWouldRunProto) {
|
||||
return false;
|
||||
}
|
||||
debuggeeWouldRunCtor = global->getConstructor(JSProto_DebuggeeWouldRun);
|
||||
debuggeeWouldRunCtor =
|
||||
ObjectValue(global->getConstructor(JSProto_DebuggeeWouldRun));
|
||||
RootedId debuggeeWouldRunId(
|
||||
cx, NameToId(ClassName(JSProto_DebuggeeWouldRun, cx)));
|
||||
if (!DefineDataProperty(cx, debugCtor, debuggeeWouldRunId,
|
||||
|
@ -4626,8 +4626,8 @@ AttachDecision InstanceOfIRGenerator::tryAttachStub() {
|
||||
return AttachDecision::NoAction;
|
||||
}
|
||||
|
||||
Value funProto = cx_->global()->getPrototype(JSProto_Function);
|
||||
if (hasInstanceHolder != &funProto.toObject()) {
|
||||
JSObject& funProto = cx_->global()->getPrototype(JSProto_Function);
|
||||
if (hasInstanceHolder != &funProto) {
|
||||
trackAttached(IRGenerator::NotAttached);
|
||||
return AttachDecision::NoAction;
|
||||
}
|
||||
|
@ -7940,8 +7940,8 @@ static bool GetSharedObject(JSContext* cx, unsigned argc, Value* vp) {
|
||||
JSProto_WebAssembly)) {
|
||||
return false;
|
||||
}
|
||||
RootedObject proto(
|
||||
cx, &cx->global()->getPrototype(JSProto_WasmMemory).toObject());
|
||||
RootedObject proto(cx,
|
||||
&cx->global()->getPrototype(JSProto_WasmMemory));
|
||||
newObj = WasmMemoryObject::create(cx, maybesab, proto);
|
||||
MOZ_ASSERT_IF(newObj, newObj->as<WasmMemoryObject>().isShared());
|
||||
if (!newObj) {
|
||||
|
@ -274,8 +274,7 @@ bool GlobalObject::resolveConstructor(JSContext* cx,
|
||||
// for Function, which is a problem. So if Function is being resolved
|
||||
// before Object.prototype exists, we just resolve Object instead, since we
|
||||
// know that Function will also be resolved before we return.
|
||||
if (key == JSProto_Function &&
|
||||
global->getPrototype(JSProto_Object).isUndefined()) {
|
||||
if (key == JSProto_Function && !global->hasPrototype(JSProto_Object)) {
|
||||
return resolveConstructor(cx, global, JSProto_Object,
|
||||
IfClassIsDisabled::DoNothing);
|
||||
}
|
||||
@ -316,7 +315,7 @@ bool GlobalObject::resolveConstructor(JSContext* cx,
|
||||
// criteria that protects entry into this function.
|
||||
MOZ_ASSERT(!global->isStandardClassResolved(key));
|
||||
|
||||
global->setPrototype(key, ObjectValue(*proto));
|
||||
global->setPrototype(key, proto);
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,7 +334,7 @@ bool GlobalObject::resolveConstructor(JSContext* cx,
|
||||
}
|
||||
}
|
||||
|
||||
global->setConstructor(key, ObjectValue(*ctor));
|
||||
global->setConstructor(key, ctor);
|
||||
}
|
||||
|
||||
if (const JSFunctionSpec* funs = clasp->specPrototypeFunctions()) {
|
||||
@ -403,9 +402,9 @@ bool GlobalObject::resolveConstructor(JSContext* cx,
|
||||
}
|
||||
|
||||
// Infallible operations that modify the global object.
|
||||
global->setConstructor(key, ObjectValue(*ctor));
|
||||
global->setConstructor(key, ctor);
|
||||
if (proto) {
|
||||
global->setPrototype(key, ObjectValue(*proto));
|
||||
global->setPrototype(key, proto);
|
||||
}
|
||||
}
|
||||
|
||||
@ -476,7 +475,7 @@ const JSClass GlobalObject::OffThreadPlaceholderObject::class_ = {
|
||||
"off-thread-prototype-placeholder", JSCLASS_HAS_RESERVED_SLOTS(1)};
|
||||
|
||||
/* static */ GlobalObject::OffThreadPlaceholderObject*
|
||||
GlobalObject::OffThreadPlaceholderObject::New(JSContext* cx, unsigned slot) {
|
||||
GlobalObject::OffThreadPlaceholderObject::New(JSContext* cx, JSProtoKey key) {
|
||||
Rooted<OffThreadPlaceholderObject*> placeholder(cx);
|
||||
placeholder =
|
||||
NewObjectWithGivenProto<OffThreadPlaceholderObject>(cx, nullptr);
|
||||
@ -484,7 +483,7 @@ GlobalObject::OffThreadPlaceholderObject::New(JSContext* cx, unsigned slot) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
placeholder->setReservedSlot(SlotIndexOrProtoKindSlot, Int32Value(slot));
|
||||
placeholder->setReservedSlot(ProtoKeyOrProtoKindSlot, Int32Value(key));
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
@ -497,14 +496,14 @@ GlobalObject::OffThreadPlaceholderObject::New(JSContext* cx, ProtoKind kind) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
placeholder->setReservedSlot(SlotIndexOrProtoKindSlot,
|
||||
placeholder->setReservedSlot(ProtoKeyOrProtoKindSlot,
|
||||
Int32Value(-int32_t(kind)));
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
inline int32_t
|
||||
GlobalObject::OffThreadPlaceholderObject::getSlotIndexOrProtoKind() const {
|
||||
return getReservedSlot(SlotIndexOrProtoKindSlot).toInt32();
|
||||
GlobalObject::OffThreadPlaceholderObject::getProtoKeyOrProtoKind() const {
|
||||
return getReservedSlot(ProtoKeyOrProtoKindSlot).toInt32();
|
||||
}
|
||||
|
||||
/* static */
|
||||
@ -523,7 +522,7 @@ bool GlobalObject::resolveOffThreadConstructor(JSContext* cx,
|
||||
key == JSProto_AsyncGeneratorFunction);
|
||||
|
||||
Rooted<OffThreadPlaceholderObject*> placeholder(cx);
|
||||
placeholder = OffThreadPlaceholderObject::New(cx, prototypeSlot(key));
|
||||
placeholder = OffThreadPlaceholderObject::New(cx, key);
|
||||
if (!placeholder) {
|
||||
return false;
|
||||
}
|
||||
@ -533,8 +532,11 @@ bool GlobalObject::resolveOffThreadConstructor(JSContext* cx,
|
||||
return false;
|
||||
}
|
||||
|
||||
global->setPrototype(key, ObjectValue(*placeholder));
|
||||
global->setConstructor(key, MagicValue(JS_OFF_THREAD_CONSTRUCTOR));
|
||||
// Use the placeholder for both constructor and prototype. The constructor
|
||||
// isn't used off-thread, but we need to initialize both at the same time to
|
||||
// satisfy invariants.
|
||||
global->setPrototype(key, placeholder);
|
||||
global->setConstructor(key, placeholder);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -563,9 +565,10 @@ JSObject* GlobalObject::createOffThreadBuiltinProto(
|
||||
|
||||
JSObject* GlobalObject::getPrototypeForOffThreadPlaceholder(JSObject* obj) {
|
||||
auto placeholder = &obj->as<OffThreadPlaceholderObject>();
|
||||
int32_t value = placeholder->getSlotIndexOrProtoKind();
|
||||
int32_t value = placeholder->getProtoKeyOrProtoKind();
|
||||
if (value >= 0) {
|
||||
return &getSlot(value).toObject();
|
||||
MOZ_ASSERT(value < int32_t(JSProto_LIMIT));
|
||||
return &getPrototype(JSProtoKey(value));
|
||||
}
|
||||
MOZ_ASSERT(-value < int32_t(ProtoKind::Limit));
|
||||
return &getBuiltinProto(ProtoKind(-value));
|
||||
@ -589,8 +592,8 @@ bool GlobalObject::initBuiltinConstructor(JSContext* cx,
|
||||
return false;
|
||||
}
|
||||
|
||||
global->setConstructor(key, ObjectValue(*ctor));
|
||||
global->setPrototype(key, ObjectValue(*proto));
|
||||
global->setConstructor(key, ctor);
|
||||
global->setPrototype(key, proto);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1126,7 +1129,7 @@ JSObject* GlobalObject::createIteratorPrototype(JSContext* cx,
|
||||
if (!ensureConstructor(cx, global, JSProto_Iterator)) {
|
||||
return nullptr;
|
||||
}
|
||||
JSObject* proto = &global->getPrototype(JSProto_Iterator).toObject();
|
||||
JSObject* proto = &global->getPrototype(JSProto_Iterator);
|
||||
global->initBuiltinProto(ProtoKind::IteratorProto, proto);
|
||||
return proto;
|
||||
}
|
||||
@ -1142,7 +1145,7 @@ JSObject* GlobalObject::createAsyncIteratorPrototype(
|
||||
if (!ensureConstructor(cx, global, JSProto_AsyncIterator)) {
|
||||
return nullptr;
|
||||
}
|
||||
JSObject* proto = &global->getPrototype(JSProto_AsyncIterator).toObject();
|
||||
JSObject* proto = &global->getPrototype(JSProto_AsyncIterator);
|
||||
global->initBuiltinProto(ProtoKind::AsyncIteratorProto, proto);
|
||||
return proto;
|
||||
}
|
||||
@ -1154,6 +1157,12 @@ void GlobalObject::releaseData(JSFreeOp* fop) {
|
||||
}
|
||||
|
||||
void GlobalObjectData::trace(JSTracer* trc) {
|
||||
for (auto& ctorWithProto : builtinConstructors) {
|
||||
TraceNullableEdge(trc, &ctorWithProto.constructor, "global-builtin-ctor");
|
||||
TraceNullableEdge(trc, &ctorWithProto.prototype,
|
||||
"global-builtin-ctor-proto");
|
||||
}
|
||||
|
||||
for (auto& proto : builtinProtos) {
|
||||
TraceNullableEdge(trc, &proto, "global-builtin-proto");
|
||||
}
|
||||
|
@ -68,6 +68,21 @@ class GlobalObjectData {
|
||||
public:
|
||||
GlobalObjectData() = default;
|
||||
|
||||
// The original values for built-in constructors (with their prototype
|
||||
// objects) based on JSProtoKey.
|
||||
//
|
||||
// This is necessary to implement spec language speaking in terms of "the
|
||||
// original Array prototype object", or "as if by the expression new Array()"
|
||||
// referring to the original Array constructor. The actual (writable and even
|
||||
// deletable) Object, Array, &c. properties are not stored here.
|
||||
struct ConstructorWithProto {
|
||||
HeapPtr<JSObject*> constructor;
|
||||
HeapPtr<JSObject*> prototype;
|
||||
};
|
||||
using CtorArray =
|
||||
mozilla::EnumeratedArray<JSProtoKey, JSProto_LIMIT, ConstructorWithProto>;
|
||||
CtorArray builtinConstructors;
|
||||
|
||||
// Built-in prototypes for this global. Note that this is different from the
|
||||
// set of built-in constructors/prototypes based on JSProtoKey.
|
||||
enum class ProtoKind {
|
||||
@ -159,15 +174,8 @@ class GlobalObject : public NativeObject {
|
||||
/* Count of slots set aside for application use. */
|
||||
static const unsigned APPLICATION_SLOTS = JSCLASS_GLOBAL_APPLICATION_SLOTS;
|
||||
|
||||
/*
|
||||
* Count of slots to store built-in prototypes and initial visible
|
||||
* properties for the constructors.
|
||||
*/
|
||||
static const unsigned STANDARD_CLASS_SLOTS = JSProto_LIMIT * 2;
|
||||
|
||||
enum : unsigned {
|
||||
/* One-off properties stored after slots for built-ins. */
|
||||
GLOBAL_DATA_SLOT = APPLICATION_SLOTS + STANDARD_CLASS_SLOTS,
|
||||
GLOBAL_DATA_SLOT = APPLICATION_SLOTS,
|
||||
WINDOW_PROXY,
|
||||
|
||||
/* Total reserved-slot count for global objects. */
|
||||
@ -184,16 +192,6 @@ class GlobalObject : public NativeObject {
|
||||
|
||||
using ProtoKind = GlobalObjectData::ProtoKind;
|
||||
|
||||
static unsigned constructorSlot(JSProtoKey key) {
|
||||
MOZ_ASSERT(key < JSProto_LIMIT);
|
||||
return APPLICATION_SLOTS + key;
|
||||
}
|
||||
|
||||
static unsigned prototypeSlot(JSProtoKey key) {
|
||||
MOZ_ASSERT(key < JSProto_LIMIT);
|
||||
return APPLICATION_SLOTS + JSProto_LIMIT + key;
|
||||
}
|
||||
|
||||
GlobalObjectData* maybeData() {
|
||||
Value v = getReservedSlot(GLOBAL_DATA_SLOT);
|
||||
return static_cast<GlobalObjectData*>(v.toPrivate());
|
||||
@ -237,9 +235,14 @@ class GlobalObject : public NativeObject {
|
||||
data().eval.init(evalFun);
|
||||
}
|
||||
|
||||
Value getConstructor(JSProtoKey key) const {
|
||||
return getReservedSlot(constructorSlot(key));
|
||||
bool hasConstructor(JSProtoKey key) const {
|
||||
return bool(data().builtinConstructors[key].constructor);
|
||||
}
|
||||
JSObject& getConstructor(JSProtoKey key) const {
|
||||
MOZ_ASSERT(hasConstructor(key));
|
||||
return *maybeGetConstructor(key);
|
||||
}
|
||||
|
||||
static bool skipDeselectedConstructor(JSContext* cx, JSProtoKey key);
|
||||
static bool initBuiltinConstructor(JSContext* cx,
|
||||
Handle<GlobalObject*> global,
|
||||
@ -267,7 +270,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!GlobalObject::ensureConstructor(cx, global, key)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getConstructor(key).toObject();
|
||||
return &global->getConstructor(key);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreatePrototype(JSContext* cx, JSProtoKey key) {
|
||||
@ -276,61 +279,60 @@ class GlobalObject : public NativeObject {
|
||||
if (!GlobalObject::ensureConstructor(cx, global, key)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(key).toObject();
|
||||
return &global->getPrototype(key);
|
||||
}
|
||||
|
||||
JSObject* maybeGetConstructor(JSProtoKey protoKey) const {
|
||||
MOZ_ASSERT(JSProto_Null < protoKey);
|
||||
MOZ_ASSERT(protoKey < JSProto_LIMIT);
|
||||
const Value& v = getConstructor(protoKey);
|
||||
return v.isObject() ? &v.toObject() : nullptr;
|
||||
return data().builtinConstructors[protoKey].constructor;
|
||||
}
|
||||
|
||||
JSObject* maybeGetPrototype(JSProtoKey protoKey) const {
|
||||
MOZ_ASSERT(JSProto_Null < protoKey);
|
||||
MOZ_ASSERT(protoKey < JSProto_LIMIT);
|
||||
const Value& v = getPrototype(protoKey);
|
||||
return v.isObject() ? &v.toObject() : nullptr;
|
||||
return data().builtinConstructors[protoKey].prototype;
|
||||
}
|
||||
|
||||
static bool maybeResolveGlobalThis(JSContext* cx,
|
||||
Handle<GlobalObject*> global,
|
||||
bool* resolved);
|
||||
|
||||
void setConstructor(JSProtoKey key, const Value& v) {
|
||||
setReservedSlot(constructorSlot(key), v);
|
||||
void setConstructor(JSProtoKey key, JSObject* obj) {
|
||||
MOZ_ASSERT(obj);
|
||||
data().builtinConstructors[key].constructor = obj;
|
||||
}
|
||||
|
||||
Value getPrototype(JSProtoKey key) const {
|
||||
return getReservedSlot(prototypeSlot(key));
|
||||
bool hasPrototype(JSProtoKey key) const {
|
||||
return bool(data().builtinConstructors[key].prototype);
|
||||
}
|
||||
JSObject& getPrototype(JSProtoKey key) const {
|
||||
MOZ_ASSERT(hasPrototype(key));
|
||||
return *maybeGetPrototype(key);
|
||||
}
|
||||
|
||||
void setPrototype(JSProtoKey key, const Value& value) {
|
||||
setReservedSlot(prototypeSlot(key), value);
|
||||
void setPrototype(JSProtoKey key, JSObject* obj) {
|
||||
MOZ_ASSERT(obj);
|
||||
data().builtinConstructors[key].prototype = obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lazy standard classes need a way to indicate they have been initialized.
|
||||
* Otherwise, when we delete them, we might accidentally recreate them via
|
||||
* a lazy initialization. We use the presence of an object in the
|
||||
* getConstructor(key) reserved slot to indicate that they've been
|
||||
* initialized.
|
||||
* a lazy initialization. We use the presence of an object in the constructor
|
||||
* array to indicate that they've been initialized.
|
||||
*
|
||||
* Note: A few builtin objects, like JSON and Math, are not constructors,
|
||||
* so getConstructor is a bit of a misnomer.
|
||||
*/
|
||||
bool isStandardClassResolved(JSProtoKey key) const {
|
||||
// If the constructor is undefined, then it hasn't been initialized.
|
||||
Value value = getConstructor(key);
|
||||
MOZ_ASSERT(value.isUndefined() || value.isObject() ||
|
||||
value.isMagic(JS_OFF_THREAD_CONSTRUCTOR));
|
||||
return !value.isUndefined();
|
||||
return hasConstructor(key);
|
||||
}
|
||||
|
||||
private:
|
||||
bool classIsInitialized(JSProtoKey key) const {
|
||||
bool inited = !getConstructor(key).isUndefined();
|
||||
MOZ_ASSERT(inited == !getPrototype(key).isUndefined());
|
||||
bool inited = hasConstructor(key);
|
||||
MOZ_ASSERT(inited == hasPrototype(key));
|
||||
return inited;
|
||||
}
|
||||
|
||||
@ -400,7 +402,7 @@ class GlobalObject : public NativeObject {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return &global->getPrototype(JSProto_Object).toObject();
|
||||
return &global->getPrototype(JSProto_Object);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateFunctionConstructor(
|
||||
@ -410,7 +412,7 @@ class GlobalObject : public NativeObject {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return &global->getConstructor(JSProto_Function).toObject();
|
||||
return &global->getConstructor(JSProto_Function);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateFunctionPrototype(JSContext* cx,
|
||||
@ -420,7 +422,7 @@ class GlobalObject : public NativeObject {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return &global->getPrototype(JSProto_Function).toObject();
|
||||
return &global->getPrototype(JSProto_Function);
|
||||
}
|
||||
|
||||
static NativeObject* getOrCreateArrayPrototype(JSContext* cx,
|
||||
@ -428,12 +430,12 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_Array)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_Array).toObject().as<NativeObject>();
|
||||
return &global->getPrototype(JSProto_Array).as<NativeObject>();
|
||||
}
|
||||
|
||||
NativeObject* maybeGetArrayPrototype() {
|
||||
if (classIsInitialized(JSProto_Array)) {
|
||||
return &getPrototype(JSProto_Array).toObject().as<NativeObject>();
|
||||
return &getPrototype(JSProto_Array).as<NativeObject>();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -443,7 +445,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_Boolean)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_Boolean).toObject();
|
||||
return &global->getPrototype(JSProto_Boolean);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateNumberPrototype(JSContext* cx,
|
||||
@ -451,7 +453,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_Number)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_Number).toObject();
|
||||
return &global->getPrototype(JSProto_Number);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateStringPrototype(JSContext* cx,
|
||||
@ -459,7 +461,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_String)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_String).toObject();
|
||||
return &global->getPrototype(JSProto_String);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateSymbolPrototype(JSContext* cx,
|
||||
@ -467,7 +469,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_Symbol)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_Symbol).toObject();
|
||||
return &global->getPrototype(JSProto_Symbol);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateBigIntPrototype(JSContext* cx,
|
||||
@ -475,7 +477,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_BigInt)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_BigInt).toObject();
|
||||
return &global->getPrototype(JSProto_BigInt);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreatePromisePrototype(JSContext* cx,
|
||||
@ -483,7 +485,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_Promise)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_Promise).toObject();
|
||||
return &global->getPrototype(JSProto_Promise);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateRegExpPrototype(JSContext* cx,
|
||||
@ -491,12 +493,12 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_RegExp)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_RegExp).toObject();
|
||||
return &global->getPrototype(JSProto_RegExp);
|
||||
}
|
||||
|
||||
JSObject* maybeGetRegExpPrototype() {
|
||||
if (classIsInitialized(JSProto_RegExp)) {
|
||||
return &getPrototype(JSProto_RegExp).toObject();
|
||||
return &getPrototype(JSProto_RegExp);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -506,7 +508,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_SavedFrame)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_SavedFrame).toObject();
|
||||
return &global->getPrototype(JSProto_SavedFrame);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateArrayBufferConstructor(
|
||||
@ -514,7 +516,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_ArrayBuffer)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getConstructor(JSProto_ArrayBuffer).toObject();
|
||||
return &global->getConstructor(JSProto_ArrayBuffer);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateArrayBufferPrototype(
|
||||
@ -522,7 +524,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_ArrayBuffer)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_ArrayBuffer).toObject();
|
||||
return &global->getPrototype(JSProto_ArrayBuffer);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateSharedArrayBufferPrototype(
|
||||
@ -530,7 +532,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_SharedArrayBuffer)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_SharedArrayBuffer).toObject();
|
||||
return &global->getPrototype(JSProto_SharedArrayBuffer);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateCustomErrorPrototype(JSContext* cx,
|
||||
@ -540,7 +542,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, key)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(key).toObject();
|
||||
return &global->getPrototype(key);
|
||||
}
|
||||
|
||||
static JSFunction* getOrCreateErrorConstructor(JSContext* cx,
|
||||
@ -548,7 +550,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_Error)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getConstructor(JSProto_Error).toObject().as<JSFunction>();
|
||||
return &global->getConstructor(JSProto_Error).as<JSFunction>();
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateErrorPrototype(JSContext* cx,
|
||||
@ -561,7 +563,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_Set)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_Set).toObject().as<NativeObject>();
|
||||
return &global->getPrototype(JSProto_Set).as<NativeObject>();
|
||||
}
|
||||
|
||||
static NativeObject* getOrCreateWeakSetPrototype(
|
||||
@ -569,7 +571,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_WeakSet)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_WeakSet).toObject().as<NativeObject>();
|
||||
return &global->getPrototype(JSProto_WeakSet).as<NativeObject>();
|
||||
}
|
||||
|
||||
static bool ensureModulePrototypesCreated(JSContext* cx,
|
||||
@ -611,9 +613,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_TypedArray)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getConstructor(JSProto_TypedArray)
|
||||
.toObject()
|
||||
.as<JSFunction>();
|
||||
return &global->getConstructor(JSProto_TypedArray).as<JSFunction>();
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateTypedArrayPrototype(
|
||||
@ -621,7 +621,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_TypedArray)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_TypedArray).toObject();
|
||||
return &global->getPrototype(JSProto_TypedArray);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -703,7 +703,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_GeneratorFunction)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_GeneratorFunction).toObject();
|
||||
return &global->getPrototype(JSProto_GeneratorFunction);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateGeneratorFunction(JSContext* cx,
|
||||
@ -711,7 +711,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_GeneratorFunction)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getConstructor(JSProto_GeneratorFunction).toObject();
|
||||
return &global->getConstructor(JSProto_GeneratorFunction);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateAsyncFunctionPrototype(
|
||||
@ -719,7 +719,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_AsyncFunction)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_AsyncFunction).toObject();
|
||||
return &global->getPrototype(JSProto_AsyncFunction);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateAsyncFunction(JSContext* cx,
|
||||
@ -727,7 +727,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_AsyncFunction)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getConstructor(JSProto_AsyncFunction).toObject();
|
||||
return &global->getConstructor(JSProto_AsyncFunction);
|
||||
}
|
||||
|
||||
static JSObject* createAsyncIteratorPrototype(JSContext* cx,
|
||||
@ -754,7 +754,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_AsyncGeneratorFunction)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_AsyncGeneratorFunction).toObject();
|
||||
return &global->getPrototype(JSProto_AsyncGeneratorFunction);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateAsyncGeneratorFunction(
|
||||
@ -762,7 +762,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_AsyncGeneratorFunction)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getConstructor(JSProto_AsyncGeneratorFunction).toObject();
|
||||
return &global->getConstructor(JSProto_AsyncGeneratorFunction);
|
||||
}
|
||||
|
||||
void setAsyncGeneratorPrototype(JSObject* obj) {
|
||||
@ -794,7 +794,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_DataView)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_DataView).toObject();
|
||||
return &global->getPrototype(JSProto_DataView);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreatePromiseConstructor(JSContext* cx,
|
||||
@ -802,7 +802,7 @@ class GlobalObject : public NativeObject {
|
||||
if (!ensureConstructor(cx, global, JSProto_Promise)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getConstructor(JSProto_Promise).toObject();
|
||||
return &global->getConstructor(JSProto_Promise);
|
||||
}
|
||||
|
||||
static NativeObject* getOrCreateWrapForValidIteratorPrototype(
|
||||
@ -972,13 +972,13 @@ class GlobalObject : public NativeObject {
|
||||
|
||||
// A class used in place of a prototype during off-thread parsing.
|
||||
struct OffThreadPlaceholderObject : public NativeObject {
|
||||
// The slot either stores a slot index (Int32Value >= 0) or a ProtoKind
|
||||
// The slot either stores a JSProtoKey (Int32Value >= 0) or a ProtoKind
|
||||
// (Int32Value < 0).
|
||||
static const int32_t SlotIndexOrProtoKindSlot = 0;
|
||||
static const int32_t ProtoKeyOrProtoKindSlot = 0;
|
||||
static const JSClass class_;
|
||||
static OffThreadPlaceholderObject* New(JSContext* cx, unsigned slot);
|
||||
static OffThreadPlaceholderObject* New(JSContext* cx, JSProtoKey key);
|
||||
static OffThreadPlaceholderObject* New(JSContext* cx, ProtoKind kind);
|
||||
inline int32_t getSlotIndexOrProtoKind() const;
|
||||
inline int32_t getProtoKeyOrProtoKind() const;
|
||||
};
|
||||
|
||||
static bool isOffThreadPrototypePlaceholder(JSObject* obj) {
|
||||
|
@ -1044,7 +1044,7 @@ static bool EnsureConstructor(JSContext* cx, Handle<GlobalObject*> global,
|
||||
}
|
||||
|
||||
// Set the used-as-prototype flag here because we can't GC in mergeRealms.
|
||||
RootedObject proto(cx, &global->getPrototype(key).toObject());
|
||||
RootedObject proto(cx, &global->getPrototype(key));
|
||||
return JSObject::setIsUsedAsPrototype(cx, proto);
|
||||
}
|
||||
|
||||
|
@ -798,8 +798,7 @@ static void fun_trace(JSTracer* trc, JSObject* obj) {
|
||||
|
||||
static JSObject* CreateFunctionConstructor(JSContext* cx, JSProtoKey key) {
|
||||
Rooted<GlobalObject*> global(cx, cx->global());
|
||||
RootedObject functionProto(
|
||||
cx, &global->getPrototype(JSProto_Function).toObject());
|
||||
RootedObject functionProto(cx, &global->getPrototype(JSProto_Function));
|
||||
|
||||
RootedObject functionCtor(
|
||||
cx, NewFunctionWithProto(
|
||||
@ -822,7 +821,7 @@ static bool FunctionPrototype(JSContext* cx, unsigned argc, Value* vp) {
|
||||
static JSObject* CreateFunctionPrototype(JSContext* cx, JSProtoKey key) {
|
||||
Rooted<GlobalObject*> self(cx, cx->global());
|
||||
|
||||
RootedObject objectProto(cx, &self->getPrototype(JSProto_Object).toObject());
|
||||
RootedObject objectProto(cx, &self->getPrototype(JSProto_Object));
|
||||
|
||||
return NewFunctionWithProto(
|
||||
cx, FunctionPrototype, 0, FunctionFlags::NATIVE_FUN, nullptr,
|
||||
|
@ -1796,8 +1796,7 @@ bool js::GetObjectFromIncumbentGlobal(JSContext* cx, MutableHandleObject obj) {
|
||||
}
|
||||
|
||||
static bool IsStandardPrototype(JSObject* obj, JSProtoKey key) {
|
||||
Value v = obj->nonCCWGlobal().getPrototype(key);
|
||||
return v.isObject() && obj == &v.toObject();
|
||||
return obj->nonCCWGlobal().maybeGetPrototype(key) == obj;
|
||||
}
|
||||
|
||||
JSProtoKey JS::IdentifyStandardInstance(JSObject* obj) {
|
||||
@ -1835,10 +1834,13 @@ JSProtoKey JS::IdentifyStandardConstructor(JSObject* obj) {
|
||||
return JSProto_Null;
|
||||
}
|
||||
|
||||
static_assert(JSProto_Null == 0,
|
||||
"Loop below can start at 1 to skip JSProto_Null");
|
||||
|
||||
GlobalObject& global = obj->as<JSFunction>().global();
|
||||
for (size_t k = 0; k < JSProto_LIMIT; ++k) {
|
||||
for (size_t k = 1; k < JSProto_LIMIT; ++k) {
|
||||
JSProtoKey key = static_cast<JSProtoKey>(k);
|
||||
if (global.getConstructor(key) == ObjectValue(*obj)) {
|
||||
if (global.maybeGetConstructor(key) == obj) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
@ -30,13 +30,13 @@ using JS::Value;
|
||||
using js::NativeObject;
|
||||
|
||||
JSFunction* js::PromiseLookup::getPromiseConstructor(JSContext* cx) {
|
||||
const Value& val = cx->global()->getConstructor(JSProto_Promise);
|
||||
return val.isObject() ? &val.toObject().as<JSFunction>() : nullptr;
|
||||
JSObject* obj = cx->global()->maybeGetConstructor(JSProto_Promise);
|
||||
return obj ? &obj->as<JSFunction>() : nullptr;
|
||||
}
|
||||
|
||||
NativeObject* js::PromiseLookup::getPromisePrototype(JSContext* cx) {
|
||||
const Value& val = cx->global()->getPrototype(JSProto_Promise);
|
||||
return val.isObject() ? &val.toObject().as<NativeObject>() : nullptr;
|
||||
JSObject* obj = cx->global()->maybeGetPrototype(JSProto_Promise);
|
||||
return obj ? &obj->as<NativeObject>() : nullptr;
|
||||
}
|
||||
|
||||
bool js::PromiseLookup::isDataPropertyNative(JSContext* cx, NativeObject* obj,
|
||||
|
@ -2492,8 +2492,7 @@ bool JSStructuredCloneReader::readSharedWasmMemory(uint32_t nbytes,
|
||||
cx, &payload.toObject().as<SharedArrayBufferObject>());
|
||||
|
||||
// Construct the memory.
|
||||
RootedObject proto(
|
||||
cx, &cx->global()->getPrototype(JSProto_WasmMemory).toObject());
|
||||
RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmMemory));
|
||||
RootedObject memory(cx, WasmMemoryObject::create(cx, sab, proto));
|
||||
if (!memory) {
|
||||
return false;
|
||||
|
@ -3903,8 +3903,7 @@ WasmExceptionObject* WasmExceptionObject::create(JSContext* cx,
|
||||
wasm::SharedExceptionTag tag,
|
||||
HandleArrayBufferObject values,
|
||||
HandleArrayObject refs) {
|
||||
RootedObject proto(
|
||||
cx, &cx->global()->getPrototype(JSProto_WasmException).toObject());
|
||||
RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmException));
|
||||
|
||||
AutoSetNewObjectMetadata metadata(cx);
|
||||
RootedWasmExceptionObject obj(
|
||||
@ -4141,7 +4140,7 @@ class AsyncInstantiateTask : public OffThreadPromiseTask {
|
||||
|
||||
bool resolve(JSContext* cx, Handle<PromiseObject*> promise) override {
|
||||
RootedObject instanceProto(
|
||||
cx, &cx->global()->getPrototype(JSProto_WasmInstance).toObject());
|
||||
cx, &cx->global()->getPrototype(JSProto_WasmInstance));
|
||||
|
||||
RootedWasmInstanceObject instanceObj(cx);
|
||||
if (!module_->instantiate(cx, imports_.get(), instanceProto,
|
||||
@ -4158,8 +4157,8 @@ class AsyncInstantiateTask : public OffThreadPromiseTask {
|
||||
return RejectWithPendingException(cx, promise);
|
||||
}
|
||||
|
||||
RootedObject moduleProto(
|
||||
cx, &cx->global()->getPrototype(JSProto_WasmModule).toObject());
|
||||
RootedObject moduleProto(cx,
|
||||
&cx->global()->getPrototype(JSProto_WasmModule));
|
||||
RootedObject moduleObj(
|
||||
cx, WasmModuleObject::create(cx, *module_, moduleProto));
|
||||
if (!moduleObj) {
|
||||
@ -4207,8 +4206,7 @@ static bool AsyncInstantiate(JSContext* cx, const Module& module,
|
||||
|
||||
static bool ResolveCompile(JSContext* cx, const Module& module,
|
||||
Handle<PromiseObject*> promise) {
|
||||
RootedObject proto(
|
||||
cx, &cx->global()->getPrototype(JSProto_WasmModule).toObject());
|
||||
RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmModule));
|
||||
RootedObject moduleObj(cx, WasmModuleObject::create(cx, module, proto));
|
||||
if (!moduleObj) {
|
||||
return RejectWithPendingException(cx, promise);
|
||||
|
@ -350,8 +350,7 @@ JSObject* Module::createObject(JSContext* cx) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RootedObject proto(
|
||||
cx, &cx->global()->getPrototype(JSProto_WasmModule).toObject());
|
||||
RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmModule));
|
||||
return WasmModuleObject::create(cx, *this, proto);
|
||||
}
|
||||
|
||||
@ -741,8 +740,7 @@ bool Module::instantiateMemory(JSContext* cx,
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedObject proto(
|
||||
cx, &cx->global()->getPrototype(JSProto_WasmMemory).toObject());
|
||||
RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmMemory));
|
||||
memory.set(WasmMemoryObject::create(cx, buffer, proto));
|
||||
if (!memory) {
|
||||
return false;
|
||||
@ -788,8 +786,7 @@ bool Module::instantiateLocalTag(JSContext* cx, const TagDesc& ed,
|
||||
if (ed.isExport) {
|
||||
// If the tag description is exported, create an export tag
|
||||
// object for it.
|
||||
RootedObject proto(cx,
|
||||
&cx->global()->getPrototype(JSProto_WasmTag).toObject());
|
||||
RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmTag));
|
||||
RootedWasmTagObject tagObj(cx, WasmTagObject::create(cx, ed.type, proto));
|
||||
if (!tagObj) {
|
||||
return false;
|
||||
@ -875,8 +872,7 @@ bool Module::instantiateLocalTable(JSContext* cx, const TableDesc& td,
|
||||
SharedTable table;
|
||||
Rooted<WasmTableObject*> tableObj(cx);
|
||||
if (td.importedOrExported) {
|
||||
RootedObject proto(
|
||||
cx, &cx->global()->getPrototype(JSProto_WasmTable).toObject());
|
||||
RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmTable));
|
||||
tableObj.set(WasmTableObject::create(cx, td.initialLength, td.maximumLength,
|
||||
td.elemType, proto));
|
||||
if (!tableObj) {
|
||||
@ -950,8 +946,7 @@ static bool EnsureExportedGlobalObject(JSContext* cx,
|
||||
val.set(Val(global.type()));
|
||||
}
|
||||
|
||||
RootedObject proto(
|
||||
cx, &cx->global()->getPrototype(JSProto_WasmGlobal).toObject());
|
||||
RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmGlobal));
|
||||
RootedWasmGlobalObject go(
|
||||
cx, WasmGlobalObject::create(cx, val, global.isMutable(), proto));
|
||||
if (!go) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user