Bug 1321374 - Simplify js::Class handling relating to nsIXPCScriptable. r=mccr8, sr=bholley.

This patch removes XPCNativeScriptableShared and XPCNativeScriptableSharedMap,
which results in a net reduction of ~100 lines of code.
This commit is contained in:
Nicholas Nethercote 2016-12-14 08:33:46 +11:00
parent 78f7bd1dd7
commit df925b776c
24 changed files with 279 additions and 384 deletions

View File

@ -19,6 +19,7 @@
#include "xpcpublic.h"
#include "xpcprivate.h"
#include "xpc_make_class.h"
#include "XPCWrapper.h"
#include "mozilla/DOMEventTargetHelper.h"
@ -134,6 +135,9 @@ using namespace mozilla::dom;
_chromeOnly, _allowXBL) \
{ #_class, \
nullptr, \
XPC_MAKE_CLASS_OPS(_flags), \
XPC_MAKE_CLASS(#_class, _flags, \
&sClassInfoData[eDOMClassInfo_##_class##_id].mClassOps), \
_helper::doCreate, \
nullptr, \
nullptr, \
@ -783,6 +787,13 @@ nsDOMClassInfo::GetScriptableFlags()
return mData->mScriptableFlags;
}
// virtual
const js::Class*
nsDOMClassInfo::GetClass()
{
return &mData->mClass;
}
NS_IMETHODIMP
nsDOMClassInfo::PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj)

View File

@ -11,6 +11,7 @@
#include "nsDOMClassInfoID.h"
#include "nsIXPCScriptable.h"
#include "nsIScriptGlobalObject.h"
#include "js/Class.h"
#include "js/Id.h"
#include "nsIXPConnect.h"
@ -30,8 +31,12 @@ typedef nsresult (*nsDOMConstructorFunc)(nsISupports** aNewObject);
struct nsDOMClassInfoData
{
// XXX: mName is the same as the name gettable from the callback. This
// redundancy should be removed eventually.
const char *mName;
const char16_t *mNameUTF16;
const js::ClassOps mClassOps;
const js::Class mClass;
nsDOMClassInfoConstructorFnc mConstructorFptr;
nsIClassInfo *mCachedClassInfo;

View File

@ -15,6 +15,9 @@
#include "js/TypeDecls.h"
struct JSFreeOp;
namespace js {
struct Class;
}
%}
interface nsIXPConnectWrappedNative;
@ -25,6 +28,7 @@ interface nsIXPConnectWrappedNative;
[ptr] native JSFreeOpPtr(JSFreeOp);
[ref] native JSCallArgsRef(const JS::CallArgs);
[ref] native JSAutoIdVector(JS::AutoIdVector);
[ptr] native jsClassPtr(const js::Class);
/**
* Note: This is not really an XPCOM interface. For example, callers must
@ -73,6 +77,7 @@ interface nsIXPCScriptable : nsISupports
readonly attribute string className;
[notxpcom,nostdcall] uint32_t getScriptableFlags();
[notxpcom,nostdcall] jsClassPtr getClass();
void preCreate(in nsISupports nativeObj, in JSContextPtr cx,
in JSObjectPtr globalObj, out JSObjectPtr parentObj);

View File

@ -7,6 +7,7 @@
EXPORTS += [
'nsAXPCNativeCallContext.h',
'nsTArrayHelpers.h',
'xpc_make_class.h',
'xpc_map_end.h',
]

View File

@ -0,0 +1,175 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=4 et sw=4 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef xpc_make_class_h
#define xpc_make_class_h
// This file should be used to create js::Class instances for nsIXPCScriptable
// instances. This includes any file that uses xpc_map_end.h.
#include "xpcpublic.h"
#include "mozilla/dom/DOMJSClass.h"
bool
XPC_WN_MaybeResolvingPropertyStub(JSContext* cx, JS::HandleObject obj,
JS::HandleId id, JS::HandleValue v);
bool
XPC_WN_CannotModifyPropertyStub(JSContext* cx, JS::HandleObject obj,
JS::HandleId id, JS::HandleValue v);
bool
XPC_WN_MaybeResolvingDeletePropertyStub(JSContext* cx, JS::HandleObject obj,
JS::HandleId id,
JS::ObjectOpResult& result);
bool
XPC_WN_CantDeletePropertyStub(JSContext* cx, JS::HandleObject obj,
JS::HandleId id, JS::ObjectOpResult& result);
bool
XPC_WN_Helper_GetProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
JS::MutableHandleValue vp);
bool
XPC_WN_Helper_SetProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
JS::MutableHandleValue vp,
JS::ObjectOpResult& result);
bool
XPC_WN_MaybeResolvingSetPropertyStub(JSContext* cx, JS::HandleObject obj,
JS::HandleId id, JS::MutableHandleValue vp,
JS::ObjectOpResult& result);
bool
XPC_WN_CannotModifySetPropertyStub(JSContext* cx, JS::HandleObject obj,
JS::HandleId id, JS::MutableHandleValue vp,
JS::ObjectOpResult& result);
bool
XPC_WN_Helper_Enumerate(JSContext* cx, JS::HandleObject obj);
bool
XPC_WN_Shared_Enumerate(JSContext* cx, JS::HandleObject obj);
bool
XPC_WN_Helper_Resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
bool* resolvedp);
void
XPC_WN_Helper_Finalize(js::FreeOp* fop, JSObject* obj);
void
XPC_WN_NoHelper_Finalize(js::FreeOp* fop, JSObject* obj);
bool
XPC_WN_Helper_Call(JSContext* cx, unsigned argc, JS::Value* vp);
bool
XPC_WN_Helper_HasInstance(JSContext* cx, JS::HandleObject obj,
JS::MutableHandleValue valp, bool* bp);
bool
XPC_WN_Helper_Construct(JSContext* cx, unsigned argc, JS::Value* vp);
void
XPCWrappedNative_Trace(JSTracer* trc, JSObject* obj);
extern const js::ClassExtension XPC_WN_JSClassExtension;
extern const js::ObjectOps XPC_WN_ObjectOpsWithEnumerate;
#define XPC_MAKE_CLASS_OPS(_flags) { \
/* addProperty */ \
((_flags) & nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY) \
? nullptr \
: ((_flags) & nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE) \
? XPC_WN_MaybeResolvingPropertyStub \
: XPC_WN_CannotModifyPropertyStub, \
\
/* delProperty */ \
((_flags) & nsIXPCScriptable::USE_JSSTUB_FOR_DELPROPERTY) \
? nullptr \
: ((_flags) & nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE) \
? XPC_WN_MaybeResolvingDeletePropertyStub \
: XPC_WN_CantDeletePropertyStub, \
\
/* getProperty */ \
((_flags) & nsIXPCScriptable::WANT_GETPROPERTY) \
? XPC_WN_Helper_GetProperty \
: nullptr, \
\
/* setProperty */ \
((_flags) & nsIXPCScriptable::WANT_SETPROPERTY) \
? XPC_WN_Helper_SetProperty \
: ((_flags) & nsIXPCScriptable::USE_JSSTUB_FOR_SETPROPERTY) \
? nullptr \
: ((_flags) & nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE) \
? XPC_WN_MaybeResolvingSetPropertyStub \
: XPC_WN_CannotModifySetPropertyStub, \
\
/* enumerate */ \
((_flags) & nsIXPCScriptable::WANT_NEWENUMERATE) \
? nullptr /* We will use oOps->enumerate set below in this case */ \
: ((_flags) & nsIXPCScriptable::WANT_ENUMERATE) \
? XPC_WN_Helper_Enumerate \
: XPC_WN_Shared_Enumerate, \
\
/* resolve */ \
/* We have to figure out resolve strategy at call time */ \
XPC_WN_Helper_Resolve, \
\
/* mayResolve */ \
nullptr, \
\
/* finalize */ \
((_flags) & nsIXPCScriptable::WANT_FINALIZE) \
? XPC_WN_Helper_Finalize \
: XPC_WN_NoHelper_Finalize, \
\
/* call */ \
((_flags) & nsIXPCScriptable::WANT_CALL) \
? XPC_WN_Helper_Call \
: nullptr, \
\
/* hasInstance */ \
((_flags) & nsIXPCScriptable::WANT_HASINSTANCE) \
? XPC_WN_Helper_HasInstance \
: nullptr, \
\
/* construct */ \
((_flags) & nsIXPCScriptable::WANT_CONSTRUCT) \
? XPC_WN_Helper_Construct \
: nullptr, \
\
/* trace */ \
((_flags) & nsIXPCScriptable::IS_GLOBAL_OBJECT) \
? JS_GlobalObjectTraceHook \
: XPCWrappedNative_Trace, \
}
#define XPC_MAKE_CLASS(_name, _flags, _classOps) { \
/* name */ \
_name, \
\
/* flags */ \
XPC_WRAPPER_FLAGS | \
JSCLASS_PRIVATE_IS_NSISUPPORTS | \
JSCLASS_IS_WRAPPED_NATIVE | \
(((_flags) & nsIXPCScriptable::IS_GLOBAL_OBJECT) \
? XPCONNECT_GLOBAL_FLAGS \
: 0), \
\
/* cOps */ \
_classOps, \
\
/* spec */ \
nullptr, \
\
/* ext */ \
&XPC_WN_JSClassExtension, \
\
/* oOps */ \
((_flags) & nsIXPCScriptable::WANT_NEWENUMERATE) \
? &XPC_WN_ObjectOpsWithEnumerate \
: nullptr, \
}
#endif

