Bug 1261723 (part 2) - Separate class ops from js::Class. code=njn,h4writer. r=efaust,bz.

js::Class op are often all null. And when they're not all null, they're often
duplicated among classes. By pulling them out into their own struct, and using a
(possibly null) pointer in js::Class, we can save 114 KiB per process on
64-bit, and half that on 32-bit.
* * *
imported patch separate-ClassOps-2

--HG--
extra : rebase_source : bd751bf247e9491c1966a123dbeffa573657dfb1
This commit is contained in:
Nicholas Nethercote 2016-04-01 11:00:01 +11:00
parent 754dc0bd49
commit 60dcde7875
103 changed files with 1269 additions and 935 deletions

View File

@ -98,13 +98,16 @@ struct DevTools : public ::testing::Test {
}
static const JSClass* getGlobalClass() {
static const JSClass globalClass = {
"global", JSCLASS_GLOBAL_FLAGS,
static const JSClassOps globalClassOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr,
JS_GlobalObjectTraceHook
};
static const JSClass globalClass = {
"global", JSCLASS_GLOBAL_FLAGS,
&globalClassOps
};
return &globalClass;
}

View File

@ -1806,6 +1806,21 @@ NativePropertyHooks sEmptyNativePropertyHooks = {
nullptr
};
const js::ClassOps sBoringInterfaceObjectClassClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
ThrowingConstructor, /* call */
InterfaceHasInstance, /* hasInstance */
ThrowingConstructor, /* construct */
nullptr, /* trace */
};
const js::ObjectOps sInterfaceObjectClassObjectOps = {
nullptr, /* lookupProperty */
nullptr, /* defineProperty */

View File

@ -2508,6 +2508,8 @@ XrayGetNativeProto(JSContext* cx, JS::Handle<JSObject*> obj,
extern NativePropertyHooks sEmptyNativePropertyHooks;
extern const js::ClassOps sBoringInterfaceObjectClassClassOps;
extern const js::ObjectOps sInterfaceObjectClassObjectOps;
// We use one constructor JSNative to represent all DOM interface objects (so
@ -2540,7 +2542,7 @@ inline bool
HasConstructor(JSObject* obj)
{
return JS_IsNativeFunction(obj, Constructor) ||
js::GetObjectClass(obj)->construct;
js::GetObjectClass(obj)->getConstruct();
}
#endif

View File

@ -440,6 +440,21 @@ class CGDOMJSClass(CGThing):
return fill(
"""
static const js::ClassOps sClassOps = {
${addProperty}, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
${enumerate}, /* enumerate */
${resolve}, /* resolve */
${mayResolve}, /* mayResolve */
${finalize}, /* finalize */
${call}, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
${trace}, /* trace */
};
static const js::ClassExtension sClassExtension = {
nullptr, /* weakmapKeyDelegateOp */
${objectMoved} /* objectMovedOp */
@ -448,18 +463,7 @@ class CGDOMJSClass(CGThing):
static const DOMJSClass sClass = {
{ "${name}",
${flags},
${addProperty}, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
${enumerate}, /* enumerate */
${resolve}, /* resolve */
${mayResolve}, /* mayResolve */
${finalize}, /* finalize */
${call}, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
${trace}, /* trace */
&sClassOps,
JS_NULL_CLASS_SPEC,
&sClassExtension,
JS_NULL_OBJECT_OPS
@ -594,18 +598,7 @@ class CGPrototypeJSClass(CGThing):
{
"${name}Prototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(${slotCount}),
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
@ -684,24 +677,39 @@ class CGInterfaceObjectJSClass(CGThing):
len(self.descriptor.interface.namedConstructors))
(protoGetter, _) = InterfaceObjectProtoGetter(self.descriptor)
return fill(
if ctorname == "ThrowingConstructor" and hasinstance == "InterfaceHasInstance":
ret = ""
classOpsPtr = "&sBoringInterfaceObjectClassClassOps"
else:
ret = fill(
"""
static const js::ClassOps sInterfaceObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
${ctorname}, /* call */
${hasInstance}, /* hasInstance */
${ctorname}, /* construct */
nullptr, /* trace */
};
""",
ctorname=ctorname,
hasInstance=hasinstance)
classOpsPtr = "&sInterfaceObjectClassOps"
ret = ret + fill(
"""
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
{
"Function",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(${slotCount}),
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
${ctorname}, /* call */
${hasInstance}, /* hasInstance */
${ctorname}, /* construct */
nullptr, /* trace */
${classOpsPtr},
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
&sInterfaceObjectClassObjectOps
@ -717,12 +725,13 @@ class CGInterfaceObjectJSClass(CGThing):
slotCount=slotCount,
ctorname=ctorname,
hasInstance=hasinstance,
classOpsPtr=classOpsPtr,
hooks=NativePropertyHooks(self.descriptor),
name=self.descriptor.interface.identifier.name,
prototypeID=prototypeID,
depth=depth,
protoGetter=protoGetter)
return ret
class CGList(CGThing):
"""

View File

@ -70,14 +70,7 @@ SimpleGlobal_moved(JSObject *obj, const JSObject *old)
globalObject->UpdateWrapper(obj, old);
}
static const js::ClassExtension SimpleGlobalClassExtension = {
nullptr,
SimpleGlobal_moved
};
const js::Class SimpleGlobalClass = {
"",
JSCLASS_GLOBAL_FLAGS | JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS,
static const js::ClassOps SimpleGlobalClassOps = {
nullptr,
nullptr,
nullptr,
@ -90,6 +83,17 @@ const js::Class SimpleGlobalClass = {
nullptr,
nullptr,
JS_GlobalObjectTraceHook,
};
static const js::ClassExtension SimpleGlobalClassExtension = {
nullptr,
SimpleGlobal_moved
};
const js::Class SimpleGlobalClass = {
"",
JSCLASS_GLOBAL_FLAGS | JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS,
&SimpleGlobalClassOps,
JS_NULL_CLASS_SPEC,
&SimpleGlobalClassExtension,
JS_NULL_OBJECT_OPS

View File

@ -7792,7 +7792,7 @@ class NormalJSRuntime
{
friend class nsAutoPtr<NormalJSRuntime>;
static const JSClass kGlobalClass;
static const JSClass sGlobalClass;
static const uint32_t kRuntimeHeapSize = 768 * 1024;
JSRuntime* mRuntime;
@ -23761,9 +23761,7 @@ CreateIndexOp::DoDatabaseWork(DatabaseConnection* aConnection)
return NS_OK;
}
const JSClass NormalJSRuntime::kGlobalClass = {
"IndexedDBTransactionThreadGlobal",
JSCLASS_GLOBAL_FLAGS,
static const JSClassOps sNormalJSRuntimeGlobalClassOps = {
/* addProperty */ nullptr,
/* delProperty */ nullptr,
/* getProperty */ nullptr,
@ -23778,6 +23776,12 @@ const JSClass NormalJSRuntime::kGlobalClass = {
/* trace */ JS_GlobalObjectTraceHook
};
const JSClass NormalJSRuntime::sGlobalClass = {
"IndexedDBTransactionThreadGlobal",
JSCLASS_GLOBAL_FLAGS,
&sNormalJSRuntimeGlobalClassOps
};
bool
NormalJSRuntime::Init()
{
@ -23799,7 +23803,7 @@ NormalJSRuntime::Init()
JSAutoRequest ar(mContext);
JS::CompartmentOptions options;
mGlobal = JS_NewGlobalObject(mContext, &kGlobalClass, nullptr,
mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, nullptr,
JS::FireOnNewGlobalHook, options);
if (NS_WARN_IF(!mGlobal)) {
return false;

View File

@ -218,8 +218,23 @@ CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
JS::Handle<jsid> id, NPVariant* getPropertyResult,
JS::MutableHandle<JS::Value> vp);
const static js::ClassOps sNPObjectJSWrapperClassOps = {
NPObjWrapper_AddProperty,
NPObjWrapper_DelProperty,
NPObjWrapper_GetProperty,
NPObjWrapper_SetProperty,
nullptr,
NPObjWrapper_Resolve,
nullptr, /* mayResolve */
NPObjWrapper_Finalize,
NPObjWrapper_Call,
nullptr, /* hasInstance */
NPObjWrapper_Construct,
nullptr, /* trace */
};
const static js::ClassExtension sNPObjectJSWrapperClassExtension = {
nullptr, /* weakmapKeyDelegateOp */
nullptr, /* weakmapKeyDelegateOp */
NPObjWrapper_ObjectMoved
};
@ -237,26 +252,14 @@ const static js::ObjectOps sNPObjectJSWrapperObjectOps = {
nullptr,
};
const static js::Class sNPObjectJSWrapperClass =
{
const static js::Class sNPObjectJSWrapperClass = {
NPRUNTIME_JSCLASS_NAME,
JSCLASS_HAS_PRIVATE,
NPObjWrapper_AddProperty,
NPObjWrapper_DelProperty,
NPObjWrapper_GetProperty,
NPObjWrapper_SetProperty,
nullptr,
NPObjWrapper_Resolve,
nullptr, /* mayResolve */
NPObjWrapper_Finalize,
NPObjWrapper_Call,
nullptr, /* hasInstance */
NPObjWrapper_Construct,
nullptr, /* trace */
&sNPObjectJSWrapperClassOps,
JS_NULL_CLASS_SPEC,
&sNPObjectJSWrapperClassExtension,
&sNPObjectJSWrapperObjectOps
};
};
typedef struct NPObjectMemberPrivate {
JS::Heap<JSObject *> npobjWrapper;
@ -281,14 +284,17 @@ NPObjectMember_Trace(JSTracer *trc, JSObject *obj);
static bool
NPObjectMember_toPrimitive(JSContext *cx, unsigned argc, JS::Value *vp);
static const JSClass sNPObjectMemberClass =
{
"NPObject Ambiguous Member class", JSCLASS_HAS_PRIVATE,
nullptr, nullptr, NPObjectMember_GetProperty, nullptr,
nullptr, nullptr, nullptr,
NPObjectMember_Finalize, NPObjectMember_Call,
nullptr, nullptr, NPObjectMember_Trace
};
static const JSClassOps sNPObjectMemberClassOps = {
nullptr, nullptr, NPObjectMember_GetProperty, nullptr,
nullptr, nullptr, nullptr,
NPObjectMember_Finalize, NPObjectMember_Call,
nullptr, nullptr, NPObjectMember_Trace
};
static const JSClass sNPObjectMemberClass = {
"NPObject Ambiguous Member class", JSCLASS_HAS_PRIVATE,
&sNPObjectMemberClassOps
};
static void
OnWrapperDestroyed();

View File

@ -86,15 +86,19 @@ XBLEnumerate(JSContext *cx, JS::Handle<JSObject*> obj)
return protoBinding->ResolveAllFields(cx, obj);
}
static const JSClassOps gPrototypeJSClassOps = {
nullptr, nullptr, nullptr, nullptr,
XBLEnumerate, nullptr,
nullptr, XBLFinalize,
nullptr, nullptr, nullptr, nullptr
};
static const JSClass gPrototypeJSClass = {
"XBL prototype JSClass",
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS |
// Our one reserved slot holds the relevant nsXBLPrototypeBinding
JSCLASS_HAS_RESERVED_SLOTS(1),
nullptr, nullptr, nullptr, nullptr,
XBLEnumerate, nullptr,
nullptr, XBLFinalize,
nullptr, nullptr, nullptr, nullptr
&gPrototypeJSClassOps
};
// Implementation /////////////////////////////////////////////////////////////////

View File

@ -477,23 +477,55 @@ typedef bool
typedef void
(* FinalizeOp)(FreeOp* fop, JSObject* obj);
#define JS_CLASS_MEMBERS(FinalizeOpType) \
const char* name; \
uint32_t flags; \
\
/* Function pointer members (may be null). */ \
JSAddPropertyOp addProperty; \
JSDeletePropertyOp delProperty; \
JSGetterOp getProperty; \
JSSetterOp setProperty; \
JSEnumerateOp enumerate; \
JSResolveOp resolve; \
JSMayResolveOp mayResolve; \
FinalizeOpType finalize; \
JSNative call; \
JSHasInstanceOp hasInstance; \
JSNative construct; \
JSTraceOp trace
// The special treatment of |finalize| and |trace| is necessary because if we
// assign either of those hooks to a local variable and then call it -- as is
// done with the other hooks -- the GC hazard analysis gets confused.
#define JS_CLASS_MEMBERS(ClassOpsType, FinalizeOpType, FreeOpType) \
const char* name; \
uint32_t flags; \
const ClassOpsType* cOps; \
\
JSAddPropertyOp getAddProperty() const { return cOps ? cOps->addProperty : nullptr; } \
JSDeletePropertyOp getDelProperty() const { return cOps ? cOps->delProperty : nullptr; } \
JSGetterOp getGetProperty() const { return cOps ? cOps->getProperty : nullptr; } \
JSSetterOp getSetProperty() const { return cOps ? cOps->setProperty : nullptr; } \
JSEnumerateOp getEnumerate() const { return cOps ? cOps->enumerate : nullptr; } \
JSResolveOp getResolve() const { return cOps ? cOps->resolve : nullptr; } \
JSMayResolveOp getMayResolve() const { return cOps ? cOps->mayResolve : nullptr; } \
JSNative getCall() const { return cOps ? cOps->call : nullptr; } \
JSHasInstanceOp getHasInstance() const { return cOps ? cOps->hasInstance : nullptr; } \
JSNative getConstruct() const { return cOps ? cOps->construct : nullptr; } \
\
bool hasFinalize() const { return cOps && cOps->finalize; } \
bool hasTrace() const { return cOps && cOps->trace; } \
\
bool isTrace(JSTraceOp trace) const { return cOps && cOps->trace == trace; } \
\
void doFinalize(FreeOpType* fop, JSObject* obj) const { \
MOZ_ASSERT(cOps && cOps->finalize); \
cOps->finalize(fop, obj); \
} \
void doTrace(JSTracer* trc, JSObject* obj) const { \
MOZ_ASSERT(cOps && cOps->trace); \
cOps->trace(trc, obj); \
}
struct ClassOps
{
/* Function pointer members (may be null). */
JSAddPropertyOp addProperty;
JSDeletePropertyOp delProperty;
JSGetterOp getProperty;
JSSetterOp setProperty;
JSEnumerateOp enumerate;
JSResolveOp resolve;
JSMayResolveOp mayResolve;
FinalizeOp finalize;
JSNative call;
JSHasInstanceOp hasInstance;
JSNative construct;
JSTraceOp trace;
};
/** Callback for the creation of constructor and prototype objects. */
typedef JSObject* (*ClassObjectCreationOp)(JSContext* cx, JSProtoKey key);
@ -645,8 +677,27 @@ struct ObjectOps
typedef void (*JSClassInternal)();
struct JSClassOps
{
/* Function pointer members (may be null). */
JSAddPropertyOp addProperty;
JSDeletePropertyOp delProperty;
JSGetterOp getProperty;
JSSetterOp setProperty;
JSEnumerateOp enumerate;
JSResolveOp resolve;
JSMayResolveOp mayResolve;
JSFinalizeOp finalize;
JSNative call;
JSHasInstanceOp hasInstance;
JSNative construct;
JSTraceOp trace;
};
#define JS_NULL_CLASS_OPS nullptr
struct JSClass {
JS_CLASS_MEMBERS(JSFinalizeOp);
JS_CLASS_MEMBERS(JSClassOps, JSFinalizeOp, JSFreeOp);
void* reserved[3];
};
@ -753,7 +804,7 @@ namespace js {
struct Class
{
JS_CLASS_MEMBERS(FinalizeOp);
JS_CLASS_MEMBERS(js::ClassOps, FinalizeOp, FreeOp);
const ClassSpec* spec;
const ClassExtension* ext;
const ObjectOps* oOps;
@ -785,7 +836,7 @@ struct Class
bool nonProxyCallable() const {
MOZ_ASSERT(!isProxy());
return isJSFunction() || call;
return isJSFunction() || getCall();
}
bool isProxy() const {
@ -847,33 +898,38 @@ struct Class
JSFunToStringOp getOpsFunToString() const { return oOps ? oOps->funToString : nullptr; }
};
static_assert(offsetof(JSClassOps, addProperty) == offsetof(ClassOps, addProperty),
"ClassOps and JSClassOps must be consistent");
static_assert(offsetof(JSClassOps, delProperty) == offsetof(ClassOps, delProperty),
"ClassOps and JSClassOps must be consistent");
static_assert(offsetof(JSClassOps, getProperty) == offsetof(ClassOps, getProperty),
"ClassOps and JSClassOps must be consistent");
static_assert(offsetof(JSClassOps, setProperty) == offsetof(ClassOps, setProperty),
"ClassOps and JSClassOps must be consistent");
static_assert(offsetof(JSClassOps, enumerate) == offsetof(ClassOps, enumerate),
"ClassOps and JSClassOps must be consistent");
static_assert(offsetof(JSClassOps, resolve) == offsetof(ClassOps, resolve),
"ClassOps and JSClassOps must be consistent");
static_assert(offsetof(JSClassOps, mayResolve) == offsetof(ClassOps, mayResolve),
"ClassOps and JSClassOps must be consistent");
static_assert(offsetof(JSClassOps, finalize) == offsetof(ClassOps, finalize),
"ClassOps and JSClassOps must be consistent");
static_assert(offsetof(JSClassOps, call) == offsetof(ClassOps, call),
"ClassOps and JSClassOps must be consistent");
static_assert(offsetof(JSClassOps, construct) == offsetof(ClassOps, construct),
"ClassOps and JSClassOps must be consistent");
static_assert(offsetof(JSClassOps, hasInstance) == offsetof(ClassOps, hasInstance),
"ClassOps and JSClassOps must be consistent");
static_assert(offsetof(JSClassOps, trace) == offsetof(ClassOps, trace),
"ClassOps and JSClassOps must be consistent");
static_assert(sizeof(JSClassOps) == sizeof(ClassOps),
"ClassOps and JSClassOps must be consistent");
static_assert(offsetof(JSClass, name) == offsetof(Class, name),
"Class and JSClass must be consistent");
static_assert(offsetof(JSClass, flags) == offsetof(Class, flags),
"Class and JSClass must be consistent");
static_assert(offsetof(JSClass, addProperty) == offsetof(Class, addProperty),
"Class and JSClass must be consistent");
static_assert(offsetof(JSClass, delProperty) == offsetof(Class, delProperty),
"Class and JSClass must be consistent");
static_assert(offsetof(JSClass, getProperty) == offsetof(Class, getProperty),
"Class and JSClass must be consistent");
static_assert(offsetof(JSClass, setProperty) == offsetof(Class, setProperty),
"Class and JSClass must be consistent");
static_assert(offsetof(JSClass, enumerate) == offsetof(Class, enumerate),
"Class and JSClass must be consistent");
static_assert(offsetof(JSClass, resolve) == offsetof(Class, resolve),
"Class and JSClass must be consistent");
static_assert(offsetof(JSClass, mayResolve) == offsetof(Class, mayResolve),
"Class and JSClass must be consistent");
static_assert(offsetof(JSClass, finalize) == offsetof(Class, finalize),
"Class and JSClass must be consistent");
static_assert(offsetof(JSClass, call) == offsetof(Class, call),
"Class and JSClass must be consistent");
static_assert(offsetof(JSClass, construct) == offsetof(Class, construct),
"Class and JSClass must be consistent");
static_assert(offsetof(JSClass, hasInstance) == offsetof(Class, hasInstance),
"Class and JSClass must be consistent");
static_assert(offsetof(JSClass, trace) == offsetof(Class, trace),
static_assert(offsetof(JSClass, cOps) == offsetof(Class, cOps),
"Class and JSClass must be consistent");
static_assert(sizeof(JSClass) == sizeof(Class),
"Class and JSClass must be consistent");

View File

@ -1563,10 +1563,7 @@ Module::profilingLabel(uint32_t funcIndex) const
return funcLabels_[funcIndex].get();
}
const Class WasmModuleObject::class_ = {
"WasmModuleObject",
JSCLASS_IS_ANONYMOUS | JSCLASS_DELAY_METADATA_BUILDER |
JSCLASS_HAS_RESERVED_SLOTS(WasmModuleObject::RESERVED_SLOTS),
const ClassOps WasmModuleObject::classOps_ = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -1581,6 +1578,13 @@ const Class WasmModuleObject::class_ = {
WasmModuleObject::trace
};
const Class WasmModuleObject::class_ = {
"WasmModuleObject",
JSCLASS_IS_ANONYMOUS | JSCLASS_DELAY_METADATA_BUILDER |
JSCLASS_HAS_RESERVED_SLOTS(WasmModuleObject::RESERVED_SLOTS),
&WasmModuleObject::classOps_,
};
bool
WasmModuleObject::hasModule() const
{

View File

@ -657,6 +657,8 @@ ExportedFunctionToIndex(JSFunction* fun);
class WasmModuleObject : public NativeObject
{
static const unsigned MODULE_SLOT = 0;
static const ClassOps classOps_;
bool hasModule() const;
static void finalize(FreeOp* fop, JSObject* obj);
static void trace(JSTracer* trc, JSObject* obj);

View File

@ -628,9 +628,7 @@ static void collator_finalize(FreeOp* fop, JSObject* obj);
static const uint32_t UCOLLATOR_SLOT = 0;
static const uint32_t COLLATOR_SLOTS_COUNT = 1;
static const Class CollatorClass = {
js_Object_str,
JSCLASS_HAS_RESERVED_SLOTS(COLLATOR_SLOTS_COUNT),
static const ClassOps CollatorClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -641,6 +639,12 @@ static const Class CollatorClass = {
collator_finalize
};
static const Class CollatorClass = {
js_Object_str,
JSCLASS_HAS_RESERVED_SLOTS(COLLATOR_SLOTS_COUNT),
&CollatorClassOps
};
#if JS_HAS_TOSOURCE
static bool
collator_toSource(JSContext* cx, unsigned argc, Value* vp)
@ -1122,9 +1126,7 @@ static void numberFormat_finalize(FreeOp* fop, JSObject* obj);
static const uint32_t UNUMBER_FORMAT_SLOT = 0;
static const uint32_t NUMBER_FORMAT_SLOTS_COUNT = 1;
static const Class NumberFormatClass = {
js_Object_str,
JSCLASS_HAS_RESERVED_SLOTS(NUMBER_FORMAT_SLOTS_COUNT),
static const ClassOps NumberFormatClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -1135,6 +1137,12 @@ static const Class NumberFormatClass = {
numberFormat_finalize
};
static const Class NumberFormatClass = {
js_Object_str,
JSCLASS_HAS_RESERVED_SLOTS(NUMBER_FORMAT_SLOTS_COUNT),
&NumberFormatClassOps
};
#if JS_HAS_TOSOURCE
static bool
numberFormat_toSource(JSContext* cx, unsigned argc, Value* vp)
@ -1591,9 +1599,7 @@ static void dateTimeFormat_finalize(FreeOp* fop, JSObject* obj);
static const uint32_t UDATE_FORMAT_SLOT = 0;
static const uint32_t DATE_TIME_FORMAT_SLOTS_COUNT = 1;
static const Class DateTimeFormatClass = {
js_Object_str,
JSCLASS_HAS_RESERVED_SLOTS(DATE_TIME_FORMAT_SLOTS_COUNT),
static const ClassOps DateTimeFormatClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -1604,6 +1610,12 @@ static const Class DateTimeFormatClass = {
dateTimeFormat_finalize
};
static const Class DateTimeFormatClass = {
js_Object_str,
JSCLASS_HAS_RESERVED_SLOTS(DATE_TIME_FORMAT_SLOTS_COUNT),
&DateTimeFormatClassOps
};
#if JS_HAS_TOSOURCE
static bool
dateTimeFormat_toSource(JSContext* cx, unsigned argc, Value* vp)

View File

@ -104,9 +104,7 @@ namespace {
} /* anonymous namespace */
const Class MapIteratorObject::class_ = {
"Map Iterator",
JSCLASS_HAS_RESERVED_SLOTS(MapIteratorObject::SlotCount),
static const ClassOps MapIteratorObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -117,6 +115,12 @@ const Class MapIteratorObject::class_ = {
MapIteratorObject::finalize
};
const Class MapIteratorObject::class_ = {
"Map Iterator",
JSCLASS_HAS_RESERVED_SLOTS(MapIteratorObject::SlotCount),
&MapIteratorObjectClassOps
};
const JSFunctionSpec MapIteratorObject::methods[] = {
JS_SELF_HOSTED_FN("next", "MapIteratorNext", 0, 0),
JS_FS_END
@ -259,10 +263,7 @@ MapIteratorObject::createResultPair(JSContext* cx)
/*** Map *****************************************************************************************/
const Class MapObject::class_ = {
"Map",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_CACHED_PROTO(JSProto_Map),
const ClassOps MapObject::classOps_ = {
nullptr, // addProperty
nullptr, // delProperty
nullptr, // getProperty
@ -277,6 +278,13 @@ const Class MapObject::class_ = {
mark
};
const Class MapObject::class_ = {
"Map",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_CACHED_PROTO(JSProto_Map),
&MapObject::classOps_
};
const JSPropertySpec MapObject::properties[] = {
JS_PSG("size", size, 0),
JS_PS_END
@ -870,9 +878,7 @@ class SetIteratorObject : public NativeObject
} /* anonymous namespace */
const Class SetIteratorObject::class_ = {
"Set Iterator",
JSCLASS_HAS_RESERVED_SLOTS(SetIteratorObject::SlotCount),
static const ClassOps SetIteratorObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -883,6 +889,12 @@ const Class SetIteratorObject::class_ = {
SetIteratorObject::finalize
};
const Class SetIteratorObject::class_ = {
"Set Iterator",
JSCLASS_HAS_RESERVED_SLOTS(SetIteratorObject::SlotCount),
&SetIteratorObjectClassOps
};
const JSFunctionSpec SetIteratorObject::methods[] = {
JS_FN("next", next, 0, 0),
JS_FS_END
@ -1006,10 +1018,7 @@ SetIteratorObject::next(JSContext* cx, unsigned argc, Value* vp)
/*** Set *****************************************************************************************/
const Class SetObject::class_ = {
"Set",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_CACHED_PROTO(JSProto_Set),
const ClassOps SetObject::classOps_ = {
nullptr, // addProperty
nullptr, // delProperty
nullptr, // getProperty
@ -1024,6 +1033,13 @@ const Class SetObject::class_ = {
mark
};
const Class SetObject::class_ = {
"Set",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_CACHED_PROTO(JSProto_Set),
&SetObject::classOps_
};
const JSPropertySpec SetObject::properties[] = {
JS_PSG("size", size, 0),
JS_PS_END

View File

@ -109,6 +109,8 @@ class MapObject : public NativeObject {
static bool iterator(JSContext *cx, IteratorKind kind, HandleObject obj, MutableHandleValue iter);
private:
static const ClassOps classOps_;
static const JSPropertySpec properties[];
static const JSFunctionSpec methods[];
static const JSPropertySpec staticProperties[];
@ -191,9 +193,12 @@ class SetObject : public NativeObject {
static bool delete_(JSContext *cx, HandleObject obj, HandleValue key, bool *rval);
private:
static const ClassOps classOps_;
static const JSPropertySpec properties[];
static const JSFunctionSpec methods[];
static const JSPropertySpec staticProperties[];
ValueSet* getData() { return static_cast<ValueSet*>(getPrivate()); }
static ValueSet & extract(HandleObject o);
static ValueSet & extract(CallReceiver call);

View File

@ -529,11 +529,8 @@ void FunctionDeclaration::trace(JSTracer* trc)
///////////////////////////////////////////////////////////////////////////
// ModuleObject
/* static */ const Class
ModuleObject::class_ = {
"Module",
JSCLASS_HAS_RESERVED_SLOTS(ModuleObject::SlotCount) |
JSCLASS_IS_ANONYMOUS,
/* static */ const ClassOps
ModuleObject::classOps_ = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -548,6 +545,14 @@ ModuleObject::class_ = {
ModuleObject::trace
};
/* static */ const Class
ModuleObject::class_ = {
"Module",
JSCLASS_HAS_RESERVED_SLOTS(ModuleObject::SlotCount) |
JSCLASS_IS_ANONYMOUS,
&ModuleObject::classOps_
};
#define DEFINE_ARRAY_SLOT_ACCESSOR(cls, name, slot) \
ArrayObject& \
cls::name() const \

View File

@ -264,6 +264,8 @@ class ModuleObject : public NativeObject
HandleObject exports);
private:
static const ClassOps classOps_;
static void trace(JSTracer* trc, JSObject* obj);
static void finalize(js::FreeOp* fop, JSObject* obj);

View File

@ -1224,18 +1224,7 @@ static const ClassSpec PlainObjectClassSpec = {
const Class PlainObject::class_ = {
js_Object_str,
JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
JS_NULL_CLASS_OPS,
&PlainObjectClassSpec
};

View File

@ -409,18 +409,7 @@ const Class PromiseObject::class_ = {
"Promise",
JSCLASS_HAS_RESERVED_SLOTS(RESERVED_SLOTS) | JSCLASS_HAS_CACHED_PROTO(JSProto_Promise) |
JSCLASS_HAS_XRAYED_CONSTRUCTOR,
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
JS_NULL_CLASS_OPS,
&PromiseObjectClassSpec
};
@ -438,17 +427,6 @@ static const ClassSpec PromiseObjectProtoClassSpec = {
const Class PromiseObject::protoClass_ = {
"PromiseProto",
JSCLASS_HAS_CACHED_PROTO(JSProto_Promise),
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
JS_NULL_CLASS_OPS,
&PromiseObjectProtoClassSpec
};

View File

@ -189,9 +189,7 @@ TypedObjectMemory(HandleValue v)
return reinterpret_cast<Elem>(obj.typedMem());
}
const Class SimdTypeDescr::class_ = {
"SIMD",
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS) | JSCLASS_BACKGROUND_FINALIZE,
static const ClassOps SimdTypeDescrClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -200,7 +198,13 @@ const Class SimdTypeDescr::class_ = {
nullptr, /* resolve */
nullptr, /* mayResolve */
TypeDescr::finalize,
call
SimdTypeDescr::call
};
const Class SimdTypeDescr::class_ = {
"SIMD",
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS) | JSCLASS_BACKGROUND_FINALIZE,
&SimdTypeDescrClassOps
};
namespace {
@ -424,15 +428,19 @@ SimdTypeDescr::call(JSContext* cx, unsigned argc, Value* vp)
///////////////////////////////////////////////////////////////////////////
// SIMD class
const Class SimdObject::class_ = {
"SIMD",
JSCLASS_HAS_RESERVED_SLOTS(uint32_t(SimdType::Count)),
static const ClassOps SimdObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
resolve /* resolve */
SimdObject::resolve
};
const Class SimdObject::class_ = {
"SIMD",
JSCLASS_HAS_RESERVED_SLOTS(uint32_t(SimdType::Count)),
&SimdObjectClassOps
};
bool

View File

@ -1410,8 +1410,7 @@ finalize_counter_finalize(JSFreeOp* fop, JSObject* obj)
++finalizeCount;
}
static const JSClass FinalizeCounterClass = {
"FinalizeCounter", JSCLASS_IS_ANONYMOUS,
static const JSClassOps FinalizeCounterClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -1422,6 +1421,11 @@ static const JSClass FinalizeCounterClass = {
finalize_counter_finalize
};
static const JSClass FinalizeCounterClass = {
"FinalizeCounter", JSCLASS_IS_ANONYMOUS,
&FinalizeCounterClassOps
};
static bool
MakeFinalizeObserver(JSContext* cx, unsigned argc, Value* vp)
{
@ -2113,8 +2117,7 @@ class CloneBufferObject : public NativeObject {
}
};
const Class CloneBufferObject::class_ = {
"CloneBuffer", JSCLASS_HAS_RESERVED_SLOTS(CloneBufferObject::NUM_SLOTS),
static const ClassOps CloneBufferObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -2122,7 +2125,12 @@ const Class CloneBufferObject::class_ = {
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
Finalize
CloneBufferObject::Finalize
};
const Class CloneBufferObject::class_ = {
"CloneBuffer", JSCLASS_HAS_RESERVED_SLOTS(CloneBufferObject::NUM_SLOTS),
&CloneBufferObjectClassOps
};
const JSPropertySpec CloneBufferObject::props_[] = {

View File

@ -215,9 +215,7 @@ const Class js::TypedProto::class_ = {
* distinguish which scalar type object this actually is.
*/
const Class js::ScalarTypeDescr::class_ = {
"Scalar",
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS) | JSCLASS_BACKGROUND_FINALIZE,
static const ClassOps ScalarTypeDescrClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -229,6 +227,12 @@ const Class js::ScalarTypeDescr::class_ = {
ScalarTypeDescr::call
};
const Class js::ScalarTypeDescr::class_ = {
"Scalar",
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS) | JSCLASS_BACKGROUND_FINALIZE,
&ScalarTypeDescrClassOps
};
const JSFunctionSpec js::ScalarTypeDescr::typeObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "DescrToSource", 0, 0),
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, JSFUN_HAS_REST),
@ -312,9 +316,7 @@ ScalarTypeDescr::call(JSContext* cx, unsigned argc, Value* vp)
* reference type object this actually is.
*/
const Class js::ReferenceTypeDescr::class_ = {
"Reference",
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS) | JSCLASS_BACKGROUND_FINALIZE,
static const ClassOps ReferenceTypeDescrClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -326,6 +328,12 @@ const Class js::ReferenceTypeDescr::class_ = {
ReferenceTypeDescr::call
};
const Class js::ReferenceTypeDescr::class_ = {
"Reference",
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS) | JSCLASS_BACKGROUND_FINALIZE,
&ReferenceTypeDescrClassOps
};
const JSFunctionSpec js::ReferenceTypeDescr::typeObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "DescrToSource", 0, 0),
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
@ -497,9 +505,7 @@ CreatePrototypeObjectForComplexTypeInstance(JSContext* cx, HandleObject ctorProt
return NewObjectWithGivenProto<TypedProto>(cx, ctorPrototypePrototype, SingletonObject);
}
const Class ArrayTypeDescr::class_ = {
"ArrayType",
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS) | JSCLASS_BACKGROUND_FINALIZE,
static const ClassOps ArrayTypeDescrClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -513,6 +519,12 @@ const Class ArrayTypeDescr::class_ = {
TypedObject::construct
};
const Class ArrayTypeDescr::class_ = {
"ArrayType",
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS) | JSCLASS_BACKGROUND_FINALIZE,
&ArrayTypeDescrClassOps
};
const JSPropertySpec ArrayMetaTypeDescr::typeObjectProperties[] = {
JS_PS_END
};
@ -722,9 +734,7 @@ js::IsTypedObjectArray(JSObject& obj)
* StructType class
*/
const Class StructTypeDescr::class_ = {
"StructType",
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS) | JSCLASS_BACKGROUND_FINALIZE,
static const ClassOps StructTypeDescrClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -738,6 +748,12 @@ const Class StructTypeDescr::class_ = {
TypedObject::construct
};
const Class StructTypeDescr::class_ = {
"StructType",
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS) | JSCLASS_BACKGROUND_FINALIZE,
&StructTypeDescrClassOps
};
const JSPropertySpec StructMetaTypeDescr::typeObjectProperties[] = {
JS_PS_END
};
@ -2261,9 +2277,7 @@ const ObjectOps TypedObject::objectOps_ = {
};
#define DEFINE_TYPEDOBJ_CLASS(Name, Trace, flag) \
const Class Name::class_ = { \
# Name, \
Class::NON_NATIVE | flag, \
static const ClassOps Name##ClassOps = { \
nullptr, /* addProperty */ \
nullptr, /* delProperty */ \
nullptr, /* getProperty */ \
@ -2276,6 +2290,11 @@ const ObjectOps TypedObject::objectOps_ = {
nullptr, /* hasInstance */ \
nullptr, /* construct */ \
Trace, \
}; \
const Class Name::class_ = { \
# Name, \
Class::NON_NATIVE | flag, \
&Name##ClassOps, \
JS_NULL_CLASS_SPEC, \
JS_NULL_CLASS_EXT, \
&TypedObject::objectOps_ \

View File

@ -383,10 +383,7 @@ WeakMap_construct(JSContext* cx, unsigned argc, Value* vp)
return true;
}
const Class WeakMapObject::class_ = {
"WeakMap",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_CACHED_PROTO(JSProto_WeakMap),
static const ClassOps WeakMapObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -401,6 +398,13 @@ const Class WeakMapObject::class_ = {
WeakMap_mark
};
const Class WeakMapObject::class_ = {
"WeakMap",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_CACHED_PROTO(JSProto_WeakMap),
&WeakMapObjectClassOps
};
static const JSFunctionSpec weak_map_methods[] = {
JS_FN("has", WeakMap_has, 1, 0),
JS_FN("get", WeakMap_get, 1, 0),

View File

@ -546,13 +546,16 @@ static const JSClass sCABIClass = {
// Class representing ctypes.{C,Pointer,Array,Struct,Function}Type.prototype.
// This exists to give said prototypes a class of "CType", and to provide
// reserved slots for stashing various other prototype objects.
static const JSClass sCTypeProtoClass = {
"CType",
JSCLASS_HAS_RESERVED_SLOTS(CTYPEPROTO_SLOTS),
static const JSClassOps sCTypeProtoClassOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
ConstructAbstract, nullptr, ConstructAbstract
};
static const JSClass sCTypeProtoClass = {
"CType",
JSCLASS_HAS_RESERVED_SLOTS(CTYPEPROTO_SLOTS),
&sCTypeProtoClassOps
};
// Class representing ctypes.CData.prototype and the 'prototype' properties
// of CTypes. This exists to give said prototypes a class of "CData".
@ -561,30 +564,39 @@ static const JSClass sCDataProtoClass = {
0
};
static const JSClass sCTypeClass = {
"CType",
JSCLASS_HAS_RESERVED_SLOTS(CTYPE_SLOTS),
static const JSClassOps sCTypeClassOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, CType::Finalize,
CType::ConstructData, CType::HasInstance, CType::ConstructData,
CType::Trace
};
static const JSClass sCTypeClass = {
"CType",
JSCLASS_HAS_RESERVED_SLOTS(CTYPE_SLOTS),
&sCTypeClassOps
};
static const JSClass sCDataClass = {
"CData",
JSCLASS_HAS_RESERVED_SLOTS(CDATA_SLOTS),
static const JSClassOps sCDataClassOps = {
nullptr, nullptr, ArrayType::Getter, ArrayType::Setter,
nullptr, nullptr, nullptr, CData::Finalize,
FunctionType::Call, nullptr, FunctionType::Call
};
static const JSClass sCDataClass = {
"CData",
JSCLASS_HAS_RESERVED_SLOTS(CDATA_SLOTS),
&sCDataClassOps
};
static const JSClass sCClosureClass = {
"CClosure",
JSCLASS_HAS_RESERVED_SLOTS(CCLOSURE_SLOTS),
static const JSClassOps sCClosureClassOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, CClosure::Finalize,
nullptr, nullptr, nullptr, CClosure::Trace
};
static const JSClass sCClosureClass = {
"CClosure",
JSCLASS_HAS_RESERVED_SLOTS(CCLOSURE_SLOTS),
&sCClosureClassOps
};
/*
* Class representing the prototype of CDataFinalizer.
@ -600,11 +612,14 @@ static const JSClass sCDataFinalizerProtoClass = {
* Instances of CDataFinalizer have both private data (with type
* |CDataFinalizer::Private|) and slots (see |CDataFinalizerSlots|).
*/
static const JSClassOps sCDataFinalizerClassOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, CDataFinalizer::Finalize
};
static const JSClass sCDataFinalizerClass = {
"CDataFinalizer",
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(CDATAFINALIZER_SLOTS),
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, CDataFinalizer::Finalize
&sCDataFinalizerClassOps
};
@ -786,18 +801,21 @@ static const JSClass sUInt64ProtoClass = {
0
};
static const JSClassOps sInt64ClassOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, Int64Base::Finalize
};
static const JSClass sInt64Class = {
"Int64",
JSCLASS_HAS_RESERVED_SLOTS(INT64_SLOTS),
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, Int64Base::Finalize
&sInt64ClassOps
};
static const JSClass sUInt64Class = {
"UInt64",
JSCLASS_HAS_RESERVED_SLOTS(INT64_SLOTS),
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, Int64Base::Finalize
&sInt64ClassOps
};
static const JSFunctionSpec sInt64StaticFunctions[] = {

View File

@ -32,11 +32,15 @@ namespace Library
typedef Rooted<JSFlatString*> RootedFlatString;
static const JSClassOps sLibraryClassOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, Library::Finalize
};
static const JSClass sLibraryClass = {
"Library",
JSCLASS_HAS_RESERVED_SLOTS(LIBRARY_SLOTS),
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, Library::Finalize
&sLibraryClassOps
};
#define CTYPESFN_FLAGS \

View File

@ -68,8 +68,8 @@ var ignoreClasses = {
// Ignore calls through TYPE.FIELD, where TYPE is the class or struct name containing
// a function pointer field named FIELD.
var ignoreCallees = {
"js::Class.trace" : true,
"js::Class.finalize" : true,
"js::ClassOps.trace" : true,
"js::ClassOps.finalize" : true,
"JSRuntime.destroyPrincipals" : true,
"icu_50::UObject.__deleting_dtor" : true, // destructors in ICU code can't cause GC
"mozilla::CycleCollectedJSRuntime.DescribeCustomObjects" : true, // During tracing, cannot GC.

View File

@ -1268,10 +1268,10 @@ CallTraceHook(Functor f, JSTracer* trc, JSObject* obj, CheckGeneration check, Ar
MOZ_ASSERT(clasp);
MOZ_ASSERT(obj->isNative() == clasp->isNative());
if (!clasp->trace)
if (!clasp->hasTrace())
return &obj->as<NativeObject>();
if (clasp->trace == InlineTypedObject::obj_trace) {
if (clasp->isTrace(InlineTypedObject::obj_trace)) {
Shape** pshape = obj->as<InlineTypedObject>().addressOfShapeFromGC();
f(pshape, mozilla::Forward<Args>(args)...);
@ -1301,7 +1301,7 @@ CallTraceHook(Functor f, JSTracer* trc, JSObject* obj, CheckGeneration check, Ar
return nullptr;
}
clasp->trace(trc, obj);
clasp->doTrace(trc, obj);
if (!clasp->isNative())
return nullptr;

View File

@ -175,7 +175,7 @@ js::Nursery::allocateObject(JSContext* cx, size_t size, size_t numDynamic, const
* heap. The finalizers for these classes must do nothing except free data
* which was allocated via Nursery::allocateBuffer.
*/
MOZ_ASSERT_IF(clasp->finalize, clasp->flags & JSCLASS_SKIP_NURSERY_FINALIZE);
MOZ_ASSERT_IF(clasp->hasFinalize(), clasp->flags & JSCLASS_SKIP_NURSERY_FINALIZE);
/* Make the object allocation. */
JSObject* obj = static_cast<JSObject*>(allocate(size));

View File

@ -13,15 +13,19 @@
using namespace JS;
/* The class of the global object. */
const JSClass global_class = {
"global", JSCLASS_GLOBAL_FLAGS,
static const JSClassOps global_classOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr,
JS_GlobalObjectTraceHook
};
/* The class of the global object. */
static const JSClass global_class = {
"global", JSCLASS_GLOBAL_FLAGS,
&global_classOps
};
template<typename T>
static inline T*
checkPtr(T* ptr)

View File

@ -927,7 +927,7 @@ IsCacheableSetPropAddSlot(JSContext* cx, JSObject* obj, Shape* oldShape,
// Watch out for resolve or addProperty hooks.
if (ClassMayResolveId(cx->names(), obj->getClass(), id, obj) ||
obj->getClass()->addProperty)
obj->getClass()->getAddProperty())
{
return false;
}

View File

@ -10699,19 +10699,28 @@ CodeGenerator::visitIsCallable(LIsCallable* ins)
OutOfLineIsCallable* ool = new(alloc()) OutOfLineIsCallable(ins);
addOutOfLineCode(ool, ins->mir());
Label notFunction, done;
Label notFunction, hasCOps, done;
masm.loadObjClass(object, output);
// Just skim proxies off. Their notion of isCallable() is more complicated.
masm.branchTestClassIsProxy(true, output, ool->entry());
// An object is callable iff (is<JSFunction>() || getClass()->call.
// An object is callable iff:
// is<JSFunction>() || (getClass()->cOps && getClass()->cOps->call).
masm.branchPtr(Assembler::NotEqual, output, ImmPtr(&JSFunction::class_), &notFunction);
masm.move32(Imm32(1), output);
masm.jump(&done);
masm.bind(&notFunction);
masm.cmpPtrSet(Assembler::NonZero, Address(output, offsetof(js::Class, call)), ImmPtr(nullptr), output);
masm.branchPtr(Assembler::NonZero, Address(output, offsetof(js::Class, cOps)),
ImmPtr(nullptr), &hasCOps);
masm.move32(Imm32(0), output);
masm.jump(&done);
masm.bind(&hasCOps);
masm.cmpPtrSet(Assembler::NonZero, Address(output, offsetof(js::ClassOps, call)),
ImmPtr(nullptr), output);
masm.bind(&done);
masm.bind(ool->rejoin());
}
@ -10761,7 +10770,7 @@ CodeGenerator::visitIsConstructor(LIsConstructor* ins)
OutOfLineIsConstructor* ool = new(alloc()) OutOfLineIsConstructor(ins);
addOutOfLineCode(ool, ins->mir());
Label notFunction, notConstructor, done;
Label notFunction, notConstructor, hasCOps, done;
masm.loadObjClass(object, output);
// Just skim proxies off. Their notion of isConstructor() is more complicated.
@ -10769,7 +10778,7 @@ CodeGenerator::visitIsConstructor(LIsConstructor* ins)
// An object is constructor iff
// ((is<JSFunction>() && as<JSFunction>().isConstructor) ||
// getClass()->construct).
// (getClass()->cOps && getClass()->cOps->construct)).
masm.branchPtr(Assembler::NotEqual, output, ImmPtr(&JSFunction::class_), &notFunction);
masm.load16ZeroExtend(Address(object, JSFunction::offsetOfFlags()), output);
masm.and32(Imm32(JSFunction::CONSTRUCTOR), output);
@ -10781,7 +10790,15 @@ CodeGenerator::visitIsConstructor(LIsConstructor* ins)
masm.jump(&done);
masm.bind(&notFunction);
masm.cmpPtrSet(Assembler::NonZero, Address(output, offsetof(js::Class, construct)), ImmPtr(nullptr), output);
masm.branchPtr(Assembler::NonZero, Address(output, offsetof(js::Class, cOps)),
ImmPtr(nullptr), &hasCOps);
masm.move32(Imm32(0), output);
masm.jump(&done);
masm.bind(&hasCOps);
masm.cmpPtrSet(Assembler::NonZero, Address(output, offsetof(js::ClassOps, construct)),
ImmPtr(nullptr), output);
masm.bind(&done);
masm.bind(ool->rejoin());
}

View File

@ -484,7 +484,7 @@ IsCacheableNoProperty(JSObject* obj, JSObject* holder, Shape* shape, jsbytecode*
// Just because we didn't find the property on the object doesn't mean it
// won't magically appear through various engine hacks.
if (obj->getClass()->getProperty)
if (obj->getClass()->getGetProperty())
return false;
// Don't generate missing property ICs if we skipped a non-native object, as
@ -3280,7 +3280,7 @@ IsPropertyAddInlineable(JSContext* cx, NativeObject* obj, HandleId id, ConstantO
return false;
// Likewise for an addProperty hook, since we'll need to invoke it.
if (obj->getClass()->addProperty)
if (obj->getClass()->getAddProperty())
return false;
if (!obj->nonProxyIsExtensible() || !shape->writable())

View File

@ -2744,7 +2744,7 @@ CheckHasNoSuchProperty(JSContext* cx, JSObject* obj, PropertyName* name,
return false;
if (curObj->as<NativeObject>().contains(cx, NameToId(name)))
return false;
if (curObj->getClass()->getProperty)
if (curObj->getClass()->getGetProperty())
return false;
} else if (curObj != obj) {
// Non-native objects are only handled as the original receiver.

View File

@ -16,10 +16,14 @@ AddProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValu
return true;
}
static const JSClassOps AddPropertyClassOps = {
AddProperty
};
static const JSClass AddPropertyClass = {
"AddPropertyTester",
0,
AddProperty
&AddPropertyClassOps
};
BEGIN_TEST(testAddPropertyHook)

View File

@ -8,9 +8,7 @@
static TestJSPrincipals system_principals(1);
static const JSClass global_class = {
"global",
JSCLASS_IS_GLOBAL | JSCLASS_GLOBAL_FLAGS,
static const JSClassOps global_classOps = {
nullptr,
nullptr,
nullptr,
@ -25,6 +23,12 @@ static const JSClass global_class = {
JS_GlobalObjectTraceHook
};
static const JSClass global_class = {
"global",
JSCLASS_IS_GLOBAL | JSCLASS_GLOBAL_FLAGS,
&global_classOps
};
static JS::PersistentRootedObject trusted_glob;
static JS::PersistentRootedObject trusted_fun;

View File

@ -21,15 +21,19 @@ static bool test_prop_get( JSContext* cx, JS::HandleObject obj, JS::HandleId id,
static bool
PTest(JSContext* cx, unsigned argc, JS::Value* vp);
static const JSClass ptestClass = {
"PTest",
JSCLASS_HAS_PRIVATE,
static const JSClassOps ptestClassOps = {
nullptr, // addProperty
nullptr, // delProperty
test_prop_get,
nullptr // setProperty
};
static const JSClass ptestClass = {
"PTest",
JSCLASS_HAS_PRIVATE,
&ptestClassOps
};
static bool
PTest(JSContext* cx, unsigned argc, JS::Value* vp)
{

View File

@ -21,14 +21,18 @@ GlobalResolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolv
BEGIN_TEST(testRedefineGlobalEval)
{
static const JSClass cls = {
"global", JSCLASS_GLOBAL_FLAGS,
static const JSClassOps clsOps = {
nullptr, nullptr, nullptr, nullptr,
GlobalEnumerate, GlobalResolve, nullptr, nullptr,
nullptr, nullptr, nullptr,
JS_GlobalObjectTraceHook
};
static const JSClass cls = {
"global", JSCLASS_GLOBAL_FLAGS,
&clsOps
};
/* Create the global object. */
JS::CompartmentOptions options;
JS::Rooted<JSObject*> g(cx, JS_NewGlobalObject(cx, &cls, nullptr, JS::FireOnNewGlobalHook, options));

View File

@ -73,12 +73,16 @@ document_resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* res
return true;
}
static const JSClass document_class = {
"document", 0,
static const JSClassOps document_classOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, document_resolve, nullptr
};
static const JSClass document_class = {
"document", 0,
&document_classOps
};
BEGIN_TEST(testLookup_bug570195)
{
JS::RootedObject obj(cx, JS_NewObject(cx, &document_class));

View File

@ -98,13 +98,16 @@ BEGIN_TEST(testNewObject_1)
CHECK(v.isInt32(N - 1));
// With JSClass.construct.
static const JSClass cls = {
"testNewObject_1",
0,
static const JSClassOps clsOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, constructHook
};
static const JSClass cls = {
"testNewObject_1",
0,
&clsOps
};
JS::RootedObject ctor(cx, JS_NewObject(cx, &cls));
CHECK(ctor);
JS::RootedValue rt2(cx, JS::ObjectValue(*ctor));

View File

@ -20,21 +20,25 @@ struct BarkWhenTracedClass {
int BarkWhenTracedClass::finalizeCount;
int BarkWhenTracedClass::traceCount;
static const JSClassOps BarkWhenTracedClassClassOps = {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
BarkWhenTracedClass::finalize,
nullptr,
nullptr,
nullptr,
BarkWhenTracedClass::trace
};
const JSClass BarkWhenTracedClass::class_ = {
"BarkWhenTracedClass",
0,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
finalize,
nullptr,
nullptr,
nullptr,
trace
&BarkWhenTracedClassClassOps
};
struct Kennel {

View File

@ -16,10 +16,14 @@ CounterAdd(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue
return true;
}
static const JSClassOps CounterClassOps = {
CounterAdd
};
static const JSClass CounterClass = {
"Counter", /* name */
0, /* flags */
CounterAdd
&CounterClassOps
};
BEGIN_TEST(testPropCache_bug505798)

View File

@ -13,9 +13,7 @@
*/
BEGIN_TEST(testResolveRecursion)
{
static const JSClass my_resolve_class = {
"MyResolve",
JSCLASS_HAS_PRIVATE,
static const JSClassOps my_resolve_classOps = {
nullptr, // add
nullptr, // delete
nullptr, // get
@ -24,6 +22,12 @@ BEGIN_TEST(testResolveRecursion)
my_resolve
};
static const JSClass my_resolve_class = {
"MyResolve",
JSCLASS_HAS_PRIVATE,
&my_resolve_classOps
};
obj1.init(cx, JS_NewObject(cx, &my_resolve_class));
CHECK(obj1);
obj2.init(cx, JS_NewObject(cx, &my_resolve_class));
@ -150,9 +154,7 @@ BEGIN_TEST(testResolveRecursion_InitStandardClasses)
}
const JSClass* getGlobalClass() override {
static const JSClass myGlobalClass = {
"testResolveRecursion_InitStandardClasses_myGlobalClass",
JSCLASS_GLOBAL_FLAGS,
static const JSClassOps myGlobalClassOps = {
nullptr, // add
nullptr, // delete
nullptr, // get
@ -167,6 +169,12 @@ const JSClass* getGlobalClass() override {
JS_GlobalObjectTraceHook
};
static const JSClass myGlobalClass = {
"testResolveRecursion_InitStandardClasses_myGlobalClass",
JSCLASS_GLOBAL_FLAGS,
&myGlobalClassOps
};
return &myGlobalClass;
}

View File

@ -68,7 +68,7 @@ BEGIN_TEST(testSetProperty_InheritedGlobalSetter)
// This is a JSAPI test because jsapi-test globals do not have a resolve
// hook and therefore can use the property cache in some cases where the
// shell can't.
MOZ_RELEASE_ASSERT(!JS_GetClass(global)->resolve);
MOZ_RELEASE_ASSERT(!JS_GetClass(global)->getResolve());
CHECK(JS_DefineProperty(cx, global, "HOTLOOP", 8, 0));
EXEC("var n = 0;\n"

View File

@ -159,18 +159,7 @@ JSObject* newKey()
static const js::Class keyClass = {
"keyWithDelegate",
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1),
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
&keyClassExtension,
JS_NULL_OBJECT_OPS
@ -207,14 +196,7 @@ JSObject* newCCW(JS::HandleObject sourceZone, JS::HandleObject destZone)
JSObject* newDelegate()
{
static const js::ClassExtension delegateClassExtension = {
nullptr,
DelegateObjectMoved
};
static const js::Class delegateClass = {
"delegate",
JSCLASS_GLOBAL_FLAGS | JSCLASS_HAS_RESERVED_SLOTS(1),
static const js::ClassOps delegateClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -227,6 +209,17 @@ JSObject* newDelegate()
nullptr, /* hasInstance */
nullptr, /* construct */
JS_GlobalObjectTraceHook,
};
static const js::ClassExtension delegateClassExtension = {
nullptr,
DelegateObjectMoved
};
static const js::Class delegateClass = {
"delegate",
JSCLASS_GLOBAL_FLAGS | JSCLASS_HAS_RESERVED_SLOTS(1),
&delegateClassOps,
JS_NULL_CLASS_SPEC,
&delegateClassExtension,
JS_NULL_OBJECT_OPS

View File

@ -226,13 +226,16 @@ class JSAPITest
JSAPITestString messages() const { return msgs; }
static const JSClass * basicGlobalClass() {
static const JSClass c = {
"global", JSCLASS_GLOBAL_FLAGS,
static const JSClassOps cOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr,
JS_GlobalObjectTraceHook
};
static const JSClass c = {
"global", JSCLASS_GLOBAL_FLAGS,
&cOps
};
return &c;
}

View File

@ -2196,9 +2196,9 @@ DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, HandleValue val
// setProperty ops".
if (!(attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
if (!getter)
getter = obj->getClass()->getProperty;
getter = obj->getClass()->getGetProperty();
if (!setter)
setter = obj->getClass()->setProperty;
setter = obj->getClass()->getSetProperty();
}
if (getter == JS_PropertyStub)
getter = nullptr;

View File

@ -498,7 +498,8 @@ array_length_setter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleV
// we're here, do an impression of SetPropertyByDefining.
const Class* clasp = obj->getClass();
return DefineProperty(cx, obj, cx->names().length, vp,
clasp->getProperty, clasp->setProperty, JSPROP_ENUMERATE, result);
clasp->getGetProperty(), clasp->getSetProperty(),
JSPROP_ENUMERATE, result);
}
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
@ -2700,7 +2701,7 @@ GetIndexedPropertiesInRange(JSContext* cx, HandleObject obj, uint32_t begin, uin
// properties.
JSObject* pobj = obj;
do {
if (!pobj->isNative() || pobj->getClass()->resolve || pobj->getOpsLookupProperty())
if (!pobj->isNative() || pobj->getClass()->getResolve() || pobj->getOpsLookupProperty())
return true;
} while ((pobj = pobj->getProto()));
@ -3285,6 +3286,21 @@ array_proto_finish(JSContext* cx, JS::HandleObject ctor, JS::HandleObject proto)
return DefineProperty(cx, proto, id, value, nullptr, nullptr, JSPROP_READONLY);
}
static const ClassOps ArrayObjectClassOps = {
array_addProperty,
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
};
static const ClassSpec ArrayObjectClassSpec = {
GenericCreateConstructor<ArrayConstructor, 1, AllocKind::FUNCTION, &jit::JitInfo_Array>,
CreateArrayPrototype,
@ -3298,18 +3314,7 @@ static const ClassSpec ArrayObjectClassSpec = {
const Class ArrayObject::class_ = {
"Array",
JSCLASS_HAS_CACHED_PROTO(JSProto_Array) | JSCLASS_DELAY_METADATA_BUILDER,
array_addProperty,
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
&ArrayObjectClassOps,
&ArrayObjectClassSpec
};

View File

@ -3286,18 +3286,7 @@ const Class DateObject::class_ = {
js_Date_str,
JSCLASS_HAS_RESERVED_SLOTS(RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Date),
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
JS_NULL_CLASS_OPS,
&DateObjectClassSpec
};
@ -3315,18 +3304,7 @@ static const ClassSpec DateObjectProtoClassSpec = {
const Class DateObject::protoClass_ = {
js_Object_str,
JSCLASS_HAS_CACHED_PROTO(JSProto_Date),
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
JS_NULL_CLASS_OPS,
&DateObjectProtoClassSpec
};

View File

@ -65,23 +65,27 @@ static const JSFunctionSpec exception_methods[] = {
JS_FS_END
};
static const ClassOps ErrorObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
exn_finalize,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
};
#define IMPLEMENT_ERROR_CLASS(name, classSpecPtr) \
{ \
js_Error_str, /* yes, really */ \
JSCLASS_HAS_CACHED_PROTO(JSProto_##name) | \
JSCLASS_HAS_RESERVED_SLOTS(ErrorObject::RESERVED_SLOTS), \
nullptr, /* addProperty */ \
nullptr, /* delProperty */ \
nullptr, /* getProperty */ \
nullptr, /* setProperty */ \
nullptr, /* enumerate */ \
nullptr, /* resolve */ \
nullptr, /* mayResolve */ \
exn_finalize, \
nullptr, /* call */ \
nullptr, /* hasInstance */ \
nullptr, /* construct */ \
nullptr, /* trace */ \
&ErrorObjectClassOps, \
classSpecPtr \
}

View File

@ -314,6 +314,7 @@ JS_DefineFunctionsWithHelp(JSContext* cx, JS::HandleObject obj, const JSFunction
namespace js {
extern JS_FRIEND_DATA(const js::ClassOps) ProxyClassOps;
extern JS_FRIEND_DATA(const js::ClassExtension) ProxyClassExtension;
extern JS_FRIEND_DATA(const js::ObjectOps) ProxyObjectOps;
@ -336,18 +337,7 @@ extern JS_FRIEND_DATA(const js::ObjectOps) ProxyObjectOps;
JSCLASS_IS_PROXY | \
JSCLASS_DELAY_METADATA_BUILDER | \
flags, \
nullptr, /* addProperty */ \
nullptr, /* delProperty */ \
nullptr, /* getProperty */ \
nullptr, /* setProperty */ \
nullptr, /* enumerate */ \
nullptr, /* resolve */ \
nullptr, /* mayResolve */ \
js::proxy_Finalize, /* finalize */ \
nullptr, /* call */ \
js::proxy_HasInstance, /* hasInstance */ \
nullptr, /* construct */ \
js::proxy_Trace, /* trace */ \
&js::ProxyClassOps, \
JS_NULL_CLASS_SPEC, \
extPtr, \
&js::ProxyObjectOps \

View File

@ -834,18 +834,7 @@ CreateFunctionPrototype(JSContext* cx, JSProtoKey key)
return functionProto;
}
static const ClassSpec JSFunctionClassSpec = {
CreateFunctionConstructor,
CreateFunctionPrototype,
nullptr,
nullptr,
function_methods,
function_properties
};
const Class JSFunction::class_ = {
js_Function_str,
JSCLASS_HAS_CACHED_PROTO(JSProto_Function),
static const ClassOps JSFunctionClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -858,6 +847,21 @@ const Class JSFunction::class_ = {
fun_hasInstance,
nullptr, /* construct */
fun_trace,
};
static const ClassSpec JSFunctionClassSpec = {
CreateFunctionConstructor,
CreateFunctionPrototype,
nullptr,
nullptr,
function_methods,
function_properties
};
const Class JSFunction::class_ = {
js_Function_str,
JSCLASS_HAS_CACHED_PROTO(JSProto_Function),
&JSFunctionClassOps,
&JSFunctionClassSpec
};
@ -2110,8 +2114,8 @@ js::DefineFunction(JSContext* cx, HandleObject obj, HandleId id, Native native,
gop = nullptr;
sop = nullptr;
} else {
gop = obj->getClass()->getProperty;
sop = obj->getClass()->setProperty;
gop = obj->getClass()->getGetProperty();
sop = obj->getClass()->getSetProperty();
MOZ_ASSERT(gop != JS_PropertyStub);
MOZ_ASSERT(sop != JS_StrictPropertyStub);
}

View File

@ -7200,7 +7200,8 @@ JS_FRIEND_API(void)
JS::AssertGCThingMustBeTenured(JSObject* obj)
{
MOZ_ASSERT(obj->isTenured() &&
(!IsNurseryAllocable(obj->asTenured().getAllocKind()) || obj->getClass()->finalize));
(!IsNurseryAllocable(obj->asTenured().getAllocKind()) ||
obj->getClass()->hasFinalize()));
}
JS_FRIEND_API(void)

View File

@ -155,7 +155,7 @@ CanBeFinalizedInBackground(AllocKind kind, const Class* clasp)
* the alloc kind; kind may already be a background finalize kind.
*/
return (!IsBackgroundFinalized(kind) &&
(!clasp->finalize || (clasp->flags & JSCLASS_BACKGROUND_FINALIZE)));
(!clasp->hasFinalize() || (clasp->flags & JSCLASS_BACKGROUND_FINALIZE)));
}
/* Capacity for slotsToThingKind */

View File

@ -381,7 +381,7 @@ Snapshot(JSContext* cx, HandleObject pobj_, unsigned flags, AutoIdVector* props)
}
} else if (pobj->isNative()) {
// Give the object a chance to resolve all lazy properties
if (JSEnumerateOp enumerate = pobj->getClass()->enumerate) {
if (JSEnumerateOp enumerate = pobj->getClass()->getEnumerate()) {
if (!enumerate(cx, pobj.as<NativeObject>()))
return false;
}
@ -798,7 +798,7 @@ CanCacheIterableObject(JSContext* cx, JSObject* obj)
if (obj->is<TypedArrayObject>() ||
obj->hasUncacheableProto() ||
obj->getOpsEnumerate() ||
obj->getClass()->enumerate ||
obj->getClass()->getEnumerate() ||
obj->as<NativeObject>().containsPure(cx->names().iteratorIntrinsic))
{
return false;
@ -1084,11 +1084,7 @@ PropertyIteratorObject::finalize(FreeOp* fop, JSObject* obj)
fop->free_(ni);
}
const Class PropertyIteratorObject::class_ = {
"Iterator",
JSCLASS_HAS_CACHED_PROTO(JSProto_Iterator) |
JSCLASS_HAS_PRIVATE |
JSCLASS_BACKGROUND_FINALIZE,
const ClassOps PropertyIteratorObject::classOps_ = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -1103,6 +1099,14 @@ const Class PropertyIteratorObject::class_ = {
trace
};
const Class PropertyIteratorObject::class_ = {
"Iterator",
JSCLASS_HAS_CACHED_PROTO(JSProto_Iterator) |
JSCLASS_HAS_PRIVATE |
JSCLASS_BACKGROUND_FINALIZE,
&PropertyIteratorObject::classOps_
};
static const Class ArrayIteratorPrototypeClass = {
"Array Iterator",
0
@ -1425,9 +1429,7 @@ stopiter_hasInstance(JSContext* cx, HandleObject obj, MutableHandleValue v, bool
return true;
}
const Class StopIterationObject::class_ = {
"StopIteration",
JSCLASS_HAS_CACHED_PROTO(JSProto_StopIteration),
static const ClassOps StopIterationObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -1440,6 +1442,12 @@ const Class StopIterationObject::class_ = {
stopiter_hasInstance
};
const Class StopIterationObject::class_ = {
"StopIteration",
JSCLASS_HAS_CACHED_PROTO(JSProto_StopIteration),
&StopIterationObjectClassOps
};
static const JSFunctionSpec iterator_proto_methods[] = {
JS_SELF_HOSTED_SYM_FN(iterator, "IteratorIdentity", 0, 0),
JS_FS_END

View File

@ -120,6 +120,8 @@ struct NativeIterator
class PropertyIteratorObject : public NativeObject
{
static const ClassOps classOps_;
public:
static const Class class_;

View File

@ -1855,8 +1855,8 @@ js::InitClass(JSContext* cx, HandleObject obj, HandleObject protoProto_,
RootedObject protoProto(cx, protoProto_);
/* Check function pointer members. */
MOZ_ASSERT(clasp->getProperty != JS_PropertyStub);
MOZ_ASSERT(clasp->setProperty != JS_StrictPropertyStub);
MOZ_ASSERT(clasp->getGetProperty() != JS_PropertyStub);
MOZ_ASSERT(clasp->getSetProperty() != JS_StrictPropertyStub);
RootedAtom atom(cx, Atomize(cx, clasp->name, strlen(clasp->name)));
if (!atom)
@ -2112,8 +2112,8 @@ JSObject::callHook() const
{
const js::Class* clasp = getClass();
if (clasp->call)
return clasp->call;
if (JSNative call = clasp->getCall())
return call;
if (is<js::ProxyObject>()) {
const js::ProxyObject& p = as<js::ProxyObject>();
@ -2128,8 +2128,8 @@ JSObject::constructHook() const
{
const js::Class* clasp = getClass();
if (clasp->construct)
return clasp->construct;
if (JSNative construct = clasp->getConstruct())
return construct;
if (is<js::ProxyObject>()) {
const js::ProxyObject& p = as<js::ProxyObject>();
@ -2944,8 +2944,8 @@ DefineFunctionFromSpec(JSContext* cx, HandleObject obj, const JSFunctionSpec* fs
gop = nullptr;
sop = nullptr;
} else {
gop = obj->getClass()->getProperty;
sop = obj->getClass()->setProperty;
gop = obj->getClass()->getGetProperty();
sop = obj->getClass()->getSetProperty();
MOZ_ASSERT(gop != JS_PropertyStub);
MOZ_ASSERT(sop != JS_StrictPropertyStub);
}
@ -3909,8 +3909,8 @@ JSObject::traceChildren(JSTracer* trc)
// Call the trace hook at the end so that during a moving GC the trace hook
// will see updated fields and slots.
if (clasp->trace)
clasp->trace(trc, this);
if (clasp->hasTrace())
clasp->doTrace(trc, this);
}
static JSAtom*

View File

@ -1098,7 +1098,7 @@ GetInitialHeap(NewObjectKind newKind, const Class* clasp)
{
if (newKind != GenericObject)
return gc::TenuredHeap;
if (clasp->finalize && !(clasp->flags & JSCLASS_SKIP_NURSERY_FINALIZE))
if (clasp->hasFinalize() && !(clasp->flags & JSCLASS_SKIP_NURSERY_FINALIZE))
return gc::TenuredHeap;
return gc::DefaultHeap;
}

View File

@ -78,8 +78,8 @@ JSObject::finalize(js::FreeOp* fop)
#endif
const js::Class* clasp = getClass();
if (clasp->finalize)
clasp->finalize(fop, this);
if (clasp->hasFinalize())
clasp->doFinalize(fop, this);
if (!clasp->isNative())
return;
@ -321,7 +321,7 @@ JSObject::create(js::ExclusiveContext* cx, js::gc::AllocKind kind, js::gc::Initi
js::gc::GetGCKindSlots(kind, group->clasp()) == shape->numFixedSlots());
MOZ_ASSERT_IF(group->clasp()->flags & JSCLASS_BACKGROUND_FINALIZE,
IsBackgroundFinalized(kind));
MOZ_ASSERT_IF(group->clasp()->finalize,
MOZ_ASSERT_IF(group->clasp()->hasFinalize(),
heap == js::gc::TenuredHeap ||
(group->clasp()->flags & JSCLASS_SKIP_NURSERY_FINALIZE));
MOZ_ASSERT_IF(group->hasUnanalyzedPreliminaryObjects(),

View File

@ -1702,10 +1702,7 @@ ScriptSourceObject::finalize(FreeOp* fop, JSObject* obj)
sso->setReservedSlot(SOURCE_SLOT, PrivateValue(nullptr));
}
const Class ScriptSourceObject::class_ = {
"ScriptSource",
JSCLASS_HAS_RESERVED_SLOTS(RESERVED_SLOTS) |
JSCLASS_IS_ANONYMOUS,
static const ClassOps ScriptSourceObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -1713,11 +1710,18 @@ const Class ScriptSourceObject::class_ = {
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
finalize,
ScriptSourceObject::finalize,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
trace
ScriptSourceObject::trace
};
const Class ScriptSourceObject::class_ = {
"ScriptSource",
JSCLASS_HAS_RESERVED_SLOTS(RESERVED_SLOTS) |
JSCLASS_IS_ANONYMOUS,
&ScriptSourceObjectClassOps
};
ScriptSourceObject*

View File

@ -880,6 +880,8 @@ typedef HashSet<ScriptSource*, CompressedSourceHasher, SystemAllocPolicy> Compre
class ScriptSourceObject : public NativeObject
{
static const ClassOps classOps_;
public:
static const Class class_;

View File

@ -430,10 +430,7 @@ str_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
return true;
}
const Class StringObject::class_ = {
js_String_str,
JSCLASS_HAS_RESERVED_SLOTS(StringObject::RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_String),
static const ClassOps StringObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -443,6 +440,13 @@ const Class StringObject::class_ = {
str_mayResolve
};
const Class StringObject::class_ = {
js_String_str,
JSCLASS_HAS_RESERVED_SLOTS(StringObject::RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_String),
&StringObjectClassOps
};
/*
* Returns a JSString * for the |this| value associated with 'call', or throws
* a TypeError if |this| is null or undefined. This algorithm is the same as

View File

@ -159,10 +159,21 @@ static const struct pm_const {
static bool pm_construct(JSContext* cx, unsigned argc, Value* vp);
static void pm_finalize(JSFreeOp* fop, JSObject* obj);
static const JSClassOps pm_classOps = {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
pm_finalize
};
static const JSClass pm_class = {
"PerfMeasurement", JSCLASS_HAS_PRIVATE,
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, pm_finalize
"PerfMeasurement",
JSCLASS_HAS_PRIVATE,
&pm_classOps
};
// Constructor and destructor

View File

@ -228,10 +228,10 @@ js::SetPropertyIgnoringNamedGetter(JSContext* cx, HandleObject obj, HandleId id,
// A very old nonstandard SpiderMonkey extension: default to the Class
// getter and setter ops.
const Class* clasp = receiverObj->getClass();
MOZ_ASSERT(clasp->getProperty != JS_PropertyStub);
MOZ_ASSERT(clasp->setProperty != JS_StrictPropertyStub);
return DefineProperty(cx, receiverObj, id, v, clasp->getProperty, clasp->setProperty,
attrs, result);
MOZ_ASSERT(clasp->getGetProperty() != JS_PropertyStub);
MOZ_ASSERT(clasp->getSetProperty() != JS_StrictPropertyStub);
return DefineProperty(cx, receiverObj, id, v,
clasp->getGetProperty(), clasp->getSetProperty(), attrs, result);
}
// Step 6.

View File

@ -716,6 +716,21 @@ js::proxy_FunToString(JSContext* cx, HandleObject proxy, unsigned indent)
return Proxy::fun_toString(cx, proxy, indent);
}
const ClassOps js::ProxyClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
js::proxy_Finalize, /* finalize */
nullptr, /* call */
js::proxy_HasInstance, /* hasInstance */
nullptr, /* construct */
js::proxy_Trace, /* trace */
};
const ClassExtension js::ProxyClassExtension = PROXY_MAKE_EXT(
js::proxy_ObjectMoved
);

View File

@ -395,9 +395,7 @@ class FileObject : public JSObject {
}
};
const js::Class FileObject::class_ = {
"File",
JSCLASS_HAS_RESERVED_SLOTS(FileObject::NUM_SLOTS),
static const js::ClassOps FileObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -412,6 +410,12 @@ const js::Class FileObject::class_ = {
nullptr /* trace */
};
const js::Class FileObject::class_ = {
"File",
JSCLASS_HAS_RESERVED_SLOTS(FileObject::NUM_SLOTS),
&FileObjectClassOps
};
static FileObject*
redirect(JSContext* cx, HandleString relFilename, RCFile** globalFile)
{

View File

@ -2746,9 +2746,7 @@ sandbox_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
return true;
}
static const JSClass sandbox_class = {
"sandbox",
JSCLASS_GLOBAL_FLAGS,
static const JSClassOps sandbox_classOps = {
nullptr, nullptr, nullptr, nullptr,
sandbox_enumerate, sandbox_resolve,
nullptr, nullptr,
@ -2756,6 +2754,12 @@ static const JSClass sandbox_class = {
JS_GlobalObjectTraceHook
};
static const JSClass sandbox_class = {
"sandbox",
JSCLASS_GLOBAL_FLAGS,
&sandbox_classOps
};
static void
SetStandardCompartmentOptions(JS::CompartmentOptions& options)
{
@ -6026,8 +6030,7 @@ global_mayResolve(const JSAtomState& names, jsid id, JSObject* maybeObj)
return JS_MayResolveStandardClass(names, id, maybeObj);
}
static const JSClass global_class = {
"global", JSCLASS_GLOBAL_FLAGS,
static const JSClassOps global_classOps = {
nullptr, nullptr, nullptr, nullptr,
global_enumerate, global_resolve, global_mayResolve,
nullptr,
@ -6035,6 +6038,11 @@ static const JSClass global_class = {
JS_GlobalObjectTraceHook
};
static const JSClass global_class = {
"global", JSCLASS_GLOBAL_FLAGS,
&global_classOps
};
/*
* Define a FakeDOMObject constructor. It returns an object with a getter,
* setter and method with attached JitInfo. This object can be used to test

View File

@ -675,13 +675,7 @@ ArgumentsObject::objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObject
* stack frame with their corresponding property values in the frame's
* arguments object.
*/
const Class MappedArgumentsObject::class_ = {
"Arguments",
JSCLASS_DELAY_METADATA_BUILDER |
JSCLASS_HAS_RESERVED_SLOTS(MappedArgumentsObject::RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Object) |
JSCLASS_SKIP_NURSERY_FINALIZE |
JSCLASS_BACKGROUND_FINALIZE,
const ClassOps MappedArgumentsObject::classOps_ = {
nullptr, /* addProperty */
ArgumentsObject::obj_delProperty,
nullptr, /* getProperty */
@ -696,17 +690,21 @@ const Class MappedArgumentsObject::class_ = {
ArgumentsObject::trace
};
const Class MappedArgumentsObject::class_ = {
"Arguments",
JSCLASS_DELAY_METADATA_BUILDER |
JSCLASS_HAS_RESERVED_SLOTS(MappedArgumentsObject::RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Object) |
JSCLASS_SKIP_NURSERY_FINALIZE |
JSCLASS_BACKGROUND_FINALIZE,
&MappedArgumentsObject::classOps_
};
/*
* Unmapped arguments is significantly less magical than mapped arguments, so
* it is represented by a different class while sharing some functionality.
*/
const Class UnmappedArgumentsObject::class_ = {
"Arguments",
JSCLASS_DELAY_METADATA_BUILDER |
JSCLASS_HAS_RESERVED_SLOTS(UnmappedArgumentsObject::RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Object) |
JSCLASS_SKIP_NURSERY_FINALIZE |
JSCLASS_BACKGROUND_FINALIZE,
const ClassOps UnmappedArgumentsObject::classOps_ = {
nullptr, /* addProperty */
ArgumentsObject::obj_delProperty,
nullptr, /* getProperty */
@ -720,3 +718,13 @@ const Class UnmappedArgumentsObject::class_ = {
nullptr, /* construct */
ArgumentsObject::trace
};
const Class UnmappedArgumentsObject::class_ = {
"Arguments",
JSCLASS_DELAY_METADATA_BUILDER |
JSCLASS_HAS_RESERVED_SLOTS(UnmappedArgumentsObject::RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Object) |
JSCLASS_SKIP_NURSERY_FINALIZE |
JSCLASS_BACKGROUND_FINALIZE,
&UnmappedArgumentsObject::classOps_
};

View File

@ -329,6 +329,8 @@ class ArgumentsObject : public NativeObject
class MappedArgumentsObject : public ArgumentsObject
{
static const ClassOps classOps_;
public:
static const Class class_;
@ -352,6 +354,8 @@ class MappedArgumentsObject : public ArgumentsObject
class UnmappedArgumentsObject : public ArgumentsObject
{
static const ClassOps classOps_;
public:
static const Class class_;

View File

@ -96,6 +96,21 @@ const Class ArrayBufferObject::protoClass = {
JSCLASS_HAS_CACHED_PROTO(JSProto_ArrayBuffer)
};
const ClassOps ArrayBufferObject::classOps_ = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
ArrayBufferObject::finalize,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
ArrayBufferObject::trace,
};
static const ClassExtension ArrayBufferObjectClassExtension = {
nullptr, /* weakmapKeyDelegateOp */
ArrayBufferObject::objectMoved
@ -107,18 +122,7 @@ const Class ArrayBufferObject::class_ = {
JSCLASS_HAS_RESERVED_SLOTS(RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_ArrayBuffer) |
JSCLASS_BACKGROUND_FINALIZE,
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
ArrayBufferObject::finalize,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
ArrayBufferObject::trace,
&ArrayBufferObject::classOps_,
JS_NULL_CLASS_SPEC,
&ArrayBufferObjectClassExtension
};

View File

@ -102,6 +102,8 @@ class ArrayBufferObject : public ArrayBufferObjectMaybeShared
static bool byteLengthGetterImpl(JSContext* cx, const CallArgs& args);
static bool fun_slice_impl(JSContext* cx, const CallArgs& args);
static const ClassOps classOps_;
public:
static const uint8_t DATA_SLOT = 0;
static const uint8_t BYTE_LENGTH_SLOT = 1;

View File

@ -41,7 +41,7 @@ ArrayObject::createArrayInternal(ExclusiveContext* cx, gc::AllocKind kind, gc::I
MOZ_ASSERT(shape && group);
MOZ_ASSERT(group->clasp() == shape->getObjectClass());
MOZ_ASSERT(group->clasp() == &ArrayObject::class_);
MOZ_ASSERT_IF(group->clasp()->finalize, heap == gc::TenuredHeap);
MOZ_ASSERT_IF(group->clasp()->hasFinalize(), heap == gc::TenuredHeap);
MOZ_ASSERT_IF(group->hasUnanalyzedPreliminaryObjects(),
heap == js::gc::TenuredHeap);
MOZ_ASSERT(group->clasp()->shouldDelayMetadataBuilder());

View File

@ -29,7 +29,7 @@ js::Debugger::onLeaveFrame(JSContext* cx, AbstractFramePtr frame, jsbytecode* pc
/* static */ inline js::Debugger*
js::Debugger::fromJSObject(const JSObject* obj)
{
MOZ_ASSERT(js::GetObjectClass(obj) == &jsclass);
MOZ_ASSERT(js::GetObjectClass(obj) == &class_);
return (Debugger*) obj->as<NativeObject>().getPrivate();
}

View File

@ -59,9 +59,13 @@ using mozilla::Variant;
using mozilla::AsVariant;
/*** Forward declarations ************************************************************************/
/*** Forward declarations, ClassOps and Classes **************************************************/
extern const Class DebuggerFrame_class;
static void DebuggerFrame_finalize(FreeOp* fop, JSObject* obj);
static void DebuggerEnv_trace(JSTracer* trc, JSObject* obj);
static void DebuggerObject_trace(JSTracer* trc, JSObject* obj);
static void DebuggerScript_trace(JSTracer* trc, JSObject* obj);
static void DebuggerSource_trace(JSTracer* trc, JSObject* obj);
enum {
JSSLOT_DEBUGFRAME_OWNER,
@ -71,35 +75,117 @@ enum {
JSSLOT_DEBUGFRAME_COUNT
};
extern const Class DebuggerArguments_class;
static const ClassOps DebuggerFrame_classOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
DebuggerFrame_finalize,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
};
static const Class DebuggerFrame_class = {
"Frame",
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGFRAME_COUNT),
&DebuggerFrame_classOps
};
enum {
JSSLOT_DEBUGARGUMENTS_FRAME,
JSSLOT_DEBUGARGUMENTS_COUNT
};
extern const Class DebuggerEnv_class;
static const Class DebuggerArguments_class = {
"Arguments",
JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGARGUMENTS_COUNT)
};
enum {
JSSLOT_DEBUGENV_OWNER,
JSSLOT_DEBUGENV_COUNT
};
extern const Class DebuggerObject_class;
static const ClassOps DebuggerEnv_classOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
DebuggerEnv_trace
};
static const Class DebuggerEnv_class = {
"Environment",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGENV_COUNT),
&DebuggerEnv_classOps
};
enum {
JSSLOT_DEBUGOBJECT_OWNER,
JSSLOT_DEBUGOBJECT_COUNT
};
extern const Class DebuggerScript_class;
static const ClassOps DebuggerObject_classOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
DebuggerObject_trace
};
static const Class DebuggerObject_class = {
"Object",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGOBJECT_COUNT),
&DebuggerObject_classOps
};
enum {
JSSLOT_DEBUGSCRIPT_OWNER,
JSSLOT_DEBUGSCRIPT_COUNT
};
extern const Class DebuggerSource_class;
static const ClassOps DebuggerScript_classOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
DebuggerScript_trace
};
static const Class DebuggerScript_class = {
"Script",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGSCRIPT_COUNT),
&DebuggerScript_classOps
};
enum {
JSSLOT_DEBUGSOURCE_OWNER,
@ -107,10 +193,27 @@ enum {
JSSLOT_DEBUGSOURCE_COUNT
};
void DebuggerObject_trace(JSTracer* trc, JSObject* obj);
void DebuggerEnv_trace(JSTracer* trc, JSObject* obj);
void DebuggerScript_trace(JSTracer* trc, JSObject* obj);
void DebuggerSource_trace(JSTracer* trc, JSObject* obj);
static const ClassOps DebuggerSource_classOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
DebuggerSource_trace
};
static const Class DebuggerSource_class = {
"Source",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGSOURCE_COUNT),
&DebuggerSource_classOps
};
/*** Utils ***************************************************************************************/
@ -2790,16 +2893,26 @@ Debugger::finalize(FreeOp* fop, JSObject* obj)
fop->delete_(dbg);
}
const Class Debugger::jsclass = {
const ClassOps Debugger::classOps_ = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
Debugger::finalize,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
Debugger::traceObject
};
const Class Debugger::class_ = {
"Debugger",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUG_COUNT),
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, Debugger::finalize,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
Debugger::traceObject
&Debugger::classOps_
};
/* static */ Debugger*
@ -2808,7 +2921,7 @@ Debugger::fromThisValue(JSContext* cx, const CallArgs& args, const char* fnname)
JSObject* thisobj = NonNullObject(cx, args.thisv());
if (!thisobj)
return nullptr;
if (thisobj->getClass() != &Debugger::jsclass) {
if (thisobj->getClass() != &Debugger::class_) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
"Debugger", fnname, thisobj->getClass()->name);
return nullptr;
@ -3395,13 +3508,13 @@ Debugger::construct(JSContext* cx, unsigned argc, Value* vp)
if (!GetProperty(cx, callee, callee, cx->names().prototype, &v))
return false;
RootedNativeObject proto(cx, &v.toObject().as<NativeObject>());
MOZ_ASSERT(proto->getClass() == &Debugger::jsclass);
MOZ_ASSERT(proto->getClass() == &Debugger::class_);
/*
* Make the new Debugger object. Each one has a reference to
* Debugger.{Frame,Object,Script,Memory}.prototype in reserved slots. The
* rest of the reserved slots are for hooks; they default to undefined.
*/
RootedNativeObject obj(cx, NewNativeObjectWithGivenProto(cx, &Debugger::jsclass, proto));
RootedNativeObject obj(cx, NewNativeObjectWithGivenProto(cx, &Debugger::class_, proto));
if (!obj)
return false;
for (unsigned slot = JSSLOT_DEBUG_PROTO_START; slot < JSSLOT_DEBUG_PROTO_STOP; slot++)
@ -4884,18 +4997,6 @@ DebuggerScript_trace(JSTracer* trc, JSObject* obj)
}
}
const Class DebuggerScript_class = {
"Script",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGSCRIPT_COUNT),
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
DebuggerScript_trace
};
class DebuggerScriptSetPrivateMatcher
{
NativeObject* obj_;
@ -6157,18 +6258,6 @@ DebuggerSource_trace(JSTracer* trc, JSObject* obj)
}
}
const Class DebuggerSource_class = {
"Source",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGSOURCE_COUNT),
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
DebuggerSource_trace
};
class SetDebuggerSourcePrivateMatcher
{
NativeObject* obj_;
@ -6720,12 +6809,6 @@ DebuggerFrame_finalize(FreeOp* fop, JSObject* obj)
DebuggerFrame_freeScriptFrameIterData(fop, obj);
}
const Class DebuggerFrame_class = {
"Frame", JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGFRAME_COUNT),
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, DebuggerFrame_finalize
};
static NativeObject*
CheckThisFrame(JSContext* cx, const CallArgs& args, const char* fnname, bool checkLive)
{
@ -6949,10 +7032,6 @@ DebuggerFrame_getOlder(JSContext* cx, unsigned argc, Value* vp)
return true;
}
const Class DebuggerArguments_class = {
"Arguments", JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGARGUMENTS_COUNT)
};
/* The getter used for each element of frame.arguments. See DebuggerFrame_getArguments. */
static bool
DebuggerArguments_getArg(JSContext* cx, unsigned argc, Value* vp)
@ -7489,18 +7568,6 @@ DebuggerObject_trace(JSTracer* trc, JSObject* obj)
}
}
const Class DebuggerObject_class = {
"Object",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGOBJECT_COUNT),
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
DebuggerObject_trace
};
static NativeObject*
DebuggerObject_checkThis(JSContext* cx, const CallArgs& args, const char* fnname)
{
@ -8710,18 +8777,6 @@ DebuggerEnv_trace(JSTracer* trc, JSObject* obj)
}
}
const Class DebuggerEnv_class = {
"Environment",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGENV_COUNT),
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
DebuggerEnv_trace
};
static NativeObject*
DebuggerEnv_checkThis(JSContext* cx, const CallArgs& args, const char* fnname,
bool requireDebuggee = true)
@ -9206,7 +9261,7 @@ JS_DefineDebuggerObject(JSContext* cx, HandleObject obj)
if (!objProto)
return false;
debugProto = InitClass(cx, obj,
objProto, &Debugger::jsclass, Debugger::construct,
objProto, &Debugger::class_, Debugger::construct,
1, Debugger::properties, Debugger::methods, nullptr,
Debugger::static_methods, debugCtor.address());
if (!debugProto)
@ -9310,7 +9365,7 @@ JS::dbg::IsDebugger(JSObject& obj)
{
JSObject* unwrapped = CheckedUnwrap(&obj);
return unwrapped &&
js::GetObjectClass(unwrapped) == &Debugger::jsclass &&
js::GetObjectClass(unwrapped) == &Debugger::class_ &&
js::Debugger::fromJSObject(unwrapped) != nullptr;
}

View File

@ -559,7 +559,8 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
static void finalize(FreeOp* fop, JSObject* obj);
void markCrossCompartmentEdges(JSTracer* tracer);
static const Class jsclass;
static const ClassOps classOps_;
static const Class class_;
static bool getHookImpl(JSContext* cx, CallArgs& args, Debugger& dbg, Hook which);
static bool setHookImpl(JSContext* cx, CallArgs& args, Debugger& dbg, Hook which);

View File

@ -293,7 +293,7 @@ GlobalObject*
GlobalObject::createInternal(JSContext* cx, const Class* clasp)
{
MOZ_ASSERT(clasp->flags & JSCLASS_IS_GLOBAL);
MOZ_ASSERT(clasp->trace == JS_GlobalObjectTraceHook);
MOZ_ASSERT(clasp->isTrace(JS_GlobalObjectTraceHook));
JSObject* obj = NewObjectWithGivenProto(cx, clasp, nullptr, SingletonObject);
if (!obj)
@ -620,11 +620,22 @@ GlobalDebuggees_finalize(FreeOp* fop, JSObject* obj)
fop->delete_((GlobalObject::DebuggerVector*) obj->as<NativeObject>().getPrivate());
}
static const ClassOps
GlobalDebuggees_classOps = {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
GlobalDebuggees_finalize
};
static const Class
GlobalDebuggees_class = {
"GlobalDebuggee", JSCLASS_HAS_PRIVATE,
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, GlobalDebuggees_finalize
&GlobalDebuggees_classOps
};
GlobalObject::DebuggerVector*

View File

@ -187,14 +187,18 @@ js::CancelOffThreadIonCompile(JSCompartment* compartment, JSScript* script)
}
}
static const JSClass parseTaskGlobalClass = {
"internal-parse-task-global", JSCLASS_GLOBAL_FLAGS,
static const JSClassOps parseTaskGlobalClassOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr,
JS_GlobalObjectTraceHook
};
static const JSClass parseTaskGlobalClass = {
"internal-parse-task-global", JSCLASS_GLOBAL_FLAGS,
&parseTaskGlobalClassOps
};
ParseTask::ParseTask(ParseTaskKind kind, ExclusiveContext* cx, JSObject* exclusiveContextGlobal,
JSContext* initCx, const char16_t* chars, size_t length,
JS::OffThreadCompileCallback callback, void* callbackData)

View File

@ -576,8 +576,8 @@ static MOZ_ALWAYS_INLINE bool
InitElemOperation(JSContext* cx, jsbytecode* pc, HandleObject obj, HandleValue idval, HandleValue val)
{
MOZ_ASSERT(!val.isMagic(JS_ELEMENTS_HOLE));
MOZ_ASSERT(!obj->getClass()->getProperty);
MOZ_ASSERT(!obj->getClass()->setProperty);
MOZ_ASSERT(!obj->getClass()->getGetProperty());
MOZ_ASSERT(!obj->getClass()->getSetProperty());
RootedId id(cx);
if (!ToPropertyKey(cx, idval, &id))

View File

@ -537,7 +537,7 @@ InternalConstruct(JSContext* cx, const AnyConstructArgs& args)
{
MOZ_ASSERT(args.array() + args.length() + 1 == args.end(),
"must pass constructing arguments to a construction attempt");
MOZ_ASSERT(!JSFunction::class_.construct);
MOZ_ASSERT(!JSFunction::class_.getConstruct());
// Callers are responsible for enforcing these preconditions.
MOZ_ASSERT(IsConstructor(args.calleev()),
@ -720,8 +720,8 @@ js::HasInstance(JSContext* cx, HandleObject obj, HandleValue v, bool* bp)
{
const Class* clasp = obj->getClass();
RootedValue local(cx, v);
if (clasp->hasInstance)
return clasp->hasInstance(cx, obj, &local, bp);
if (JSHasInstanceOp hasInstance = clasp->getHasInstance())
return hasInstance(cx, obj, &local, bp);
RootedValue val(cx, ObjectValue(*obj));
ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,

View File

@ -394,7 +394,7 @@ CallResolveOp(JSContext* cx, HandleNativeObject obj, HandleId id, MutableHandleS
*recursedp = false;
bool resolved = false;
if (!obj->getClass()->resolve(cx, obj, id, &resolved))
if (!obj->getClass()->getResolve()(cx, obj, id, &resolved))
return false;
if (!resolved)
@ -402,8 +402,8 @@ CallResolveOp(JSContext* cx, HandleNativeObject obj, HandleId id, MutableHandleS
// Assert the mayResolve hook, if there is one, returns true for this
// property.
MOZ_ASSERT_IF(obj->getClass()->mayResolve,
obj->getClass()->mayResolve(cx->names(), id, obj));
MOZ_ASSERT_IF(obj->getClass()->getMayResolve(),
obj->getClass()->getMayResolve()(cx->names(), id, obj));
if (JSID_IS_INT(id) && obj->containsDenseElement(JSID_TO_INT(id))) {
MarkDenseOrTypedArrayElementFound<CanGC>(propp);
@ -421,17 +421,17 @@ ClassMayResolveId(const JSAtomState& names, const Class* clasp, jsid id, JSObjec
{
MOZ_ASSERT_IF(maybeObj, maybeObj->getClass() == clasp);
if (!clasp->resolve) {
if (!clasp->getResolve()) {
// Sanity check: we should only have a mayResolve hook if we have a
// resolve hook.
MOZ_ASSERT(!clasp->mayResolve, "Class with mayResolve hook but no resolve hook");
MOZ_ASSERT(!clasp->getMayResolve(), "Class with mayResolve hook but no resolve hook");
return false;
}
if (clasp->mayResolve) {
if (JSMayResolveOp mayResolve = clasp->getMayResolve()) {
// Tell the analysis our mayResolve hooks won't trigger GC.
JS::AutoSuppressGCAnalysis nogc;
if (!clasp->mayResolve(names, id, maybeObj))
if (!mayResolve(names, id, maybeObj))
return false;
}
@ -477,8 +477,7 @@ LookupOwnPropertyInline(ExclusiveContext* cx,
}
// id was not found in obj. Try obj's resolve hook, if any.
if (obj->getClass()->resolve)
{
if (obj->getClass()->getResolve()) {
if (!cx->shouldBeJSContext() || !allowGC)
return false;

View File

@ -1000,7 +1000,7 @@ static inline bool
CallAddPropertyHook(ExclusiveContext* cx, HandleNativeObject obj, HandleShape shape,
HandleValue value)
{
if (JSAddPropertyOp addProperty = obj->getClass()->addProperty) {
if (JSAddPropertyOp addProperty = obj->getClass()->getAddProperty()) {
if (!cx->shouldBeJSContext())
return false;
@ -1026,7 +1026,7 @@ CallAddPropertyHookDense(ExclusiveContext* cx, HandleNativeObject obj, uint32_t
return true;
}
if (JSAddPropertyOp addProperty = obj->getClass()->addProperty) {
if (JSAddPropertyOp addProperty = obj->getClass()->getAddProperty()) {
if (!cx->shouldBeJSContext())
return false;
@ -1873,7 +1873,7 @@ GetNonexistentProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
// Non-standard extension: Call the getProperty hook. If it sets vp to a
// value other than undefined, we're done. If not, fall through to the
// warning/error checks below.
if (JSGetterOp getProperty = obj->getClass()->getProperty) {
if (JSGetterOp getProperty = obj->getClass()->getGetProperty()) {
if (!CallJSGetterOp(cx, getProperty, obj, id, vp))
return false;
@ -2180,8 +2180,8 @@ js::SetPropertyByDefining(JSContext* cx, HandleId id, HandleValue v, HandleValue
existing
? JSPROP_IGNORE_ENUMERATE | JSPROP_IGNORE_READONLY | JSPROP_IGNORE_PERMANENT
: JSPROP_ENUMERATE;
JSGetterOp getter = clasp->getProperty;
JSSetterOp setter = clasp->setProperty;
JSGetterOp getter = clasp->getGetProperty();
JSSetterOp setter = clasp->getSetProperty();
MOZ_ASSERT(getter != JS_PropertyStub);
MOZ_ASSERT(setter != JS_StrictPropertyStub);
if (!DefineProperty(cx, receiver, id, v, getter, setter, attrs, result))
@ -2451,7 +2451,7 @@ js::NativeDeleteProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
if (!shape) {
// If no property call the class's delProperty hook, passing succeeded
// as the result parameter. This always succeeds when there is no hook.
return CallJSDeletePropertyOp(cx, obj->getClass()->delProperty, obj, id, result);
return CallJSDeletePropertyOp(cx, obj->getClass()->getDelProperty(), obj, id, result);
}
cx->runtime()->gc.poke();
@ -2460,7 +2460,7 @@ js::NativeDeleteProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
if (GetShapeAttributes(obj, shape) & JSPROP_PERMANENT)
return result.failCantDelete();
if (!CallJSDeletePropertyOp(cx, obj->getClass()->delProperty, obj, id, result))
if (!CallJSDeletePropertyOp(cx, obj->getClass()->getDelProperty(), obj, id, result))
return false;
if (!result)
return true;

View File

@ -1280,10 +1280,8 @@ inline void
NativeObject::privateWriteBarrierPre(void** oldval)
{
JS::shadow::Zone* shadowZone = this->shadowZoneFromAnyThread();
if (shadowZone->needsIncrementalBarrier()) {
if (*oldval && getClass()->trace)
getClass()->trace(shadowZone->barrierTracer(), this);
}
if (shadowZone->needsIncrementalBarrier() && *oldval && getClass()->hasTrace())
getClass()->doTrace(shadowZone->barrierTracer(), this);
}
#ifdef DEBUG

View File

@ -294,8 +294,7 @@ ForOfPIC_traceObject(JSTracer* trc, JSObject* obj)
chain->mark(trc);
}
const Class ForOfPIC::jsclass = {
"ForOfPIC", JSCLASS_HAS_PRIVATE,
static const ClassOps ForOfPICClassOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, ForOfPIC_finalize,
nullptr, /* call */
@ -304,11 +303,16 @@ const Class ForOfPIC::jsclass = {
ForOfPIC_traceObject
};
const Class ForOfPIC::class_ = {
"ForOfPIC", JSCLASS_HAS_PRIVATE,
&ForOfPICClassOps
};
/* static */ NativeObject*
js::ForOfPIC::createForOfPICObject(JSContext* cx, Handle<GlobalObject*> global)
{
assertSameCompartment(cx, global);
NativeObject* obj = NewNativeObjectWithGivenProto(cx, &ForOfPIC::jsclass, nullptr);
NativeObject* obj = NewNativeObjectWithGivenProto(cx, &ForOfPIC::class_, nullptr);
if (!obj)
return nullptr;
ForOfPIC::Chain* chain = cx->new_<ForOfPIC::Chain>();

View File

@ -253,12 +253,12 @@ struct ForOfPIC
};
// Class for object that holds ForOfPIC chain.
static const Class jsclass;
static const Class class_;
static NativeObject* createForOfPICObject(JSContext* cx, Handle<GlobalObject*> global);
static inline Chain* fromJSObject(NativeObject* obj) {
MOZ_ASSERT(js::GetObjectClass(obj) == &ForOfPIC::jsclass);
MOZ_ASSERT(js::GetObjectClass(obj) == &ForOfPIC::class_);
return (ForOfPIC::Chain*) obj->getPrivate();
}
static inline Chain* getOrCreate(JSContext* cx) {

View File

@ -91,8 +91,8 @@ class ProxyObject : public JSObject
// Proxy classes are not allowed to have call or construct hooks directly. Their
// callability is instead decided by handler()->isCallable().
return clasp->isProxy() &&
clasp->trace == proxy_Trace &&
!clasp->call && !clasp->construct;
clasp->isTrace(proxy_Trace) &&
!clasp->getCall() && !clasp->getConstruct();
}
public:

View File

@ -185,6 +185,21 @@ RegExpObject::trace(JSTracer* trc, JSObject* obj)
}
}
static const ClassOps RegExpObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
RegExpObject::trace,
};
static const ClassSpec RegExpObjectClassSpec = {
GenericCreateConstructor<js::regexp_construct, 2, gc::AllocKind::FUNCTION>,
CreateRegExpPrototype,
@ -199,18 +214,7 @@ const Class RegExpObject::class_ = {
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_RESERVED_SLOTS(RegExpObject::RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_RegExp),
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
RegExpObject::trace,
&RegExpObjectClassOps,
&RegExpObjectClassSpec
};

View File

@ -34,9 +34,7 @@ resc_trace(JSTracer* trc, JSObject* obj)
static_cast<RegExpStatics*>(pdata)->mark(trc);
}
const Class RegExpStaticsObject::class_ = {
"RegExpStatics",
JSCLASS_HAS_PRIVATE,
static const ClassOps RegExpStaticsObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -51,6 +49,12 @@ const Class RegExpStaticsObject::class_ = {
resc_trace
};
const Class RegExpStaticsObject::class_ = {
"RegExpStatics",
JSCLASS_HAS_PRIVATE,
&RegExpStaticsObjectClassOps
};
RegExpStaticsObject*
RegExpStatics::create(ExclusiveContext* cx, Handle<GlobalObject*> parent)
{

View File

@ -289,6 +289,21 @@ SavedFrame::finishSavedFrameInit(JSContext* cx, HandleObject ctor, HandleObject
return FreezeObject(cx, proto);
}
static const ClassOps SavedFrameClassOps = {
nullptr, // addProperty
nullptr, // delProperty
nullptr, // getProperty
nullptr, // setProperty
nullptr, // enumerate
nullptr, // resolve
nullptr, // mayResolve
SavedFrame::finalize, // finalize
nullptr, // call
nullptr, // hasInstance
nullptr, // construct
nullptr, // trace
};
const ClassSpec SavedFrame::classSpec_ = {
GenericCreateConstructor<SavedFrame::construct, 0, gc::AllocKind::FUNCTION>,
GenericCreatePrototype,
@ -306,18 +321,7 @@ const ClassSpec SavedFrame::classSpec_ = {
JSCLASS_HAS_RESERVED_SLOTS(SavedFrame::JSSLOT_COUNT) |
JSCLASS_HAS_CACHED_PROTO(JSProto_SavedFrame) |
JSCLASS_IS_ANONYMOUS,
nullptr, // addProperty
nullptr, // delProperty
nullptr, // getProperty
nullptr, // setProperty
nullptr, // enumerate
nullptr, // resolve
nullptr, // mayResolve
SavedFrame::finalize, // finalize
nullptr, // call
nullptr, // hasInstance
nullptr, // construct
nullptr, // trace
&SavedFrameClassOps,
&SavedFrame::classSpec_
};

View File

@ -458,18 +458,7 @@ const Class ModuleEnvironmentObject::class_ = {
"ModuleEnvironmentObject",
JSCLASS_HAS_RESERVED_SLOTS(ModuleEnvironmentObject::RESERVED_SLOTS) |
JSCLASS_IS_ANONYMOUS,
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
&ModuleEnvironmentObject::objectOps_
@ -698,8 +687,8 @@ DeclEnvObject::createTemplateObject(JSContext* cx, HandleFunction fun, NewObject
const Class* clasp = obj->getClass();
unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY;
JSGetterOp getter = clasp->getProperty;
JSSetterOp setter = clasp->setProperty;
JSGetterOp getter = clasp->getGetProperty();
JSSetterOp setter = clasp->getSetProperty();
MOZ_ASSERT(getter != JS_PropertyStub);
MOZ_ASSERT(setter != JS_StrictPropertyStub);
@ -886,18 +875,7 @@ const Class DynamicWithObject::class_ = {
"With",
JSCLASS_HAS_RESERVED_SLOTS(DynamicWithObject::RESERVED_SLOTS) |
JSCLASS_IS_ANONYMOUS,
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
&DynamicWithObjectObjectOps
@ -1128,18 +1106,7 @@ const Class ClonedBlockObject::class_ = {
"Block",
JSCLASS_HAS_RESERVED_SLOTS(ClonedBlockObject::RESERVED_SLOTS) |
JSCLASS_IS_ANONYMOUS,
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
@ -1401,18 +1368,7 @@ const Class RuntimeLexicalErrorObject::class_ = {
"RuntimeLexicalError",
JSCLASS_HAS_RESERVED_SLOTS(RuntimeLexicalErrorObject::RESERVED_SLOTS) |
JSCLASS_IS_ANONYMOUS,
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
&RuntimeLexicalErrorObjectObjectOps

View File

@ -2643,14 +2643,18 @@ JSRuntime::createSelfHostingGlobal(JSContext* cx)
if (!compartment)
return nullptr;
static const Class shgClass = {
"self-hosting-global", JSCLASS_GLOBAL_FLAGS,
static const ClassOps shgClassOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr,
JS_GlobalObjectTraceHook
};
static const Class shgClass = {
"self-hosting-global", JSCLASS_GLOBAL_FLAGS,
&shgClassOps
};
AutoCompartment ac(cx, compartment);
Rooted<GlobalObject*> shg(cx, GlobalObject::createInternal(cx, &shgClass));
if (!shg)

View File

@ -346,11 +346,7 @@ const Class SharedArrayBufferObject::protoClass = {
JSCLASS_HAS_CACHED_PROTO(JSProto_SharedArrayBuffer)
};
const Class SharedArrayBufferObject::class_ = {
"SharedArrayBuffer",
JSCLASS_DELAY_METADATA_BUILDER |
JSCLASS_HAS_RESERVED_SLOTS(SharedArrayBufferObject::RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_SharedArrayBuffer),
static const ClassOps SharedArrayBufferObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -363,6 +359,14 @@ const Class SharedArrayBufferObject::class_ = {
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
};
const Class SharedArrayBufferObject::class_ = {
"SharedArrayBuffer",
JSCLASS_DELAY_METADATA_BUILDER |
JSCLASS_HAS_RESERVED_SLOTS(SharedArrayBufferObject::RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_SharedArrayBuffer),
&SharedArrayBufferObjectClassOps,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT
};

View File

@ -2466,7 +2466,7 @@ js::ClassCanHaveExtraProperties(const Class* clasp)
{
if (clasp == &UnboxedPlainObject::class_ || clasp == &UnboxedArrayObject::class_)
return false;
return clasp->resolve
return clasp->getResolve()
|| clasp->getOpsLookupProperty()
|| clasp->getOpsGetProperty()
|| IsTypedArrayClass(clasp);
@ -3409,7 +3409,7 @@ PreliminaryObjectArray::sweep()
obj->setGroup(objectProto->groupRaw());
MOZ_ASSERT(obj->is<NativeObject>());
MOZ_ASSERT(obj->getClass() == objectProto->getClass());
MOZ_ASSERT(!obj->getClass()->finalize);
MOZ_ASSERT(!obj->getClass()->hasFinalize());
}
*ptr = nullptr;

View File

@ -1144,18 +1144,7 @@ TypedArrayObject::sharedTypedArrayPrototypeClass = {
// until we implement @@toStringTag.
"???",
JSCLASS_HAS_CACHED_PROTO(JSProto_TypedArray),
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr, /* trace */
JS_NULL_CLASS_OPS,
&TypedArrayObjectSharedTypedArrayPrototypeClassSpec
};
@ -2169,6 +2158,21 @@ IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Uint32, uint32_t, uint32_t)
IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Float32, float, float)
IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Float64, double, double)
static const ClassOps TypedArrayClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
TypedArrayObject::trace, /* trace */
};
#define IMPL_TYPED_ARRAY_CLASS_SPEC(_type) \
{ \
_type##Array::createConstructor, \
@ -2200,18 +2204,7 @@ static const ClassSpec TypedArrayObjectClassSpecs[Scalar::MaxTypedArrayViewType]
JSCLASS_HAS_PRIVATE | \
JSCLASS_HAS_CACHED_PROTO(JSProto_##_type##Array) | \
JSCLASS_DELAY_METADATA_BUILDER, \
nullptr, /* addProperty */ \
nullptr, /* delProperty */ \
nullptr, /* getProperty */ \
nullptr, /* setProperty */ \
nullptr, /* enumerate */ \
nullptr, /* resolve */ \
nullptr, /* mayResolve */ \
nullptr, /* finalize */ \
nullptr, /* call */ \
nullptr, /* hasInstance */ \
nullptr, /* construct */ \
TypedArrayObject::trace, /* trace */ \
&TypedArrayClassOps, \
&TypedArrayObjectClassSpecs[Scalar::Type::_type] \
}
@ -2269,18 +2262,7 @@ static const ClassSpec TypedArrayObjectProtoClassSpecs[Scalar::MaxTypedArrayView
*/ \
#_type "ArrayPrototype", \
JSCLASS_HAS_CACHED_PROTO(JSProto_##_type##Array), \
nullptr, /* addProperty */ \
nullptr, /* delProperty */ \
nullptr, /* getProperty */ \
nullptr, /* setProperty */ \
nullptr, /* enumerate */ \
nullptr, /* resolve */ \
nullptr, /* mayResolve */ \
nullptr, /* finalize */ \
nullptr, /* call */ \
nullptr, /* hasInstance */ \
nullptr, /* construct */ \
nullptr, /* trace */ \
JS_NULL_CLASS_OPS, \
&TypedArrayObjectProtoClassSpecs[Scalar::Type::_type] \
}
@ -2309,11 +2291,7 @@ const Class DataViewObject::protoClass = {
JSCLASS_HAS_CACHED_PROTO(JSProto_DataView)
};
const Class DataViewObject::class_ = {
"DataView",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_RESERVED_SLOTS(TypedArrayObject::RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_DataView),
static const ClassOps DataViewObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -2328,6 +2306,14 @@ const Class DataViewObject::class_ = {
ArrayBufferViewObject::trace
};
const Class DataViewObject::class_ = {
"DataView",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_RESERVED_SLOTS(TypedArrayObject::RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_DataView),
&DataViewObjectClassOps
};
const JSFunctionSpec DataViewObject::jsfuncs[] = {
JS_FN("getInt8", DataViewObject::fun_getInt8, 1,0),
JS_FN("getUint8", DataViewObject::fun_getUint8, 1,0),

View File

@ -905,6 +905,21 @@ const Class UnboxedExpandoObject::class_ = {
0
};
static const ClassOps UnboxedPlainObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
UnboxedPlainObject::trace,
};
static const ObjectOps UnboxedPlainObjectObjectOps = {
UnboxedPlainObject::obj_lookupProperty,
UnboxedPlainObject::obj_defineProperty,
@ -925,18 +940,7 @@ const Class UnboxedPlainObject::class_ = {
Class::NON_NATIVE |
JSCLASS_HAS_CACHED_PROTO(JSProto_Object) |
JSCLASS_DELAY_METADATA_BUILDER,
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
nullptr, /* finalize */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
UnboxedPlainObject::trace,
&UnboxedPlainObjectClassOps,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
&UnboxedPlainObjectObjectOps
@ -1591,6 +1595,21 @@ UnboxedArrayObject::obj_enumerate(JSContext* cx, HandleObject obj, AutoIdVector&
return true;
}
static const ClassOps UnboxedArrayObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
UnboxedArrayObject::finalize,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
UnboxedArrayObject::trace,
};
static const ClassExtension UnboxedArrayObjectClassExtension = {
nullptr, /* weakmapKeyDelegateOp */
UnboxedArrayObject::objectMoved
@ -1616,18 +1635,7 @@ const Class UnboxedArrayObject::class_ = {
Class::NON_NATIVE |
JSCLASS_SKIP_NURSERY_FINALIZE |
JSCLASS_BACKGROUND_FINALIZE,
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
UnboxedArrayObject::finalize,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
UnboxedArrayObject::trace,
&UnboxedArrayObjectClassOps,
JS_NULL_CLASS_SPEC,
&UnboxedArrayObjectClassExtension,
&UnboxedArrayObjectObjectOps

View File

@ -550,6 +550,14 @@ sandbox_addProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue v)
#define XPCONNECT_SANDBOX_CLASS_METADATA_SLOT (XPCONNECT_GLOBAL_EXTRA_SLOT_OFFSET)
static const js::ClassOps SandboxClassOps = {
nullptr, nullptr, nullptr, nullptr,
sandbox_enumerate, sandbox_resolve,
nullptr, /* mayResolve */
sandbox_finalize,
nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook,
};
static const js::ClassExtension SandboxClassExtension = {
nullptr, /* weakmapKeyDelegateOp */
sandbox_moved /* objectMovedOp */
@ -558,11 +566,7 @@ static const js::ClassExtension SandboxClassExtension = {
static const js::Class SandboxClass = {
"Sandbox",
XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(1),
nullptr, nullptr, nullptr, nullptr,
sandbox_enumerate, sandbox_resolve,
nullptr, /* mayResolve */
sandbox_finalize,
nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook,
&SandboxClassOps,
JS_NULL_CLASS_SPEC,
&SandboxClassExtension,
JS_NULL_OBJECT_OPS
@ -570,14 +574,18 @@ static const js::Class SandboxClass = {
// Note to whomever comes here to remove addProperty hooks: billm has promised
// to do the work for this class.
static const js::Class SandboxWriteToProtoClass = {
"Sandbox",
XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(1),
static const js::ClassOps SandboxWriteToProtoClassOps = {
sandbox_addProperty, nullptr, nullptr, nullptr,
sandbox_enumerate, sandbox_resolve,
nullptr, /* mayResolve */
sandbox_finalize,
nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook,
};
static const js::Class SandboxWriteToProtoClass = {
"Sandbox",
XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(1),
&SandboxWriteToProtoClassOps,
JS_NULL_CLASS_SPEC,
&SandboxClassExtension,
JS_NULL_OBJECT_OPS

View File

@ -794,12 +794,16 @@ env_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
return true;
}
static const JSClass env_class = {
"environment", JSCLASS_HAS_PRIVATE,
static const JSClassOps env_classOps = {
nullptr, nullptr, nullptr, env_setProperty,
env_enumerate, env_resolve
};
static const JSClass env_class = {
"environment", JSCLASS_HAS_PRIVATE,
&env_classOps
};
/***************************************************************************/
typedef enum JSShellErrNum {

View File

@ -1428,9 +1428,7 @@ FinalizeStub(JSFreeOp* fop, JSObject* obj)
{
}
static const JSClass XPCOutParamClass = {
"XPCOutParam",
0,
static const JSClassOps XPCOutParamClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
@ -1445,6 +1443,12 @@ static const JSClass XPCOutParamClass = {
nullptr /* trace */
};
static const JSClass XPCOutParamClass = {
"XPCOutParam",
0,
&XPCOutParamClassOps
};
bool
xpc::IsOutObject(JSContext* cx, JSObject* obj)
{

View File

@ -775,8 +775,8 @@ XPCWrappedNative::Init(const XPCNativeScriptableCreateInfo* sci)
MOZ_ASSERT(jsclazz &&
jsclazz->name &&
jsclazz->flags &&
jsclazz->resolve &&
jsclazz->finalize, "bad class");
jsclazz->getResolve() &&
jsclazz->hasFinalize(), "bad class");
// XXXbz JS_GetObjectPrototype wants an object, even though it then asserts
// that this object is same-compartment with cx, which means it could just

View File

@ -620,39 +620,34 @@ XPC_WN_NoHelper_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* reso
resolvedp);
}
static const js::ClassOps XPC_WN_NoHelper_JSClassOps = {
XPC_WN_OnlyIWrite_AddPropertyStub, // addProperty
XPC_WN_CantDeletePropertyStub, // delProperty
nullptr, // getProperty
nullptr, // setProperty
XPC_WN_Shared_Enumerate, // enumerate
XPC_WN_NoHelper_Resolve, // resolve
nullptr, // mayResolve
XPC_WN_NoHelper_Finalize, // finalize
nullptr, // call
nullptr, // construct
nullptr, // hasInstance
XPCWrappedNative::Trace, // trace
};
static const js::ClassExtension XPC_WN_JSClassExtension = {
nullptr, // weakmapKeyDelegateOp
WrappedNativeObjectMoved
};
const js::Class XPC_WN_NoHelper_JSClass = {
"XPCWrappedNative_NoHelper", // name;
"XPCWrappedNative_NoHelper",
WRAPPER_FLAGS |
JSCLASS_IS_WRAPPED_NATIVE |
JSCLASS_PRIVATE_IS_NSISUPPORTS, // flags
/* Mandatory non-null function pointer members. */
XPC_WN_OnlyIWrite_AddPropertyStub, // addProperty
XPC_WN_CantDeletePropertyStub, // delProperty
nullptr, // getProperty
nullptr, // setProperty
XPC_WN_Shared_Enumerate, // enumerate
XPC_WN_NoHelper_Resolve, // resolve
nullptr, // mayResolve
XPC_WN_NoHelper_Finalize, // finalize
/* Optionally non-null members start here. */
nullptr, // call
nullptr, // construct
nullptr, // hasInstance
XPCWrappedNative::Trace, // trace
JSCLASS_PRIVATE_IS_NSISUPPORTS,
&XPC_WN_NoHelper_JSClassOps,
JS_NULL_CLASS_SPEC,
// ClassExtension
&XPC_WN_JSClassExtension,
// ObjectOps
JS_NULL_OBJECT_OPS
};
@ -984,73 +979,75 @@ XPCNativeScriptableShared::XPCNativeScriptableShared(uint32_t aFlags,
if (mFlags.IsGlobalObject())
mJSClass.flags |= XPCONNECT_GLOBAL_FLAGS;
JSAddPropertyOp addProperty;
if (mFlags.WantAddProperty())
addProperty = XPC_WN_Helper_AddProperty;
else if (mFlags.UseJSStubForAddProperty())
addProperty = nullptr;
else if (mFlags.AllowPropModsDuringResolve())
addProperty = XPC_WN_MaybeResolvingPropertyStub;
else
addProperty = XPC_WN_CannotModifyPropertyStub;
mJSClass.addProperty = addProperty;
// Initialize the js::ClassExtension.
JSDeletePropertyOp delProperty;
if (mFlags.UseJSStubForDelProperty())
delProperty = nullptr;
// This is an unusual js::ClassOps: it is heap-allocated and belongs to
// |this|.
js::ClassOps* cOps = new js::ClassOps;
memset(cOps, 0, sizeof(js::ClassOps));
mJSClass.cOps = cOps;
if (mFlags.WantAddProperty())
cOps->addProperty = XPC_WN_Helper_AddProperty;
else if (mFlags.UseJSStubForAddProperty())
cOps->addProperty = nullptr;
else if (mFlags.AllowPropModsDuringResolve())
delProperty = XPC_WN_MaybeResolvingDeletePropertyStub;
cOps->addProperty = XPC_WN_MaybeResolvingPropertyStub;
else
delProperty = XPC_WN_CantDeletePropertyStub;
mJSClass.delProperty = delProperty;
cOps->addProperty = XPC_WN_CannotModifyPropertyStub;
if (mFlags.UseJSStubForDelProperty())
cOps->delProperty = nullptr;
else if (mFlags.AllowPropModsDuringResolve())
cOps->delProperty = XPC_WN_MaybeResolvingDeletePropertyStub;
else
cOps->delProperty = XPC_WN_CantDeletePropertyStub;
if (mFlags.WantGetProperty())
mJSClass.getProperty = XPC_WN_Helper_GetProperty;
cOps->getProperty = XPC_WN_Helper_GetProperty;
else
mJSClass.getProperty = nullptr;
cOps->getProperty = nullptr;
JSSetterOp setProperty;
if (mFlags.WantSetProperty())
setProperty = XPC_WN_Helper_SetProperty;
cOps->setProperty = XPC_WN_Helper_SetProperty;
else if (mFlags.UseJSStubForSetProperty())
setProperty = nullptr;
cOps->setProperty = nullptr;
else if (mFlags.AllowPropModsDuringResolve())
setProperty = XPC_WN_MaybeResolvingSetPropertyStub;
cOps->setProperty = XPC_WN_MaybeResolvingSetPropertyStub;
else
setProperty = XPC_WN_CannotModifySetPropertyStub;
mJSClass.setProperty = setProperty;
cOps->setProperty = XPC_WN_CannotModifySetPropertyStub;
MOZ_ASSERT_IF(mFlags.WantEnumerate(), !mFlags.WantNewEnumerate());
MOZ_ASSERT_IF(mFlags.WantNewEnumerate(), !mFlags.WantEnumerate());
// We will use ops->enumerate set below for NewEnumerate
if (mFlags.WantNewEnumerate())
mJSClass.enumerate = nullptr;
cOps->enumerate = nullptr;
else if (mFlags.WantEnumerate())
mJSClass.enumerate = XPC_WN_Helper_Enumerate;
cOps->enumerate = XPC_WN_Helper_Enumerate;
else
mJSClass.enumerate = XPC_WN_Shared_Enumerate;
cOps->enumerate = XPC_WN_Shared_Enumerate;
// We have to figure out resolve strategy at call time
mJSClass.resolve = XPC_WN_Helper_Resolve;
cOps->resolve = XPC_WN_Helper_Resolve;
if (mFlags.WantFinalize())
mJSClass.finalize = XPC_WN_Helper_Finalize;
cOps->finalize = XPC_WN_Helper_Finalize;
else
mJSClass.finalize = XPC_WN_NoHelper_Finalize;
cOps->finalize = XPC_WN_NoHelper_Finalize;
if (mFlags.WantCall())
mJSClass.call = XPC_WN_Helper_Call;
cOps->call = XPC_WN_Helper_Call;
if (mFlags.WantConstruct())
mJSClass.construct = XPC_WN_Helper_Construct;
cOps->construct = XPC_WN_Helper_Construct;
if (mFlags.WantHasInstance())
mJSClass.hasInstance = XPC_WN_Helper_HasInstance;
cOps->hasInstance = XPC_WN_Helper_HasInstance;
if (mFlags.IsGlobalObject())
mJSClass.trace = JS_GlobalObjectTraceHook;
cOps->trace = JS_GlobalObjectTraceHook;
else
mJSClass.trace = XPCWrappedNative::Trace;
cOps->trace = XPCWrappedNative::Trace;
// Initialize the js::ClassExtension.
@ -1259,56 +1256,39 @@ XPC_WN_ModsAllowed_Proto_Resolve(JSContext* cx, HandleObject obj, HandleId id, b
JSPROP_ENUMERATE, resolvep);
}
static const js::ClassOps XPC_WN_ModsAllowed_Proto_JSClassOps = {
nullptr, // addProperty
nullptr, // delProperty
nullptr, // getProperty
nullptr, // setProperty
XPC_WN_Shared_Proto_Enumerate, // enumerate
XPC_WN_ModsAllowed_Proto_Resolve, // resolve
nullptr, // mayResolve
XPC_WN_Shared_Proto_Finalize, // finalize
nullptr, // call
nullptr, // construct
nullptr, // hasInstance
XPC_WN_Shared_Proto_Trace, // trace
};
static const js::ClassExtension XPC_WN_Shared_Proto_ClassExtension = {
nullptr, /* weakmapKeyDelegateOp */
XPC_WN_Shared_Proto_ObjectMoved
};
const js::Class XPC_WN_ModsAllowed_WithCall_Proto_JSClass = {
"XPC_WN_ModsAllowed_WithCall_Proto_JSClass", // name;
WRAPPER_FLAGS, // flags;
/* Function pointer members. */
nullptr, // addProperty;
nullptr, // delProperty;
nullptr, // getProperty;
nullptr, // setProperty;
XPC_WN_Shared_Proto_Enumerate, // enumerate;
XPC_WN_ModsAllowed_Proto_Resolve, // resolve;
nullptr, // mayResolve;
XPC_WN_Shared_Proto_Finalize, // finalize;
/* Optionally non-null members start here. */
nullptr, // call;
nullptr, // construct;
nullptr, // hasInstance;
XPC_WN_Shared_Proto_Trace, // trace;
"XPC_WN_ModsAllowed_WithCall_Proto_JSClass",
WRAPPER_FLAGS,
&XPC_WN_ModsAllowed_Proto_JSClassOps,
JS_NULL_CLASS_SPEC,
&XPC_WN_Shared_Proto_ClassExtension,
XPC_WN_WithCall_ObjectOps
};
const js::Class XPC_WN_ModsAllowed_NoCall_Proto_JSClass = {
"XPC_WN_ModsAllowed_NoCall_Proto_JSClass", // name;
WRAPPER_FLAGS, // flags;
/* Function pointer members. */
nullptr, // addProperty;
nullptr, // delProperty;
nullptr, // getProperty;
nullptr, // setProperty;
XPC_WN_Shared_Proto_Enumerate, // enumerate;
XPC_WN_ModsAllowed_Proto_Resolve, // resolve;
nullptr, // mayResolve;
XPC_WN_Shared_Proto_Finalize, // finalize;
/* Optionally non-null members start here. */
nullptr, // call;
nullptr, // construct;
nullptr, // hasInstance;
XPC_WN_Shared_Proto_Trace, // trace;
"XPC_WN_ModsAllowed_NoCall_Proto_JSClass",
WRAPPER_FLAGS,
&XPC_WN_ModsAllowed_Proto_JSClassOps,
JS_NULL_CLASS_SPEC,
&XPC_WN_Shared_Proto_ClassExtension,
XPC_WN_NoCall_ObjectOps
@ -1367,51 +1347,34 @@ XPC_WN_NoMods_Proto_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool*
JSPROP_ENUMERATE, resolvedp);
}
static const js::ClassOps XPC_WN_NoMods_Proto_JSClassOps = {
XPC_WN_OnlyIWrite_Proto_AddPropertyStub, // addProperty
XPC_WN_CantDeletePropertyStub, // delProperty
nullptr, // getProperty
nullptr, // setProperty
XPC_WN_Shared_Proto_Enumerate, // enumerate
XPC_WN_NoMods_Proto_Resolve, // resolve
nullptr, // mayResolve
XPC_WN_Shared_Proto_Finalize, // finalize
nullptr, // call
nullptr, // construct
nullptr, // hasInstance
XPC_WN_Shared_Proto_Trace, // trace
};
const js::Class XPC_WN_NoMods_WithCall_Proto_JSClass = {
"XPC_WN_NoMods_WithCall_Proto_JSClass", // name;
WRAPPER_FLAGS, // flags;
/* Mandatory non-null function pointer members. */
XPC_WN_OnlyIWrite_Proto_AddPropertyStub, // addProperty;
XPC_WN_CantDeletePropertyStub, // delProperty;
nullptr, // getProperty;
nullptr, // setProperty;
XPC_WN_Shared_Proto_Enumerate, // enumerate;
XPC_WN_NoMods_Proto_Resolve, // resolve;
nullptr, // mayResolve;
XPC_WN_Shared_Proto_Finalize, // finalize;
/* Optionally non-null members start here. */
nullptr, // call;
nullptr, // construct;
nullptr, // hasInstance;
XPC_WN_Shared_Proto_Trace, // trace;
"XPC_WN_NoMods_WithCall_Proto_JSClass",
WRAPPER_FLAGS,
&XPC_WN_NoMods_Proto_JSClassOps,
JS_NULL_CLASS_SPEC,
&XPC_WN_Shared_Proto_ClassExtension,
XPC_WN_WithCall_ObjectOps
};
const js::Class XPC_WN_NoMods_NoCall_Proto_JSClass = {
"XPC_WN_NoMods_NoCall_Proto_JSClass", // name;
WRAPPER_FLAGS, // flags;
/* Mandatory non-null function pointer members. */
XPC_WN_OnlyIWrite_Proto_AddPropertyStub, // addProperty;
XPC_WN_CantDeletePropertyStub, // delProperty;
nullptr, // getProperty;
nullptr, // setProperty;
XPC_WN_Shared_Proto_Enumerate, // enumerate;
XPC_WN_NoMods_Proto_Resolve, // resolve;
nullptr, // mayResolve;
XPC_WN_Shared_Proto_Finalize, // finalize;
/* Optionally non-null members start here. */
nullptr, // call;
nullptr, // construct;
nullptr, // hasInstance;
XPC_WN_Shared_Proto_Trace, // trace;
"XPC_WN_NoMods_NoCall_Proto_JSClass",
WRAPPER_FLAGS,
&XPC_WN_NoMods_Proto_JSClassOps,
JS_NULL_CLASS_SPEC,
&XPC_WN_Shared_Proto_ClassExtension,
XPC_WN_NoCall_ObjectOps
@ -1488,31 +1451,31 @@ static_assert(((WRAPPER_FLAGS >> JSCLASS_RESERVED_SLOTS_SHIFT) &
JSCLASS_RESERVED_SLOTS_MASK) == 0,
"WRAPPER_FLAGS should not include any reserved slots");
static const js::ClassOps XPC_WN_Tearoff_JSClassOps = {
XPC_WN_OnlyIWrite_AddPropertyStub, // addProperty
XPC_WN_CantDeletePropertyStub, // delProperty
nullptr, // getProperty
nullptr, // setProperty
XPC_WN_TearOff_Enumerate, // enumerate
XPC_WN_TearOff_Resolve, // resolve
nullptr, // mayResolve
XPC_WN_TearOff_Finalize, // finalize
nullptr, // call
nullptr, // construct
nullptr, // hasInstance
nullptr, // trace
};
static const js::ClassExtension XPC_WN_Tearoff_JSClassExtension = {
nullptr, // weakmapKeyDelegateOp
nullptr, // weakmapKeyDelegateOp
XPC_WN_TearOff_ObjectMoved
};
const js::Class XPC_WN_Tearoff_JSClass = {
"WrappedNative_TearOff", // name;
"WrappedNative_TearOff",
WRAPPER_FLAGS |
JSCLASS_HAS_RESERVED_SLOTS(XPC_WN_TEAROFF_RESERVED_SLOTS), // flags;
XPC_WN_OnlyIWrite_AddPropertyStub, // addProperty;
XPC_WN_CantDeletePropertyStub, // delProperty;
nullptr, // getProperty;
nullptr, // setProperty;
XPC_WN_TearOff_Enumerate, // enumerate;
XPC_WN_TearOff_Resolve, // resolve;
nullptr, // mayResolve;
XPC_WN_TearOff_Finalize, // finalize;
/* Optionally non-null members start here. */
nullptr, // call
nullptr, // construct
nullptr, // hasInstance
nullptr, // trace
JSCLASS_HAS_RESERVED_SLOTS(XPC_WN_TEAROFF_RESERVED_SLOTS),
&XPC_WN_Tearoff_JSClassOps,
JS_NULL_CLASS_SPEC,
// ClassExtension
&XPC_WN_Tearoff_JSClassExtension
};

View File

@ -1650,8 +1650,8 @@ public:
XPCNativeScriptableShared(uint32_t aFlags, char* aName, bool aPopulate);
~XPCNativeScriptableShared() {
if (mJSClass.name)
free((void*)mJSClass.name);
free((void*)mJSClass.name);
free((void*)mJSClass.cOps);
MOZ_COUNT_DTOR(XPCNativeScriptableShared);
}
@ -1667,6 +1667,10 @@ public:
private:
XPCNativeScriptableFlags mFlags;
// This is an unusual js::Class instance: its name and cOps members are
// heap-allocated, unlike all other instances for which they are statically
// allocated. So we must free them in the destructor.
js::Class mJSClass;
};

View File

@ -1055,11 +1055,15 @@ ExpandoObjectFinalize(JSFreeOp* fop, JSObject* obj)
NS_RELEASE(principal);
}
static const JSClassOps ExpandoObjectClassOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, ExpandoObjectFinalize
};
const JSClass ExpandoObjectClass = {
"XrayExpandoObject",
JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_EXPANDO_COUNT),
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, ExpandoObjectFinalize
&ExpandoObjectClassOps
};
bool
@ -1706,14 +1710,15 @@ DOMXrayTraits::call(JSContext* cx, HandleObject wrapper,
// are using "legacycaller", which basically means plug-ins. We want to
// call those on the content compartment.
if (clasp->flags & JSCLASS_IS_DOMIFACEANDPROTOJSCLASS) {
if (!clasp->call) {
if (JSNative call = clasp->getCall()) {
// call it on the Xray compartment
if (!call(cx, args.length(), args.base()))
return false;
} else {
RootedValue v(cx, ObjectValue(*wrapper));
js::ReportIsNotFunction(cx, v);
return false;
}
// call it on the Xray compartment
if (!clasp->call(cx, args.length(), args.base()))
return false;
} else {
// This is only reached for WebIDL instance objects, and in practice
// only for plugins. Just call them on the content compartment.
@ -1732,13 +1737,14 @@ DOMXrayTraits::construct(JSContext* cx, HandleObject wrapper,
const js::Class* clasp = js::GetObjectClass(obj);
// See comments in DOMXrayTraits::call() explaining what's going on here.
if (clasp->flags & JSCLASS_IS_DOMIFACEANDPROTOJSCLASS) {
if (!clasp->construct) {
if (JSNative construct = clasp->getConstruct()) {
if (!construct(cx, args.length(), args.base()))
return false;
} else {
RootedValue v(cx, ObjectValue(*wrapper));
js::ReportIsNotFunction(cx, v);
return false;
}
if (!clasp->construct(cx, args.length(), args.base()))
return false;
} else {
if (!baseInstance.construct(cx, wrapper, args))
return false;

View File

@ -666,15 +666,19 @@ private:
}
};
const JSClass JSRuntimeWrapper::sGlobalClass = {
"PACResolutionThreadGlobal",
JSCLASS_GLOBAL_FLAGS,
static const JSClassOps sJSRuntimeWrapperGlobalClassOps = {
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr,
JS_GlobalObjectTraceHook
};
const JSClass JSRuntimeWrapper::sGlobalClass = {
"PACResolutionThreadGlobal",
JSCLASS_GLOBAL_FLAGS,
&sJSRuntimeWrapperGlobalClassOps
};
void
ProxyAutoConfig::SetThreadLocalIndex(uint32_t index)
{

Some files were not shown because too many files have changed in this diff Show More