diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 758cf62369cb..518ce18a3567 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -476,6 +476,7 @@ class CGDOMJSClass(CGThing): nullptr, /* setProperty */ ${enumerate}, /* enumerate */ ${resolve}, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ ${finalize}, /* finalize */ ${call}, /* call */ @@ -616,6 +617,7 @@ class CGPrototypeJSClass(CGThing): nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ @@ -709,6 +711,7 @@ class CGInterfaceObjectJSClass(CGThing): nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ ${ctorname}, /* call */ diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index ad44a4eddb68..28eadab0766f 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -20125,6 +20125,7 @@ const JSClass CreateIndexOp::ThreadLocalJSRuntime::kGlobalClass = { /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ nullptr, + /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ nullptr, diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index e796f24cce80..091aee752f8a 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -213,6 +213,7 @@ const static js::Class sNPObjectJSWrapperClass = NPObjWrapper_SetProperty, nullptr, NPObjWrapper_Resolve, + nullptr, /* mayResolve */ NPObjWrapper_Convert, NPObjWrapper_Finalize, NPObjWrapper_Call, @@ -265,7 +266,7 @@ static const JSClass sNPObjectMemberClass = { "NPObject Ambiguous Member class", JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, NPObjectMember_Convert, + nullptr, nullptr, nullptr, NPObjectMember_Convert, NPObjectMember_Finalize, NPObjectMember_Call, nullptr, nullptr, NPObjectMember_Trace }; diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp index bb1e3e9ee291..0ee3106b8fc7 100644 --- a/dom/workers/WorkerScope.cpp +++ b/dom/workers/WorkerScope.cpp @@ -599,6 +599,7 @@ const js::Class workerdebuggersandbox_class = { nullptr, workerdebuggersandbox_enumerate, workerdebuggersandbox_resolve, + nullptr, /* mayResolve */ workerdebuggersandbox_convert, workerdebuggersandbox_finalize, nullptr, diff --git a/dom/xbl/nsXBLBinding.cpp b/dom/xbl/nsXBLBinding.cpp index 274ed388ba62..1bb0eb8d9d94 100644 --- a/dom/xbl/nsXBLBinding.cpp +++ b/dom/xbl/nsXBLBinding.cpp @@ -93,7 +93,7 @@ static const JSClass gPrototypeJSClass = { // Our one reserved slot holds the relevant nsXBLPrototypeBinding JSCLASS_HAS_RESERVED_SLOTS(1), nullptr, nullptr, nullptr, nullptr, - XBLEnumerate, nullptr, + XBLEnumerate, nullptr, nullptr, nullptr, XBLFinalize, nullptr, nullptr, nullptr, nullptr }; diff --git a/js/public/Class.h b/js/public/Class.h index cdcc760b6be5..34af88671f4d 100644 --- a/js/public/Class.h +++ b/js/public/Class.h @@ -24,6 +24,7 @@ * object behavior and, e.g., allows custom slow layout. */ +struct JSAtomState; struct JSFreeOp; struct JSFunctionSpec; @@ -281,6 +282,18 @@ typedef bool (* JSResolveOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolvedp); +// A class with a resolve hook can optionally have a mayResolve hook. This hook +// must have no side effects and must return true for a given id if the resolve +// hook may resolve this id. This is useful when we're doing a "pure" lookup: if +// mayResolve returns false, we know we don't have to call the effectful resolve +// hook. +// +// maybeObj, if non-null, is the object on which we're doing the lookup. This +// can be nullptr: during JIT compilation we sometimes know the Class but not +// the object. +typedef bool +(* JSMayResolveOp)(const JSAtomState& names, jsid id, JSObject* maybeObj); + // Convert obj to the given type, returning true with the resulting value in // *vp on success, and returning false on error or exception. typedef bool @@ -420,6 +433,7 @@ typedef void JSSetterOp setProperty; \ JSEnumerateOp enumerate; \ JSResolveOp resolve; \ + JSMayResolveOp mayResolve; \ JSConvertOp convert; \ FinalizeOpType finalize; \ JSNative call; \ @@ -688,6 +702,8 @@ static_assert(offsetof(JSClass, enumerate) == offsetof(Class, enumerate), "Class and JSClass must be consistent"); static_assert(offsetof(JSClass, resolve) == offsetof(Class, resolve), "Class and JSClass must be consistent"); +static_assert(offsetof(JSClass, mayResolve) == offsetof(Class, mayResolve), + "Class and JSClass must be consistent"); static_assert(offsetof(JSClass, convert) == offsetof(Class, convert), "Class and JSClass must be consistent"); static_assert(offsetof(JSClass, finalize) == offsetof(Class, finalize), diff --git a/js/src/asmjs/AsmJSModule.cpp b/js/src/asmjs/AsmJSModule.cpp index 3d45e892ce06..ecfb533d3c9a 100644 --- a/js/src/asmjs/AsmJSModule.cpp +++ b/js/src/asmjs/AsmJSModule.cpp @@ -998,6 +998,7 @@ const Class AsmJSModuleObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ AsmJSModuleObject_finalize, nullptr, /* call */ diff --git a/js/src/builtin/Intl.cpp b/js/src/builtin/Intl.cpp index 08811268117b..dbc2c44cd25c 100644 --- a/js/src/builtin/Intl.cpp +++ b/js/src/builtin/Intl.cpp @@ -565,6 +565,7 @@ static const Class CollatorClass = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ collator_finalize }; @@ -1057,6 +1058,7 @@ static const Class NumberFormatClass = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ numberFormat_finalize }; @@ -1516,6 +1518,7 @@ static const Class DateTimeFormatClass = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ dateTimeFormat_finalize }; diff --git a/js/src/builtin/MapObject.cpp b/js/src/builtin/MapObject.cpp index 2626b5923a55..358eb90f91dc 100644 --- a/js/src/builtin/MapObject.cpp +++ b/js/src/builtin/MapObject.cpp @@ -880,6 +880,7 @@ const Class MapIteratorObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ MapIteratorObject::finalize }; @@ -1024,6 +1025,7 @@ const Class MapObject::class_ = { nullptr, // setProperty nullptr, // enumerate nullptr, // resolve + nullptr, // mayResolve nullptr, // convert finalize, nullptr, // call @@ -1616,6 +1618,7 @@ const Class SetIteratorObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ SetIteratorObject::finalize }; @@ -1756,6 +1759,7 @@ const Class SetObject::class_ = { nullptr, // setProperty nullptr, // enumerate nullptr, // resolve + nullptr, // mayResolve nullptr, // convert finalize, nullptr, // call diff --git a/js/src/builtin/Object.cpp b/js/src/builtin/Object.cpp index 6d3413c0c1b9..206b76ef8065 100644 --- a/js/src/builtin/Object.cpp +++ b/js/src/builtin/Object.cpp @@ -1189,6 +1189,7 @@ const Class PlainObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ diff --git a/js/src/builtin/SIMD.cpp b/js/src/builtin/SIMD.cpp index 2ff61409f677..bf6674d66fbf 100644 --- a/js/src/builtin/SIMD.cpp +++ b/js/src/builtin/SIMD.cpp @@ -180,6 +180,7 @@ const Class SimdTypeDescr::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ TypeDescr::finalize, call diff --git a/js/src/builtin/SymbolObject.cpp b/js/src/builtin/SymbolObject.cpp index bb188b6d271f..f166df2626f7 100644 --- a/js/src/builtin/SymbolObject.cpp +++ b/js/src/builtin/SymbolObject.cpp @@ -25,6 +25,7 @@ const Class SymbolObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ convert }; diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index a355cfef6c01..ba2cd99e80fc 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -1154,6 +1154,7 @@ static const JSClass FinalizeCounterClass = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ finalize_counter_finalize }; @@ -1835,6 +1836,7 @@ const Class CloneBufferObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ Finalize }; diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp index 8e1b9f21ab10..53120d7ec123 100644 --- a/js/src/builtin/TypedObject.cpp +++ b/js/src/builtin/TypedObject.cpp @@ -224,6 +224,7 @@ const Class js::ScalarTypeDescr::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ TypeDescr::finalize, ScalarTypeDescr::call @@ -321,6 +322,7 @@ const Class js::ReferenceTypeDescr::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ TypeDescr::finalize, ReferenceTypeDescr::call @@ -500,6 +502,7 @@ const Class ArrayTypeDescr::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ TypeDescr::finalize, nullptr, /* call */ @@ -727,6 +730,7 @@ const Class StructTypeDescr::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ TypeDescr::finalize, nullptr, /* call */ @@ -2246,6 +2250,7 @@ OutlineTransparentTypedObject::getOrCreateBuffer(JSContext* cx) nullptr, /* setProperty */ \ nullptr, /* enumerate */ \ nullptr, /* resolve */ \ + nullptr, /* mayResolve */ \ nullptr, /* convert */ \ nullptr, /* finalize */ \ nullptr, /* call */ \ diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index cd2d667a2f26..0249a2adc5c4 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -533,7 +533,7 @@ static const JSClass sCABIClass = { static const JSClass sCTypeProtoClass = { "CType", JSCLASS_HAS_RESERVED_SLOTS(CTYPEPROTO_SLOTS), - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, ConstructAbstract, nullptr, ConstructAbstract }; @@ -548,7 +548,7 @@ static const JSClass sCDataProtoClass = { static const JSClass sCTypeClass = { "CType", JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(CTYPE_SLOTS), - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, CType::Finalize, CType::ConstructData, CType::HasInstance, CType::ConstructData, CType::Trace @@ -558,14 +558,14 @@ static const JSClass sCDataClass = { "CData", JSCLASS_HAS_RESERVED_SLOTS(CDATA_SLOTS), nullptr, nullptr, ArrayType::Getter, ArrayType::Setter, - nullptr, nullptr, nullptr, CData::Finalize, + nullptr, nullptr, nullptr, nullptr, CData::Finalize, FunctionType::Call, nullptr, FunctionType::Call }; static const JSClass sCClosureClass = { "CClosure", JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(CCLOSURE_SLOTS), - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, CClosure::Finalize, nullptr, nullptr, nullptr, CClosure::Trace }; @@ -587,7 +587,7 @@ static const JSClass sCDataFinalizerProtoClass = { static const JSClass sCDataFinalizerClass = { "CDataFinalizer", JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(CDATAFINALIZER_SLOTS), - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, CDataFinalizer::Finalize }; @@ -773,14 +773,14 @@ static const JSClass sUInt64ProtoClass = { static const JSClass sInt64Class = { "Int64", JSCLASS_HAS_RESERVED_SLOTS(INT64_SLOTS), - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, Int64Base::Finalize }; static const JSClass sUInt64Class = { "UInt64", JSCLASS_HAS_RESERVED_SLOTS(INT64_SLOTS), - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, Int64Base::Finalize }; diff --git a/js/src/ctypes/Library.cpp b/js/src/ctypes/Library.cpp index 688c8a03d836..394fa8a5882b 100644 --- a/js/src/ctypes/Library.cpp +++ b/js/src/ctypes/Library.cpp @@ -35,7 +35,7 @@ typedef Rooted RootedFlatString; static const JSClass sLibraryClass = { "Library", JSCLASS_HAS_RESERVED_SLOTS(LIBRARY_SLOTS), - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, Library::Finalize }; diff --git a/js/src/gdb/gdb-tests.cpp b/js/src/gdb/gdb-tests.cpp index 9ab81825c70d..ada42171ba77 100644 --- a/js/src/gdb/gdb-tests.cpp +++ b/js/src/gdb/gdb-tests.cpp @@ -17,7 +17,7 @@ const JSClass global_class = { "global", JSCLASS_GLOBAL_FLAGS, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook }; diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 00f6806c8a04..397eb88178f3 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -7102,18 +7102,8 @@ ObjectHasExtraOwnProperty(CompileCompartment* comp, TypeSet::ObjectKey* object, return name == comp->runtime()->names().length; // Resolve hooks can install new properties on objects on demand. - if (!clasp->resolve) - return false; - - if (clasp->resolve == str_resolve) { - // str_resolve only resolves integers, not names. - return false; - } - - if (clasp->resolve == fun_resolve) - return FunctionHasResolveHook(comp->runtime()->names(), NameToId(name)); - - return true; + JSObject* singleton = object->isSingleton() ? object->singleton() : nullptr; + return ClassMayResolveId(comp->runtime()->names(), clasp, NameToId(name), singleton); } void diff --git a/js/src/jsapi-tests/testChromeBuffer.cpp b/js/src/jsapi-tests/testChromeBuffer.cpp index 555598d41541..a7e94195229a 100644 --- a/js/src/jsapi-tests/testChromeBuffer.cpp +++ b/js/src/jsapi-tests/testChromeBuffer.cpp @@ -22,6 +22,7 @@ static const JSClass global_class = { nullptr, nullptr, nullptr, + nullptr, JS_GlobalObjectTraceHook }; diff --git a/js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp b/js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp index 59f33c9d31df..0646de6a84c4 100644 --- a/js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp +++ b/js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp @@ -25,7 +25,7 @@ BEGIN_TEST(testRedefineGlobalEval) "global", JSCLASS_GLOBAL_FLAGS, nullptr, nullptr, nullptr, nullptr, GlobalEnumerate, GlobalResolve, nullptr, - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook }; diff --git a/js/src/jsapi-tests/testGCNursery.cpp b/js/src/jsapi-tests/testGCNursery.cpp index d7d2cea1fb40..db7276ac810f 100644 --- a/js/src/jsapi-tests/testGCNursery.cpp +++ b/js/src/jsapi-tests/testGCNursery.cpp @@ -27,6 +27,7 @@ static const js::Class TenuredClass = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* ??? */ _finalize, nullptr, /* call */ @@ -47,6 +48,7 @@ static const js::Class NurseryClass = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* ??? */ _finalize, nullptr, /* call */ diff --git a/js/src/jsapi-tests/testNewObject.cpp b/js/src/jsapi-tests/testNewObject.cpp index f4da9bdfc13a..335c3736b8c2 100644 --- a/js/src/jsapi-tests/testNewObject.cpp +++ b/js/src/jsapi-tests/testNewObject.cpp @@ -98,7 +98,7 @@ BEGIN_TEST(testNewObject_1) 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, constructHook + nullptr, nullptr, nullptr, constructHook }; JS::RootedObject ctor(cx, JS_NewObject(cx, &cls)); CHECK(ctor); diff --git a/js/src/jsapi-tests/testOps.cpp b/js/src/jsapi-tests/testOps.cpp index f0072c2850f8..c3030f7c619c 100644 --- a/js/src/jsapi-tests/testOps.cpp +++ b/js/src/jsapi-tests/testOps.cpp @@ -23,7 +23,7 @@ static const JSClass myClass = { "MyClass", 0, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, my_convert + nullptr, nullptr, nullptr, my_convert }; static bool diff --git a/js/src/jsapi-tests/testPersistentRooted.cpp b/js/src/jsapi-tests/testPersistentRooted.cpp index 3273ab8963f1..9b86e8dba038 100644 --- a/js/src/jsapi-tests/testPersistentRooted.cpp +++ b/js/src/jsapi-tests/testPersistentRooted.cpp @@ -29,6 +29,7 @@ const JSClass BarkWhenTracedClass::class_ = { nullptr, nullptr, nullptr, + nullptr, finalize, nullptr, nullptr, diff --git a/js/src/jsapi-tests/testWeakMap.cpp b/js/src/jsapi-tests/testWeakMap.cpp index 24861e59ec06..acb3b9487b58 100644 --- a/js/src/jsapi-tests/testWeakMap.cpp +++ b/js/src/jsapi-tests/testWeakMap.cpp @@ -148,6 +148,7 @@ JSObject* newKey() nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ @@ -204,6 +205,7 @@ JSObject* newDelegate() nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ diff --git a/js/src/jsapi-tests/tests.h b/js/src/jsapi-tests/tests.h index a57a0b7b218b..d3423fea0572 100644 --- a/js/src/jsapi-tests/tests.h +++ b/js/src/jsapi-tests/tests.h @@ -230,7 +230,7 @@ class JSAPITest "global", JSCLASS_GLOBAL_FLAGS, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook }; return &c; diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 83221f89435d..2bf2db2fd5eb 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -1138,13 +1138,12 @@ typedef struct JSStdName { } JSStdName; static const JSStdName* -LookupStdName(JSRuntime* rt, HandleString name, const JSStdName* table) +LookupStdName(const JSAtomState& names, JSAtom* name, const JSStdName* table) { - MOZ_ASSERT(name->isAtom()); for (unsigned i = 0; !table[i].isSentinel(); i++) { if (table[i].isDummy()) continue; - JSAtom* atom = AtomStateOffsetToName(*rt->commonNames, table[i].atomOffset); + JSAtom* atom = AtomStateOffsetToName(names, table[i].atomOffset); MOZ_ASSERT(atom); if (name == atom) return &table[i]; @@ -1220,11 +1219,10 @@ JS_ResolveStandardClass(JSContext* cx, HandleObject obj, HandleId id, bool* reso if (!rt->hasContexts() || !JSID_IS_ATOM(id)) return true; - RootedString idstr(cx, JSID_TO_STRING(id)); - /* Check whether we're resolving 'undefined', and define it if so. */ + JSAtom* idAtom = JSID_TO_ATOM(id); JSAtom* undefinedAtom = cx->names().undefined; - if (idstr == undefinedAtom) { + if (idAtom == undefinedAtom) { *resolved = true; return DefineProperty(cx, obj, undefinedAtom->asPropertyName(), UndefinedHandleValue, nullptr, nullptr, @@ -1232,11 +1230,11 @@ JS_ResolveStandardClass(JSContext* cx, HandleObject obj, HandleId id, bool* reso } /* Try for class constructors/prototypes named by well-known atoms. */ - stdnm = LookupStdName(rt, idstr, standard_class_names); + stdnm = LookupStdName(cx->names(), idAtom, standard_class_names); /* Try less frequently used top-level functions and constants. */ if (!stdnm) - stdnm = LookupStdName(rt, idstr, builtin_property_names); + stdnm = LookupStdName(cx->names(), idAtom, builtin_property_names); // If this class is anonymous, then it doesn't exist as a global // property, so we won't resolve anything. @@ -1260,6 +1258,27 @@ JS_ResolveStandardClass(JSContext* cx, HandleObject obj, HandleId id, bool* reso return true; } +JS_PUBLIC_API(bool) +JS_MayResolveStandardClass(const JSAtomState& names, jsid id, JSObject* maybeObj) +{ + MOZ_ASSERT_IF(maybeObj, maybeObj->is()); + + // The global object's resolve hook is special: JS_ResolveStandardClass + // initializes the prototype chain lazily. Only attempt to optimize here + // if we know the prototype chain has been initialized. + if (!maybeObj || !maybeObj->getProto()) + return true; + + if (!JSID_IS_ATOM(id)) + return false; + + JSAtom* atom = JSID_TO_ATOM(id); + + return atom == names.undefined || + LookupStdName(names, atom, standard_class_names) || + LookupStdName(names, atom, builtin_property_names); +} + JS_PUBLIC_API(bool) JS_EnumerateStandardClasses(JSContext* cx, HandleObject obj) { @@ -1305,8 +1324,9 @@ JS_IdToProtoKey(JSContext* cx, HandleId id) if (!JSID_IS_ATOM(id)) return JSProto_Null; - RootedString idstr(cx, JSID_TO_STRING(id)); - const JSStdName* stdnm = LookupStdName(cx->runtime(), idstr, standard_class_names); + + JSAtom* atom = JSID_TO_ATOM(id); + const JSStdName* stdnm = LookupStdName(cx->names(), atom, standard_class_names); if (!stdnm) return JSProto_Null; diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 3918b0d837c5..61d6654b50ae 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -1506,6 +1506,9 @@ JS_InitStandardClasses(JSContext* cx, JS::Handle obj); extern JS_PUBLIC_API(bool) JS_ResolveStandardClass(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolved); +extern JS_PUBLIC_API(bool) +JS_MayResolveStandardClass(const JSAtomState& names, jsid id, JSObject* maybeObj); + extern JS_PUBLIC_API(bool) JS_EnumerateStandardClasses(JSContext* cx, JS::HandleObject obj); diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index 772052733155..66a502b8f353 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -3249,6 +3249,7 @@ const Class ArrayObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ diff --git a/js/src/jsdate.cpp b/js/src/jsdate.cpp index 58f3fa391882..1b7f78678b50 100644 --- a/js/src/jsdate.cpp +++ b/js/src/jsdate.cpp @@ -3044,6 +3044,7 @@ const Class DateObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ date_convert, nullptr, /* finalize */ nullptr, /* call */ diff --git a/js/src/jsexn.cpp b/js/src/jsexn.cpp index 703ff7de5f34..a5511588f984 100644 --- a/js/src/jsexn.cpp +++ b/js/src/jsexn.cpp @@ -77,6 +77,7 @@ static const JSFunctionSpec exception_methods[] = { nullptr, /* setProperty */ \ nullptr, /* enumerate */ \ nullptr, /* resolve */ \ + nullptr, /* mayResolve */ \ nullptr, /* convert */ \ exn_finalize, \ nullptr, /* call */ \ @@ -108,6 +109,7 @@ ErrorObject::classes[JSEXN_LIMIT] = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ exn_finalize, nullptr, /* call */ diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 7dd7aa217f3b..ade724c5928b 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -319,6 +319,7 @@ namespace js { nullptr, /* setProperty */ \ nullptr, /* enumerate */ \ nullptr, /* resolve */ \ + nullptr, /* mayResolve */ \ js::proxy_Convert, \ js::proxy_Finalize, /* finalize */ \ nullptr, /* call */ \ diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index 6da5747f8b53..9d9862e58fb4 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -419,18 +419,18 @@ ResolveInterpretedFunctionPrototype(JSContext* cx, HandleObject obj) return proto; } -bool -js::FunctionHasResolveHook(const JSAtomState& atomState, jsid id) +static bool +fun_mayResolve(const JSAtomState& names, jsid id, JSObject*) { if (!JSID_IS_ATOM(id)) return false; JSAtom* atom = JSID_TO_ATOM(id); - return atom == atomState.prototype || atom == atomState.length || atom == atomState.name; + return atom == names.prototype || atom == names.length || atom == names.name; } -bool -js::fun_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp) +static bool +fun_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp) { if (!JSID_IS_ATOM(id)) return true; @@ -891,7 +891,8 @@ const Class JSFunction::class_ = { nullptr, /* getProperty */ nullptr, /* setProperty */ fun_enumerate, - js::fun_resolve, + fun_resolve, + fun_mayResolve, nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ diff --git a/js/src/jsfun.h b/js/src/jsfun.h index cf4a5e999281..ba008df11cd8 100644 --- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -53,8 +53,8 @@ class JSFunction : public js::NativeObject must be constructible but not decompilable. */ HAS_REST = 0x0200, /* function has a rest (...) parameter */ INTERPRETED_LAZY = 0x0400, /* function is interpreted but doesn't have a script yet */ - RESOLVED_LENGTH = 0x0800, /* f.length has been resolved (see js::fun_resolve). */ - RESOLVED_NAME = 0x1000, /* f.name has been resolved (see js::fun_resolve). */ + RESOLVED_LENGTH = 0x0800, /* f.length has been resolved (see fun_resolve). */ + RESOLVED_NAME = 0x1000, /* f.name has been resolved (see fun_resolve). */ FUNCTION_KIND_SHIFT = 13, FUNCTION_KIND_MASK = 0x3 << FUNCTION_KIND_SHIFT, @@ -568,9 +568,6 @@ DefineFunction(JSContext* cx, HandleObject obj, HandleId id, JSNative native, bool FunctionHasResolveHook(const JSAtomState& atomState, jsid id); -extern bool -fun_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp); - extern bool fun_toString(JSContext* cx, unsigned argc, Value* vp); diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index eb02601a7b3f..041958b7f08b 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -988,6 +988,7 @@ const Class PropertyIteratorObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ finalize, nullptr, /* call */ @@ -1375,6 +1376,7 @@ const Class StopIterationObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 7c7fde519fbb..39fa4770c4d6 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -2784,19 +2784,10 @@ js::LookupPropertyPure(ExclusiveContext* cx, JSObject* obj, jsid id, JSObject** return true; } - // Fail if there's a resolve hook. We allow the JSFunction resolve hook - // if we know it will never add a property with this name or str_resolve - // with a non-integer property. - do { - const Class* clasp = obj->getClass(); - if (!clasp->resolve) - break; - if (clasp->resolve == fun_resolve && !FunctionHasResolveHook(cx->names(), id)) - break; - if (clasp->resolve == str_resolve && !JSID_IS_INT(id)) - break; + // Fail if there's a resolve hook, unless the mayResolve hook tells + // us the resolve hook won't define a property with this id. + if (ClassMayResolveId(cx->names(), obj->getClass(), id, obj)) return false; - } while (0); } else if (obj->is()) { if (obj->as().containsUnboxedOrExpandoProperty(cx, id)) { *objp = obj; diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 26ef199aebd7..abc7a5e24ff3 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1361,6 +1361,7 @@ const Class ScriptSourceObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ finalize, nullptr, /* call */ diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 7752217af047..2fc3c3924e68 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -394,8 +394,15 @@ str_enumerate(JSContext* cx, HandleObject obj) return true; } -bool -js::str_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp) +static bool +str_mayResolve(const JSAtomState&, jsid id, JSObject*) +{ + // str_resolve ignores non-integer ids. + return JSID_IS_INT(id); +} + +static bool +str_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp) { if (!JSID_IS_INT(id)) return true; @@ -424,7 +431,8 @@ const Class StringObject::class_ = { nullptr, /* getProperty */ nullptr, /* setProperty */ str_enumerate, - str_resolve + str_resolve, + str_mayResolve }; /* diff --git a/js/src/jsstr.h b/js/src/jsstr.h index 217a85077fdc..feec7846e1e4 100644 --- a/js/src/jsstr.h +++ b/js/src/jsstr.h @@ -408,9 +408,6 @@ str_split(JSContext* cx, unsigned argc, Value* vp); JSObject* str_split_string(JSContext* cx, HandleObjectGroup group, HandleString str, HandleString sep); -bool -str_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp); - bool str_replace_regexp_raw(JSContext* cx, HandleString string, HandleObject regexp, HandleString replacement, MutableHandleValue rval); diff --git a/js/src/jsweakmap.cpp b/js/src/jsweakmap.cpp index 97a660e9ce39..027076214949 100644 --- a/js/src/jsweakmap.cpp +++ b/js/src/jsweakmap.cpp @@ -616,6 +616,7 @@ const Class WeakMapObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ WeakMap_finalize, nullptr, /* call */ diff --git a/js/src/perf/jsperf.cpp b/js/src/perf/jsperf.cpp index d113db0cce3f..143ea2a468e2 100644 --- a/js/src/perf/jsperf.cpp +++ b/js/src/perf/jsperf.cpp @@ -163,7 +163,7 @@ static void pm_finalize(JSFreeOp* fop, JSObject* obj); static const JSClass pm_class = { "PerfMeasurement", JSCLASS_HAS_PRIVATE, - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, pm_finalize }; diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 0bf8e8c92ce0..4f0e1b4ada69 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -2660,7 +2660,7 @@ static const JSClass sandbox_class = { JSCLASS_GLOBAL_FLAGS, nullptr, nullptr, nullptr, nullptr, sandbox_enumerate, sandbox_resolve, - nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook }; @@ -5119,10 +5119,16 @@ global_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp) return true; } +static bool +global_mayResolve(const JSAtomState& names, jsid id, JSObject* maybeObj) +{ + return JS_MayResolveStandardClass(names, id, maybeObj); +} + static const JSClass global_class = { "global", JSCLASS_GLOBAL_FLAGS, nullptr, nullptr, nullptr, nullptr, - global_enumerate, global_resolve, + global_enumerate, global_resolve, global_mayResolve, nullptr, nullptr, nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook diff --git a/js/src/vm/ArgumentsObject.cpp b/js/src/vm/ArgumentsObject.cpp index 1352b1f9b0e4..73539d58cb74 100644 --- a/js/src/vm/ArgumentsObject.cpp +++ b/js/src/vm/ArgumentsObject.cpp @@ -560,6 +560,7 @@ const Class NormalArgumentsObject::class_ = { nullptr, /* setProperty */ args_enumerate, args_resolve, + nullptr, /* mayResolve */ nullptr, /* convert */ ArgumentsObject::finalize, nullptr, /* call */ @@ -584,6 +585,7 @@ const Class StrictArgumentsObject::class_ = { nullptr, /* setProperty */ strictargs_enumerate, strictargs_resolve, + nullptr, /* mayResolve */ nullptr, /* convert */ ArgumentsObject::finalize, nullptr, /* call */ diff --git a/js/src/vm/ArrayBufferObject.cpp b/js/src/vm/ArrayBufferObject.cpp index 39a03adcd762..c73f0b7be6ab 100644 --- a/js/src/vm/ArrayBufferObject.cpp +++ b/js/src/vm/ArrayBufferObject.cpp @@ -108,6 +108,7 @@ const Class ArrayBufferObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ ArrayBufferObject::finalize, nullptr, /* call */ diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index 566c48cb4f73..ec8db41fcbfb 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -2405,7 +2405,7 @@ const Class Debugger::jsclass = { "Debugger", JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUG_COUNT), - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, Debugger::finalize, nullptr, /* call */ nullptr, /* hasInstance */ @@ -4204,7 +4204,7 @@ const Class DebuggerScript_class = { "Script", JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGSCRIPT_COUNT), - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, /* call */ nullptr, /* hasInstance */ @@ -5225,7 +5225,7 @@ const Class DebuggerSource_class = { "Source", JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGSOURCE_COUNT), - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, /* call */ nullptr, /* hasInstance */ @@ -5580,7 +5580,7 @@ DebuggerFrame_finalize(FreeOp* fop, JSObject* obj) const Class DebuggerFrame_class = { "Frame", JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGFRAME_COUNT), - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, DebuggerFrame_finalize }; @@ -6342,7 +6342,7 @@ const Class DebuggerObject_class = { "Object", JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGOBJECT_COUNT), - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, /* call */ nullptr, /* hasInstance */ @@ -7252,7 +7252,7 @@ const Class DebuggerEnv_class = { "Environment", JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGENV_COUNT), - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, /* call */ nullptr, /* hasInstance */ diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index 39c20a3ce7d3..badefdfffa0b 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -506,7 +506,7 @@ GlobalDebuggees_finalize(FreeOp* fop, JSObject* obj) static const Class GlobalDebuggees_class = { "GlobalDebuggee", JSCLASS_HAS_PRIVATE, - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, GlobalDebuggees_finalize }; diff --git a/js/src/vm/HelperThreads.cpp b/js/src/vm/HelperThreads.cpp index bcd75cc8234d..536fd45b668a 100644 --- a/js/src/vm/HelperThreads.cpp +++ b/js/src/vm/HelperThreads.cpp @@ -192,7 +192,7 @@ static const JSClass parseTaskGlobalClass = { "internal-parse-task-global", JSCLASS_GLOBAL_FLAGS, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook }; diff --git a/js/src/vm/NativeObject-inl.h b/js/src/vm/NativeObject-inl.h index 98e5c6adddeb..b13bdf1facb9 100644 --- a/js/src/vm/NativeObject-inl.h +++ b/js/src/vm/NativeObject-inl.h @@ -414,6 +414,11 @@ CallResolveOp(JSContext* cx, HandleNativeObject obj, HandleId id, MutableHandleS if (!resolved) return true; + // Assert the mayResolve hook, if there is one, returns true for this + // property. + MOZ_ASSERT_IF(obj->getClass()->mayResolve, + obj->getClass()->mayResolve(cx->names(), id, obj)); + if (JSID_IS_INT(id) && obj->containsDenseElement(JSID_TO_INT(id))) { MarkDenseOrTypedArrayElementFound(propp); return true; @@ -425,6 +430,28 @@ CallResolveOp(JSContext* cx, HandleNativeObject obj, HandleId id, MutableHandleS return true; } +static MOZ_ALWAYS_INLINE bool +ClassMayResolveId(const JSAtomState& names, const Class* clasp, jsid id, JSObject* maybeObj) +{ + MOZ_ASSERT_IF(maybeObj, maybeObj->getClass() == clasp); + + if (!clasp->resolve) { + // Sanity check: we should only have a mayResolve hook if we have a + // resolve hook. + MOZ_ASSERT(!clasp->mayResolve, "Class with mayResolve hook but no resolve hook"); + return false; + } + + if (clasp->mayResolve) { + // Tell the analysis our mayResolve hooks won't trigger GC. + JS::AutoSuppressGCAnalysis nogc; + if (!clasp->mayResolve(names, id, maybeObj)) + return false; + } + + return true; +} + template static MOZ_ALWAYS_INLINE bool LookupOwnPropertyInline(ExclusiveContext* cx, diff --git a/js/src/vm/PIC.cpp b/js/src/vm/PIC.cpp index 36bb59189a7f..4019d11cbd4d 100644 --- a/js/src/vm/PIC.cpp +++ b/js/src/vm/PIC.cpp @@ -296,7 +296,7 @@ ForOfPIC_traceObject(JSTracer* trc, JSObject* obj) const Class ForOfPIC::jsclass = { "ForOfPIC", JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS, - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, ForOfPIC_finalize, nullptr, /* call */ nullptr, /* hasInstance */ diff --git a/js/src/vm/RegExpObject.cpp b/js/src/vm/RegExpObject.cpp index dd9dbc1a90a4..e50ff21c6ecb 100644 --- a/js/src/vm/RegExpObject.cpp +++ b/js/src/vm/RegExpObject.cpp @@ -269,6 +269,7 @@ const Class RegExpObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ diff --git a/js/src/vm/RegExpStatics.cpp b/js/src/vm/RegExpStatics.cpp index 2732f8b30840..5e72091a8f1b 100644 --- a/js/src/vm/RegExpStatics.cpp +++ b/js/src/vm/RegExpStatics.cpp @@ -44,6 +44,7 @@ const Class RegExpStaticsObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ resc_finalize, nullptr, /* call */ diff --git a/js/src/vm/SavedStacks.cpp b/js/src/vm/SavedStacks.cpp index da1819c8111e..0ca9b14efbea 100644 --- a/js/src/vm/SavedStacks.cpp +++ b/js/src/vm/SavedStacks.cpp @@ -185,6 +185,7 @@ SavedFrame::finishSavedFrameInit(JSContext* cx, HandleObject ctor, HandleObject nullptr, // setProperty nullptr, // enumerate nullptr, // resolve + nullptr, // mayResolve nullptr, // convert SavedFrame::finalize, // finalize nullptr, // call diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index e5eed90776d3..dbc432944de2 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -540,6 +540,7 @@ const Class DynamicWithObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ @@ -977,6 +978,7 @@ const Class UninitializedLexicalObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 7358a6670b9d..199ae9466528 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -1542,7 +1542,7 @@ JSRuntime::createSelfHostingGlobal(JSContext* cx) "self-hosting-global", JSCLASS_GLOBAL_FLAGS, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook }; diff --git a/js/src/vm/SharedArrayObject.cpp b/js/src/vm/SharedArrayObject.cpp index 1d666cad1574..32234681d1c7 100644 --- a/js/src/vm/SharedArrayObject.cpp +++ b/js/src/vm/SharedArrayObject.cpp @@ -313,6 +313,7 @@ const Class SharedArrayBufferObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ SharedArrayBufferObject::Finalize, nullptr, /* call */ diff --git a/js/src/vm/SharedTypedArrayObject.cpp b/js/src/vm/SharedTypedArrayObject.cpp index 37b4132595d4..16b582962dd2 100644 --- a/js/src/vm/SharedTypedArrayObject.cpp +++ b/js/src/vm/SharedTypedArrayObject.cpp @@ -711,6 +711,7 @@ IMPL_SHARED_TYPED_ARRAY_COMBINED_UNWRAPPERS(Float64, double, double) nullptr, /* setProperty */ \ nullptr, /* enumerate */ \ nullptr, /* resolve */ \ + nullptr, /* mayResolve */ \ nullptr, /* convert */ \ nullptr, /* finalize */ \ nullptr, /* call */ \ @@ -732,6 +733,7 @@ IMPL_SHARED_TYPED_ARRAY_COMBINED_UNWRAPPERS(Float64, double, double) nullptr, /* setProperty */ \ nullptr, /* enumerate */ \ nullptr, /* resolve */ \ + nullptr, /* mayResolve */ \ nullptr, /* convert */ \ nullptr, /* finalize */ \ nullptr, /* call */ \ diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index d710804ac71c..568779fb165e 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -839,6 +839,7 @@ TypedArrayObject::sharedTypedArrayPrototypeClass = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ @@ -1801,6 +1802,7 @@ IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Float64, double, double) nullptr, /* setProperty */ \ nullptr, /* enumerate */ \ nullptr, /* resolve */ \ + nullptr, /* mayResolve */ \ nullptr, /* convert */ \ nullptr, /* finalize */ \ nullptr, /* call */ \ @@ -1846,6 +1848,7 @@ const Class TypedArrayObject::classes[Scalar::MaxTypedArrayViewType] = { nullptr, /* setProperty */ \ nullptr, /* enumerate */ \ nullptr, /* resolve */ \ + nullptr, /* mayResolve */ \ nullptr, /* convert */ \ nullptr, /* finalize */ \ nullptr, /* call */ \ @@ -1901,6 +1904,7 @@ const Class DataViewObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ diff --git a/js/src/vm/UnboxedObject.cpp b/js/src/vm/UnboxedObject.cpp index 763896e7f26c..2d2865cf9cf9 100644 --- a/js/src/vm/UnboxedObject.cpp +++ b/js/src/vm/UnboxedObject.cpp @@ -893,6 +893,7 @@ const Class UnboxedPlainObject::class_ = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index 99f3ec4e7705..b2ca02d92b51 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -468,7 +468,9 @@ static const js::Class SandboxClass = { "Sandbox", XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(1), nullptr, nullptr, nullptr, nullptr, - sandbox_enumerate, sandbox_resolve, sandbox_convert, sandbox_finalize, + sandbox_enumerate, sandbox_resolve, + nullptr, /* mayResolve */ + sandbox_convert, sandbox_finalize, nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook, JS_NULL_CLASS_SPEC, { @@ -487,7 +489,9 @@ static const js::Class SandboxWriteToProtoClass = { "Sandbox", XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(1), sandbox_addProperty, nullptr, nullptr, nullptr, - sandbox_enumerate, sandbox_resolve, sandbox_convert, sandbox_finalize, + sandbox_enumerate, sandbox_resolve, + nullptr, /* mayResolve */ + sandbox_convert, sandbox_finalize, nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook, JS_NULL_CLASS_SPEC, { diff --git a/js/xpconnect/src/XPCWrappedJSClass.cpp b/js/xpconnect/src/XPCWrappedJSClass.cpp index ab7f2b90f2bc..3c67954a10b6 100644 --- a/js/xpconnect/src/XPCWrappedJSClass.cpp +++ b/js/xpconnect/src/XPCWrappedJSClass.cpp @@ -1456,6 +1456,7 @@ static const JSClass XPCOutParamClass = { nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ + nullptr, /* mayResolve */ nullptr, /* convert */ FinalizeStub, nullptr, /* call */ diff --git a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp index e42501dde5a6..ae1e1b565d9d 100644 --- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp +++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp @@ -648,6 +648,7 @@ const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = { XPC_WN_Shared_Enumerate, // enumerate XPC_WN_NoHelper_Resolve, // resolve + nullptr, // mayResolve XPC_WN_Shared_Convert, // convert XPC_WN_NoHelper_Finalize, // finalize @@ -1288,6 +1289,7 @@ const js::Class XPC_WN_ModsAllowed_WithCall_Proto_JSClass = { nullptr, // setProperty; XPC_WN_Shared_Proto_Enumerate, // enumerate; XPC_WN_ModsAllowed_Proto_Resolve, // resolve; + nullptr, // mayResolve; nullptr, // convert; XPC_WN_Shared_Proto_Finalize, // finalize; @@ -1313,6 +1315,7 @@ const js::Class XPC_WN_ModsAllowed_NoCall_Proto_JSClass = { nullptr, // setProperty; XPC_WN_Shared_Proto_Enumerate, // enumerate; XPC_WN_ModsAllowed_Proto_Resolve, // resolve; + nullptr, // mayResolve; nullptr, // convert; XPC_WN_Shared_Proto_Finalize, // finalize; @@ -1391,6 +1394,7 @@ const js::Class XPC_WN_NoMods_WithCall_Proto_JSClass = { nullptr, // setProperty; XPC_WN_Shared_Proto_Enumerate, // enumerate; XPC_WN_NoMods_Proto_Resolve, // resolve; + nullptr, // mayResolve; nullptr, // convert; XPC_WN_Shared_Proto_Finalize, // finalize; @@ -1416,6 +1420,7 @@ const js::Class XPC_WN_NoMods_NoCall_Proto_JSClass = { nullptr, // setProperty; XPC_WN_Shared_Proto_Enumerate, // enumerate; XPC_WN_NoMods_Proto_Resolve, // resolve; + nullptr, // mayResolve; nullptr, // convert; XPC_WN_Shared_Proto_Finalize, // finalize; @@ -1511,6 +1516,7 @@ const js::Class XPC_WN_Tearoff_JSClass = { nullptr, // setProperty; XPC_WN_TearOff_Enumerate, // enumerate; XPC_WN_TearOff_Resolve, // resolve; + nullptr, // mayResolve; XPC_WN_Shared_Convert, // convert; XPC_WN_TearOff_Finalize, // finalize; diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index 21ce6ff77b11..55c024a02f48 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -887,7 +887,7 @@ ExpandoObjectFinalize(JSFreeOp* fop, JSObject* obj) const JSClass ExpandoObjectClass = { "XrayExpandoObject", JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_EXPANDO_COUNT), - nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, ExpandoObjectFinalize }; diff --git a/netwerk/base/ProxyAutoConfig.cpp b/netwerk/base/ProxyAutoConfig.cpp index 994608c99b8b..a7dddb9191dc 100644 --- a/netwerk/base/ProxyAutoConfig.cpp +++ b/netwerk/base/ProxyAutoConfig.cpp @@ -669,7 +669,7 @@ const JSClass JSRuntimeWrapper::sGlobalClass = { "PACResolutionThreadGlobal", JSCLASS_GLOBAL_FLAGS, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook }; diff --git a/toolkit/components/finalizationwitness/FinalizationWitnessService.cpp b/toolkit/components/finalizationwitness/FinalizationWitnessService.cpp index dd70c4c87a48..0678ceddd2f5 100644 --- a/toolkit/components/finalizationwitness/FinalizationWitnessService.cpp +++ b/toolkit/components/finalizationwitness/FinalizationWitnessService.cpp @@ -120,6 +120,7 @@ static const JSClass sWitnessClass = { nullptr /* setProperty */, nullptr /* enumerate */, nullptr /* resolve */, + nullptr /* mayResolve */, nullptr /* convert */, Finalize /* finalize */ }; diff --git a/xpcom/glue/tests/gtest/TestGCPostBarriers.cpp b/xpcom/glue/tests/gtest/TestGCPostBarriers.cpp index 569b7a6af5e6..c44b8c2e27e0 100644 --- a/xpcom/glue/tests/gtest/TestGCPostBarriers.cpp +++ b/xpcom/glue/tests/gtest/TestGCPostBarriers.cpp @@ -88,7 +88,7 @@ CreateGlobalAndRunTest(JSRuntime* rt, JSContext* cx) "global", JSCLASS_GLOBAL_FLAGS, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook };