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
parent f2526ec66b
commit 59967ca2ab
4 changed files with 35 additions and 89 deletions

View File

@ -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<uintptr_t>(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<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
@ -573,11 +524,6 @@ struct ClassExtension
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_EXT {nullptr,nullptr,false,nullptr,nullptr}

View File

@ -153,8 +153,8 @@ GlobalObject::resolveConstructor(JSContext* cx, Handle<GlobalObject*> 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<GlobalObject*> 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<GlobalObject*> 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<GlobalObject*> 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<GlobalObject*> 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;

View File

@ -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

View File

@ -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;