View File

@ -4,6 +4,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// If you include this file you must also include xpc_make_class.h at the top
// of the file doing the including.
#ifndef XPC_MAP_CLASSNAME
#error "Must #define XPC_MAP_CLASSNAME before #including xpc_map_end.h"
@ -67,6 +69,18 @@ XPC_MAP_CLASSNAME::GetScriptableFlags()
0;
}
// virtual
const js::Class*
XPC_MAP_CLASSNAME::GetClass()
{
static const js::ClassOps classOps =
XPC_MAKE_CLASS_OPS(GetScriptableFlags());
static const js::Class klass =
XPC_MAKE_CLASS(XPC_MAP_QUOTED_CLASSNAME, GetScriptableFlags(),
&classOps);
return &klass;
}
/**************************************************************/
#ifndef XPC_MAP_WANT_PRECREATE

View File

@ -23,6 +23,7 @@
#include "nsPrincipal.h"
#include "WrapperFactory.h"
#include "xpcprivate.h"
#include "xpc_make_class.h"
#include "XPCWrapper.h"
#include "XrayWrapper.h"
#include "Crypto.h"

View File

@ -7,6 +7,7 @@
/* The "Components" xpcom objects for JavaScript. */
#include "xpcprivate.h"
#include "xpc_make_class.h"
#include "xpcIJSModuleLoader.h"
#include "XPCJSWeakReference.h"
#include "WrapperFactory.h"

