Backed out changeset 3841e37b0e2f (bug 861219) for JS Crashes on a CLOSED TREE

This commit is contained in:
Carsten "Tomcat" Book 2015-05-12 12:27:52 +02:00
Родитель f2526ec66b
Коммит 59967ca2ab
4 изменённых файлов: 35 добавлений и 89 удалений

Просмотреть файл

@ -454,14 +454,13 @@ const size_t JSCLASS_CACHED_PROTO_WIDTH = 6;
struct ClassSpec struct ClassSpec
{ {
// All properties except flags should be accessed through get* accessor. ClassObjectCreationOp createConstructor;
ClassObjectCreationOp createConstructor_; ClassObjectCreationOp createPrototype;
ClassObjectCreationOp createPrototype_; const JSFunctionSpec* constructorFunctions;
const JSFunctionSpec* constructorFunctions_; const JSPropertySpec* constructorProperties;
const JSPropertySpec* constructorProperties_; const JSFunctionSpec* prototypeFunctions;
const JSFunctionSpec* prototypeFunctions_; const JSPropertySpec* prototypeProperties;
const JSPropertySpec* prototypeProperties_; FinishClassInitOp finishInit;
FinishClassInitOp finishInit_;
uintptr_t flags; uintptr_t flags;
static const size_t ParentKeyWidth = JSCLASS_CACHED_PROTO_WIDTH; 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 ParentKeyMask = (1 << ParentKeyWidth) - 1;
static const uintptr_t DontDefineConstructor = 1 << ParentKeyWidth; static const uintptr_t DontDefineConstructor = 1 << ParentKeyWidth;
static const uintptr_t DelegatedTag = 1; bool defined() const { return !!createConstructor; }
bool defined() const { return !!createConstructor_; }
bool delegated() const {
return !!(reinterpret_cast<uintptr_t>(createConstructor_) & DelegatedTag);
}
bool dependent() const { bool dependent() const {
MOZ_ASSERT(defined()); MOZ_ASSERT(defined());
@ -491,48 +484,6 @@ struct ClassSpec
MOZ_ASSERT(defined()); MOZ_ASSERT(defined());
return !(flags & DontDefineConstructor); return !(flags & DontDefineConstructor);
} }
const ClassSpec* delegatedClassSpec() const {
MOZ_ASSERT(delegated());
return reinterpret_cast<ClassSpec*>(reinterpret_cast<uintptr_t>(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 struct ClassExtension
@ -573,11 +524,6 @@ struct ClassExtension
JSObjectMovedOp objectMovedOp; JSObjectMovedOp objectMovedOp;
}; };
inline ClassObjectCreationOp DELEGATED_CLASSSPEC(const ClassSpec* spec) {
return reinterpret_cast<ClassObjectCreationOp>(reinterpret_cast<uintptr_t>(spec) |
ClassSpec::DelegatedTag);
}
#define JS_NULL_CLASS_SPEC {nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr} #define JS_NULL_CLASS_SPEC {nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr}
#define JS_NULL_CLASS_EXT {nullptr,nullptr,false,nullptr,nullptr} #define JS_NULL_CLASS_EXT {nullptr,nullptr,false,nullptr,nullptr}

Просмотреть файл

@ -153,8 +153,8 @@ GlobalObject::resolveConstructor(JSContext* cx, Handle<GlobalObject*> global, JS
// |createPrototype|, |prototypeFunctions|, and |prototypeProperties| // |createPrototype|, |prototypeFunctions|, and |prototypeProperties|
// should all be null. // should all be null.
RootedObject proto(cx); RootedObject proto(cx);
if (clasp->spec.createPrototypeHook()) { if (clasp->spec.createPrototype) {
proto = clasp->spec.createPrototypeHook()(cx, key); proto = clasp->spec.createPrototype(cx, key);
if (!proto) if (!proto)
return false; return false;
@ -162,7 +162,7 @@ GlobalObject::resolveConstructor(JSContext* cx, Handle<GlobalObject*> global, JS
} }
// Create the constructor. // Create the constructor.
RootedObject ctor(cx, clasp->spec.createConstructorHook()(cx, key)); RootedObject ctor(cx, clasp->spec.createConstructor(cx, key));
if (!ctor) if (!ctor)
return false; return false;
@ -178,19 +178,19 @@ GlobalObject::resolveConstructor(JSContext* cx, Handle<GlobalObject*> global, JS
// Define any specified functions and properties, unless we're a dependent // Define any specified functions and properties, unless we're a dependent
// standard class (in which case they live on the prototype). // standard class (in which case they live on the prototype).
if (!StandardClassIsDependent(key)) { if (!StandardClassIsDependent(key)) {
if (const JSFunctionSpec* funs = clasp->spec.prototypeFunctions()) { if (const JSFunctionSpec* funs = clasp->spec.prototypeFunctions) {
if (!JS_DefineFunctions(cx, proto, funs, DontDefineLateProperties)) if (!JS_DefineFunctions(cx, proto, funs, DontDefineLateProperties))
return false; return false;
} }
if (const JSPropertySpec* props = clasp->spec.prototypeProperties()) { if (const JSPropertySpec* props = clasp->spec.prototypeProperties) {
if (!JS_DefineProperties(cx, proto, props)) if (!JS_DefineProperties(cx, proto, props))
return false; return false;
} }
if (const JSFunctionSpec* funs = clasp->spec.constructorFunctions()) { if (const JSFunctionSpec* funs = clasp->spec.constructorFunctions) {
if (!JS_DefineFunctions(cx, ctor, funs, DontDefineLateProperties)) if (!JS_DefineFunctions(cx, ctor, funs, DontDefineLateProperties))
return false; return false;
} }
if (const JSPropertySpec* props = clasp->spec.constructorProperties()) { if (const JSPropertySpec* props = clasp->spec.constructorProperties) {
if (!JS_DefineProperties(cx, ctor, props)) if (!JS_DefineProperties(cx, ctor, props))
return false; return false;
} }
@ -201,7 +201,7 @@ GlobalObject::resolveConstructor(JSContext* cx, Handle<GlobalObject*> global, JS
return false; return false;
// Call the post-initialization hook, if provided. // 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; return false;
if (clasp->spec.shouldDefineConstructor()) { if (clasp->spec.shouldDefineConstructor()) {
@ -354,11 +354,11 @@ InitBareBuiltinCtor(JSContext* cx, Handle<GlobalObject*> global, JSProtoKey prot
MOZ_ASSERT(cx->runtime()->isSelfHostingGlobal(global)); MOZ_ASSERT(cx->runtime()->isSelfHostingGlobal(global));
const Class* clasp = ProtoKeyToClass(protoKey); const Class* clasp = ProtoKeyToClass(protoKey);
RootedObject proto(cx); RootedObject proto(cx);
proto = clasp->spec.createPrototypeHook()(cx, protoKey); proto = clasp->spec.createPrototype(cx, protoKey);
if (!proto) if (!proto)
return false; return false;
RootedObject ctor(cx, clasp->spec.createConstructorHook()(cx, protoKey)); RootedObject ctor(cx, clasp->spec.createConstructor(cx, protoKey));
if (!ctor) if (!ctor)
return false; return false;

Просмотреть файл

@ -1833,8 +1833,8 @@ const Class TypedArrayObject::classes[Scalar::MaxTypedArrayViewType] = {
// @@toStringTag) a custom class. The third requirement mandates that each // @@toStringTag) a custom class. The third requirement mandates that each
// prototype's class have the relevant typed array's cached JSProtoKey in them. // 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 // Thus we need one class with cached prototype per kind of typed array, with a
// delegated ClassSpec. // dummy createConstructor to placate js::ClassSpec::defined().
#define IMPL_TYPED_ARRAY_PROTO_CLASS(typedArray, i) \ #define IMPL_TYPED_ARRAY_PROTO_CLASS(typedArray) \
{ \ { \
/* /*
* Actually ({}).toString.call(Uint8Array.prototype) should throw, because * Actually ({}).toString.call(Uint8Array.prototype) should throw, because
@ -1859,8 +1859,8 @@ const Class TypedArrayObject::classes[Scalar::MaxTypedArrayViewType] = {
nullptr, /* construct */ \ nullptr, /* construct */ \
nullptr, /* trace */ \ nullptr, /* trace */ \
{ \ { \
DELEGATED_CLASSSPEC(&TypedArrayObject::classes[i].spec), \ typedArray::createConstructor, \
nullptr, \ typedArray::createPrototype, \
nullptr, \ nullptr, \
nullptr, \ nullptr, \
nullptr, \ nullptr, \
@ -1871,15 +1871,15 @@ const Class TypedArrayObject::classes[Scalar::MaxTypedArrayViewType] = {
} }
const Class TypedArrayObject::protoClasses[Scalar::MaxTypedArrayViewType] = { const Class TypedArrayObject::protoClasses[Scalar::MaxTypedArrayViewType] = {
IMPL_TYPED_ARRAY_PROTO_CLASS(Int8Array, 0), IMPL_TYPED_ARRAY_PROTO_CLASS(Int8Array),
IMPL_TYPED_ARRAY_PROTO_CLASS(Uint8Array, 1), IMPL_TYPED_ARRAY_PROTO_CLASS(Uint8Array),
IMPL_TYPED_ARRAY_PROTO_CLASS(Int16Array, 2), IMPL_TYPED_ARRAY_PROTO_CLASS(Int16Array),
IMPL_TYPED_ARRAY_PROTO_CLASS(Uint16Array, 3), IMPL_TYPED_ARRAY_PROTO_CLASS(Uint16Array),
IMPL_TYPED_ARRAY_PROTO_CLASS(Int32Array, 4), IMPL_TYPED_ARRAY_PROTO_CLASS(Int32Array),
IMPL_TYPED_ARRAY_PROTO_CLASS(Uint32Array, 5), IMPL_TYPED_ARRAY_PROTO_CLASS(Uint32Array),
IMPL_TYPED_ARRAY_PROTO_CLASS(Float32Array, 6), IMPL_TYPED_ARRAY_PROTO_CLASS(Float32Array),
IMPL_TYPED_ARRAY_PROTO_CLASS(Float64Array, 7), IMPL_TYPED_ARRAY_PROTO_CLASS(Float64Array),
IMPL_TYPED_ARRAY_PROTO_CLASS(Uint8ClampedArray, 8) IMPL_TYPED_ARRAY_PROTO_CLASS(Uint8ClampedArray)
}; };
/* static */ bool /* static */ bool

Просмотреть файл

@ -504,7 +504,7 @@ JSXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsWrapper,
// Scan through the functions. Indexed array properties are handled above. // Scan through the functions. Indexed array properties are handled above.
const JSFunctionSpec* fsMatch = nullptr; 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)) { if (PropertySpecNameEqualsId(fs->name, id)) {
fsMatch = fs; fsMatch = fs;
break; break;
@ -532,7 +532,7 @@ JSXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsWrapper,
// Scan through the properties. // Scan through the properties.
const JSPropertySpec* psMatch = nullptr; 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)) { if (PropertySpecNameEqualsId(ps->name, id)) {
psMatch = ps; psMatch = ps;
break; break;
@ -765,14 +765,14 @@ JSXrayTraits::enumerateNames(JSContext* cx, HandleObject wrapper, unsigned flags
MOZ_ASSERT(clasp->spec.defined()); MOZ_ASSERT(clasp->spec.defined());
// Convert the method and property names to jsids and pass them to the caller. // 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; jsid id;
if (!PropertySpecNameToPermanentId(cx, fs->name, &id)) if (!PropertySpecNameToPermanentId(cx, fs->name, &id))
return false; return false;
if (!MaybeAppend(id, flags, props)) if (!MaybeAppend(id, flags, props))
return false; 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; jsid id;
if (!PropertySpecNameToPermanentId(cx, ps->name, &id)) if (!PropertySpecNameToPermanentId(cx, ps->name, &id))
return false; return false;