Bug 992958 - Switch Function and Object to ClassSpec. r=luke
This commit is contained in:
@@ -618,7 +618,15 @@ const Class JSFunction::class_ = {
|
|||||||
nullptr, /* call */
|
nullptr, /* call */
|
||||||
fun_hasInstance,
|
fun_hasInstance,
|
||||||
nullptr, /* construct */
|
nullptr, /* construct */
|
||||||
fun_trace
|
fun_trace,
|
||||||
|
{
|
||||||
|
CreateFunctionConstructor,
|
||||||
|
CreateFunctionPrototype,
|
||||||
|
nullptr,
|
||||||
|
function_methods,
|
||||||
|
nullptr,
|
||||||
|
FinishFunctionClassInit
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const Class* const js::FunctionClassPtr = &JSFunction::class_;
|
const Class* const js::FunctionClassPtr = &JSFunction::class_;
|
||||||
|
|||||||
@@ -80,7 +80,20 @@ const Class JSObject::class_ = {
|
|||||||
JS_StrictPropertyStub, /* setProperty */
|
JS_StrictPropertyStub, /* setProperty */
|
||||||
JS_EnumerateStub,
|
JS_EnumerateStub,
|
||||||
JS_ResolveStub,
|
JS_ResolveStub,
|
||||||
JS_ConvertStub
|
JS_ConvertStub,
|
||||||
|
nullptr, /* finalize */
|
||||||
|
nullptr, /* call */
|
||||||
|
nullptr, /* hasInstance */
|
||||||
|
nullptr, /* construct */
|
||||||
|
nullptr, /* trace */
|
||||||
|
{
|
||||||
|
CreateObjectConstructor,
|
||||||
|
CreateObjectPrototype,
|
||||||
|
object_static_methods,
|
||||||
|
object_methods,
|
||||||
|
object_properties,
|
||||||
|
FinishObjectClassInit
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const Class* const js::ObjectClassPtr = &JSObject::class_;
|
const Class* const js::ObjectClassPtr = &JSObject::class_;
|
||||||
|
|||||||
@@ -62,8 +62,8 @@
|
|||||||
|
|
||||||
#define JS_FOR_PROTOTYPES(real,imaginary) \
|
#define JS_FOR_PROTOTYPES(real,imaginary) \
|
||||||
imaginary(Null, 0, js_InitNullClass, dummy) \
|
imaginary(Null, 0, js_InitNullClass, dummy) \
|
||||||
real(Object, 1, js_InitObjectClass, &JSObject::class_) \
|
real(Object, 1, js_InitViaClassSpec, &JSObject::class_) \
|
||||||
real(Function, 2, js_InitFunctionClass, &JSFunction::class_) \
|
real(Function, 2, js_InitViaClassSpec, &JSFunction::class_) \
|
||||||
real(Array, 3, js_InitArrayClass, OCLASP(Array)) \
|
real(Array, 3, js_InitArrayClass, OCLASP(Array)) \
|
||||||
real(Boolean, 4, js_InitBooleanClass, OCLASP(Boolean)) \
|
real(Boolean, 4, js_InitBooleanClass, OCLASP(Boolean)) \
|
||||||
real(JSON, 5, js_InitJSONClass, CLASP(JSON)) \
|
real(JSON, 5, js_InitJSONClass, CLASP(JSON)) \
|
||||||
|
|||||||
@@ -80,22 +80,6 @@ js::GlobalObject::getTypedObjectModule() const {
|
|||||||
return v.toObject().as<TypedObjectModuleObject>();
|
return v.toObject().as<TypedObjectModuleObject>();
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject *
|
|
||||||
js_InitObjectClass(JSContext *cx, HandleObject obj)
|
|
||||||
{
|
|
||||||
JS_ASSERT(obj->isNative());
|
|
||||||
|
|
||||||
return obj->as<GlobalObject>().getOrCreateObjectPrototype(cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
JSObject *
|
|
||||||
js_InitFunctionClass(JSContext *cx, HandleObject obj)
|
|
||||||
{
|
|
||||||
JS_ASSERT(obj->isNative());
|
|
||||||
|
|
||||||
return obj->as<GlobalObject>().getOrCreateFunctionPrototype(cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ThrowTypeError(JSContext *cx, unsigned argc, Value *vp)
|
ThrowTypeError(JSContext *cx, unsigned argc, Value *vp)
|
||||||
{
|
{
|
||||||
@@ -210,6 +194,8 @@ JSObject *
|
|||||||
js::CreateObjectConstructor(JSContext *cx, JSProtoKey key)
|
js::CreateObjectConstructor(JSContext *cx, JSProtoKey key)
|
||||||
{
|
{
|
||||||
Rooted<GlobalObject*> self(cx, cx->global());
|
Rooted<GlobalObject*> self(cx, cx->global());
|
||||||
|
if (!GlobalObject::ensureConstructor(cx, self, JSProto_Function))
|
||||||
|
return nullptr;
|
||||||
RootedObject functionProto(cx, &self->getPrototype(JSProto_Function).toObject());
|
RootedObject functionProto(cx, &self->getPrototype(JSProto_Function).toObject());
|
||||||
|
|
||||||
/* Create the Object function now that we have a [[Prototype]] for it. */
|
/* Create the Object function now that we have a [[Prototype]] for it. */
|
||||||
@@ -242,65 +228,6 @@ js::CreateFunctionConstructor(JSContext *cx, JSProtoKey key)
|
|||||||
return functionCtor;
|
return functionCtor;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject *
|
|
||||||
GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
|
|
||||||
{
|
|
||||||
Rooted<GlobalObject*> self(cx, cx->global());
|
|
||||||
|
|
||||||
RootedObject objectProto(cx, CreateObjectPrototype(cx, JSProto_Object));
|
|
||||||
if (!objectProto)
|
|
||||||
return nullptr;
|
|
||||||
self->setPrototype(JSProto_Object, ObjectValue(*objectProto));
|
|
||||||
|
|
||||||
RootedObject functionProto(cx, CreateFunctionPrototype(cx, JSProto_Function));
|
|
||||||
if (!functionProto)
|
|
||||||
return nullptr;
|
|
||||||
self->setPrototype(JSProto_Function, ObjectValue(*functionProto));
|
|
||||||
|
|
||||||
RootedObject objectCtor(cx, CreateObjectConstructor(cx, JSProto_Object));
|
|
||||||
if (!objectCtor)
|
|
||||||
return nullptr;
|
|
||||||
self->setConstructor(JSProto_Object, ObjectValue(*objectCtor));
|
|
||||||
self->setConstructorPropertySlot(JSProto_Object, ObjectValue(*objectCtor));
|
|
||||||
|
|
||||||
RootedObject functionCtor(cx, CreateFunctionConstructor(cx, JSProto_Function));
|
|
||||||
if (!functionCtor)
|
|
||||||
return nullptr;
|
|
||||||
self->setConstructor(JSProto_Function, ObjectValue(*functionCtor));
|
|
||||||
self->setConstructorPropertySlot(JSProto_Function, ObjectValue(*functionCtor));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The hard part's done: now go back and add all the properties these
|
|
||||||
* primordial values have.
|
|
||||||
*/
|
|
||||||
if (!LinkConstructorAndPrototype(cx, objectCtor, objectProto) ||
|
|
||||||
!DefinePropertiesAndBrand(cx, objectProto, object_properties, object_methods))
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DefinePropertiesAndBrand(cx, objectCtor, nullptr, object_static_methods) ||
|
|
||||||
!LinkConstructorAndPrototype(cx, functionCtor, functionProto) ||
|
|
||||||
!DefinePropertiesAndBrand(cx, functionProto, nullptr, function_methods) ||
|
|
||||||
!DefinePropertiesAndBrand(cx, functionCtor, nullptr, nullptr))
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the global Function and Object properties now. */
|
|
||||||
if (!self->addDataProperty(cx, cx->names().Object, constructorPropertySlot(JSProto_Object), 0))
|
|
||||||
return nullptr;
|
|
||||||
if (!self->addDataProperty(cx, cx->names().Function, constructorPropertySlot(JSProto_Function), 0))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if (!FinishObjectClassInit(cx, objectCtor, objectProto))
|
|
||||||
return nullptr;
|
|
||||||
if (!FinishFunctionClassInit(cx, functionCtor, functionProto))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return functionProto;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
js::FinishObjectClassInit(JSContext *cx, JS::HandleObject ctor, JS::HandleObject proto)
|
js::FinishObjectClassInit(JSContext *cx, JS::HandleObject ctor, JS::HandleObject proto)
|
||||||
{
|
{
|
||||||
@@ -418,6 +345,14 @@ GlobalObject::resolveConstructor(JSContext *cx, Handle<GlobalObject*> global, JS
|
|||||||
// * Function
|
// * Function
|
||||||
// * Object
|
// * Object
|
||||||
//
|
//
|
||||||
|
// We get the above when Object is resolved before Function. If Function
|
||||||
|
// is resolved before Object, we'll end up re-entering resolveConstructor
|
||||||
|
// for Function, which is a problem. So if Function is being resolved before
|
||||||
|
// Object.prototype exists, we just resolve Object instead, since we know that
|
||||||
|
// Function will also be resolved before we return.
|
||||||
|
if (key == JSProto_Function && global->getPrototype(JSProto_Object).isUndefined())
|
||||||
|
return resolveConstructor(cx, global, JSProto_Object);
|
||||||
|
|
||||||
// We don't always have a prototype (i.e. Math and JSON). If we don't,
|
// We don't always have a prototype (i.e. Math and JSON). If we don't,
|
||||||
// |createPrototype|, |prototypeFunctions|, and |prototypeProperties|
|
// |createPrototype|, |prototypeFunctions|, and |prototypeProperties|
|
||||||
// should all be null.
|
// should all be null.
|
||||||
|
|||||||
@@ -18,12 +18,6 @@
|
|||||||
#include "vm/ArrayBufferObject.h"
|
#include "vm/ArrayBufferObject.h"
|
||||||
#include "vm/ErrorObject.h"
|
#include "vm/ErrorObject.h"
|
||||||
|
|
||||||
extern JSObject *
|
|
||||||
js_InitObjectClass(JSContext *cx, js::HandleObject obj);
|
|
||||||
|
|
||||||
extern JSObject *
|
|
||||||
js_InitFunctionClass(JSContext *cx, js::HandleObject obj);
|
|
||||||
|
|
||||||
extern JSObject *
|
extern JSObject *
|
||||||
js_InitTypedArrayClasses(JSContext *cx, js::HandleObject obj);
|
js_InitTypedArrayClasses(JSContext *cx, js::HandleObject obj);
|
||||||
|
|
||||||
@@ -127,10 +121,6 @@ class GlobalObject : public JSObject
|
|||||||
static_assert(JSCLASS_GLOBAL_SLOT_COUNT == RESERVED_SLOTS,
|
static_assert(JSCLASS_GLOBAL_SLOT_COUNT == RESERVED_SLOTS,
|
||||||
"global object slot counts are inconsistent");
|
"global object slot counts are inconsistent");
|
||||||
|
|
||||||
/* Initialize the Function and Object classes. Must only be called once! */
|
|
||||||
JSObject *
|
|
||||||
initFunctionAndObjectClasses(JSContext *cx);
|
|
||||||
|
|
||||||
// Emit the specified warning if the given slot in |obj|'s global isn't
|
// Emit the specified warning if the given slot in |obj|'s global isn't
|
||||||
// true, then set the slot to true. Thus calling this method warns once
|
// true, then set the slot to true. Thus calling this method warns once
|
||||||
// for each global object it's called on, and every other call does
|
// for each global object it's called on, and every other call does
|
||||||
@@ -313,7 +303,7 @@ class GlobalObject : public JSObject
|
|||||||
if (functionObjectClassesInitialized())
|
if (functionObjectClassesInitialized())
|
||||||
return &getPrototype(JSProto_Object).toObject();
|
return &getPrototype(JSProto_Object).toObject();
|
||||||
Rooted<GlobalObject*> self(cx, this);
|
Rooted<GlobalObject*> self(cx, this);
|
||||||
if (!initFunctionAndObjectClasses(cx))
|
if (!ensureConstructor(cx, self, JSProto_Object))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return &self->getPrototype(JSProto_Object).toObject();
|
return &self->getPrototype(JSProto_Object).toObject();
|
||||||
}
|
}
|
||||||
@@ -322,7 +312,7 @@ class GlobalObject : public JSObject
|
|||||||
if (functionObjectClassesInitialized())
|
if (functionObjectClassesInitialized())
|
||||||
return &getPrototype(JSProto_Function).toObject();
|
return &getPrototype(JSProto_Function).toObject();
|
||||||
Rooted<GlobalObject*> self(cx, this);
|
Rooted<GlobalObject*> self(cx, this);
|
||||||
if (!initFunctionAndObjectClasses(cx))
|
if (!ensureConstructor(cx, self, JSProto_Object))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return &self->getPrototype(JSProto_Function).toObject();
|
return &self->getPrototype(JSProto_Function).toObject();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user