View File

@ -28,7 +28,6 @@ class XPCNativeSet;
class XPCWrappedNative;
class XPCWrappedNativeProto;
class XPCWrappedNativeTearOff;
class XPCNativeScriptableShared;
class XPCNativeScriptableInfo;
class XPCNativeScriptableCreateInfo;
@ -43,7 +42,6 @@ class ClassInfo2NativeSetMap;
class ClassInfo2WrappedNativeProtoMap;
class NativeSetMap;
class IID2ThisTranslatorMap;
class XPCNativeScriptableSharedMap;
class XPCWrappedNativeProtoMap;
class JSObject2JSObjectMap;

View File

@ -1552,9 +1552,6 @@ XPCJSContext::~XPCJSContext()
delete mThisTranslatorMap;
mThisTranslatorMap = nullptr;
delete mNativeScriptableSharedMap;
mNativeScriptableSharedMap = nullptr;
delete mDyingWrappedNativeProtoMap;
mDyingWrappedNativeProtoMap = nullptr;
@ -3244,7 +3241,6 @@ XPCJSContext::XPCJSContext()
mClassInfo2NativeSetMap(ClassInfo2NativeSetMap::newMap(XPC_NATIVE_SET_MAP_LENGTH)),
mNativeSetMap(NativeSetMap::newMap(XPC_NATIVE_SET_MAP_LENGTH)),
mThisTranslatorMap(IID2ThisTranslatorMap::newMap(XPC_THIS_TRANSLATOR_MAP_LENGTH)),
mNativeScriptableSharedMap(XPCNativeScriptableSharedMap::newMap(XPC_NATIVE_JSCLASS_MAP_LENGTH)),
mDyingWrappedNativeProtoMap(XPCWrappedNativeProtoMap::newMap(XPC_DYING_NATIVE_PROTO_MAP_LENGTH)),
mGCIsRunning(false),
mNativesToReleaseArray(),
@ -3490,7 +3486,6 @@ XPCJSContext::newXPCJSContext()
self->GetClassInfo2NativeSetMap() &&
self->GetNativeSetMap() &&
self->GetThisTranslatorMap() &&
self->GetNativeScriptableSharedMap() &&
self->GetDyingWrappedNativeProtoMap() &&
self->mWatchdogManager) {
return self;

View File

@ -7,6 +7,7 @@
/* An xpcom implementation of the JavaScript nsIID and nsCID objects. */
#include "xpcprivate.h"
#include "xpc_make_class.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/Attributes.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"

View File

@ -387,105 +387,6 @@ IID2ThisTranslatorMap::IID2ThisTranslatorMap(int length)
{
}
/***************************************************************************/
PLDHashNumber
XPCNativeScriptableSharedMap::Entry::Hash(const void* key)
{
PLDHashNumber h;
const unsigned char* s;
XPCNativeScriptableShared* obj =
(XPCNativeScriptableShared*) key;
// hash together the flags and the classname string, ignore the interfaces
// bitmap since it's very rare that it's different when flags and classname
// are the same.
h = (PLDHashNumber) obj->GetFlags();
for (s = (const unsigned char*) obj->GetJSClass()->name; *s != '\0'; s++)
h = RotateLeft(h, 4) ^ *s;
return h;
}
bool
XPCNativeScriptableSharedMap::Entry::Match(const PLDHashEntryHdr* entry,
const void* key)
{
XPCNativeScriptableShared* obj1 =
((XPCNativeScriptableSharedMap::Entry*) entry)->key;
XPCNativeScriptableShared* obj2 =
(XPCNativeScriptableShared*) key;
// match the flags and the classname string
if (obj1->GetFlags() != obj2->GetFlags())
return false;
const char* name1 = obj1->GetJSClass()->name;
const char* name2 = obj2->GetJSClass()->name;
if (!name1 || !name2)
return name1 == name2;
return 0 == strcmp(name1, name2);
}
const struct PLDHashTableOps XPCNativeScriptableSharedMap::Entry::sOps =
{
Hash,
Match,
PLDHashTable::MoveEntryStub,
PLDHashTable::ClearEntryStub
};
// static
XPCNativeScriptableSharedMap*
XPCNativeScriptableSharedMap::newMap(int length)
{
return new XPCNativeScriptableSharedMap(length);
}
XPCNativeScriptableSharedMap::XPCNativeScriptableSharedMap(int length)
: mTable(&Entry::sOps, sizeof(Entry), length)
{
}
bool
XPCNativeScriptableSharedMap::GetNewOrUsed(uint32_t flags,
char* name,
XPCNativeScriptableInfo* si)
{
NS_PRECONDITION(name,"bad param");
NS_PRECONDITION(si,"bad param");
RefPtr<XPCNativeScriptableShared> key =
new XPCNativeScriptableShared(flags, name, /* populate = */ false);
auto entry = static_cast<Entry*>(mTable.Add(key, fallible));
if (!entry)
return false;
RefPtr<XPCNativeScriptableShared> shared = entry->key;
// XXX: this XPCNativeScriptableShared is heap-allocated, which means the
// js::Class it contains is also heap-allocated. This causes problems for
// memory reporting. See the comment above the BaseShape case in
// StatsCellCallback() in js/src/vm/MemoryMetrics.cpp.
//
// When the code below is removed (bug 1265271) and there are no longer any
// heap-allocated js::Class instances, the disabled code in
// StatsCellCallback() should be reinstated.
//
if (!shared) {
shared = new XPCNativeScriptableShared(flags, key->TransferNameOwnership(),
/* populate = */ true);
entry->key = shared;
}
si->SetScriptableShared(shared.forget());
return true;
}
/***************************************************************************/
// implement XPCWrappedNativeProtoMap...

View File

@ -509,41 +509,6 @@ private:
/***************************************************************************/
class XPCNativeScriptableSharedMap
{
public:
struct Entry : public PLDHashEntryHdr
{
// This is a weak reference that will be cleared
// in the XPCNativeScriptableShared destructor.
XPCNativeScriptableShared* key;
static PLDHashNumber
Hash(const void* key);
static bool
Match(const PLDHashEntryHdr* entry, const void* key);
static const struct PLDHashTableOps sOps;
};
static XPCNativeScriptableSharedMap* newMap(int length);
bool GetNewOrUsed(uint32_t flags, char* name, XPCNativeScriptableInfo* si);
inline uint32_t Count() { return mTable.EntryCount(); }
void Remove(XPCNativeScriptableShared* key) { mTable.Remove(key); }
private:
XPCNativeScriptableSharedMap(); // no implementation
explicit XPCNativeScriptableSharedMap(int size);
private:
PLDHashTable mTable;
};
/***************************************************************************/
class XPCWrappedNativeProtoMap
{
public:

View File

@ -223,19 +223,16 @@ XPCWrappedNative::WrapNewGlobal(xpcObjectHelper& nativeHelper,
// Share mScriptableInfo with the proto.
//
// This is probably more trouble than it's worth, since we've already created
// an XPCNativeScriptableInfo for ourselves. Moreover, most of that class is
// shared internally via XPCNativeScriptableInfoShared, so the memory
// savings are negligible. Nevertheless, this is what ::Init() does, and we
// want to be as consistent as possible with that code.
// This is probably more trouble than it's worth, since we've already
// created an XPCNativeScriptableInfo for ourselves. Nevertheless, this is
// what ::Init() does, and we want to be as consistent as possible with
// that code.
XPCNativeScriptableInfo* siProto = proto->GetScriptableInfo();
if (siProto && siProto->GetCallback() == sciWrapper.GetCallback()) {
wrapper->mScriptableInfo = siProto;
// XPCNativeScriptableShared instances live in a map, and are
// GCed, but XPCNativeScriptableInfo is per-instance and must be
// manually managed. If we're switching over to that of the proto, we
// need to destroy the one we've allocated, and also null out the
// AutoMarkingPtr, so that it doesn't try to mark garbage data.
// XPCNativeScriptableInfo uses manual memory management. If we're
// switching over to that of the proto, we need to destroy the one
// we've allocated.
delete si;
si = nullptr;
} else {
@ -751,8 +748,7 @@ XPCWrappedNative::Init(const XPCNativeScriptableCreateInfo* sci)
mScriptableInfo = siProto;
}
if (!mScriptableInfo) {
mScriptableInfo =
XPCNativeScriptableInfo::Construct(sci);
mScriptableInfo = XPCNativeScriptableInfo::Construct(sci);
if (!mScriptableInfo)
return false;
@ -972,9 +968,7 @@ XPCWrappedNative::SystemIsBeingShutDown()
if (HasProto())
proto->SystemIsBeingShutDown();
// Don't destroy mScriptableInfo here because this will release
// XPCNativeScriptableShared, which will destroy js::ClassOps
// which may still be in use by JS objects.
// We don't destroy mScriptableInfo here. The destructor will do it.
// Cleanup the tearoffs.
for (XPCWrappedNativeTearOff* to = &mFirstTearOff; to; to = to->GetNextTearOff()) {

View File

@ -7,6 +7,7 @@
/* JavaScript JSClasses and JSOps for our Wrapped Native JS Objects. */
#include "xpcprivate.h"
#include "xpc_make_class.h"
#include "jsprf.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/Preferences.h"
@ -470,28 +471,28 @@ XPC_WN_OnlyIWrite_AddPropertyStub(JSContext* cx, HandleObject obj, HandleId id,
return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx);
}
static bool
bool
XPC_WN_CannotModifyPropertyStub(JSContext* cx, HandleObject obj, HandleId id,
HandleValue v)
{
return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx);
}
static bool
bool
XPC_WN_CantDeletePropertyStub(JSContext* cx, HandleObject obj, HandleId id,
ObjectOpResult& result)
{
return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx);
}
static bool
bool
XPC_WN_CannotModifySetPropertyStub(JSContext* cx, HandleObject obj, HandleId id,
MutableHandleValue vp, ObjectOpResult& result)
{
return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx);
}
static bool
bool
XPC_WN_Shared_Enumerate(JSContext* cx, HandleObject obj)
{
XPCCallContext ccx(cx, obj);
@ -563,7 +564,7 @@ WrappedNativeObjectMoved(JSObject* obj, const JSObject* old)
wrapper->FlatJSObjectMoved(obj, old);
}
static void
void
XPC_WN_NoHelper_Finalize(js::FreeOp* fop, JSObject* obj)
{
WrappedNativeFinalize(fop, obj, WN_NOHELPER);
@ -577,8 +578,8 @@ XPC_WN_NoHelper_Finalize(js::FreeOp* fop, JSObject* obj)
* should mark any JS objects held by |wrapper| as members.
*/
static void
MarkWrappedNative(JSTracer* trc, JSObject* obj)
/* static */ void
XPCWrappedNative::Trace(JSTracer* trc, JSObject* obj)
{
const js::Class* clazz = js::GetObjectClass(obj);
if (clazz->flags & JSCLASS_DOM_GLOBAL) {
@ -591,10 +592,10 @@ MarkWrappedNative(JSTracer* trc, JSObject* obj)
wrapper->TraceInside(trc);
}
/* static */ void
XPCWrappedNative::Trace(JSTracer* trc, JSObject* obj)
void
XPCWrappedNative_Trace(JSTracer* trc, JSObject* obj)
{
MarkWrappedNative(trc, obj);
XPCWrappedNative::Trace(trc, obj);
}
static bool
@ -636,14 +637,14 @@ static const js::ClassOps XPC_WN_NoHelper_JSClassOps = {
XPCWrappedNative::Trace, // trace
};
static const js::ClassExtension XPC_WN_JSClassExtension = {
const js::ClassExtension XPC_WN_JSClassExtension = {
nullptr, // weakmapKeyDelegateOp
WrappedNativeObjectMoved
};
const js::Class XPC_WN_NoHelper_JSClass = {
"XPCWrappedNative_NoHelper",
WRAPPER_FLAGS |
XPC_WRAPPER_FLAGS |
JSCLASS_IS_WRAPPED_NATIVE |
JSCLASS_PRIVATE_IS_NSISUPPORTS |
JSCLASS_FOREGROUND_FINALIZE,
@ -656,7 +657,7 @@ const js::Class XPC_WN_NoHelper_JSClass = {
/***************************************************************************/
static bool
bool
XPC_WN_MaybeResolvingPropertyStub(JSContext* cx, HandleObject obj, HandleId id, HandleValue v)
{
XPCCallContext ccx(cx, obj);
@ -668,7 +669,7 @@ XPC_WN_MaybeResolvingPropertyStub(JSContext* cx, HandleObject obj, HandleId id,
return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx);
}
static bool
bool
XPC_WN_MaybeResolvingSetPropertyStub(JSContext* cx, HandleObject obj, HandleId id,
MutableHandleValue vp, ObjectOpResult& result)
{
@ -676,7 +677,7 @@ XPC_WN_MaybeResolvingSetPropertyStub(JSContext* cx, HandleObject obj, HandleId i
return XPC_WN_MaybeResolvingPropertyStub(cx, obj, id, vp);
}
static bool
bool
XPC_WN_MaybeResolvingDeletePropertyStub(JSContext* cx, HandleObject obj, HandleId id,
ObjectOpResult& result)
{
@ -733,7 +734,7 @@ XPC_WN_Helper_SetProperty(JSContext* cx, HandleObject obj, HandleId id,
POST_HELPER_STUB_WITH_OBJECTOPRESULT(failReadOnly)
}
static bool
bool
XPC_WN_Helper_Call(JSContext* cx, unsigned argc, Value* vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
@ -750,7 +751,7 @@ XPC_WN_Helper_Call(JSContext* cx, unsigned argc, Value* vp)
POST_HELPER_STUB
}
static bool
bool
XPC_WN_Helper_Construct(JSContext* cx, unsigned argc, Value* vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
@ -768,7 +769,7 @@ XPC_WN_Helper_Construct(JSContext* cx, unsigned argc, Value* vp)
POST_HELPER_STUB
}
static bool
bool
XPC_WN_Helper_HasInstance(JSContext* cx, HandleObject obj, MutableHandleValue valp, bool* bp)
{
bool retval2;
@ -778,13 +779,13 @@ XPC_WN_Helper_HasInstance(JSContext* cx, HandleObject obj, MutableHandleValue va
POST_HELPER_STUB
}
static void
void
XPC_WN_Helper_Finalize(js::FreeOp* fop, JSObject* obj)
{
WrappedNativeFinalize(fop, obj, WN_HELPER);
}
static bool
bool
XPC_WN_Helper_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
{
nsresult rv = NS_OK;
@ -856,7 +857,7 @@ XPC_WN_Helper_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolv
return retval;
}
static bool
bool
XPC_WN_Helper_Enumerate(JSContext* cx, HandleObject obj)
{
XPCCallContext ccx(cx, obj);
@ -908,34 +909,13 @@ XPCNativeScriptableInfo*
XPCNativeScriptableInfo::Construct(const XPCNativeScriptableCreateInfo* sci)
{
MOZ_ASSERT(sci, "bad param");
MOZ_ASSERT(sci->GetCallback(), "bad param");
XPCNativeScriptableInfo* newObj =
new XPCNativeScriptableInfo(sci->GetCallback());
if (!newObj)
return nullptr;
char* name = nullptr;
if (NS_FAILED(sci->GetCallback()->GetClassName(&name)) || !name) {
delete newObj;
return nullptr;
}
bool success;
XPCJSContext* cx = XPCJSContext::Get();
XPCNativeScriptableSharedMap* map = cx->GetNativeScriptableSharedMap();
success = map->GetNewOrUsed(sci->GetFlags(), name, newObj);
if (!success) {
delete newObj;
return nullptr;
}
return newObj;
nsCOMPtr<nsIXPCScriptable> callback = sci->GetCallback();
MOZ_ASSERT(callback);
MOZ_ASSERT(callback->GetScriptableFlags() == sci->GetFlags());
return new XPCNativeScriptableInfo(callback);
}
static const js::ObjectOps XPC_WN_ObjectOpsWithEnumerate = {
const js::ObjectOps XPC_WN_ObjectOpsWithEnumerate = {
nullptr, // lookupProperty
nullptr, // defineProperty
nullptr, // hasProperty
@ -950,119 +930,6 @@ static const js::ObjectOps XPC_WN_ObjectOpsWithEnumerate = {
nullptr, // funToString
};
XPCNativeScriptableShared::XPCNativeScriptableShared(uint32_t aFlags,
char* aName,
bool aPopulate)
: mFlags(aFlags)
{
// Initialize the js::Class.
memset(&mJSClass, 0, sizeof(mJSClass));
mJSClass.name = aName; // take ownership
if (!aPopulate)
return;
mJSClass.flags = WRAPPER_FLAGS |
JSCLASS_PRIVATE_IS_NSISUPPORTS |
JSCLASS_IS_WRAPPED_NATIVE;
if (mFlags.IsGlobalObject())
mJSClass.flags |= XPCONNECT_GLOBAL_FLAGS;
// Initialize the js::ClassExtension.
// 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.UseJSStubForAddProperty())
cOps->addProperty = nullptr;
else if (mFlags.AllowPropModsDuringResolve())
cOps->addProperty = XPC_WN_MaybeResolvingPropertyStub;
else
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())
cOps->getProperty = XPC_WN_Helper_GetProperty;
else
cOps->getProperty = nullptr;
if (mFlags.WantSetProperty())
cOps->setProperty = XPC_WN_Helper_SetProperty;
else if (mFlags.UseJSStubForSetProperty())
cOps->setProperty = nullptr;
else if (mFlags.AllowPropModsDuringResolve())
cOps->setProperty = XPC_WN_MaybeResolvingSetPropertyStub;
else
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())
cOps->enumerate = nullptr;
else if (mFlags.WantEnumerate())
cOps->enumerate = XPC_WN_Helper_Enumerate;
else
cOps->enumerate = XPC_WN_Shared_Enumerate;
// We have to figure out resolve strategy at call time
cOps->resolve = XPC_WN_Helper_Resolve;
if (mFlags.WantFinalize())
cOps->finalize = XPC_WN_Helper_Finalize;
else
cOps->finalize = XPC_WN_NoHelper_Finalize;
if (mFlags.WantCall())
cOps->call = XPC_WN_Helper_Call;
if (mFlags.WantConstruct())
cOps->construct = XPC_WN_Helper_Construct;
if (mFlags.WantHasInstance())
cOps->hasInstance = XPC_WN_Helper_HasInstance;
if (mFlags.IsGlobalObject())
cOps->trace = JS_GlobalObjectTraceHook;
else
cOps->trace = XPCWrappedNative::Trace;
// Initialize the js::ClassExtension.
mJSClass.ext = &XPC_WN_JSClassExtension;
// Initialize the js::ObjectOps.
if (mFlags.WantNewEnumerate())
mJSClass.oOps = &XPC_WN_ObjectOpsWithEnumerate;
}
XPCNativeScriptableShared::~XPCNativeScriptableShared()
{
// mJSClass.cOps will be null if |this| was created with
// populate=false. Otherwise, it was created with populate=true
// and there is a weak reference in a global map that must be
// removed.
if (mJSClass.cOps) {
XPCJSContext::Get()->GetNativeScriptableSharedMap()->Remove(this);
free((void*)mJSClass.cOps);
}
free((void*)mJSClass.name);
}
/***************************************************************************/
/***************************************************************************/
@ -1279,7 +1146,7 @@ static const js::ClassExtension XPC_WN_Shared_Proto_ClassExtension = {
const js::Class XPC_WN_ModsAllowed_Proto_JSClass = {
"XPC_WN_ModsAllowed_Proto_JSClass",
WRAPPER_FLAGS,
XPC_WRAPPER_FLAGS,
&XPC_WN_ModsAllowed_Proto_JSClassOps,
JS_NULL_CLASS_SPEC,
&XPC_WN_Shared_Proto_ClassExtension,
@ -1354,7 +1221,7 @@ static const js::ClassOps XPC_WN_NoMods_Proto_JSClassOps = {
const js::Class XPC_WN_NoMods_Proto_JSClass = {
"XPC_WN_NoMods_Proto_JSClass",
WRAPPER_FLAGS,
XPC_WRAPPER_FLAGS,
&XPC_WN_NoMods_Proto_JSClassOps,
JS_NULL_CLASS_SPEC,
&XPC_WN_Shared_Proto_ClassExtension,
@ -1426,11 +1293,12 @@ XPC_WN_TearOff_ObjectMoved(JSObject* obj, const JSObject* old)
p->JSObjectMoved(obj, old);
}
// Make sure WRAPPER_FLAGS has no reserved slots, so our XPC_WN_TEAROFF_RESERVED_SLOTS value is OK.
// Make sure XPC_WRAPPER_FLAGS has no reserved slots, so our
// XPC_WN_TEAROFF_RESERVED_SLOTS value is OK.
static_assert(((WRAPPER_FLAGS >> JSCLASS_RESERVED_SLOTS_SHIFT) &
static_assert(((XPC_WRAPPER_FLAGS >> JSCLASS_RESERVED_SLOTS_SHIFT) &
JSCLASS_RESERVED_SLOTS_MASK) == 0,
"WRAPPER_FLAGS should not include any reserved slots");
"XPC_WRAPPER_FLAGS should not include any reserved slots");
static const js::ClassOps XPC_WN_Tearoff_JSClassOps = {
XPC_WN_OnlyIWrite_AddPropertyStub, // addProperty
@ -1454,7 +1322,7 @@ static const js::ClassExtension XPC_WN_Tearoff_JSClassExtension = {
const js::Class XPC_WN_Tearoff_JSClass = {
"WrappedNative_TearOff",
WRAPPER_FLAGS |
XPC_WRAPPER_FLAGS |
JSCLASS_HAS_RESERVED_SLOTS(XPC_WN_TEAROFF_RESERVED_SLOTS),
&XPC_WN_Tearoff_JSClassOps,
JS_NULL_CLASS_SPEC,

View File

@ -62,11 +62,6 @@
* XPConnect. These can have pointers from XPCWrappedNativeProto and
* XPCWrappedNative (since C++ objects can have scriptable info without having
* class info).
*
* Most data in an XPCNativeScriptableInfo is shared between instances. The
* shared data is stored in an XPCNativeScriptableShared object. This type is
* important because it holds the JSClass of the flattened JS objects with the
* given scriptable info.
*/
/* All the XPConnect private declarations - only include locally. */
@ -180,7 +175,6 @@
#define XPC_DYING_NATIVE_PROTO_MAP_LENGTH 8
#define XPC_NATIVE_INTERFACE_MAP_LENGTH 32
#define XPC_NATIVE_SET_MAP_LENGTH 32
#define XPC_NATIVE_JSCLASS_MAP_LENGTH 16
#define XPC_THIS_TRANSLATOR_MAP_LENGTH 4
#define XPC_WRAPPER_MAP_LENGTH 8
@ -207,9 +201,6 @@ extern const char XPC_XPCONNECT_CONTRACTID[];
*dest = result; \
return (result || !src) ? NS_OK : NS_ERROR_OUT_OF_MEMORY
#define WRAPPER_FLAGS (JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE)
// If IS_WN_CLASS for the JSClass of an object is true, the object is a
// wrappednative wrapper, holding the XPCWrappedNative in its private slot.
static inline bool IS_WN_CLASS(const js::Class* clazz)
@ -448,9 +439,6 @@ public:
IID2ThisTranslatorMap* GetThisTranslatorMap() const
{return mThisTranslatorMap;}
XPCNativeScriptableSharedMap* GetNativeScriptableSharedMap() const
{return mNativeScriptableSharedMap;}
XPCWrappedNativeProtoMap* GetDyingWrappedNativeProtoMap() const
{return mDyingWrappedNativeProtoMap;}
@ -612,7 +600,6 @@ private:
ClassInfo2NativeSetMap* mClassInfo2NativeSetMap;
NativeSetMap* mNativeSetMap;
IID2ThisTranslatorMap* mThisTranslatorMap;
XPCNativeScriptableSharedMap* mNativeScriptableSharedMap;
XPCWrappedNativeProtoMap* mDyingWrappedNativeProtoMap;
bool mGCIsRunning;
nsTArray<nsISupports*> mNativesToReleaseArray;
@ -1455,46 +1442,8 @@ private:
};
/***************************************************************************/
// XPCNativeScriptableShared is used to hold the JSClass and the
// associated scriptable flags for XPCWrappedNatives. These are shared across
// the context and are garbage collected by xpconnect. We *used* to just store
// this inside the XPCNativeScriptableInfo (usually owned by instances of
// XPCWrappedNativeProto. This had two problems... It was wasteful, and it
// was a big problem when wrappers are reparented to different scopes (and
// thus different protos (the DOM does this).
class XPCNativeScriptableShared final
{
public:
NS_INLINE_DECL_REFCOUNTING(XPCNativeScriptableShared)
const XPCNativeScriptableFlags& GetFlags() const { return mFlags; }
const JSClass* GetJSClass() { return Jsvalify(&mJSClass); }
XPCNativeScriptableShared(uint32_t aFlags, char* aName, bool aPopulate);
char* TransferNameOwnership() {
char* name = (char*)mJSClass.name;
mJSClass.name = nullptr;
return name;
}
private:
~XPCNativeScriptableShared();
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;
};
/***************************************************************************/
// XPCNativeScriptableInfo is used to hold the nsIXPCScriptable state for a
// given class or instance.
// XPCNativeScriptableInfo is a trivial wrapper for nsIXPCScriptable which
// should be removed eventually.
class XPCNativeScriptableInfo final
{
@ -1505,18 +1454,15 @@ public:
nsIXPCScriptable*
GetCallback() const { return mCallback; }
const XPCNativeScriptableFlags&
GetFlags() const { return mShared->GetFlags(); }
XPCNativeScriptableFlags
GetFlags() const { return XPCNativeScriptableFlags(mCallback->GetScriptableFlags()); }
const JSClass*
GetJSClass() { return mShared->GetJSClass(); }
void
SetScriptableShared(already_AddRefed<XPCNativeScriptableShared>&& shared) { mShared = shared; }
GetJSClass() { return Jsvalify(mCallback->GetClass()); }
protected:
explicit XPCNativeScriptableInfo(nsIXPCScriptable* scriptable)
: mCallback(scriptable)
explicit XPCNativeScriptableInfo(nsIXPCScriptable* aCallback)
: mCallback(aCallback)
{
MOZ_COUNT_CTOR(XPCNativeScriptableInfo);
}
@ -1533,7 +1479,6 @@ private:
private:
nsCOMPtr<nsIXPCScriptable> mCallback;
RefPtr<XPCNativeScriptableShared> mShared;
};
/***************************************************************************/
@ -1570,6 +1515,8 @@ public:
SetFlags(const XPCNativeScriptableFlags& flags) {mFlags = flags;}
private:
// XXX: the flags are the same as the ones gettable from the callback. This
// redundancy should be removed eventually.
nsCOMPtr<nsIXPCScriptable> mCallback;
XPCNativeScriptableFlags mFlags;
};

View File

@ -162,6 +162,8 @@ struct RuntimeStats;
} // namespace JS
#define XPC_WRAPPER_FLAGS (JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE)
#define XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(n) \
JSCLASS_DOM_GLOBAL | JSCLASS_HAS_PRIVATE | \
JSCLASS_PRIVATE_IS_NSISUPPORTS | \

View File

@ -18,6 +18,8 @@
#include "jsapi.h"
#include "xpc_make_class.h"
namespace mozilla {
namespace storage {

View File

@ -16,6 +16,8 @@
#include "mozStorageAsyncStatementParams.h"
#include "mozIStorageStatement.h"
#include "xpc_make_class.h"
namespace mozilla {
namespace storage {

View File

@ -19,6 +19,8 @@
#include "jsapi.h"
#include "xpc_make_class.h"
namespace mozilla {
namespace storage {

View File

@ -12,6 +12,8 @@
#include "jsapi.h"
#include "xpc_make_class.h"
namespace mozilla {
namespace storage {

View File

@ -12,6 +12,7 @@
#include "mozilla/Preferences.h"
#include "mozJSComponentLoader.h"
#include "nsZipArchive.h"
#include "xpc_make_class.h"
#define JSCTYPES_CONTRACTID \
"@mozilla.org/jsctypes;1"

View File

@ -10,6 +10,7 @@
#include "mozilla/Preferences.h"
#include "mozJSComponentLoader.h"
#include "nsZipArchive.h"
#include "xpc_make_class.h"
#define JSPERF_CONTRACTID \
"@mozilla.org/jsperf;1"

View File

@ -9,6 +9,7 @@
#include "nsMemory.h"
#include "nsString.h"
#include "nsNativeCharsetUtils.h"
#include "xpc_make_class.h"
#define JSREFLECT_CONTRACTID \
"@mozilla.org/jsreflect;1"