author | Tom Schuster <evilpies@gmail.com> |
Tue, 08 Nov 2016 22:08:28 +0100 | |
changeset 321559 | d09c525ca67505ccddc16e4ddda5ccecd8e0d7df |
parent 321558 | ec8ee3aeecac15c000996ef173b0cece19b0641f |
child 321560 | 546dbaaff8e90cda29a5b539fde989e0970eca02 |
push id | 83644 |
push user | evilpies@gmail.com |
push date | Tue, 08 Nov 2016 21:08:42 +0000 |
treeherder | mozilla-inbound@138f4cfcbd9d [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bz |
bugs | 1015798 |
milestone | 52.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/public/Class.h +++ b/js/public/Class.h @@ -549,36 +549,38 @@ struct ClassSpec ClassObjectCreationOp createPrototype_; const JSFunctionSpec* constructorFunctions_; const JSPropertySpec* constructorProperties_; const JSFunctionSpec* prototypeFunctions_; const JSPropertySpec* prototypeProperties_; FinishClassInitOp finishInit_; uintptr_t flags; - static const size_t ParentKeyWidth = JSCLASS_CACHED_PROTO_WIDTH; + static const size_t ProtoKeyWidth = JSCLASS_CACHED_PROTO_WIDTH; - static const uintptr_t ParentKeyMask = (1 << ParentKeyWidth) - 1; - static const uintptr_t DontDefineConstructor = 1 << ParentKeyWidth; - static const uintptr_t IsDelegated = 1 << (ParentKeyWidth + 1); + static const uintptr_t ProtoKeyMask = (1 << ProtoKeyWidth) - 1; + static const uintptr_t DontDefineConstructor = 1 << ProtoKeyWidth; + static const uintptr_t IsDelegated = 1 << (ProtoKeyWidth + 1); bool defined() const { return !!createConstructor_; } bool delegated() const { return (flags & IsDelegated); } - bool dependent() const { + // The ProtoKey this class inherits from. + JSProtoKey inheritanceProtoKey() const { MOZ_ASSERT(defined()); - return (flags & ParentKeyMask); - } + static_assert(JSProto_Null == 0, "zeroed key must be null"); - JSProtoKey parentKey() const { - static_assert(JSProto_Null == 0, "zeroed key must be null"); - return JSProtoKey(flags & ParentKeyMask); + // Default: Inherit from Object. + if (!(flags & ProtoKeyMask)) + return JSProto_Object; + + return JSProtoKey(flags & ProtoKeyMask); } bool shouldDefineConstructor() const { MOZ_ASSERT(defined()); return !(flags & DontDefineConstructor); } const ClassSpec* delegatedClassSpec() const { @@ -860,18 +862,18 @@ struct Class bool isWrappedNative() const { return flags & JSCLASS_IS_WRAPPED_NATIVE; } static size_t offsetOfFlags() { return offsetof(Class, flags); } bool specDefined() const { return spec ? spec->defined() : false; } - bool specDependent() const { return spec ? spec->dependent() : false; } - JSProtoKey specParentKey() const { return spec ? spec->parentKey() : JSProto_Null; } + JSProtoKey specInheritanceProtoKey() + const { return spec ? spec->inheritanceProtoKey() : JSProto_Null; } bool specShouldDefineConstructor() const { return spec ? spec->shouldDefineConstructor() : true; } ClassObjectCreationOp specCreateConstructorHook() const { return spec ? spec->createConstructorHook() : nullptr; } ClassObjectCreationOp specCreatePrototypeHook() const { return spec ? spec->createPrototypeHook() : nullptr; } const JSFunctionSpec* specConstructorFunctions() const { return spec ? spec->constructorFunctions() : nullptr; }
--- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -639,44 +639,33 @@ inline const JSClass* GetObjectJSClass(JSObject* obj) { return js::Jsvalify(GetObjectClass(obj)); } JS_FRIEND_API(const Class*) ProtoKeyToClass(JSProtoKey key); -// Returns true if the standard class identified by |key| inherits from -// another standard class (in addition to Object) along its proto chain. -// -// In practice, this only returns true for Error subtypes. -inline bool -StandardClassIsDependent(JSProtoKey key) -{ - const Class* clasp = ProtoKeyToClass(key); - return clasp && clasp->specDefined() && clasp->specDependent(); -} - // Returns the key for the class inherited by a given standard class (that // is to say, the prototype of this standard class's prototype). // // You must be sure that this corresponds to a standard class with a cached // JSProtoKey before calling this function. In general |key| will match the // cached proto key, except in cases where multiple JSProtoKeys share a // JSClass. inline JSProtoKey -ParentKeyForStandardClass(JSProtoKey key) +InheritanceProtoKeyForStandardClass(JSProtoKey key) { // [Object] has nothing to inherit from. if (key == JSProto_Object) return JSProto_Null; - // If we're dependent, return the key of the class we depend on. - if (StandardClassIsDependent(key)) - return ProtoKeyToClass(key)->specParentKey(); + // If we're ClassSpec defined return the proto key from that + if (ProtoKeyToClass(key)->specDefined()) + return ProtoKeyToClass(key)->specInheritanceProtoKey(); // Otherwise, we inherit [Object]. return JSProto_Object; } JS_FRIEND_API(bool) IsFunctionObject(JSObject* obj);
--- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -223,21 +223,19 @@ GlobalObject::resolveConstructor(JSConte RootedValue ctorValue(cx, ObjectValue(*ctor)); if (!DefineProperty(cx, global, id, ctorValue, nullptr, nullptr, JSPROP_RESOLVING)) return false; } global->setConstructor(key, ObjectValue(*ctor)); } - // Define any specified functions and properties, unless we're a dependent - // standard class (in which case they live on the prototype), or we're - // operating on the self-hosting global, in which case we don't want any + // If we're operating on the self-hosting global, we don't want any // functions and properties on the builtins and their prototypes. - if (!StandardClassIsDependent(key) && !cx->runtime()->isSelfHostingGlobal(global)) { + if (!cx->runtime()->isSelfHostingGlobal(global)) { if (const JSFunctionSpec* funs = clasp->specPrototypeFunctions()) { if (!JS_DefineFunctions(cx, proto, funs)) return false; } if (const JSPropertySpec* props = clasp->specPrototypeProperties()) { if (!JS_DefineProperties(cx, proto, props)) return false; }
--- a/js/src/vm/GlobalObject.h +++ b/js/src/vm/GlobalObject.h @@ -981,20 +981,20 @@ GenericCreateConstructor(JSContext* cx, } inline JSObject* GenericCreatePrototype(JSContext* cx, JSProtoKey key) { MOZ_ASSERT(key != JSProto_Object); const Class* clasp = ProtoKeyToClass(key); MOZ_ASSERT(clasp); - JSProtoKey parentKey = ParentKeyForStandardClass(key); - if (!GlobalObject::ensureConstructor(cx, cx->global(), parentKey)) + JSProtoKey protoKey = InheritanceProtoKeyForStandardClass(key); + if (!GlobalObject::ensureConstructor(cx, cx->global(), protoKey)) return nullptr; - RootedObject parentProto(cx, &cx->global()->getPrototype(parentKey).toObject()); + RootedObject parentProto(cx, &cx->global()->getPrototype(protoKey).toObject()); return cx->global()->createBlankPrototypeInheriting(cx, clasp, parentProto); } inline JSProtoKey StandardProtoKeyOrNull(const JSObject* obj) { JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(obj->getClass()); if (key == JSProto_Error)
--- a/js/xpconnect/wrappers/XrayWrapper.h +++ b/js/xpconnect/wrappers/XrayWrapper.h @@ -272,22 +272,22 @@ public: bool getPrototype(JSContext* cx, JS::HandleObject wrapper, JS::HandleObject target, JS::MutableHandleObject protop) { JS::RootedObject holder(cx, ensureHolder(cx, wrapper)); JSProtoKey key = getProtoKey(holder); if (isPrototype(holder)) { - JSProtoKey parentKey = js::ParentKeyForStandardClass(key); - if (parentKey == JSProto_Null) { + JSProtoKey protoKey = js::InheritanceProtoKeyForStandardClass(key); + if (protoKey == JSProto_Null) { protop.set(nullptr); return true; } - key = parentKey; + key = protoKey; } { JSAutoCompartment ac(cx, target); if (!JS_GetClassPrototype(cx, key, protop)) return false; } return JS_WrapObject(cx, protop);