Bug 975589, part 2 - Avoid recursing in TypedArray initialization. r=jwalden.

This commit is contained in:
Jason Orendorff 2014-03-10 16:29:58 -05:00
Родитель 7c295cc938
Коммит a7de95340c
4 изменённых файлов: 35 добавлений и 37 удалений

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

@ -3244,8 +3244,8 @@ MaybeResolveConstructor(ExclusiveContext *cxArg, Handle<GlobalObject*> global, J
RootedId name(cx, NameToId(ClassName(key, cx)));
AutoResolving resolving(cx, global, name);
if (resolving.alreadyStarted())
return true;
return GlobalObject::ensureConstructor(cx, global, key);
return true;
return GlobalObject::resolveConstructor(cx, global, key);
}
bool

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

@ -446,7 +446,7 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
/* static */ bool
GlobalObject::ensureConstructor(JSContext *cx, Handle<GlobalObject*> global, JSProtoKey key)
{
if (global->getConstructor(key).isObject())
if (global->isStandardClassResolved(key))
return true;
return resolveConstructor(cx, global, key);
}
@ -454,7 +454,7 @@ GlobalObject::ensureConstructor(JSContext *cx, Handle<GlobalObject*> global, JSP
/* static*/ bool
GlobalObject::resolveConstructor(JSContext *cx, Handle<GlobalObject*> global, JSProtoKey key)
{
MOZ_ASSERT(global->getConstructor(key).isUndefined());
MOZ_ASSERT(!global->isStandardClassResolved(key));
// There are two different kinds of initialization hooks. One of them is
// the class js_InitFoo hook, defined in a JSProtoKey-keyed table at the

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

@ -2140,22 +2140,25 @@ IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Float64, double, double)
}
template<class ArrayType>
static inline JSObject *
static inline bool
InitTypedArrayClass(JSContext *cx)
{
Rooted<GlobalObject*> global(cx, cx->compartment()->maybeGlobal());
if (global->isStandardClassResolved(ArrayType::key))
return true;
RootedObject proto(cx, global->createBlankPrototype(cx, ArrayType::protoClass()));
if (!proto)
return nullptr;
return false;
RootedFunction ctor(cx);
ctor = global->createConstructor(cx, ArrayType::class_constructor,
ClassName(ArrayType::key, cx), 3);
if (!ctor)
return nullptr;
return false;
if (!LinkConstructorAndPrototype(cx, ctor, proto))
return nullptr;
return false;
RootedValue bytesValue(cx, Int32Value(ArrayType::BYTES_PER_ELEMENT));
@ -2168,14 +2171,14 @@ InitTypedArrayClass(JSContext *cx)
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_PERMANENT | JSPROP_READONLY))
{
return nullptr;
return false;
}
if (!ArrayType::defineGetters(cx, proto))
return nullptr;
return false;
if (!JS_DefineFunctions(cx, proto, ArrayType::jsfuncs))
return nullptr;
return false;
RootedFunction fun(cx);
fun =
@ -2183,14 +2186,14 @@ InitTypedArrayClass(JSContext *cx)
ArrayBufferObject::createTypedArrayFromBuffer<typename ArrayType::ThisType>,
0, JSFunction::NATIVE_FUN, global, NullPtr());
if (!fun)
return nullptr;
return false;
if (!GlobalObject::initBuiltinConstructor(cx, global, ArrayType::key, ctor, proto))
return nullptr;
return false;
global->setCreateArrayFromBuffer<typename ArrayType::ThisType>(fun);
return proto;
return true;
}
IMPL_TYPED_ARRAY_STATICS(Int8Array);
@ -2248,6 +2251,9 @@ static JSObject *
InitArrayBufferClass(JSContext *cx)
{
Rooted<GlobalObject*> global(cx, cx->compartment()->maybeGlobal());
if (global->isStandardClassResolved(JSProto_ArrayBuffer))
return &global->getPrototype(JSProto_ArrayBuffer).toObject();
RootedObject arrayBufferProto(cx, global->createBlankPrototype(cx, &ArrayBufferObject::protoClass));
if (!arrayBufferProto)
return nullptr;
@ -2374,33 +2380,36 @@ DataViewObject::defineGetter(JSContext *cx, PropertyName *name, HandleObject pro
flags, 0, 0);
}
/* static */ JSObject *
/* static */ bool
DataViewObject::initClass(JSContext *cx)
{
Rooted<GlobalObject*> global(cx, cx->compartment()->maybeGlobal());
if (global->isStandardClassResolved(JSProto_DataView))
return true;
RootedObject proto(cx, global->createBlankPrototype(cx, &DataViewObject::protoClass));
if (!proto)
return nullptr;
return false;
RootedFunction ctor(cx, global->createConstructor(cx, DataViewObject::class_constructor,
cx->names().DataView, 3));
if (!ctor)
return nullptr;
return false;
if (!LinkConstructorAndPrototype(cx, ctor, proto))
return nullptr;
return false;
if (!defineGetter<bufferValue>(cx, cx->names().buffer, proto))
return nullptr;
return false;
if (!defineGetter<byteLengthValue>(cx, cx->names().byteLength, proto))
return nullptr;
return false;
if (!defineGetter<byteOffsetValue>(cx, cx->names().byteOffset, proto))
return nullptr;
return false;
if (!JS_DefineFunctions(cx, proto, DataViewObject::jsfuncs))
return nullptr;
return false;
/*
* Create a helper function to implement the craziness of
@ -2410,14 +2419,14 @@ DataViewObject::initClass(JSContext *cx)
RootedFunction fun(cx, NewFunction(cx, NullPtr(), ArrayBufferObject::createDataViewForThis,
0, JSFunction::NATIVE_FUN, global, NullPtr()));
if (!fun)
return nullptr;
return false;
if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_DataView, ctor, proto))
return nullptr;
return false;
global->setCreateDataViewForThis(fun);
return proto;
return true;
}
void
@ -2431,17 +2440,6 @@ DataViewObject::neuter()
JSObject *
js_InitTypedArrayClasses(JSContext *cx, HandleObject obj)
{
JS_ASSERT(obj->isNative());
assertSameCompartment(cx, obj);
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
/* Idempotency required: we initialize several things, possibly lazily. */
RootedObject stop(cx);
if (!js_GetClassObject(cx, JSProto_ArrayBuffer, &stop))
return nullptr;
if (stop)
return stop;
if (!InitTypedArrayClass<Int8ArrayObject>(cx) ||
!InitTypedArrayClass<Uint8ArrayObject>(cx) ||
!InitTypedArrayClass<Int16ArrayObject>(cx) ||

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

@ -310,7 +310,7 @@ class DataViewObject : public ArrayBufferViewObject
static bool setFloat64Impl(JSContext *cx, CallArgs args);
static bool fun_setFloat64(JSContext *cx, unsigned argc, Value *vp);
static JSObject *initClass(JSContext *cx);
static bool initClass(JSContext *cx);
static void neuter(JSObject *view);
static bool getDataPointer(JSContext *cx, Handle<DataViewObject*> obj,
CallArgs args, size_t typeSize, uint8_t **data);