From 59967ca2abffa5f1929d8a700c1d81c09c797971 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Tue, 12 May 2015 12:27:52 +0200 Subject: [PATCH] Backed out changeset 3841e37b0e2f (bug 861219) for JS Crashes on a CLOSED TREE --- js/public/Class.h | 70 +++------------------------ js/src/vm/GlobalObject.cpp | 20 ++++---- js/src/vm/TypedArrayObject.cpp | 26 +++++----- js/xpconnect/wrappers/XrayWrapper.cpp | 8 +-- 4 files changed, 35 insertions(+), 89 deletions(-) diff --git a/js/public/Class.h b/js/public/Class.h index 4c583dc35d22..181e3890c03c 100644 --- a/js/public/Class.h +++ b/js/public/Class.h @@ -454,14 +454,13 @@ const size_t JSCLASS_CACHED_PROTO_WIDTH = 6; struct ClassSpec { - // All properties except flags should be accessed through get* accessor. - ClassObjectCreationOp createConstructor_; - ClassObjectCreationOp createPrototype_; - const JSFunctionSpec* constructorFunctions_; - const JSPropertySpec* constructorProperties_; - const JSFunctionSpec* prototypeFunctions_; - const JSPropertySpec* prototypeProperties_; - FinishClassInitOp finishInit_; + ClassObjectCreationOp createConstructor; + 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; @@ -469,13 +468,7 @@ struct ClassSpec static const uintptr_t ParentKeyMask = (1 << ParentKeyWidth) - 1; static const uintptr_t DontDefineConstructor = 1 << ParentKeyWidth; - static const uintptr_t DelegatedTag = 1; - - bool defined() const { return !!createConstructor_; } - - bool delegated() const { - return !!(reinterpret_cast(createConstructor_) & DelegatedTag); - } + bool defined() const { return !!createConstructor; } bool dependent() const { MOZ_ASSERT(defined()); @@ -491,48 +484,6 @@ struct ClassSpec MOZ_ASSERT(defined()); return !(flags & DontDefineConstructor); } - - const ClassSpec* delegatedClassSpec() const { - MOZ_ASSERT(delegated()); - return reinterpret_cast(reinterpret_cast(createConstructor_) & - ~DelegatedTag); - } - - ClassObjectCreationOp createConstructorHook() const { - if (delegated()) - return delegatedClassSpec()->createConstructorHook(); - return createConstructor_; - } - ClassObjectCreationOp createPrototypeHook() const { - if (delegated()) - return delegatedClassSpec()->createPrototypeHook(); - return createPrototype_; - } - const JSFunctionSpec* constructorFunctions() const { - if (delegated()) - return delegatedClassSpec()->constructorFunctions(); - return constructorFunctions_; - } - const JSPropertySpec* constructorProperties() const { - if (delegated()) - return delegatedClassSpec()->constructorProperties(); - return constructorProperties_; - } - const JSFunctionSpec* prototypeFunctions() const { - if (delegated()) - return delegatedClassSpec()->prototypeFunctions(); - return prototypeFunctions_; - } - const JSPropertySpec* prototypeProperties() const { - if (delegated()) - return delegatedClassSpec()->prototypeProperties(); - return prototypeProperties_; - } - FinishClassInitOp finishInitHook() const { - if (delegated()) - return delegatedClassSpec()->finishInitHook(); - return finishInit_; - } }; struct ClassExtension @@ -573,11 +524,6 @@ struct ClassExtension JSObjectMovedOp objectMovedOp; }; -inline ClassObjectCreationOp DELEGATED_CLASSSPEC(const ClassSpec* spec) { - return reinterpret_cast(reinterpret_cast(spec) | - ClassSpec::DelegatedTag); -} - #define JS_NULL_CLASS_SPEC {nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr} #define JS_NULL_CLASS_EXT {nullptr,nullptr,false,nullptr,nullptr} diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index 60b46f2d5305..7fc7e2148fd5 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -153,8 +153,8 @@ GlobalObject::resolveConstructor(JSContext* cx, Handle global, JS // |createPrototype|, |prototypeFunctions|, and |prototypeProperties| // should all be null. RootedObject proto(cx); - if (clasp->spec.createPrototypeHook()) { - proto = clasp->spec.createPrototypeHook()(cx, key); + if (clasp->spec.createPrototype) { + proto = clasp->spec.createPrototype(cx, key); if (!proto) return false; @@ -162,7 +162,7 @@ GlobalObject::resolveConstructor(JSContext* cx, Handle global, JS } // Create the constructor. - RootedObject ctor(cx, clasp->spec.createConstructorHook()(cx, key)); + RootedObject ctor(cx, clasp->spec.createConstructor(cx, key)); if (!ctor) return false; @@ -178,19 +178,19 @@ GlobalObject::resolveConstructor(JSContext* cx, Handle global, JS // Define any specified functions and properties, unless we're a dependent // standard class (in which case they live on the prototype). if (!StandardClassIsDependent(key)) { - if (const JSFunctionSpec* funs = clasp->spec.prototypeFunctions()) { + if (const JSFunctionSpec* funs = clasp->spec.prototypeFunctions) { if (!JS_DefineFunctions(cx, proto, funs, DontDefineLateProperties)) return false; } - if (const JSPropertySpec* props = clasp->spec.prototypeProperties()) { + if (const JSPropertySpec* props = clasp->spec.prototypeProperties) { if (!JS_DefineProperties(cx, proto, props)) return false; } - if (const JSFunctionSpec* funs = clasp->spec.constructorFunctions()) { + if (const JSFunctionSpec* funs = clasp->spec.constructorFunctions) { if (!JS_DefineFunctions(cx, ctor, funs, DontDefineLateProperties)) return false; } - if (const JSPropertySpec* props = clasp->spec.constructorProperties()) { + if (const JSPropertySpec* props = clasp->spec.constructorProperties) { if (!JS_DefineProperties(cx, ctor, props)) return false; } @@ -201,7 +201,7 @@ GlobalObject::resolveConstructor(JSContext* cx, Handle global, JS return false; // Call the post-initialization hook, if provided. - if (clasp->spec.finishInitHook() && !clasp->spec.finishInitHook()(cx, ctor, proto)) + if (clasp->spec.finishInit && !clasp->spec.finishInit(cx, ctor, proto)) return false; if (clasp->spec.shouldDefineConstructor()) { @@ -354,11 +354,11 @@ InitBareBuiltinCtor(JSContext* cx, Handle global, JSProtoKey prot MOZ_ASSERT(cx->runtime()->isSelfHostingGlobal(global)); const Class* clasp = ProtoKeyToClass(protoKey); RootedObject proto(cx); - proto = clasp->spec.createPrototypeHook()(cx, protoKey); + proto = clasp->spec.createPrototype(cx, protoKey); if (!proto) return false; - RootedObject ctor(cx, clasp->spec.createConstructorHook()(cx, protoKey)); + RootedObject ctor(cx, clasp->spec.createConstructor(cx, protoKey)); if (!ctor) return false; diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index 42957688e759..dc13f0818e78 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -1833,8 +1833,8 @@ const Class TypedArrayObject::classes[Scalar::MaxTypedArrayViewType] = { // @@toStringTag) a custom class. The third requirement mandates that each // prototype's class have the relevant typed array's cached JSProtoKey in them. // Thus we need one class with cached prototype per kind of typed array, with a -// delegated ClassSpec. -#define IMPL_TYPED_ARRAY_PROTO_CLASS(typedArray, i) \ +// dummy createConstructor to placate js::ClassSpec::defined(). +#define IMPL_TYPED_ARRAY_PROTO_CLASS(typedArray) \ { \ /* * Actually ({}).toString.call(Uint8Array.prototype) should throw, because @@ -1859,8 +1859,8 @@ const Class TypedArrayObject::classes[Scalar::MaxTypedArrayViewType] = { nullptr, /* construct */ \ nullptr, /* trace */ \ { \ - DELEGATED_CLASSSPEC(&TypedArrayObject::classes[i].spec), \ - nullptr, \ + typedArray::createConstructor, \ + typedArray::createPrototype, \ nullptr, \ nullptr, \ nullptr, \ @@ -1871,15 +1871,15 @@ const Class TypedArrayObject::classes[Scalar::MaxTypedArrayViewType] = { } const Class TypedArrayObject::protoClasses[Scalar::MaxTypedArrayViewType] = { - IMPL_TYPED_ARRAY_PROTO_CLASS(Int8Array, 0), - IMPL_TYPED_ARRAY_PROTO_CLASS(Uint8Array, 1), - IMPL_TYPED_ARRAY_PROTO_CLASS(Int16Array, 2), - IMPL_TYPED_ARRAY_PROTO_CLASS(Uint16Array, 3), - IMPL_TYPED_ARRAY_PROTO_CLASS(Int32Array, 4), - IMPL_TYPED_ARRAY_PROTO_CLASS(Uint32Array, 5), - IMPL_TYPED_ARRAY_PROTO_CLASS(Float32Array, 6), - IMPL_TYPED_ARRAY_PROTO_CLASS(Float64Array, 7), - IMPL_TYPED_ARRAY_PROTO_CLASS(Uint8ClampedArray, 8) + IMPL_TYPED_ARRAY_PROTO_CLASS(Int8Array), + IMPL_TYPED_ARRAY_PROTO_CLASS(Uint8Array), + IMPL_TYPED_ARRAY_PROTO_CLASS(Int16Array), + IMPL_TYPED_ARRAY_PROTO_CLASS(Uint16Array), + IMPL_TYPED_ARRAY_PROTO_CLASS(Int32Array), + IMPL_TYPED_ARRAY_PROTO_CLASS(Uint32Array), + IMPL_TYPED_ARRAY_PROTO_CLASS(Float32Array), + IMPL_TYPED_ARRAY_PROTO_CLASS(Float64Array), + IMPL_TYPED_ARRAY_PROTO_CLASS(Uint8ClampedArray) }; /* static */ bool diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index 0d3e35a047c8..55c024a02f48 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -504,7 +504,7 @@ JSXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsWrapper, // Scan through the functions. Indexed array properties are handled above. const JSFunctionSpec* fsMatch = nullptr; - for (const JSFunctionSpec* fs = clasp->spec.prototypeFunctions(); fs && fs->name; ++fs) { + for (const JSFunctionSpec* fs = clasp->spec.prototypeFunctions; fs && fs->name; ++fs) { if (PropertySpecNameEqualsId(fs->name, id)) { fsMatch = fs; break; @@ -532,7 +532,7 @@ JSXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsWrapper, // Scan through the properties. const JSPropertySpec* psMatch = nullptr; - for (const JSPropertySpec* ps = clasp->spec.prototypeProperties(); ps && ps->name; ++ps) { + for (const JSPropertySpec* ps = clasp->spec.prototypeProperties; ps && ps->name; ++ps) { if (PropertySpecNameEqualsId(ps->name, id)) { psMatch = ps; break; @@ -765,14 +765,14 @@ JSXrayTraits::enumerateNames(JSContext* cx, HandleObject wrapper, unsigned flags MOZ_ASSERT(clasp->spec.defined()); // Convert the method and property names to jsids and pass them to the caller. - for (const JSFunctionSpec* fs = clasp->spec.prototypeFunctions(); fs && fs->name; ++fs) { + for (const JSFunctionSpec* fs = clasp->spec.prototypeFunctions; fs && fs->name; ++fs) { jsid id; if (!PropertySpecNameToPermanentId(cx, fs->name, &id)) return false; if (!MaybeAppend(id, flags, props)) return false; } - for (const JSPropertySpec* ps = clasp->spec.prototypeProperties(); ps && ps->name; ++ps) { + for (const JSPropertySpec* ps = clasp->spec.prototypeProperties; ps && ps->name; ++ps) { jsid id; if (!PropertySpecNameToPermanentId(cx, ps->name, &id)) return false;