Bug 1107496 - Add PlainObject subclass, r=luke.

This commit is contained in:
Brian Hackett 2014-12-05 18:52:28 -07:00
parent a390d9a15d
commit 3addc0dc27
65 changed files with 481 additions and 482 deletions

View File

@ -759,7 +759,7 @@ CallAsmJS(JSContext *cx, unsigned argc, Value *vp)
// returns a primary type, which is the case for all asm.js exported
// functions, the returned value is discarded and an empty object is
// returned instead.
JSObject *obj = NewBuiltinClassInstance(cx, &JSObject::class_);
PlainObject *obj = NewBuiltinClassInstance<PlainObject>(cx);
callArgs.rval().set(ObjectValue(*obj));
return true;
}
@ -997,7 +997,7 @@ CreateExportObject(JSContext *cx, Handle<AsmJSModuleObject*> moduleObj)
}
gc::AllocKind allocKind = gc::GetGCObjectKind(module.numExportedFunctions());
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &JSObject::class_, allocKind));
RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx, allocKind));
if (!obj)
return nullptr;

View File

@ -420,7 +420,7 @@ IntlInitialize(JSContext *cx, HandleObject obj, Handle<PropertyName*> initialize
static bool
CreateDefaultOptions(JSContext *cx, MutableHandleValue defaultOptions)
{
RootedObject options(cx, NewObjectWithGivenProto(cx, &JSObject::class_, nullptr, cx->global()));
RootedObject options(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr, cx->global()));
if (!options)
return false;
defaultOptions.setObject(*options);
@ -439,7 +439,7 @@ static bool
intl_availableLocales(JSContext *cx, CountAvailable countAvailable,
GetAvailable getAvailable, MutableHandleValue result)
{
RootedObject locales(cx, NewObjectWithGivenProto(cx, &JSObject::class_, nullptr, nullptr));
RootedObject locales(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr, nullptr));
if (!locales)
return false;

View File

@ -904,8 +904,8 @@ GlobalObject::initMapIteratorProto(JSContext *cx, Handle<GlobalObject *> global)
JSObject *base = GlobalObject::getOrCreateIteratorPrototype(cx, global);
if (!base)
return false;
RootedNativeObject proto(cx,
NewNativeObjectWithGivenProto(cx, &MapIteratorObject::class_, base, global));
Rooted<MapIteratorObject *> proto(cx,
NewObjectWithGivenProto<MapIteratorObject>(cx, base, global));
if (!proto)
return false;
proto->setSlot(MapIteratorObject::RangeSlot, PrivateValue(nullptr));
@ -928,7 +928,7 @@ MapIteratorObject::create(JSContext *cx, HandleObject mapobj, ValueMap *data,
if (!range)
return nullptr;
NativeObject *iterobj = NewNativeObjectWithGivenProto(cx, &class_, proto, global);
MapIteratorObject *iterobj = NewObjectWithGivenProto<MapIteratorObject>(cx, proto, global);
if (!iterobj) {
js_delete(range);
return nullptr;
@ -936,7 +936,7 @@ MapIteratorObject::create(JSContext *cx, HandleObject mapobj, ValueMap *data,
iterobj->setSlot(TargetSlot, ObjectValue(*mapobj));
iterobj->setSlot(KindSlot, Int32Value(int32_t(kind)));
iterobj->setSlot(RangeSlot, PrivateValue(range));
return static_cast<MapIteratorObject *>(iterobj);
return iterobj;
}
void
@ -1207,7 +1207,7 @@ MapObject::set(JSContext *cx, HandleObject obj, HandleValue k, HandleValue v)
MapObject*
MapObject::create(JSContext *cx)
{
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &class_));
Rooted<MapObject *> obj(cx, NewBuiltinClassInstance<MapObject>(cx));
if (!obj)
return nullptr;
@ -1219,7 +1219,7 @@ MapObject::create(JSContext *cx)
}
obj->setPrivate(map);
return &obj->as<MapObject>();
return obj;
}
void
@ -1586,8 +1586,8 @@ GlobalObject::initSetIteratorProto(JSContext *cx, Handle<GlobalObject*> global)
JSObject *base = GlobalObject::getOrCreateIteratorPrototype(cx, global);
if (!base)
return false;
RootedNativeObject proto(cx, NewNativeObjectWithGivenProto(cx, &SetIteratorObject::class_,
base, global));
Rooted<SetIteratorObject *> proto(cx,
NewObjectWithGivenProto<SetIteratorObject>(cx, base, global));
if (!proto)
return false;
proto->setSlot(SetIteratorObject::RangeSlot, PrivateValue(nullptr));
@ -1610,7 +1610,7 @@ SetIteratorObject::create(JSContext *cx, HandleObject setobj, ValueSet *data,
if (!range)
return nullptr;
NativeObject *iterobj = NewNativeObjectWithGivenProto(cx, &class_, proto, global);
SetIteratorObject *iterobj = NewObjectWithGivenProto<SetIteratorObject>(cx, proto, global);
if (!iterobj) {
js_delete(range);
return nullptr;
@ -1618,7 +1618,7 @@ SetIteratorObject::create(JSContext *cx, HandleObject setobj, ValueSet *data,
iterobj->setSlot(TargetSlot, ObjectValue(*setobj));
iterobj->setSlot(KindSlot, Int32Value(int32_t(kind)));
iterobj->setSlot(RangeSlot, PrivateValue(range));
return static_cast<SetIteratorObject *>(iterobj);
return iterobj;
}
void
@ -1786,7 +1786,7 @@ SetObject::add(JSContext *cx, HandleObject obj, HandleValue k)
SetObject*
SetObject::create(JSContext *cx)
{
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &class_));
SetObject *obj = NewBuiltinClassInstance<SetObject>(cx);
if (!obj)
return nullptr;
@ -1797,7 +1797,7 @@ SetObject::create(JSContext *cx)
return nullptr;
}
obj->setPrivate(set);
return &obj->as<SetObject>();
return obj;
}
void

View File

@ -11,6 +11,7 @@
#include "jscntxt.h"
#include "builtin/Eval.h"
#include "frontend/BytecodeCompiler.h"
#include "vm/StringBuffer.h"
@ -321,7 +322,7 @@ JS_BasicObjectToString(JSContext *cx, HandleObject obj)
{
// Some classes are really common, don't allocate new strings for them.
// The ordering below is based on the measurements in bug 966264.
if (obj->is<JSObject>())
if (obj->is<PlainObject>())
return cx->names().objectObject;
if (obj->is<StringObject>())
return cx->names().objectString;
@ -429,7 +430,7 @@ DefineAccessor(JSContext *cx, unsigned argc, Value *vp)
if (!ValueToId<CanGC>(cx, args[0], &id))
return false;
RootedObject descObj(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
RootedObject descObj(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!descObj)
return false;
@ -812,7 +813,7 @@ js::obj_create(JSContext *cx, unsigned argc, Value *vp)
* Use the callee's global as the parent of the new object to avoid dynamic
* scoping (i.e., using the caller's global).
*/
RootedObject obj(cx, NewObjectWithGivenProto(cx, &JSObject::class_, proto, &args.callee().global()));
RootedObject obj(cx, NewObjectWithGivenProto<PlainObject>(cx, proto, &args.callee().global()));
if (!obj)
return false;
@ -1183,8 +1184,7 @@ ProtoSetter(JSContext *cx, unsigned argc, Value *vp)
return true;
}
const JSFunctionSpec js::object_methods[] = {
static const JSFunctionSpec object_methods[] = {
#if JS_HAS_TOSOURCE
JS_FN(js_toSource_str, obj_toSource, 0,0),
#endif
@ -1207,14 +1207,14 @@ const JSFunctionSpec js::object_methods[] = {
JS_FS_END
};
const JSPropertySpec js::object_properties[] = {
static const JSPropertySpec object_properties[] = {
#if JS_HAS_OBJ_PROTO_PROP
JS_PSGS("__proto__", ProtoGetter, ProtoSetter, 0),
#endif
JS_PS_END
};
const JSFunctionSpec js::object_static_methods[] = {
static const JSFunctionSpec object_static_methods[] = {
JS_FN("getPrototypeOf", obj_getPrototypeOf, 1,0),
JS_FN("setPrototypeOf", obj_setPrototypeOf, 2,0),
JS_FN("getOwnPropertyDescriptor", obj_getOwnPropertyDescriptor,2,0),
@ -1239,8 +1239,134 @@ const JSFunctionSpec js::object_static_methods[] = {
* time, after the intrinsic holder has been set, so we put them
* in a different array.
*/
const JSFunctionSpec js::object_static_selfhosted_methods[] = {
static const JSFunctionSpec object_static_selfhosted_methods[] = {
JS_SELF_HOSTED_FN("assign", "ObjectStaticAssign", 2,0),
JS_FS_END
};
static JSObject *
CreateObjectConstructor(JSContext *cx, JSProtoKey key)
{
Rooted<GlobalObject*> self(cx, cx->global());
if (!GlobalObject::ensureConstructor(cx, self, JSProto_Function))
return nullptr;
RootedObject functionProto(cx, &self->getPrototype(JSProto_Function).toObject());
/* Create the Object function now that we have a [[Prototype]] for it. */
RootedObject ctor(cx, NewObjectWithGivenProto(cx, &JSFunction::class_, functionProto,
self, SingletonObject));
if (!ctor)
return nullptr;
return NewFunction(cx, ctor, obj_construct, 1, JSFunction::NATIVE_CTOR, self,
HandlePropertyName(cx->names().Object));
}
static JSObject *
CreateObjectPrototype(JSContext *cx, JSProtoKey key)
{
Rooted<GlobalObject*> self(cx, cx->global());
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
MOZ_ASSERT(self->isNative());
/*
* Create |Object.prototype| first, mirroring CreateBlankProto but for the
* prototype of the created object.
*/
RootedPlainObject objectProto(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr,
self, SingletonObject));
if (!objectProto)
return nullptr;
/*
* The default 'new' type of Object.prototype is required by type inference
* to have unknown properties, to simplify handling of e.g. heterogenous
* objects in JSON and script literals.
*/
if (!JSObject::setNewTypeUnknown(cx, &PlainObject::class_, objectProto))
return nullptr;
return objectProto;
}
static bool
FinishObjectClassInit(JSContext *cx, JS::HandleObject ctor, JS::HandleObject proto)
{
Rooted<GlobalObject*> self(cx, cx->global());
/* ES5 15.1.2.1. */
RootedId evalId(cx, NameToId(cx->names().eval));
JSObject *evalobj = DefineFunction(cx, self, evalId, IndirectEval, 1, JSFUN_STUB_GSOPS);
if (!evalobj)
return false;
self->setOriginalEval(evalobj);
RootedObject intrinsicsHolder(cx);
bool isSelfHostingGlobal = cx->runtime()->isSelfHostingGlobal(self);
if (isSelfHostingGlobal) {
intrinsicsHolder = self;
} else {
intrinsicsHolder = NewObjectWithGivenProto<PlainObject>(cx, proto, self, TenuredObject);
if (!intrinsicsHolder)
return false;
}
self->setIntrinsicsHolder(intrinsicsHolder);
/* Define a property 'global' with the current global as its value. */
RootedValue global(cx, ObjectValue(*self));
if (!JSObject::defineProperty(cx, intrinsicsHolder, cx->names().global,
global, JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_PERMANENT | JSPROP_READONLY))
{
return false;
}
/*
* Define self-hosted functions after setting the intrinsics holder
* (which is needed to define self-hosted functions)
*/
if (!isSelfHostingGlobal) {
if (!JS_DefineFunctions(cx, ctor, object_static_selfhosted_methods))
return false;
}
/*
* The global object should have |Object.prototype| as its [[Prototype]].
* Eventually we'd like to have standard classes be there from the start,
* and thus we would know we were always setting what had previously been a
* null [[Prototype]], but right now some code assumes it can set the
* [[Prototype]] before standard classes have been initialized. For now,
* only set the [[Prototype]] if it hasn't already been set.
*/
Rooted<TaggedProto> tagged(cx, TaggedProto(proto));
if (self->shouldSplicePrototype(cx) && !self->splicePrototype(cx, self->getClass(), tagged))
return false;
return true;
}
const Class PlainObject::class_ = {
js_Object_str,
JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
JS_ResolveStub,
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 = &PlainObject::class_;

View File

@ -16,11 +16,6 @@ class Value;
namespace js {
extern const JSFunctionSpec object_methods[];
extern const JSPropertySpec object_properties[];
extern const JSFunctionSpec object_static_methods[];
extern const JSFunctionSpec object_static_selfhosted_methods[];
// Object constructor native. Exposed only so the JIT can know its address.
bool
obj_construct(JSContext *cx, unsigned argc, JS::Value *vp);

View File

@ -507,13 +507,13 @@ js_InitRegExpClass(JSContext *cx, HandleObject obj)
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
RootedNativeObject proto(cx, global->createBlankPrototype(cx, &RegExpObject::class_));
Rooted<RegExpObject*> proto(cx, global->createBlankPrototype<RegExpObject>(cx));
if (!proto)
return nullptr;
proto->setPrivate(nullptr);
proto->NativeObject::setPrivate(nullptr);
HandlePropertyName empty = cx->names().empty;
RegExpObjectBuilder builder(cx, &proto->as<RegExpObject>());
RegExpObjectBuilder builder(cx, proto);
if (!builder.build(empty, RegExpFlag(0)))
return nullptr;

View File

@ -63,7 +63,7 @@ SymbolObject::initClass(JSContext *cx, HandleObject obj)
// This uses &JSObject::class_ because: "The Symbol prototype object is an
// ordinary object. It is not a Symbol instance and does not have a
// [[SymbolData]] internal slot." (ES6 rev 24, 19.4.3)
RootedObject proto(cx, global->createBlankPrototype(cx, &JSObject::class_));
RootedObject proto(cx, global->createBlankPrototype<PlainObject>(cx));
if (!proto)
return nullptr;

View File

@ -1212,7 +1212,7 @@ js::testingFunc_inParallelSection(JSContext *cx, unsigned argc, jsval *vp)
static bool
ShellObjectMetadataCallback(JSContext *cx, JSObject **pmetadata)
{
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
RootedObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!obj)
return false;
@ -2025,7 +2025,7 @@ FindPath(JSContext *cx, unsigned argc, jsval *vp)
// array in start-to-target order.
for (size_t i = 0; i < length; i++) {
// Build an object describing the node and edge.
RootedObject obj(cx, NewBuiltinClassInstance<JSObject>(cx));
RootedObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!obj)
return false;

View File

@ -808,11 +808,11 @@ StructMetaTypeDescr::create(JSContext *cx,
int32_t alignment = 1; // Alignment of struct.
bool opaque = false; // Opacity of struct.
userFieldOffsets = NewObjectWithProto<JSObject>(cx, nullptr, nullptr, TenuredObject);
userFieldOffsets = NewObjectWithProto<PlainObject>(cx, nullptr, nullptr, TenuredObject);
if (!userFieldOffsets)
return nullptr;
userFieldTypes = NewObjectWithProto<JSObject>(cx, nullptr, nullptr, TenuredObject);
userFieldTypes = NewObjectWithProto<PlainObject>(cx, nullptr, nullptr, TenuredObject);
if (!userFieldTypes)
return nullptr;
@ -1067,7 +1067,7 @@ StructTypeDescr::maybeForwardedFieldCount() const
bool
StructTypeDescr::fieldIndex(jsid id, size_t *out) const
{
NativeObject &fieldNames = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_NAMES);
ArrayObject &fieldNames = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_NAMES);
size_t l = fieldNames.getDenseInitializedLength();
for (size_t i = 0; i < l; i++) {
JSAtom &a = fieldNames.getDenseElement(i).toString()->asAtom();
@ -1088,7 +1088,7 @@ StructTypeDescr::fieldName(size_t index) const
size_t
StructTypeDescr::fieldOffset(size_t index) const
{
NativeObject &fieldOffsets = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_OFFSETS);
ArrayObject &fieldOffsets = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_OFFSETS);
MOZ_ASSERT(index < fieldOffsets.getDenseInitializedLength());
return AssertedCast<size_t>(fieldOffsets.getDenseElement(index).toInt32());
}
@ -1096,7 +1096,7 @@ StructTypeDescr::fieldOffset(size_t index) const
size_t
StructTypeDescr::maybeForwardedFieldOffset(size_t index) const
{
NativeObject &fieldOffsets = maybeForwardedFieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_OFFSETS);
ArrayObject &fieldOffsets = maybeForwardedFieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_OFFSETS);
MOZ_ASSERT(index < fieldOffsets.getDenseInitializedLength());
return AssertedCast<size_t>(fieldOffsets.getDenseElement(index).toInt32());
}
@ -1104,7 +1104,7 @@ StructTypeDescr::maybeForwardedFieldOffset(size_t index) const
TypeDescr&
StructTypeDescr::fieldDescr(size_t index) const
{
NativeObject &fieldDescrs = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_TYPES);
ArrayObject &fieldDescrs = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_TYPES);
MOZ_ASSERT(index < fieldDescrs.getDenseInitializedLength());
return fieldDescrs.getDenseElement(index).toObject().as<TypeDescr>();
}
@ -1112,7 +1112,7 @@ StructTypeDescr::fieldDescr(size_t index) const
TypeDescr&
StructTypeDescr::maybeForwardedFieldDescr(size_t index) const
{
NativeObject &fieldDescrs = maybeForwardedFieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_TYPES);
ArrayObject &fieldDescrs = maybeForwardedFieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_TYPES);
MOZ_ASSERT(index < fieldDescrs.getDenseInitializedLength());
JSObject &descr =
*MaybeForwarded(&fieldDescrs.getDenseElement(index).toObject());
@ -1228,12 +1228,12 @@ DefineSimpleTypeDescr(JSContext *cx,
template<typename T>
static JSObject *
DefineMetaTypeDescr(JSContext *cx,
const char *name,
Handle<GlobalObject*> global,
HandleNativeObject module,
Handle<TypedObjectModuleObject*> module,
TypedObjectModuleObject::Slot protoSlot)
{
RootedAtom className(cx, Atomize(cx, T::class_.name,
strlen(T::class_.name)));
RootedAtom className(cx, Atomize(cx, name, strlen(name)));
if (!className)
return nullptr;
@ -1243,8 +1243,8 @@ DefineMetaTypeDescr(JSContext *cx,
// Create ctor.prototype, which inherits from Function.__proto__
RootedObject proto(cx, NewObjectWithProto<JSObject>(cx, funcProto, global,
SingletonObject));
RootedObject proto(cx, NewObjectWithProto<PlainObject>(cx, funcProto, global,
SingletonObject));
if (!proto)
return nullptr;
@ -1254,8 +1254,8 @@ DefineMetaTypeDescr(JSContext *cx,
if (!objProto)
return nullptr;
RootedObject protoProto(cx);
protoProto = NewObjectWithProto<JSObject>(cx, objProto,
global, SingletonObject);
protoProto = NewObjectWithProto<PlainObject>(cx, objProto,
global, SingletonObject);
if (!protoProto)
return nullptr;
@ -1329,7 +1329,7 @@ GlobalObject::initTypedObjectModule(JSContext *cx, Handle<GlobalObject*> global)
RootedObject arrayType(cx);
arrayType = DefineMetaTypeDescr<ArrayMetaTypeDescr>(
cx, global, module, TypedObjectModuleObject::ArrayTypePrototype);
cx, "ArrayType", global, module, TypedObjectModuleObject::ArrayTypePrototype);
if (!arrayType)
return false;
@ -1344,7 +1344,7 @@ GlobalObject::initTypedObjectModule(JSContext *cx, Handle<GlobalObject*> global)
RootedObject structType(cx);
structType = DefineMetaTypeDescr<StructMetaTypeDescr>(
cx, global, module, TypedObjectModuleObject::StructTypePrototype);
cx, "StructType", global, module, TypedObjectModuleObject::StructTypePrototype);
if (!structType)
return false;

View File

@ -162,15 +162,6 @@ class TypedProto : public NativeObject
class TypeDescr : public NativeObject
{
public:
// This is *intentionally* not defined so as to produce link
// errors if a is<FooTypeDescr>() etc goes wrong. Otherwise, the
// default implementation resolves this to a reference to
// FooTypeDescr::class_ which resolves to
// JSObject::class_. Debugging the resulting errors leads to much
// fun and rejoicing.
static const Class class_;
public:
TypedProto &typedProto() const {
return getReservedSlot(JS_DESCR_SLOT_TYPROTO).toObject().as<TypedProto>();
@ -498,12 +489,12 @@ class StructTypeDescr : public ComplexTypeDescr
size_t maybeForwardedFieldOffset(size_t index) const;
private:
NativeObject &fieldInfoObject(size_t slot) const {
return getReservedSlot(slot).toObject().as<NativeObject>();
ArrayObject &fieldInfoObject(size_t slot) const {
return getReservedSlot(slot).toObject().as<ArrayObject>();
}
NativeObject &maybeForwardedFieldInfoObject(size_t slot) const {
return MaybeForwarded(&getReservedSlot(slot).toObject())->as<NativeObject>();
ArrayObject &maybeForwardedFieldInfoObject(size_t slot) const {
return MaybeForwarded(&getReservedSlot(slot).toObject())->as<ArrayObject>();
}
};

View File

@ -51,7 +51,7 @@ WeakSetObject::initClass(JSContext *cx, JSObject *obj)
{
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
// Todo: WeakSet.prototype should not be a WeakSet!
RootedNativeObject proto(cx, global->createBlankPrototype(cx, &class_));
Rooted<WeakSetObject*> proto(cx, global->createBlankPrototype<WeakSetObject>(cx));
if (!proto)
return nullptr;
proto->setReservedSlot(WEAKSET_MAP_SLOT, UndefinedValue());
@ -70,7 +70,7 @@ WeakSetObject::initClass(JSContext *cx, JSObject *obj)
WeakSetObject*
WeakSetObject::create(JSContext *cx)
{
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &class_));
Rooted<WeakSetObject *> obj(cx, NewBuiltinClassInstance<WeakSetObject>(cx));
if (!obj)
return nullptr;
@ -79,7 +79,7 @@ WeakSetObject::create(JSContext *cx)
return nullptr;
obj->setReservedSlot(WEAKSET_MAP_SLOT, ObjectValue(*map));
return &obj->as<WeakSetObject>();
return obj;
}
bool

View File

@ -2265,9 +2265,9 @@ IteratorResultShape(ExclusiveContext *cx, BytecodeEmitter *bce, unsigned *shape)
{
MOZ_ASSERT(bce->script->compileAndGo());
RootedNativeObject obj(cx);
RootedPlainObject obj(cx);
gc::AllocKind kind = GuessObjectGCKind(2);
obj = NewNativeBuiltinClassInstance(cx, &JSObject::class_, kind);
obj = NewBuiltinClassInstance<PlainObject>(cx, kind);
if (!obj)
return false;
@ -4247,8 +4247,8 @@ ParseNode::getConstantValue(ExclusiveContext *cx, AllowConstantObjects allowObje
allowObjects = DontAllowObjects;
gc::AllocKind kind = GuessObjectGCKind(pn_count);
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &JSObject::class_,
kind, MaybeSingletonObject));
RootedPlainObject obj(cx,
NewBuiltinClassInstance<PlainObject>(cx, kind, MaybeSingletonObject));
if (!obj)
return false;
@ -6494,10 +6494,10 @@ EmitObject(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
* Try to construct the shape of the object as we go, so we can emit a
* JSOP_NEWOBJECT with the final shape instead.
*/
RootedNativeObject obj(cx);
RootedPlainObject obj(cx);
if (bce->script->compileAndGo()) {
gc::AllocKind kind = GuessObjectGCKind(pn->pn_count);
obj = NewNativeBuiltinClassInstance(cx, &JSObject::class_, kind, TenuredObject);
obj = NewBuiltinClassInstance<PlainObject>(cx, kind, TenuredObject);
if (!obj)
return false;
}

View File

@ -176,6 +176,7 @@ class LazyScript;
class NativeObject;
class NestedScopeObject;
class Nursery;
class PlainObject;
class PropertyName;
class SavedFrame;
class ScopeObject;
@ -223,6 +224,7 @@ template <> struct MapTypeToTraceKind<JSScript> { static const JSGCTrace
template <> struct MapTypeToTraceKind<JSString> { static const JSGCTraceKind kind = JSTRACE_STRING; };
template <> struct MapTypeToTraceKind<LazyScript> { static const JSGCTraceKind kind = JSTRACE_LAZY_SCRIPT; };
template <> struct MapTypeToTraceKind<NestedScopeObject>{ static const JSGCTraceKind kind = JSTRACE_OBJECT; };
template <> struct MapTypeToTraceKind<PlainObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
template <> struct MapTypeToTraceKind<PropertyName> { static const JSGCTraceKind kind = JSTRACE_STRING; };
template <> struct MapTypeToTraceKind<SavedFrame> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
template <> struct MapTypeToTraceKind<ScopeObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
@ -821,6 +823,7 @@ typedef HeapPtr<JSLinearString*> HeapPtrLinearString;
typedef HeapPtr<JSObject*> HeapPtrObject;
typedef HeapPtr<JSScript*> HeapPtrScript;
typedef HeapPtr<JSString*> HeapPtrString;
typedef HeapPtr<PlainObject*> HeapPtrPlainObject;
typedef HeapPtr<PropertyName*> HeapPtrPropertyName;
typedef HeapPtr<Shape*> HeapPtrShape;
typedef HeapPtr<UnownedBaseShape*> HeapPtrUnownedBaseShape;

View File

@ -656,6 +656,7 @@ DeclMarkerImpl(Object, GlobalObject)
DeclMarkerImpl(Object, JSObject)
DeclMarkerImpl(Object, JSFunction)
DeclMarkerImpl(Object, NestedScopeObject)
DeclMarkerImpl(Object, PlainObject)
DeclMarkerImpl(Object, SavedFrame)
DeclMarkerImpl(Object, ScopeObject)
DeclMarkerImpl(Object, SharedArrayBufferObject)

View File

@ -117,6 +117,7 @@ DeclMarker(Object, GlobalObject)
DeclMarker(Object, JSObject)
DeclMarker(Object, JSFunction)
DeclMarker(Object, NestedScopeObject)
DeclMarker(Object, PlainObject)
DeclMarker(Object, SavedFrame)
DeclMarker(Object, ScopeObject)
DeclMarker(Object, SharedArrayBufferObject)

View File

@ -17,6 +17,7 @@ namespace js {
class PropertyName;
class NativeObject;
class ArrayObject;
class PlainObject;
class ScriptSourceObject;
class Shape;
@ -31,6 +32,7 @@ typedef JS::Handle<JSAtom*> HandleAtom;
typedef JS::Handle<JSLinearString*> HandleLinearString;
typedef JS::Handle<PropertyName*> HandlePropertyName;
typedef JS::Handle<ArrayObject*> HandleArrayObject;
typedef JS::Handle<PlainObject*> HandlePlainObject;
typedef JS::Handle<ScriptSourceObject*> HandleScriptSource;
typedef JS::MutableHandle<Shape*> MutableHandleShape;
@ -44,6 +46,7 @@ typedef JS::Rooted<JSAtom*> RootedAtom;
typedef JS::Rooted<JSLinearString*> RootedLinearString;
typedef JS::Rooted<PropertyName*> RootedPropertyName;
typedef JS::Rooted<ArrayObject*> RootedArrayObject;
typedef JS::Rooted<PlainObject*> RootedPlainObject;
typedef JS::Rooted<ScriptSourceObject*> RootedScriptSource;
} /* namespace js */

View File

@ -0,0 +1,8 @@
if (typeof TypedObject === "undefined")
quit();
// Make sure some builtin TypedObject functions are given sensible names.
assertEq(TypedObject.ArrayType.name, "ArrayType");
assertEq(TypedObject.StructType.name, "StructType");
assertEq(TypedObject.storage.name, "storage");

View File

@ -1684,7 +1684,7 @@ BaselineCompiler::emit_JSOP_NEWARRAY()
return true;
}
typedef JSObject *(*NewArrayCopyOnWriteFn)(JSContext *, HandleNativeObject, gc::InitialHeap);
typedef JSObject *(*NewArrayCopyOnWriteFn)(JSContext *, HandleArrayObject, gc::InitialHeap);
const VMFunction jit::NewArrayCopyOnWriteInfo =
FunctionInfo<NewArrayCopyOnWriteFn>(js::NewDenseCopyOnWriteArray);
@ -1742,8 +1742,8 @@ BaselineCompiler::emit_JSOP_NEWOBJECT()
return false;
}
RootedNativeObject baseObject(cx, script->getObject(pc));
RootedNativeObject templateObject(cx, CopyInitializerObject(cx, baseObject, TenuredObject));
RootedPlainObject baseObject(cx, &script->getObject(pc)->as<PlainObject>());
RootedPlainObject templateObject(cx, CopyInitializerObject(cx, baseObject, TenuredObject));
if (!templateObject)
return false;
@ -1809,8 +1809,8 @@ BaselineCompiler::emit_JSOP_NEWINIT()
} else {
MOZ_ASSERT(key == JSProto_Object);
RootedNativeObject templateObject(cx);
templateObject = NewNativeBuiltinClassInstance(cx, &JSObject::class_, TenuredObject);
RootedPlainObject templateObject(cx,
NewBuiltinClassInstance<PlainObject>(cx, TenuredObject));
if (!templateObject)
return false;
@ -1857,7 +1857,7 @@ BaselineCompiler::emit_JSOP_INITELEM()
return true;
}
typedef bool (*MutateProtoFn)(JSContext *cx, HandleObject obj, HandleValue newProto);
typedef bool (*MutateProtoFn)(JSContext *cx, HandlePlainObject obj, HandleValue newProto);
static const VMFunction MutateProtoInfo = FunctionInfo<MutateProtoFn>(MutatePrototype);
bool

View File

@ -1787,7 +1787,7 @@ DoNewObject(JSContext *cx, ICNewObject_Fallback *stub, MutableHandleValue res)
{
FallbackICSpew(cx, stub, "NewObject");
RootedNativeObject templateObject(cx, stub->templateObject());
RootedPlainObject templateObject(cx, stub->templateObject());
JSObject *obj = NewInitObject(cx, templateObject);
if (!obj)
return false;
@ -8248,8 +8248,8 @@ DoSetPropFallback(JSContext *cx, BaselineFrame *frame, ICSetProp_Fallback *stub_
}
if (op == JSOP_INITPROP) {
MOZ_ASSERT(obj->is<JSObject>());
if (!DefineNativeProperty(cx, obj.as<NativeObject>(), id, rhs,
MOZ_ASSERT(obj->is<PlainObject>());
if (!DefineNativeProperty(cx, obj.as<PlainObject>(), id, rhs,
nullptr, nullptr, JSPROP_ENUMERATE))
{
return false;
@ -9202,7 +9202,7 @@ TryAttachCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, jsb
// Remember the template object associated with any script being called
// as a constructor, for later use during Ion compilation.
RootedNativeObject templateObject(cx);
RootedPlainObject templateObject(cx);
if (constructing) {
templateObject = CreateThisForFunction(cx, fun, MaybeSingletonObject);
if (!templateObject)

View File

@ -1927,26 +1927,26 @@ class ICNewObject_Fallback : public ICFallbackStub
{
friend class ICStubSpace;
HeapPtrNativeObject templateObject_;
HeapPtrPlainObject templateObject_;
ICNewObject_Fallback(JitCode *stubCode, NativeObject *templateObject)
ICNewObject_Fallback(JitCode *stubCode, PlainObject *templateObject)
: ICFallbackStub(ICStub::NewObject_Fallback, stubCode), templateObject_(templateObject)
{}
public:
static inline ICNewObject_Fallback *New(ICStubSpace *space, JitCode *code,
NativeObject *templateObject) {
PlainObject *templateObject) {
if (!code)
return nullptr;
return space->allocate<ICNewObject_Fallback>(code, templateObject);
}
class Compiler : public ICStubCompiler {
RootedNativeObject templateObject;
RootedPlainObject templateObject;
bool generateStubCode(MacroAssembler &masm);
public:
Compiler(JSContext *cx, NativeObject *templateObject)
Compiler(JSContext *cx, PlainObject *templateObject)
: ICStubCompiler(cx, ICStub::NewObject_Fallback),
templateObject(cx, templateObject)
{}
@ -1956,7 +1956,7 @@ class ICNewObject_Fallback : public ICFallbackStub
}
};
HeapPtrNativeObject &templateObject() {
HeapPtrPlainObject &templateObject() {
return templateObject_;
}
};
@ -6371,10 +6371,10 @@ class ICCall_StringSplit : public ICMonitoredStub
uint32_t pcOffset_;
HeapPtrString expectedThis_;
HeapPtrString expectedArg_;
HeapPtrNativeObject templateObject_;
HeapPtrArrayObject templateObject_;
ICCall_StringSplit(JitCode *stubCode, ICStub *firstMonitorStub, uint32_t pcOffset, HandleString thisString,
HandleString argString, HandleNativeObject templateObject)
HandleString argString, HandleArrayObject templateObject)
: ICMonitoredStub(ICStub::Call_StringSplit, stubCode, firstMonitorStub),
pcOffset_(pcOffset), expectedThis_(thisString), expectedArg_(argString),
templateObject_(templateObject)
@ -6383,7 +6383,7 @@ class ICCall_StringSplit : public ICMonitoredStub
public:
static inline ICCall_StringSplit *New(ICStubSpace *space, JitCode *code,
ICStub *firstMonitorStub, uint32_t pcOffset, HandleString thisString,
HandleString argString, HandleNativeObject templateObject)
HandleString argString, HandleArrayObject templateObject)
{
if (!code)
return nullptr;
@ -6411,7 +6411,7 @@ class ICCall_StringSplit : public ICMonitoredStub
return expectedArg_;
}
HeapPtrNativeObject &templateObject() {
HeapPtrArrayObject &templateObject() {
return templateObject_;
}
@ -6421,7 +6421,7 @@ class ICCall_StringSplit : public ICMonitoredStub
uint32_t pcOffset_;
RootedString expectedThis_;
RootedString expectedArg_;
RootedNativeObject templateObject_;
RootedArrayObject templateObject_;
bool generateStubCode(MacroAssembler &masm);
@ -6437,7 +6437,7 @@ class ICCall_StringSplit : public ICMonitoredStub
pcOffset_(pcOffset),
expectedThis_(cx, thisString),
expectedArg_(cx, argString),
templateObject_(cx, &templateObject.toObject().as<NativeObject>())
templateObject_(cx, &templateObject.toObject().as<ArrayObject>())
{ }
ICStub *getStub(ICStubSpace *space) {

View File

@ -4197,10 +4197,10 @@ class OutOfLineNewObject : public OutOfLineCodeBase<CodeGenerator>
}
};
typedef JSObject *(*NewInitObjectFn)(JSContext *, HandleNativeObject);
typedef JSObject *(*NewInitObjectFn)(JSContext *, HandlePlainObject);
static const VMFunction NewInitObjectInfo = FunctionInfo<NewInitObjectFn>(NewInitObject);
typedef JSObject *(*NewInitObjectWithClassPrototypeFn)(JSContext *, HandleObject);
typedef JSObject *(*NewInitObjectWithClassPrototypeFn)(JSContext *, HandlePlainObject);
static const VMFunction NewInitObjectWithClassPrototypeInfo =
FunctionInfo<NewInitObjectWithClassPrototypeFn>(NewInitObjectWithClassPrototype);
@ -4321,7 +4321,7 @@ CodeGenerator::visitNewObject(LNewObject *lir)
MOZ_ASSERT(gen->info().executionMode() == SequentialExecution);
Register objReg = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
NativeObject *templateObject = lir->mir()->templateObject();
PlainObject *templateObject = lir->mir()->templateObject();
if (lir->mir()->shouldUseVM()) {
visitNewObjectVMCall(lir);
@ -4375,7 +4375,7 @@ CodeGenerator::visitNewDeclEnvObject(LNewDeclEnvObject *lir)
{
Register objReg = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
NativeObject *templateObj = lir->mir()->templateObj();
DeclEnvObject *templateObj = lir->mir()->templateObj();
CompileInfo &info = lir->mir()->block()->info();
// If we have a template object, we can inline call object creation.
@ -4401,7 +4401,7 @@ CodeGenerator::visitNewCallObject(LNewCallObject *lir)
Register objReg = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
NativeObject *templateObj = lir->mir()->templateObject();
CallObject *templateObj = lir->mir()->templateObject();
JSScript *script = lir->mir()->block()->info().script();
uint32_t lexicalBegin = script->bindings.aliasedBodyLevelLexicalBegin();
@ -4452,7 +4452,7 @@ CodeGenerator::visitNewCallObjectPar(LNewCallObjectPar *lir)
Register cxReg = ToRegister(lir->forkJoinContext());
Register tempReg1 = ToRegister(lir->getTemp0());
Register tempReg2 = ToRegister(lir->getTemp1());
NativeObject *templateObj = lir->mir()->templateObj();
CallObject *templateObj = lir->mir()->templateObj();
emitAllocateGCThingPar(lir, resultReg, cxReg, tempReg1, tempReg2, templateObj);
}
@ -4624,7 +4624,7 @@ CodeGenerator::visitInitElemGetterSetter(LInitElemGetterSetter *lir)
callVM(InitElemGetterSetterInfo, lir);
}
typedef bool(*MutatePrototypeFn)(JSContext *cx, HandleObject obj, HandleValue value);
typedef bool(*MutatePrototypeFn)(JSContext *cx, HandlePlainObject obj, HandleValue value);
static const VMFunction MutatePrototypeInfo =
FunctionInfo<MutatePrototypeFn>(MutatePrototype);
@ -4728,7 +4728,7 @@ static const VMFunction NewGCObjectInfo =
void
CodeGenerator::visitCreateThisWithTemplate(LCreateThisWithTemplate *lir)
{
NativeObject *templateObject = lir->mir()->templateObject();
PlainObject *templateObject = lir->mir()->templateObject();
gc::AllocKind allocKind = templateObject->asTenured().getAllocKind();
gc::InitialHeap initialHeap = lir->mir()->initialHeap();
Register objReg = ToRegister(lir->output());

View File

@ -2818,7 +2818,7 @@ jit::ConvertLinearInequality(TempAllocator &alloc, MBasicBlock *block, const Lin
static bool
AnalyzePoppedThis(JSContext *cx, types::TypeObject *type,
MDefinition *thisValue, MInstruction *ins, bool definitelyExecuted,
HandleNativeObject baseobj,
HandlePlainObject baseobj,
Vector<types::TypeNewScript::Initializer> *initializerList,
Vector<PropertyName *> *accessedProperties,
bool *phandled)
@ -2952,7 +2952,7 @@ CmpInstructions(const void *a, const void *b)
bool
jit::AnalyzeNewScriptDefiniteProperties(JSContext *cx, JSFunction *fun,
types::TypeObject *type, HandleNativeObject baseobj,
types::TypeObject *type, HandlePlainObject baseobj,
Vector<types::TypeNewScript::Initializer> *initializerList)
{
MOZ_ASSERT(cx->zone()->types.activeAnalysis);

View File

@ -170,7 +170,7 @@ ConvertLinearInequality(TempAllocator &alloc, MBasicBlock *block, const LinearSu
bool
AnalyzeNewScriptDefiniteProperties(JSContext *cx, JSFunction *fun,
types::TypeObject *type, HandleNativeObject baseobj,
types::TypeObject *type, HandlePlainObject baseobj,
Vector<types::TypeNewScript::Initializer> *initializerList);
bool

View File

@ -5301,7 +5301,7 @@ IonBuilder::createThisScriptedSingleton(JSFunction *target, MDefinition *callee)
return nullptr;
JSObject *templateObject = inspector->getTemplateObject(pc);
if (!templateObject || !templateObject->is<JSObject>())
if (!templateObject || !templateObject->is<PlainObject>())
return nullptr;
if (!templateObject->hasTenuredProto() || templateObject->getProto() != proto)
return nullptr;
@ -6037,7 +6037,7 @@ IonBuilder::jsop_newobject()
return abort("No template object for NEWOBJECT");
}
MOZ_ASSERT(templateObject->is<JSObject>());
MOZ_ASSERT(templateObject->is<PlainObject>());
MConstant *templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject);
current->add(templateConst);
MNewObject *ins = MNewObject::New(alloc(), constraints(), templateConst,

View File

@ -3374,7 +3374,7 @@ MBeta::printOpcode(FILE *fp) const
bool
MNewObject::shouldUseVM() const
{
NativeObject *obj = templateObject();
PlainObject *obj = templateObject();
return obj->hasSingletonType() || obj->hasDynamicSlots();
}
@ -3391,7 +3391,7 @@ MObjectState::MObjectState(MDefinition *obj)
// This instruction is only used as a summary for bailout paths.
setResultType(MIRType_Object);
setRecoveredOnBailout();
NativeObject *templateObject = nullptr;
PlainObject *templateObject = nullptr;
if (obj->isNewObject())
templateObject = obj->toNewObject()->templateObject();
else

View File

@ -2709,7 +2709,7 @@ class MNewObject : public MUnaryInstruction
initialHeap_(initialHeap),
templateObjectIsClassPrototype_(templateObjectIsClassPrototype)
{
JSObject *obj = templateObject();
PlainObject *obj = templateObject();
MOZ_ASSERT_IF(templateObjectIsClassPrototype, !shouldUseVM());
setResultType(MIRType_Object);
if (!obj->hasSingletonType())
@ -2742,8 +2742,8 @@ class MNewObject : public MUnaryInstruction
return templateObjectIsClassPrototype_;
}
NativeObject *templateObject() const {
return &getOperand(0)->toConstant()->value().toObject().as<NativeObject>();
PlainObject *templateObject() const {
return &getOperand(0)->toConstant()->value().toObject().as<PlainObject>();
}
gc::InitialHeap initialHeap() const {
@ -4081,8 +4081,8 @@ class MCreateThisWithTemplate
}
// Template for |this|, provided by TI.
NativeObject *templateObject() const {
return &getOperand(0)->toConstant()->value().toObject().as<NativeObject>();
PlainObject *templateObject() const {
return &getOperand(0)->toConstant()->value().toObject().as<PlainObject>();
}
gc::InitialHeap initialHeap() const {
@ -11420,9 +11420,9 @@ class MPostWriteBarrier : public MBinaryInstruction, public ObjectPolicy<0>::Dat
class MNewDeclEnvObject : public MNullaryInstruction
{
AlwaysTenuredNativeObject templateObj_;
AlwaysTenured<DeclEnvObject*> templateObj_;
explicit MNewDeclEnvObject(NativeObject *templateObj)
explicit MNewDeclEnvObject(DeclEnvObject *templateObj)
: MNullaryInstruction(),
templateObj_(templateObj)
{
@ -11432,11 +11432,11 @@ class MNewDeclEnvObject : public MNullaryInstruction
public:
INSTRUCTION_HEADER(NewDeclEnvObject);
static MNewDeclEnvObject *New(TempAllocator &alloc, NativeObject *templateObj) {
static MNewDeclEnvObject *New(TempAllocator &alloc, DeclEnvObject *templateObj) {
return new(alloc) MNewDeclEnvObject(templateObj);
}
NativeObject *templateObj() {
DeclEnvObject *templateObj() {
return templateObj_;
}
AliasSet getAliasSet() const {
@ -11446,10 +11446,10 @@ class MNewDeclEnvObject : public MNullaryInstruction
class MNewCallObjectBase : public MNullaryInstruction
{
AlwaysTenuredNativeObject templateObj_;
AlwaysTenured<CallObject*> templateObj_;
protected:
explicit MNewCallObjectBase(NativeObject *templateObj)
explicit MNewCallObjectBase(CallObject *templateObj)
: MNullaryInstruction(),
templateObj_(templateObj)
{
@ -11457,7 +11457,7 @@ class MNewCallObjectBase : public MNullaryInstruction
}
public:
NativeObject *templateObject() {
CallObject *templateObject() {
return templateObj_;
}
AliasSet getAliasSet() const {
@ -11470,12 +11470,12 @@ class MNewCallObject : public MNewCallObjectBase
public:
INSTRUCTION_HEADER(NewCallObject)
explicit MNewCallObject(NativeObject *templateObj)
explicit MNewCallObject(CallObject *templateObj)
: MNewCallObjectBase(templateObj)
{}
static MNewCallObject *
New(TempAllocator &alloc, NativeObject *templateObj)
New(TempAllocator &alloc, CallObject *templateObj)
{
return new(alloc) MNewCallObject(templateObj);
}
@ -11486,12 +11486,12 @@ class MNewRunOnceCallObject : public MNewCallObjectBase
public:
INSTRUCTION_HEADER(NewRunOnceCallObject)
explicit MNewRunOnceCallObject(NativeObject *templateObj)
explicit MNewRunOnceCallObject(CallObject *templateObj)
: MNewCallObjectBase(templateObj)
{}
static MNewRunOnceCallObject *
New(TempAllocator &alloc, NativeObject *templateObj)
New(TempAllocator &alloc, CallObject *templateObj)
{
return new(alloc) MNewRunOnceCallObject(templateObj);
}
@ -11499,9 +11499,9 @@ class MNewRunOnceCallObject : public MNewCallObjectBase
class MNewCallObjectPar : public MUnaryInstruction
{
AlwaysTenuredNativeObject templateObj_;
AlwaysTenured<CallObject*> templateObj_;
MNewCallObjectPar(MDefinition *cx, NativeObject *templateObj)
MNewCallObjectPar(MDefinition *cx, CallObject *templateObj)
: MUnaryInstruction(cx),
templateObj_(templateObj)
{
@ -11519,7 +11519,7 @@ class MNewCallObjectPar : public MUnaryInstruction
return getOperand(0);
}
NativeObject *templateObj() const {
CallObject *templateObj() const {
return templateObj_;
}

View File

@ -1105,7 +1105,7 @@ RNewObject::RNewObject(CompactBufferReader &reader)
bool
RNewObject::recover(JSContext *cx, SnapshotIterator &iter) const
{
RootedNativeObject templateObject(cx, &iter.read().toObject().as<NativeObject>());
RootedPlainObject templateObject(cx, &iter.read().toObject().as<PlainObject>());
RootedValue result(cx);
JSObject *resultObject = nullptr;
@ -1203,7 +1203,7 @@ RCreateThisWithTemplate::RCreateThisWithTemplate(CompactBufferReader &reader)
bool
RCreateThisWithTemplate::recover(JSContext *cx, SnapshotIterator &iter) const
{
RootedNativeObject templateObject(cx, &iter.read().toObject().as<NativeObject>());
RootedPlainObject templateObject(cx, &iter.read().toObject().as<PlainObject>());
// See CodeGenerator::visitCreateThisWithTemplate
gc::AllocKind allocKind = templateObject->asTenured().getAllocKind();
@ -1235,7 +1235,7 @@ RObjectState::RObjectState(CompactBufferReader &reader)
bool
RObjectState::recover(JSContext *cx, SnapshotIterator &iter) const
{
RootedNativeObject object(cx, &iter.read().toObject().as<NativeObject>());
RootedPlainObject object(cx, &iter.read().toObject().as<PlainObject>());
MOZ_ASSERT(object->slotSpan() == numSlots());
RootedValue val(cx);

View File

@ -194,9 +194,8 @@ SetConst(JSContext *cx, HandlePropertyName name, HandleObject scopeChain, Handle
}
bool
MutatePrototype(JSContext *cx, HandleObject obj, HandleValue value)
MutatePrototype(JSContext *cx, HandlePlainObject obj, HandleValue value)
{
MOZ_ASSERT(obj->is<JSObject>(), "must only be used with object literals");
if (!value.isObjectOrNull())
return true;
@ -283,7 +282,7 @@ template bool StringsEqual<true>(JSContext *cx, HandleString lhs, HandleString r
template bool StringsEqual<false>(JSContext *cx, HandleString lhs, HandleString rhs, bool *res);
JSObject*
NewInitObject(JSContext *cx, HandleNativeObject templateObject)
NewInitObject(JSContext *cx, HandlePlainObject templateObject)
{
NewObjectKind newKind = templateObject->hasSingletonType() ? SingletonObject : GenericObject;
if (!templateObject->hasLazyType() && templateObject->type()->shouldPreTenure())
@ -300,7 +299,7 @@ NewInitObject(JSContext *cx, HandleNativeObject templateObject)
}
JSObject *
NewInitObjectWithClassPrototype(JSContext *cx, HandleObject templateObject)
NewInitObjectWithClassPrototype(JSContext *cx, HandlePlainObject templateObject)
{
MOZ_ASSERT(!templateObject->hasSingletonType());
MOZ_ASSERT(!templateObject->hasLazyType());
@ -308,11 +307,10 @@ NewInitObjectWithClassPrototype(JSContext *cx, HandleObject templateObject)
NewObjectKind newKind = templateObject->type()->shouldPreTenure()
? TenuredObject
: GenericObject;
JSObject *obj = NewObjectWithGivenProto(cx,
templateObject->getClass(),
templateObject->getProto(),
cx->global(),
newKind);
PlainObject *obj = NewObjectWithGivenProto<PlainObject>(cx,
templateObject->getProto(),
cx->global(),
newKind);
if (!obj)
return nullptr;

View File

@ -314,6 +314,7 @@ template <> struct TypeToDataType<HandleFunction> { static const DataType result
template <> struct TypeToDataType<Handle<NativeObject *> > { static const DataType result = Type_Handle; };
template <> struct TypeToDataType<Handle<InlineTypedObject *> > { static const DataType result = Type_Handle; };
template <> struct TypeToDataType<Handle<ArrayObject *> > { static const DataType result = Type_Handle; };
template <> struct TypeToDataType<Handle<PlainObject *> > { static const DataType result = Type_Handle; };
template <> struct TypeToDataType<Handle<StaticWithObject *> > { static const DataType result = Type_Handle; };
template <> struct TypeToDataType<Handle<StaticBlockObject *> > { static const DataType result = Type_Handle; };
template <> struct TypeToDataType<HandleScript> { static const DataType result = Type_Handle; };
@ -349,6 +350,9 @@ template <> struct TypeToArgProperties<Handle<InlineTypedObject *> > {
template <> struct TypeToArgProperties<Handle<ArrayObject *> > {
static const uint32_t result = TypeToArgProperties<ArrayObject *>::result | VMFunction::ByRef;
};
template <> struct TypeToArgProperties<Handle<PlainObject *> > {
static const uint32_t result = TypeToArgProperties<PlainObject *>::result | VMFunction::ByRef;
};
template <> struct TypeToArgProperties<Handle<StaticWithObject *> > {
static const uint32_t result = TypeToArgProperties<StaticWithObject *>::result | VMFunction::ByRef;
};
@ -420,6 +424,9 @@ template <> struct TypeToRootType<Handle<InlineTypedObject *> > {
template <> struct TypeToRootType<Handle<ArrayObject *> > {
static const uint32_t result = VMFunction::RootObject;
};
template <> struct TypeToRootType<Handle<PlainObject *> > {
static const uint32_t result = VMFunction::RootObject;
};
template <> struct TypeToRootType<Handle<StaticBlockObject *> > {
static const uint32_t result = VMFunction::RootObject;
};
@ -665,7 +672,7 @@ bool CheckOverRecursedWithExtra(JSContext *cx, BaselineFrame *frame,
bool DefVarOrConst(JSContext *cx, HandlePropertyName dn, unsigned attrs, HandleObject scopeChain);
bool SetConst(JSContext *cx, HandlePropertyName name, HandleObject scopeChain, HandleValue rval);
bool MutatePrototype(JSContext *cx, HandleObject obj, HandleValue value);
bool MutatePrototype(JSContext *cx, HandlePlainObject obj, HandleValue value);
bool InitProp(JSContext *cx, HandleNativeObject obj, HandlePropertyName name, HandleValue value);
template<bool Equal>
@ -682,10 +689,8 @@ bool GreaterThanOrEqual(JSContext *cx, MutableHandleValue lhs, MutableHandleValu
template<bool Equal>
bool StringsEqual(JSContext *cx, HandleString left, HandleString right, bool *res);
// Allocation functions for JSOP_NEWARRAY and JSOP_NEWOBJECT and parallel array inlining
JSObject *NewInitParallelArray(JSContext *cx, HandleObject templateObj);
JSObject *NewInitObject(JSContext *cx, HandleNativeObject templateObject);
JSObject *NewInitObjectWithClassPrototype(JSContext *cx, HandleObject templateObject);
JSObject *NewInitObject(JSContext *cx, HandlePlainObject templateObject);
JSObject *NewInitObjectWithClassPrototype(JSContext *cx, HandlePlainObject templateObject);
bool ArrayPopDense(JSContext *cx, HandleObject obj, MutableHandleValue rval);
bool ArrayPushDense(JSContext *cx, HandleArrayObject obj, HandleValue v, uint32_t *length);

View File

@ -14,7 +14,7 @@ constructHook(JSContext *cx, unsigned argc, jsval *vp)
// Check that arguments were passed properly from JS_New.
JS::RootedObject obj(cx, JS_NewObject(cx, js::Jsvalify(&JSObject::class_), JS::NullPtr(), JS::NullPtr()));
JS::RootedObject obj(cx, JS_NewObject(cx, js::Jsvalify(&js::PlainObject::class_), JS::NullPtr(), JS::NullPtr()));
if (!obj) {
JS_ReportError(cx, "test failed, could not construct object");
return false;

View File

@ -2472,7 +2472,7 @@ JS_NewObject(JSContext *cx, const JSClass *jsclasp, HandleObject proto, HandleOb
const Class *clasp = Valueify(jsclasp);
if (!clasp)
clasp = &JSObject::class_; /* default class is Object */
clasp = &PlainObject::class_; /* default class is Object */
MOZ_ASSERT(clasp != &JSFunction::class_);
MOZ_ASSERT(!(clasp->flags & JSCLASS_IS_GLOBAL));
@ -2492,7 +2492,7 @@ JS_NewObjectWithGivenProto(JSContext *cx, const JSClass *jsclasp, HandleObject p
const Class *clasp = Valueify(jsclasp);
if (!clasp)
clasp = &JSObject::class_; /* default class is Object */
clasp = &PlainObject::class_; /* default class is Object */
MOZ_ASSERT(clasp != &JSFunction::class_);
MOZ_ASSERT(!(clasp->flags & JSCLASS_IS_GLOBAL));
@ -3198,7 +3198,7 @@ JS_DefineObject(JSContext *cx, HandleObject obj, const char *name, const JSClass
const Class *clasp = Valueify(jsclasp);
if (!clasp)
clasp = &JSObject::class_; /* default class is Object */
clasp = &PlainObject::class_; /* default class is Object */
RootedObject nobj(cx, NewObjectWithClassProto(cx, clasp, proto, obj));
if (!nobj)

View File

@ -3627,7 +3627,7 @@ js::NewDenseFullyAllocatedArrayWithTemplate(JSContext *cx, uint32_t length, JSOb
}
JSObject *
js::NewDenseCopyOnWriteArray(JSContext *cx, HandleNativeObject templateObject, gc::InitialHeap heap)
js::NewDenseCopyOnWriteArray(JSContext *cx, HandleArrayObject templateObject, gc::InitialHeap heap)
{
RootedShape shape(cx, templateObject->lastProperty());

View File

@ -99,7 +99,7 @@ NewDenseFullyAllocatedArrayWithTemplate(JSContext *cx, uint32_t length, JSObject
/* Create a dense array with the same copy-on-write elements as another object. */
extern JSObject *
NewDenseCopyOnWriteArray(JSContext *cx, HandleNativeObject templateObject, gc::InitialHeap heap);
NewDenseCopyOnWriteArray(JSContext *cx, HandleArrayObject templateObject, gc::InitialHeap heap);
/*
* Determines whether a write to the given element on |obj| should fail because

View File

@ -140,7 +140,7 @@ js_InitBooleanClass(JSContext *cx, HandleObject obj)
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
RootedNativeObject booleanProto(cx, global->createBlankPrototype(cx, &BooleanObject::class_));
Rooted<BooleanObject*> booleanProto(cx, global->createBlankPrototype<BooleanObject>(cx));
if (!booleanProto)
return nullptr;
booleanProto->setFixedSlot(BooleanObject::PRIMITIVE_VALUE_SLOT, BooleanValue(false));

View File

@ -523,7 +523,7 @@ js::ReportUsageError(JSContext *cx, HandleObject callee, const char *msg)
const char *usageStr = "usage";
PropertyName *usageAtom = Atomize(cx, usageStr, strlen(usageStr))->asPropertyName();
RootedId id(cx, NameToId(usageAtom));
DebugOnly<Shape *> shape = static_cast<Shape *>(callee->as<NativeObject>().lookup(cx, id));
DebugOnly<Shape *> shape = static_cast<Shape *>(callee->as<JSFunction>().lookup(cx, id));
MOZ_ASSERT(!shape->configurable());
MOZ_ASSERT(!shape->writable());
MOZ_ASSERT(shape->hasDefaultGetter());

View File

@ -3011,8 +3011,8 @@ FinishDateClassInit(JSContext *cx, HandleObject ctor, HandleObject proto)
RootedValue toUTCStringFun(cx);
RootedId toUTCStringId(cx, NameToId(cx->names().toUTCString));
RootedId toGMTStringId(cx, NameToId(cx->names().toGMTString));
return baseops::GetProperty(cx, proto.as<NativeObject>(), toUTCStringId, &toUTCStringFun) &&
baseops::DefineGeneric(cx, proto.as<NativeObject>(), toGMTStringId, toUTCStringFun,
return baseops::GetProperty(cx, proto.as<DateObject>(), toUTCStringId, &toUTCStringFun) &&
baseops::DefineGeneric(cx, proto.as<DateObject>(), toGMTStringId, toUTCStringFun,
JS_PropertyStub, JS_StrictPropertyStub, 0);
}

View File

@ -410,9 +410,9 @@ ResolveInterpretedFunctionPrototype(JSContext *cx, HandleObject obj)
objProto = obj->global().getOrCreateObjectPrototype(cx);
if (!objProto)
return nullptr;
const Class *clasp = &JSObject::class_;
RootedObject proto(cx, NewObjectWithGivenProto(cx, clasp, objProto, nullptr, SingletonObject));
RootedPlainObject proto(cx, NewObjectWithGivenProto<PlainObject>(cx, objProto,
nullptr, SingletonObject));
if (!proto)
return nullptr;

View File

@ -2769,7 +2769,7 @@ UpdateObjectTableEntryTypes(ExclusiveContext *cx, ObjectTableEntry &entry,
}
void
TypeCompartment::fixObjectType(ExclusiveContext *cx, NativeObject *obj)
TypeCompartment::fixObjectType(ExclusiveContext *cx, PlainObject *obj)
{
AutoEnterAnalysis enter(cx);
@ -2785,10 +2785,7 @@ TypeCompartment::fixObjectType(ExclusiveContext *cx, NativeObject *obj)
/*
* Use the same type object for all singleton/JSON objects with the same
* base shape, i.e. the same fields written in the same order.
*/
MOZ_ASSERT(obj->is<JSObject>());
/*
*
* Exclude some objects we can't readily associate common types for based on their
* shape. Objects with metadata are excluded so that the metadata does not need to
* be included in the table lookup (the metadata object might be in the nursery).
@ -2822,7 +2819,7 @@ TypeCompartment::fixObjectType(ExclusiveContext *cx, NativeObject *obj)
/* Make a new type to use for the object and similar future ones. */
Rooted<TaggedProto> objProto(cx, obj->getTaggedProto());
TypeObject *objType = newTypeObject(cx, &JSObject::class_, objProto);
TypeObject *objType = newTypeObject(cx, &PlainObject::class_, objProto);
if (!objType || !objType->addDefiniteProperties(cx, obj->lastProperty()))
return;
@ -2895,7 +2892,7 @@ TypeCompartment::newTypedObject(JSContext *cx, IdValuePair *properties, size_t n
return nullptr;
gc::AllocKind allocKind = gc::GetGCObjectKind(nproperties);
size_t nfixed = gc::GetGCKindSlots(allocKind, &JSObject::class_);
size_t nfixed = gc::GetGCKindSlots(allocKind, &PlainObject::class_);
ObjectTableKey::Lookup lookup(properties, nproperties, nfixed);
ObjectTypeTable::AddPtr p = objectTypeTable->lookupForAdd(lookup);
@ -2903,7 +2900,7 @@ TypeCompartment::newTypedObject(JSContext *cx, IdValuePair *properties, size_t n
if (!p)
return nullptr;
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &JSObject::class_, allocKind));
RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx, allocKind));
if (!obj) {
cx->clearPendingException();
return nullptr;
@ -3776,8 +3773,8 @@ TypeNewScript::make(JSContext *cx, TypeObject *type, JSFunction *fun)
newScript->fun = fun;
NativeObject **preliminaryObjects =
type->zone()->pod_calloc<NativeObject *>(PRELIMINARY_OBJECT_COUNT);
PlainObject **preliminaryObjects =
type->zone()->pod_calloc<PlainObject *>(PRELIMINARY_OBJECT_COUNT);
if (!preliminaryObjects)
return;
@ -3788,7 +3785,7 @@ TypeNewScript::make(JSContext *cx, TypeObject *type, JSFunction *fun)
}
void
TypeNewScript::registerNewObject(NativeObject *res)
TypeNewScript::registerNewObject(PlainObject *res)
{
MOZ_ASSERT(!analyzed());
@ -3813,7 +3810,7 @@ TypeNewScript::registerNewObject(NativeObject *res)
}
void
TypeNewScript::unregisterNewObject(NativeObject *res)
TypeNewScript::unregisterNewObject(PlainObject *res)
{
MOZ_ASSERT(!analyzed());
@ -3871,7 +3868,7 @@ CommonPrefix(Shape *first, Shape *second)
}
static bool
ChangeObjectFixedSlotCount(JSContext *cx, NativeObject *obj, gc::AllocKind allocKind)
ChangeObjectFixedSlotCount(JSContext *cx, PlainObject *obj, gc::AllocKind allocKind)
{
MOZ_ASSERT(OnlyHasDataProperties(obj->lastProperty()));
@ -3945,7 +3942,7 @@ TypeNewScript::maybeAnalyze(JSContext *cx, TypeObject *type, bool *regenerate, b
Shape *prefixShape = nullptr;
size_t maxSlotSpan = 0;
for (size_t i = 0; i < PRELIMINARY_OBJECT_COUNT; i++) {
NativeObject *obj = preliminaryObjects[i];
PlainObject *obj = preliminaryObjects[i];
if (!obj)
continue;
@ -3984,7 +3981,7 @@ TypeNewScript::maybeAnalyze(JSContext *cx, TypeObject *type, bool *regenerate, b
// old number of fixed slots.
Shape *newPrefixShape = nullptr;
for (size_t i = 0; i < PRELIMINARY_OBJECT_COUNT; i++) {
NativeObject *obj = preliminaryObjects[i];
PlainObject *obj = preliminaryObjects[i];
if (!obj)
continue;
if (!ChangeObjectFixedSlotCount(cx, obj, kind))
@ -4001,13 +3998,13 @@ TypeNewScript::maybeAnalyze(JSContext *cx, TypeObject *type, bool *regenerate, b
}
RootedTypeObject typeRoot(cx, type);
templateObject_ = NewNativeObjectWithType(cx, typeRoot, cx->global(), kind, MaybeSingletonObject);
templateObject_ = NewObjectWithType<PlainObject>(cx, typeRoot, cx->global(), kind, MaybeSingletonObject);
if (!templateObject_)
return false;
Vector<Initializer> initializerVector(cx);
RootedNativeObject templateRoot(cx, templateObject());
RootedPlainObject templateRoot(cx, templateObject());
if (!jit::AnalyzeNewScriptDefiniteProperties(cx, fun, type, templateRoot, &initializerVector))
return false;
@ -4141,7 +4138,7 @@ TypeNewScript::rollbackPartiallyInitializedObjects(JSContext *cx, TypeObject *ty
}
// Found a matching frame.
RootedNativeObject obj(cx, &thisv.toObject().as<NativeObject>());
RootedPlainObject obj(cx, &thisv.toObject().as<PlainObject>());
// Whether all identified 'new' properties have been initialized.
bool finished = false;
@ -4219,7 +4216,7 @@ TypeNewScript::sweep()
// are about to be destroyed.
if (preliminaryObjects) {
for (size_t i = 0; i < PRELIMINARY_OBJECT_COUNT; i++) {
NativeObject **ptr = &preliminaryObjects[i];
PlainObject **ptr = &preliminaryObjects[i];
if (*ptr && IsObjectAboutToBeFinalized(ptr))
*ptr = nullptr;
}

View File

@ -939,13 +939,14 @@ class TypeNewScript
// analyses are performed and this array is cleared. The pointers in this
// array are weak.
static const uint32_t PRELIMINARY_OBJECT_COUNT = 20;
NativeObject **preliminaryObjects;
PlainObject **preliminaryObjects;
// After the new script properties analyses have been performed, a template
// object to use for newly constructed objects. The shape of this object
// reflects all definite properties the object will have, and the
// allocation kind to use.
HeapPtrNativeObject templateObject_;
// allocation kind to use. Note that this is actually a PlainObject, but is
// JSObject here to avoid cyclic include dependencies.
HeapPtrPlainObject templateObject_;
// Order in which definite properties become initialized. We need this in
// case the definite properties are invalidated (such as by adding a setter
@ -990,7 +991,7 @@ class TypeNewScript
return true;
}
NativeObject *templateObject() const {
PlainObject *templateObject() const {
return templateObject_;
}
@ -1009,8 +1010,8 @@ class TypeNewScript
void fixupAfterMovingGC();
#endif
void registerNewObject(NativeObject *res);
void unregisterNewObject(NativeObject *res);
void registerNewObject(PlainObject *res);
void unregisterNewObject(PlainObject *res);
bool maybeAnalyze(JSContext *cx, TypeObject *type, bool *regenerate, bool force = false);
void rollbackPartiallyInitializedObjects(JSContext *cx, TypeObject *type);
@ -1688,7 +1689,7 @@ struct TypeCompartment
public:
void fixArrayType(ExclusiveContext *cx, ArrayObject *obj);
void fixObjectType(ExclusiveContext *cx, NativeObject *obj);
void fixObjectType(ExclusiveContext *cx, PlainObject *obj);
void fixRestArgumentsType(ExclusiveContext *cx, ArrayObject *obj);
JSObject *newTypedObject(JSContext *cx, IdValuePair *properties, size_t nproperties);

View File

@ -311,7 +311,7 @@ GetClassForProtoKey(JSProtoKey key)
{
switch (key) {
case JSProto_Object:
return &JSObject::class_;
return &PlainObject::class_;
case JSProto_Array:
return &ArrayObject::class_;
@ -573,7 +573,7 @@ FixArrayType(ExclusiveContext *cx, ArrayObject *obj)
}
inline void
FixObjectType(ExclusiveContext *cx, NativeObject *obj)
FixObjectType(ExclusiveContext *cx, PlainObject *obj)
{
cx->compartment()->types.fixObjectType(cx, obj);
}

View File

@ -484,21 +484,17 @@ NewPropertyIteratorObject(JSContext *cx, unsigned flags)
if (!shape)
return nullptr;
NativeObject *obj =
MaybeNativeObject(JSObject::create(cx, ITERATOR_FINALIZE_KIND,
GetInitialHeap(GenericObject, clasp), shape, type));
JSObject *obj = JSObject::create(cx, ITERATOR_FINALIZE_KIND,
GetInitialHeap(GenericObject, clasp), shape, type);
if (!obj)
return nullptr;
PropertyIteratorObject *res = &obj->as<PropertyIteratorObject>();
MOZ_ASSERT(obj->numFixedSlots() == JSObject::ITER_CLASS_NFIXED_SLOTS);
return &obj->as<PropertyIteratorObject>();
MOZ_ASSERT(res->numFixedSlots() == JSObject::ITER_CLASS_NFIXED_SLOTS);
return res;
}
JSObject *obj = NewBuiltinClassInstance(cx, &PropertyIteratorObject::class_);
if (!obj)
return nullptr;
return &obj->as<PropertyIteratorObject>();
return NewBuiltinClassInstance<PropertyIteratorObject>(cx);
}
NativeIterator *
@ -809,7 +805,7 @@ js::CreateItrResultObject(JSContext *cx, HandleValue value, bool done)
if (!proto)
return nullptr;
RootedObject obj(cx, NewObjectWithGivenProto(cx, &JSObject::class_, proto, cx->global()));
RootedPlainObject obj(cx, NewObjectWithGivenProto<PlainObject>(cx, proto, cx->global()));
if (!obj)
return nullptr;

View File

@ -72,135 +72,6 @@ using namespace js::types;
using mozilla::DebugOnly;
using mozilla::Maybe;
static JSObject *
CreateObjectConstructor(JSContext *cx, JSProtoKey key)
{
Rooted<GlobalObject*> self(cx, cx->global());
if (!GlobalObject::ensureConstructor(cx, self, JSProto_Function))
return nullptr;
RootedObject functionProto(cx, &self->getPrototype(JSProto_Function).toObject());
/* Create the Object function now that we have a [[Prototype]] for it. */
RootedObject ctor(cx, NewObjectWithGivenProto(cx, &JSFunction::class_, functionProto,
self, SingletonObject));
if (!ctor)
return nullptr;
return NewFunction(cx, ctor, obj_construct, 1, JSFunction::NATIVE_CTOR, self,
HandlePropertyName(cx->names().Object));
}
static JSObject *
CreateObjectPrototype(JSContext *cx, JSProtoKey key)
{
Rooted<GlobalObject*> self(cx, cx->global());
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
MOZ_ASSERT(self->isNative());
/*
* Create |Object.prototype| first, mirroring CreateBlankProto but for the
* prototype of the created object.
*/
RootedObject objectProto(cx, NewObjectWithGivenProto(cx, &JSObject::class_, nullptr,
self, SingletonObject));
if (!objectProto)
return nullptr;
/*
* The default 'new' type of Object.prototype is required by type inference
* to have unknown properties, to simplify handling of e.g. heterogenous
* objects in JSON and script literals.
*/
if (!JSObject::setNewTypeUnknown(cx, &JSObject::class_, objectProto))
return nullptr;
return objectProto;
}
static bool
FinishObjectClassInit(JSContext *cx, JS::HandleObject ctor, JS::HandleObject proto)
{
Rooted<GlobalObject*> self(cx, cx->global());
/* ES5 15.1.2.1. */
RootedId evalId(cx, NameToId(cx->names().eval));
JSObject *evalobj = DefineFunction(cx, self, evalId, IndirectEval, 1, JSFUN_STUB_GSOPS);
if (!evalobj)
return false;
self->setOriginalEval(evalobj);
RootedObject intrinsicsHolder(cx);
bool isSelfHostingGlobal = cx->runtime()->isSelfHostingGlobal(self);
if (isSelfHostingGlobal) {
intrinsicsHolder = self;
} else {
intrinsicsHolder = NewObjectWithGivenProto(cx, &JSObject::class_, proto, self,
TenuredObject);
if (!intrinsicsHolder)
return false;
}
self->setIntrinsicsHolder(intrinsicsHolder);
/* Define a property 'global' with the current global as its value. */
RootedValue global(cx, ObjectValue(*self));
if (!JSObject::defineProperty(cx, intrinsicsHolder, cx->names().global,
global, JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_PERMANENT | JSPROP_READONLY))
{
return false;
}
/*
* Define self-hosted functions after setting the intrinsics holder
* (which is needed to define self-hosted functions)
*/
if (!isSelfHostingGlobal) {
if (!JS_DefineFunctions(cx, ctor, object_static_selfhosted_methods))
return false;
}
/*
* The global object should have |Object.prototype| as its [[Prototype]].
* Eventually we'd like to have standard classes be there from the start,
* and thus we would know we were always setting what had previously been a
* null [[Prototype]], but right now some code assumes it can set the
* [[Prototype]] before standard classes have been initialized. For now,
* only set the [[Prototype]] if it hasn't already been set.
*/
Rooted<TaggedProto> tagged(cx, TaggedProto(proto));
if (self->shouldSplicePrototype(cx) && !self->splicePrototype(cx, self->getClass(), tagged))
return false;
return true;
}
const Class JSObject::class_ = {
js_Object_str,
JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
JS_ResolveStub,
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_;
JS_FRIEND_API(JSObject *)
JS_ObjectToInnerObject(JSContext *cx, HandleObject obj)
{
@ -335,7 +206,7 @@ PropDesc::makeObject(JSContext *cx, MutableHandleObject obj)
{
MOZ_ASSERT(!isUndefined());
obj.set(NewBuiltinClassInstance(cx, &JSObject::class_));
obj.set(NewBuiltinClassInstance<PlainObject>(cx));
if (!obj)
return false;
@ -1648,8 +1519,8 @@ js::NewObjectWithClassProtoCommon(ExclusiveContext *cxArg,
* avoid losing creation site information for objects made by scripted 'new'.
*/
JSObject *
js::NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc::AllocKind allocKind,
NewObjectKind newKind)
js::NewObjectWithTypeCommon(JSContext *cx, HandleTypeObject type, JSObject *parent, gc::AllocKind allocKind,
NewObjectKind newKind)
{
MOZ_ASSERT(parent);
@ -1691,11 +1562,11 @@ js::NewObjectScriptedCall(JSContext *cx, MutableHandleObject pobj)
{
jsbytecode *pc;
RootedScript script(cx, cx->currentScript(&pc));
gc::AllocKind allocKind = NewObjectGCKind(&JSObject::class_);
gc::AllocKind allocKind = NewObjectGCKind(&PlainObject::class_);
NewObjectKind newKind = script
? UseNewTypeForInitializer(script, pc, &JSObject::class_)
? UseNewTypeForInitializer(script, pc, &PlainObject::class_)
: GenericObject;
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_, allocKind, newKind));
RootedObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx, allocKind, newKind));
if (!obj)
return false;
@ -1722,7 +1593,7 @@ js::CreateThis(JSContext *cx, const Class *newclasp, HandleObject callee)
return NewObjectWithClassProto(cx, newclasp, proto, parent, kind);
}
static inline NativeObject *
static inline PlainObject *
CreateThisForFunctionWithType(JSContext *cx, HandleTypeObject type, JSObject *parent,
NewObjectKind newKind)
{
@ -1731,16 +1602,16 @@ CreateThisForFunctionWithType(JSContext *cx, HandleTypeObject type, JSObject *pa
// The definite properties analysis has been performed for this
// type, so get the shape and finalize kind to use from the
// TypeNewScript's template.
RootedNativeObject templateObject(cx, newScript->templateObject());
RootedPlainObject templateObject(cx, newScript->templateObject());
MOZ_ASSERT(templateObject->type() == type);
RootedNativeObject res(cx, CopyInitializerObject(cx, templateObject, newKind));
RootedPlainObject res(cx, CopyInitializerObject(cx, templateObject, newKind));
if (!res)
return nullptr;
if (newKind == SingletonObject) {
Rooted<TaggedProto> proto(cx, TaggedProto(templateObject->getProto()));
if (!res->splicePrototype(cx, &JSObject::class_, proto))
if (!res->splicePrototype(cx, &PlainObject::class_, proto))
return nullptr;
} else {
res->setType(type);
@ -1757,7 +1628,7 @@ CreateThisForFunctionWithType(JSContext *cx, HandleTypeObject type, JSObject *pa
// plain object and register it with the type. Use the maximum number
// of fixed slots, as is also required by the TypeNewScript.
gc::AllocKind allocKind = GuessObjectGCKind(NativeObject::MAX_FIXED_SLOTS);
NativeObject *res = NewNativeObjectWithType(cx, type, parent, allocKind, newKind);
PlainObject *res = NewObjectWithType<PlainObject>(cx, type, parent, allocKind, newKind);
if (!res)
return nullptr;
@ -1767,18 +1638,19 @@ CreateThisForFunctionWithType(JSContext *cx, HandleTypeObject type, JSObject *pa
return res;
}
gc::AllocKind allocKind = NewObjectGCKind(&JSObject::class_);
return NewNativeObjectWithType(cx, type, parent, allocKind, newKind);
gc::AllocKind allocKind = NewObjectGCKind(&PlainObject::class_);
return NewObjectWithType<PlainObject>(cx, type, parent, allocKind, newKind);
}
NativeObject *
PlainObject *
js::CreateThisForFunctionWithProto(JSContext *cx, HandleObject callee, JSObject *proto,
NewObjectKind newKind /* = GenericObject */)
{
RootedNativeObject res(cx);
RootedPlainObject res(cx);
if (proto) {
RootedTypeObject type(cx, cx->getNewType(&JSObject::class_, TaggedProto(proto), &callee->as<JSFunction>()));
RootedTypeObject type(cx, cx->getNewType(&PlainObject::class_, TaggedProto(proto),
&callee->as<JSFunction>()));
if (!type)
return nullptr;
@ -1789,16 +1661,16 @@ js::CreateThisForFunctionWithProto(JSContext *cx, HandleObject callee, JSObject
if (regenerate) {
// The script was analyzed successfully and may have changed
// the new type table, so refetch the type.
type = cx->getNewType(&JSObject::class_, TaggedProto(proto), &callee->as<JSFunction>());
type = cx->getNewType(&PlainObject::class_, TaggedProto(proto),
&callee->as<JSFunction>());
MOZ_ASSERT(type && type->newScript());
}
}
res = CreateThisForFunctionWithType(cx, type, callee->getParent(), newKind);
} else {
gc::AllocKind allocKind = NewObjectGCKind(&JSObject::class_);
res = NewNativeObjectWithClassProto(cx, &JSObject::class_, proto,
callee->getParent(), allocKind, newKind);
gc::AllocKind allocKind = NewObjectGCKind(&PlainObject::class_);
res = NewObjectWithProto<PlainObject>(cx, proto, callee->getParent(), allocKind, newKind);
}
if (res) {
@ -1811,7 +1683,7 @@ js::CreateThisForFunctionWithProto(JSContext *cx, HandleObject callee, JSObject
return res;
}
NativeObject *
PlainObject *
js::CreateThisForFunction(JSContext *cx, HandleObject callee, NewObjectKind newKind)
{
RootedValue protov(cx);
@ -1822,10 +1694,10 @@ js::CreateThisForFunction(JSContext *cx, HandleObject callee, NewObjectKind newK
proto = &protov.toObject();
else
proto = nullptr;
NativeObject *obj = CreateThisForFunctionWithProto(cx, callee, proto, newKind);
PlainObject *obj = CreateThisForFunctionWithProto(cx, callee, proto, newKind);
if (obj && newKind == SingletonObject) {
RootedNativeObject nobj(cx, obj);
RootedPlainObject nobj(cx, obj);
/* Reshape the singleton before passing it as the 'this' value. */
NativeObject::clear(cx, nobj);
@ -1990,7 +1862,7 @@ js::DeepCloneObjectLiteral(JSContext *cx, HandleNativeObject obj, NewObjectKind
/* NB: Keep this in sync with XDRObjectLiteral. */
MOZ_ASSERT_IF(obj->hasSingletonType(),
JS::CompartmentOptionsRef(cx).getSingletonsAsTemplates());
MOZ_ASSERT(obj->is<JSObject>() || obj->is<ArrayObject>());
MOZ_ASSERT(obj->is<PlainObject>() || obj->is<ArrayObject>());
// Result of the clone function.
RootedNativeObject clone(cx);
@ -2009,7 +1881,7 @@ js::DeepCloneObjectLiteral(JSContext *cx, HandleNativeObject obj, NewObjectKind
if (!typeObj)
return nullptr;
RootedObject parent(cx, obj->getParent());
clone = NewNativeObjectWithGivenProto(cx, &JSObject::class_,
clone = NewNativeObjectWithGivenProto(cx, &PlainObject::class_,
TaggedProto(typeObj->proto().toObject()),
parent, kind, newKind);
}
@ -2061,7 +1933,7 @@ js::DeepCloneObjectLiteral(JSContext *cx, HandleNativeObject obj, NewObjectKind
} else if (obj->is<ArrayObject>()) {
FixArrayType(cx, &clone->as<ArrayObject>());
} else {
FixObjectType(cx, clone);
FixObjectType(cx, &clone->as<PlainObject>());
}
if (obj->is<ArrayObject>() && obj->denseElementsAreCopyOnWrite()) {
@ -2086,7 +1958,7 @@ js::XDRObjectLiteral(XDRState<mode> *xdr, MutableHandleNativeObject obj)
uint32_t isArray = 0;
{
if (mode == XDR_ENCODE) {
MOZ_ASSERT(obj->is<JSObject>() || obj->is<ArrayObject>());
MOZ_ASSERT(obj->is<PlainObject>() || obj->is<ArrayObject>());
isArray = obj->getClass() == &ArrayObject::class_ ? 1 : 0;
}
@ -2111,7 +1983,7 @@ js::XDRObjectLiteral(XDRState<mode> *xdr, MutableHandleNativeObject obj)
AllocKind kind;
{
if (mode == XDR_ENCODE) {
MOZ_ASSERT(obj->getClass() == &JSObject::class_);
MOZ_ASSERT(obj->is<PlainObject>());
MOZ_ASSERT(obj->isTenured());
kind = obj->asTenured().getAllocKind();
}
@ -2120,8 +1992,7 @@ js::XDRObjectLiteral(XDRState<mode> *xdr, MutableHandleNativeObject obj)
return false;
if (mode == XDR_DECODE) {
obj.set(NewNativeBuiltinClassInstance(cx, &JSObject::class_, kind,
MaybeSingletonObject));
obj.set(NewBuiltinClassInstance<PlainObject>(cx, kind, MaybeSingletonObject));
if (!obj)
return false;
}
@ -2269,7 +2140,7 @@ js::XDRObjectLiteral(XDRState<mode> *xdr, MutableHandleNativeObject obj)
} else if (isArray) {
FixArrayType(cx, &obj->as<ArrayObject>());
} else {
FixObjectType(cx, obj);
FixObjectType(cx, &obj->as<PlainObject>());
}
}
@ -2313,14 +2184,14 @@ js::XDRObjectLiteral(XDRState<XDR_DECODE> *xdr, MutableHandleNativeObject obj);
JSObject *
js::CloneObjectLiteral(JSContext *cx, HandleObject parent, HandleObject srcObj)
{
if (srcObj->getClass() == &JSObject::class_) {
AllocKind kind = GetBackgroundAllocKind(GuessObjectGCKind(srcObj->as<NativeObject>().numFixedSlots()));
if (srcObj->is<PlainObject>()) {
AllocKind kind = GetBackgroundAllocKind(GuessObjectGCKind(srcObj->as<PlainObject>().numFixedSlots()));
MOZ_ASSERT_IF(srcObj->isTenured(), kind == srcObj->asTenured().getAllocKind());
JSObject *proto = cx->global()->getOrCreateObjectPrototype(cx);
if (!proto)
return nullptr;
Rooted<TypeObject*> typeObj(cx, cx->getNewType(&JSObject::class_, TaggedProto(proto)));
Rooted<TypeObject*> typeObj(cx, cx->getNewType(&PlainObject::class_, TaggedProto(proto)));
if (!typeObj)
return nullptr;
@ -3897,7 +3768,7 @@ dumpValue(const Value &v)
const Class *clasp = obj->getClass();
fprintf(stderr, "<%s%s at %p>",
clasp->name,
(clasp == &JSObject::class_) ? "" : " object",
(clasp == &PlainObject::class_) ? "" : " object",
(void *) obj);
} else if (v.isBoolean()) {
if (v.toBoolean())
@ -4186,7 +4057,7 @@ JSObject::addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::ClassIn
// Other things may be measured in the future if DMD indicates it is worthwhile.
if (is<JSFunction>() ||
is<JSObject>() ||
is<PlainObject>() ||
is<ArrayObject>() ||
is<CallObject>() ||
is<RegExpObject>() ||

View File

@ -123,8 +123,6 @@ class JSObject : public js::gc::Cell
static js::types::TypeObject *makeLazyType(JSContext *cx, js::HandleObject obj);
public:
static const js::Class class_;
js::Shape * lastProperty() const {
MOZ_ASSERT(shape_);
return shape_;
@ -1030,12 +1028,12 @@ GetInitialHeap(NewObjectKind newKind, const Class *clasp)
// Specialized call for constructing |this| with a known function callee,
// and a known prototype.
extern NativeObject *
extern PlainObject *
CreateThisForFunctionWithProto(JSContext *cx, js::HandleObject callee, JSObject *proto,
NewObjectKind newKind = GenericObject);
// Specialized call for constructing |this| with a known function callee.
extern NativeObject *
extern PlainObject *
CreateThisForFunction(JSContext *cx, js::HandleObject callee, NewObjectKind newKind);
// Generic call for constructing |this|.

View File

@ -614,6 +614,23 @@ NewObjectWithGivenProto(ExclusiveContext *cx, const js::Class *clasp, JSObject *
return NewObjectWithGivenProto(cx, clasp, TaggedProto(proto), parent, newKind);
}
template <typename T>
inline T *
NewObjectWithGivenProto(ExclusiveContext *cx, TaggedProto proto, JSObject *parent,
NewObjectKind newKind = GenericObject)
{
JSObject *obj = NewObjectWithGivenProto(cx, &T::class_, proto, parent, newKind);
return obj ? &obj->as<T>() : nullptr;
}
template <typename T>
inline T *
NewObjectWithGivenProto(ExclusiveContext *cx, JSObject *proto, JSObject *parent,
NewObjectKind newKind = GenericObject)
{
return NewObjectWithGivenProto<T>(cx, TaggedProto(proto), parent, newKind);
}
inline bool
FindProto(ExclusiveContext *cx, const js::Class *clasp, MutableHandleObject proto)
{
@ -667,16 +684,22 @@ NewObjectWithClassProto(ExclusiveContext *cx, const js::Class *clasp, JSObject *
return NewObjectWithClassProto(cx, clasp, proto, parent, allocKind, newKind);
}
template<typename T>
inline T *
NewObjectWithProto(ExclusiveContext *cx, JSObject *proto, JSObject *parent,
gc::AllocKind allocKind, NewObjectKind newKind = GenericObject)
{
JSObject *obj = NewObjectWithClassProto(cx, &T::class_, proto, parent, allocKind, newKind);
return obj ? &obj->as<T>() : nullptr;
}
template<typename T>
inline T *
NewObjectWithProto(ExclusiveContext *cx, JSObject *proto, JSObject *parent,
NewObjectKind newKind = GenericObject)
{
JSObject *obj = NewObjectWithClassProto(cx, &T::class_, proto, parent, newKind);
if (!obj)
return nullptr;
return &obj->as<T>();
return obj ? &obj->as<T>() : nullptr;
}
/*
@ -702,10 +725,7 @@ inline T *
NewBuiltinClassInstance(ExclusiveContext *cx, NewObjectKind newKind = GenericObject)
{
JSObject *obj = NewBuiltinClassInstance(cx, &T::class_, newKind);
if (!obj)
return nullptr;
return &obj->as<T>();
return obj ? &obj->as<T>() : nullptr;
}
template<typename T>
@ -713,10 +733,7 @@ inline T *
NewBuiltinClassInstance(ExclusiveContext *cx, gc::AllocKind allocKind, NewObjectKind newKind = GenericObject)
{
JSObject *obj = NewBuiltinClassInstance(cx, &T::class_, allocKind, newKind);
if (!obj)
return nullptr;
return &obj->as<T>();
return obj ? &obj->as<T>() : nullptr;
}
// Used to optimize calls to (new Object())
@ -724,15 +741,25 @@ bool
NewObjectScriptedCall(JSContext *cx, MutableHandleObject obj);
JSObject *
NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc::AllocKind allocKind,
NewObjectKind newKind = GenericObject);
NewObjectWithTypeCommon(JSContext *cx, HandleTypeObject type, JSObject *parent,
gc::AllocKind allocKind, NewObjectKind newKind);
inline JSObject *
template <typename T>
inline T *
NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent,
gc::AllocKind allocKind, NewObjectKind newKind = GenericObject)
{
JSObject *obj = NewObjectWithTypeCommon(cx, type, parent, allocKind, newKind);
return obj ? &obj->as<T>() : nullptr;
}
template <typename T>
inline T *
NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent,
NewObjectKind newKind = GenericObject)
{
gc::AllocKind allocKind = gc::GetGCObjectKind(type->clasp());
return NewObjectWithType(cx, type, parent, allocKind, newKind);
return NewObjectWithType<T>(cx, type, parent, allocKind, newKind);
}
JSObject *
@ -768,7 +795,7 @@ ObjectClassIs(HandleObject obj, ESClassValue classValue, JSContext *cx)
return Proxy::objectClassIs(obj, classValue, cx);
switch (classValue) {
case ESClass_Object: return obj->is<JSObject>();
case ESClass_Object: return obj->is<PlainObject>();
case ESClass_Array: return obj->is<ArrayObject>();
case ESClass_Number: return obj->is<NumberObject>();
case ESClass_String: return obj->is<StringObject>();

View File

@ -665,7 +665,7 @@ js_Stringify(JSContext *cx, MutableHandleValue vp, JSObject *replacer_, Value sp
}
/* Step 9. */
RootedNativeObject wrapper(cx, NewNativeBuiltinClassInstance(cx, &JSObject::class_));
RootedPlainObject wrapper(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!wrapper)
return false;
@ -786,7 +786,7 @@ Walk(JSContext *cx, HandleObject holder, HandleId name, HandleValue reviver, Mut
static bool
Revive(JSContext *cx, HandleValue reviver, MutableHandleValue vp)
{
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!obj)
return false;

View File

@ -70,7 +70,7 @@
#define JS_FOR_PROTOTYPES(real,imaginary) \
imaginary(Null, 0, js_InitNullClass, dummy) \
real(Object, 1, js_InitViaClassSpec, &JSObject::class_) \
real(Object, 1, js_InitViaClassSpec, OCLASP(Plain)) \
real(Function, 2, js_InitViaClassSpec, &JSFunction::class_) \
real(Array, 3, js_InitViaClassSpec, OCLASP(Array)) \
real(Boolean, 4, js_InitBooleanClass, OCLASP(Boolean)) \

View File

@ -357,7 +357,7 @@ class NodeBuilder
}
bool newObject(MutableHandleObject dst) {
RootedObject nobj(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
RootedPlainObject nobj(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!nobj)
return false;
@ -704,7 +704,7 @@ NodeBuilder::newNode(ASTType type, TokenPos *pos, MutableHandleObject dst)
MOZ_ASSERT(type > AST_ERROR && type < AST_LIMIT);
RootedValue tv(cx);
RootedObject node(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
RootedPlainObject node(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!node ||
!setNodeLoc(node, pos) ||
!atomValue(nodeTypeNames[type], &tv) ||
@ -3537,8 +3537,8 @@ JS_InitReflect(JSContext *cx, HandleObject obj)
RootedObject proto(cx, obj->as<GlobalObject>().getOrCreateObjectPrototype(cx));
if (!proto)
return nullptr;
RootedObject Reflect(cx, NewObjectWithGivenProto(cx, &JSObject::class_, proto,
obj, SingletonObject));
RootedPlainObject Reflect(cx, NewObjectWithGivenProto<PlainObject>(cx, proto, obj,
SingletonObject));
if (!Reflect)
return nullptr;

View File

@ -921,7 +921,7 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
classk = CK_WithObject;
else if (obj->is<JSFunction>())
classk = CK_JSFunction;
else if (obj->is<JSObject>() || obj->is<ArrayObject>())
else if (obj->is<PlainObject>() || obj->is<ArrayObject>())
classk = CK_JSObject;
else
MOZ_CRASH("Cannot encode this class of object.");

View File

@ -1201,7 +1201,7 @@ js::proxy_revocable(JSContext *cx, unsigned argc, Value *vp)
revoker->as<JSFunction>().initExtendedSlot(ScriptedDirectProxyHandler::REVOKE_SLOT, proxyVal);
RootedObject result(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
RootedPlainObject result(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!result)
return false;

View File

@ -193,14 +193,15 @@ ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction calle
if (!data)
return nullptr;
RootedNativeObject obj(cx);
obj = MaybeNativeObject(JSObject::create(cx, FINALIZE_KIND,
GetInitialHeap(GenericObject, clasp),
shape, type));
if (!obj) {
Rooted<ArgumentsObject *> obj(cx);
JSObject *base = JSObject::create(cx, FINALIZE_KIND,
GetInitialHeap(GenericObject, clasp),
shape, type);
if (!base) {
js_free(data);
return nullptr;
}
obj = &base->as<ArgumentsObject>();
data->numArgs = numArgs;
data->callee.init(ObjectValue(*callee.get()));
@ -222,12 +223,11 @@ ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction calle
obj->initFixedSlot(INITIAL_LENGTH_SLOT, Int32Value(numActuals << PACKED_BITS_COUNT));
copy.maybeForwardToCallObject(&obj->as<ArgumentsObject>(), data);
copy.maybeForwardToCallObject(obj, data);
ArgumentsObject &argsobj = obj->as<ArgumentsObject>();
MOZ_ASSERT(argsobj.initialLength() == numActuals);
MOZ_ASSERT(!argsobj.hasOverriddenLength());
return &argsobj;
MOZ_ASSERT(obj->initialLength() == numActuals);
MOZ_ASSERT(!obj->hasOverriddenLength());
return obj;
}
ArgumentsObject *

View File

@ -104,7 +104,7 @@ ArrayObject::createArray(ExclusiveContext *cx, gc::InitialHeap heap,
/* static */ inline ArrayObject *
ArrayObject::createCopyOnWriteArray(ExclusiveContext *cx, gc::InitialHeap heap,
HandleShape shape,
HandleNativeObject sharedElementsOwner)
HandleArrayObject sharedElementsOwner)
{
MOZ_ASSERT(sharedElementsOwner->getElementsHeader()->isCopyOnWrite());
MOZ_ASSERT(sharedElementsOwner->getElementsHeader()->ownerObject() == sharedElementsOwner);

View File

@ -61,7 +61,7 @@ class ArrayObject : public NativeObject
createCopyOnWriteArray(ExclusiveContext *cx,
gc::InitialHeap heap,
HandleShape shape,
HandleNativeObject sharedElementsOwner);
HandleArrayObject sharedElementsOwner);
private:
// Helper for the above methods.

View File

@ -847,7 +847,7 @@ Debugger::wrapDebuggeeValue(JSContext *cx, MutableHandleValue vp)
vp.setObject(*dobj);
}
} else if (vp.isMagic()) {
RootedObject optObj(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
RootedPlainObject optObj(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!optObj)
return false;
@ -1050,7 +1050,7 @@ Debugger::newCompletionValue(JSContext *cx, JSTrapStatus status, Value value_,
}
/* Common tail for JSTRAP_RETURN and JSTRAP_THROW. */
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &JSObject::class_));
RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!obj ||
!wrapDebuggeeValue(cx, &value) ||
!DefineNativeProperty(cx, obj, key, value, JS_PropertyStub, JS_StrictPropertyStub,
@ -1102,7 +1102,7 @@ Debugger::parseResumptionValue(Maybe<AutoCompartment> &ac, bool ok, const Value
bool okResumption = rv.isObject();
if (okResumption) {
obj = &rv.toObject();
okResumption = obj->is<JSObject>();
okResumption = obj->is<PlainObject>();
}
if (okResumption) {
shape = obj->lastProperty();
@ -4402,7 +4402,7 @@ DebuggerScript_getAllColumnOffsets(JSContext *cx, unsigned argc, Value *vp)
if (!flowData[offset].hasNoEdges() &&
(flowData[offset].lineno() != lineno ||
flowData[offset].column() != column)) {
RootedObject entry(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
RootedPlainObject entry(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!entry)
return false;
@ -5748,8 +5748,7 @@ DebuggerGenericEval(JSContext *cx, const char *fullMethodName, const Value &code
/* If evalWithBindings, create the inner environment. */
if (evalWithBindings) {
/* TODO - This should probably be a Call object, like ES5 strict eval. */
RootedNativeObject nenv(cx, NewNativeObjectWithGivenProto(cx, &JSObject::class_,
nullptr, env));
RootedPlainObject nenv(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr, env));
if (!nenv)
return false;
RootedId id(cx);
@ -7175,7 +7174,7 @@ Builder::newObject(JSContext *cx)
{
AutoCompartment ac(cx, debuggerObject);
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
// If the allocation failed, this will return a false Object, as the spec promises.
return Object(cx, *this, obj);

View File

@ -201,7 +201,7 @@ DebuggerMemory::drainAllocationsLog(JSContext *cx, unsigned argc, Value *vp)
result->ensureDenseInitializedLength(cx, 0, length);
for (size_t i = 0; i < length; i++) {
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!obj)
return false;
@ -363,7 +363,7 @@ class Tally {
size_t total() const { return total_; }
bool report(Census &census, MutableHandleValue report) {
RootedObject obj(census.cx, NewBuiltinClassInstance(census.cx, &JSObject::class_));
RootedPlainObject obj(census.cx, NewBuiltinClassInstance<PlainObject>(census.cx));
RootedValue countValue(census.cx, NumberValue(total_));
if (!obj ||
!JSObject::defineProperty(census.cx, obj, census.cx->names().count, countValue))
@ -435,7 +435,7 @@ class ByJSType {
bool report(Census &census, MutableHandleValue report) {
JSContext *cx = census.cx;
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!obj)
return false;
@ -552,7 +552,7 @@ class ByObjectClass {
qsort(entries.begin(), entries.length(), sizeof(*entries.begin()), compareEntries);
// Now build the result by iterating over the sorted vector.
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!obj)
return false;
for (Entry **entryPtr = entries.begin(); entryPtr < entries.end(); entryPtr++) {
@ -661,7 +661,7 @@ class ByUbinodeType {
qsort(entries.begin(), entries.length(), sizeof(*entries.begin()), compareEntries);
// Now build the result by iterating over the sorted vector.
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!obj)
return false;
for (Entry **entryPtr = entries.begin(); entryPtr < entries.end(); entryPtr++) {

View File

@ -261,7 +261,7 @@ NewSingletonObjectWithObjectPrototype(JSContext *cx, Handle<GlobalObject *> glob
JSObject *proto = global->getOrCreateObjectPrototype(cx);
if (!proto)
return nullptr;
return NewObjectWithGivenProto(cx, &JSObject::class_, proto, global, SingletonObject);
return NewObjectWithGivenProto<PlainObject>(cx, proto, global, SingletonObject);
}
static JSObject*
@ -270,7 +270,7 @@ NewSingletonObjectWithFunctionPrototype(JSContext *cx, Handle<GlobalObject *> gl
JSObject *proto = global->getOrCreateFunctionPrototype(cx);
if (!proto)
return nullptr;
return NewObjectWithGivenProto(cx, &JSObject::class_, proto, global, SingletonObject);
return NewObjectWithGivenProto<PlainObject>(cx, proto, global, SingletonObject);
}
/* static */ bool

View File

@ -286,6 +286,12 @@ class GlobalObject : public NativeObject
*/
NativeObject *createBlankPrototypeInheriting(JSContext *cx, const js::Class *clasp, JSObject &proto);
template <typename T>
T *createBlankPrototype(JSContext *cx) {
NativeObject *res = createBlankPrototype(cx, &T::class_);
return res ? &res->template as<T>() : nullptr;
}
NativeObject *getOrCreateObjectPrototype(JSContext *cx) {
if (functionObjectClassesInitialized())
return &getPrototype(JSProto_Object).toObject().as<NativeObject>();

View File

@ -3074,8 +3074,8 @@ CASE(JSOP_NEWINIT)
obj = NewDenseEmptyArray(cx, nullptr, newKind);
} else {
gc::AllocKind allocKind = GuessObjectGCKind(0);
newKind = UseNewTypeForInitializer(script, REGS.pc, &JSObject::class_);
obj = NewBuiltinClassInstance(cx, &JSObject::class_, allocKind, newKind);
newKind = UseNewTypeForInitializer(script, REGS.pc, &PlainObject::class_);
obj = NewBuiltinClassInstance<PlainObject>(cx, allocKind, newKind);
}
if (!obj || !SetInitializerObjectType(cx, script, REGS.pc, obj, newKind))
goto error;
@ -3099,13 +3099,13 @@ END_CASE(JSOP_NEWARRAY)
CASE(JSOP_NEWARRAY_COPYONWRITE)
{
RootedNativeObject &baseobj = rootNativeObject0;
RootedObject &baseobj = rootObject0;
baseobj = types::GetOrFixupCopyOnWriteObject(cx, script, REGS.pc);
if (!baseobj)
goto error;
RootedObject &obj = rootObject1;
obj = NewDenseCopyOnWriteArray(cx, baseobj, gc::DefaultHeap);
obj = NewDenseCopyOnWriteArray(cx, baseobj.as<ArrayObject>(), gc::DefaultHeap);
if (!obj)
goto error;
@ -3115,12 +3115,12 @@ END_CASE(JSOP_NEWARRAY_COPYONWRITE)
CASE(JSOP_NEWOBJECT)
{
RootedNativeObject &baseobj = rootNativeObject0;
RootedObject &baseobj = rootObject0;
baseobj = script->getObject(REGS.pc);
RootedObject &obj = rootObject1;
NewObjectKind newKind = UseNewTypeForInitializer(script, REGS.pc, baseobj->getClass());
obj = CopyInitializerObject(cx, baseobj, newKind);
obj = CopyInitializerObject(cx, baseobj.as<PlainObject>(), newKind);
if (!obj || !SetInitializerObjectType(cx, script, REGS.pc, obj, newKind))
goto error;
@ -3138,7 +3138,7 @@ CASE(JSOP_MUTATEPROTO)
RootedObject &obj = rootObject0;
obj = &REGS.sp[-2].toObject();
MOZ_ASSERT(obj->is<JSObject>());
MOZ_ASSERT(obj->is<PlainObject>());
bool succeeded;
if (!JSObject::setProto(cx, obj, newProto, &succeeded))
@ -3159,8 +3159,7 @@ CASE(JSOP_INITPROP)
/* Load the object being initialized into lval/obj. */
RootedNativeObject &obj = rootNativeObject0;
obj = &REGS.sp[-2].toObject().as<NativeObject>();
MOZ_ASSERT(obj->is<JSObject>());
obj = &REGS.sp[-2].toObject().as<PlainObject>();
PropertyName *name = script->getName(REGS.pc);

View File

@ -596,7 +596,7 @@ JSONParserBase::createFinishedObject(PropertyVector &properties)
* shape in manually.
*/
gc::AllocKind allocKind = gc::GetGCObjectKind(properties.length());
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &JSObject::class_, allocKind));
RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx, allocKind));
if (!obj)
return nullptr;

View File

@ -370,19 +370,17 @@ NativeObject::setSlotWithType(ExclusiveContext *cx, Shape *shape,
}
/* Make an object with pregenerated shape from a NEWOBJECT bytecode. */
static inline NativeObject *
CopyInitializerObject(JSContext *cx, HandleNativeObject baseobj, NewObjectKind newKind = GenericObject)
static inline PlainObject *
CopyInitializerObject(JSContext *cx, HandlePlainObject baseobj, NewObjectKind newKind = GenericObject)
{
MOZ_ASSERT(baseobj->getClass() == &JSObject::class_);
MOZ_ASSERT(!baseobj->inDictionaryMode());
gc::AllocKind allocKind = gc::GetGCObjectFixedSlotsKind(baseobj->numFixedSlots());
allocKind = gc::GetBackgroundAllocKind(allocKind);
MOZ_ASSERT_IF(baseobj->isTenured(), allocKind == baseobj->asTenured().getAllocKind());
JSObject *baseObj = NewBuiltinClassInstance(cx, &JSObject::class_, allocKind, newKind);
if (!baseObj)
RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx, allocKind, newKind));
if (!obj)
return nullptr;
RootedNativeObject obj(cx, &baseObj->as<NativeObject>());
RootedObject metadata(cx, obj->getMetadata());
RootedShape lastProp(cx, baseobj->lastProperty());
@ -418,20 +416,6 @@ NewNativeObjectWithGivenProto(ExclusiveContext *cx, const js::Class *clasp,
return MaybeNativeObject(NewObjectWithGivenProto(cx, clasp, proto, parent, newKind));
}
inline NativeObject *
NewNativeBuiltinClassInstance(ExclusiveContext *cx, const Class *clasp,
gc::AllocKind allocKind, NewObjectKind newKind = GenericObject)
{
return MaybeNativeObject(NewBuiltinClassInstance(cx, clasp, allocKind, newKind));
}
inline NativeObject *
NewNativeBuiltinClassInstance(ExclusiveContext *cx, const Class *clasp,
NewObjectKind newKind = GenericObject)
{
return MaybeNativeObject(NewBuiltinClassInstance(cx, clasp, newKind));
}
inline NativeObject *
NewNativeObjectWithClassProto(ExclusiveContext *cx, const js::Class *clasp, JSObject *proto, JSObject *parent,
gc::AllocKind allocKind, NewObjectKind newKind = GenericObject)
@ -446,20 +430,6 @@ NewNativeObjectWithClassProto(ExclusiveContext *cx, const js::Class *clasp, JSOb
return MaybeNativeObject(NewObjectWithClassProto(cx, clasp, proto, parent, newKind));
}
inline NativeObject *
NewNativeObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc::AllocKind allocKind,
NewObjectKind newKind = GenericObject)
{
return MaybeNativeObject(NewObjectWithType(cx, type, parent, allocKind, newKind));
}
inline NativeObject *
NewNativeObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent,
NewObjectKind newKind = GenericObject)
{
return MaybeNativeObject(NewObjectWithType(cx, type, parent, newKind));
}
/*
* Call obj's resolve hook.
*

View File

@ -1237,6 +1237,14 @@ class NativeObject : public JSObject
static size_t offsetOfSlots() { return offsetof(NativeObject, slots_); }
};
// Object class for plain native objects created using '{}' object literals,
// 'new Object()', 'Object.create', etc.
class PlainObject : public NativeObject
{
public:
static const js::Class class_;
};
inline void
NativeObject::privateWriteBarrierPre(void **oldval)
{

View File

@ -53,12 +53,11 @@ RegExpObjectBuilder::getOrCreate()
// Note: RegExp objects are always allocated in the tenured heap. This is
// not strictly required, but simplifies embedding them in jitcode.
NativeObject *obj = NewNativeBuiltinClassInstance(cx, &RegExpObject::class_, TenuredObject);
if (!obj)
reobj_ = NewBuiltinClassInstance<RegExpObject>(cx, TenuredObject);
if (!reobj_)
return false;
obj->initPrivate(nullptr);
reobj_->initPrivate(nullptr);
reobj_ = &obj->as<RegExpObject>();
return true;
}
@ -72,12 +71,11 @@ RegExpObjectBuilder::getOrCreateClone(HandleTypeObject type)
// Note: RegExp objects are always allocated in the tenured heap. This is
// not strictly required, but simplifies embedding them in jitcode.
NativeObject *clone = NewNativeObjectWithType(cx->asJSContext(), type, parent, TenuredObject);
if (!clone)
reobj_ = NewObjectWithType<RegExpObject>(cx->asJSContext(), type, parent, TenuredObject);
if (!reobj_)
return false;
clone->initPrivate(nullptr);
reobj_->initPrivate(nullptr);
reobj_ = &clone->as<RegExpObject>();
return true;
}
@ -255,7 +253,7 @@ RegExpObject::trace(JSTracer *trc, JSObject *obj)
IS_GC_MARKING_TRACER(trc) &&
!obj->asTenured().zone()->isPreservingCode())
{
obj->as<NativeObject>().setPrivate(nullptr);
obj->as<RegExpObject>().NativeObject::setPrivate(nullptr);
} else {
shared->trace(trc);
}

View File

@ -22,14 +22,14 @@ using namespace js;
static void
resc_finalize(FreeOp *fop, JSObject *obj)
{
RegExpStatics *res = static_cast<RegExpStatics *>(obj->as<NativeObject>().getPrivate());
RegExpStatics *res = static_cast<RegExpStatics *>(obj->as<RegExpStaticsObject>().getPrivate());
fop->delete_(res);
}
static void
resc_trace(JSTracer *trc, JSObject *obj)
{
void *pdata = obj->as<NativeObject>().getPrivate();
void *pdata = obj->as<RegExpStaticsObject>().getPrivate();
MOZ_ASSERT(pdata);
RegExpStatics *res = static_cast<RegExpStatics *>(pdata);
res->mark(trc);
@ -55,14 +55,14 @@ const Class RegExpStaticsObject::class_ = {
RegExpStaticsObject *
RegExpStatics::create(ExclusiveContext *cx, GlobalObject *parent)
{
NativeObject *obj = NewNativeObjectWithGivenProto(cx, &RegExpStaticsObject::class_, nullptr, parent);
RegExpStaticsObject *obj = NewObjectWithGivenProto<RegExpStaticsObject>(cx, nullptr, parent);
if (!obj)
return nullptr;
RegExpStatics *res = cx->new_<RegExpStatics>();
if (!res)
return nullptr;
obj->setPrivate(static_cast<void *>(res));
return &obj->as<RegExpStaticsObject>();
return obj;
}
void

View File

@ -599,10 +599,8 @@ SavedStacks::getOrCreateSavedFramePrototype(JSContext *cx)
if (!global)
return nullptr;
RootedNativeObject proto(cx,
NewNativeObjectWithGivenProto(cx, &SavedFrame::class_,
global->getOrCreateObjectPrototype(cx),
global));
Rooted<SavedFrame *> proto(cx,
NewObjectWithGivenProto<SavedFrame>(cx, global->getOrCreateObjectPrototype(cx), global));
if (!proto
|| !JS_DefineProperties(cx, proto, SavedFrame::properties)
|| !JS_DefineFunctions(cx, proto, SavedFrame::methods)

View File

@ -681,7 +681,7 @@ JSObject *
js::NewReshapedObject(JSContext *cx, HandleTypeObject type, JSObject *parent,
gc::AllocKind allocKind, HandleShape shape, NewObjectKind newKind)
{
RootedNativeObject res(cx, NewNativeObjectWithType(cx, type, parent, allocKind, newKind));
RootedPlainObject res(cx, NewObjectWithType<PlainObject>(cx, type, parent, allocKind, newKind));
if (!res)
return nullptr;

View File

@ -1632,8 +1632,8 @@ JSStructuredCloneReader::startRead(MutableHandleValue vp)
case SCTAG_ARRAY_OBJECT:
case SCTAG_OBJECT_OBJECT: {
JSObject *obj = (tag == SCTAG_ARRAY_OBJECT)
? NewDenseEmptyArray(context())
: NewBuiltinClassInstance(context(), &JSObject::class_);
? (JSObject *) NewDenseEmptyArray(context())
: (JSObject *) NewBuiltinClassInstance<PlainObject>(context());
if (!obj || !objs.append(ObjectValue(*obj)))
return false;
vp.setObject(*obj);