Bug 1541513 part 6. Stop using AutoJSContext in XPCWrappedNativeInfo. r=mccr8

Differential Revision: https://phabricator.services.mozilla.com/D26006

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Boris Zbarsky 2019-04-04 13:14:40 +00:00
parent 10328fb59d
commit cb3918b746
9 changed files with 74 additions and 60 deletions

View File

@ -997,7 +997,7 @@ bool XPCConvert::NativeInterface2JSObject(JSContext* cx, MutableHandleValue d,
} }
// Go ahead and create an XPCWrappedNative for this object. // Go ahead and create an XPCWrappedNative for this object.
RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(iid); RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(cx, iid);
if (!iface) { if (!iface) {
return false; return false;
} }

View File

@ -201,7 +201,7 @@ inline size_t XPCNativeInterface::OffsetOfMembers() {
inline XPCNativeSetKey::XPCNativeSetKey(XPCNativeSet* baseSet, inline XPCNativeSetKey::XPCNativeSetKey(XPCNativeSet* baseSet,
XPCNativeInterface* addition) XPCNativeInterface* addition)
: mBaseSet(baseSet), mAddition(addition) { : mCx(nullptr), mBaseSet(baseSet), mAddition(addition) {
MOZ_ASSERT(mBaseSet); MOZ_ASSERT(mBaseSet);
MOZ_ASSERT(mAddition); MOZ_ASSERT(mAddition);
MOZ_ASSERT(!mBaseSet->HasInterface(mAddition)); MOZ_ASSERT(!mBaseSet->HasInterface(mAddition));

View File

@ -430,7 +430,7 @@ nsresult HasInstance(JSContext* cx, HandleObject objArg, const nsID* iid,
// preserve that behavior. This is just a compatibility hack, so we don't // preserve that behavior. This is just a compatibility hack, so we don't
// really care if it fails. // really care if it fails.
if (IS_WN_REFLECTOR(obj)) { if (IS_WN_REFLECTOR(obj)) {
(void)XPCWrappedNative::Get(obj)->FindTearOff(*iid); (void)XPCWrappedNative::Get(obj)->FindTearOff(cx, *iid);
} }
return NS_OK; return NS_OK;

View File

@ -247,7 +247,7 @@ nsresult XPCWrappedNative::WrapNewGlobal(xpcObjectHelper& nativeHelper,
// since we're dealing with nsISupports. But lots of code expects tearoffs // since we're dealing with nsISupports. But lots of code expects tearoffs
// to exist for everything, so we just follow along. // to exist for everything, so we just follow along.
RefPtr<XPCNativeInterface> iface = RefPtr<XPCNativeInterface> iface =
XPCNativeInterface::GetNewOrUsed(&NS_GET_IID(nsISupports)); XPCNativeInterface::GetNewOrUsed(cx, &NS_GET_IID(nsISupports));
MOZ_ASSERT(iface); MOZ_ASSERT(iface);
nsresult status; nsresult status;
success = wrapper->FindTearOff(iface, false, &status); success = wrapper->FindTearOff(iface, false, &status);
@ -412,11 +412,11 @@ nsresult XPCWrappedNative::GetNewOrUsed(xpcObjectHelper& helper,
} else { } else {
RefPtr<XPCNativeInterface> iface = Interface; RefPtr<XPCNativeInterface> iface = Interface;
if (!iface) { if (!iface) {
iface = XPCNativeInterface::GetISupports(); iface = XPCNativeInterface::GetISupports(cx);
} }
XPCNativeSetKey key(iface); XPCNativeSetKey key(cx, iface);
RefPtr<XPCNativeSet> set = XPCNativeSet::GetNewOrUsed(&key); RefPtr<XPCNativeSet> set = XPCNativeSet::GetNewOrUsed(cx, &key);
if (!set) { if (!set) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -854,10 +854,11 @@ class MOZ_STACK_CLASS AutoClonePrivateGuard {
RootedObject mNewReflector; RootedObject mNewReflector;
}; };
bool XPCWrappedNative::ExtendSet(XPCNativeInterface* aInterface) { bool XPCWrappedNative::ExtendSet(JSContext* aCx,
XPCNativeInterface* aInterface) {
if (!mSet->HasInterface(aInterface)) { if (!mSet->HasInterface(aInterface)) {
XPCNativeSetKey key(mSet, aInterface); XPCNativeSetKey key(mSet, aInterface);
RefPtr<XPCNativeSet> newSet = XPCNativeSet::GetNewOrUsed(&key); RefPtr<XPCNativeSet> newSet = XPCNativeSet::GetNewOrUsed(aCx, &key);
if (!newSet) { if (!newSet) {
return false; return false;
} }
@ -927,8 +928,9 @@ XPCWrappedNativeTearOff* XPCWrappedNative::FindTearOff(
return to; return to;
} }
XPCWrappedNativeTearOff* XPCWrappedNative::FindTearOff(const nsIID& iid) { XPCWrappedNativeTearOff* XPCWrappedNative::FindTearOff(JSContext* cx,
RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(&iid); const nsIID& iid) {
RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(cx, &iid);
return iface ? FindTearOff(iface) : nullptr; return iface ? FindTearOff(iface) : nullptr;
} }
@ -1012,7 +1014,7 @@ nsresult XPCWrappedNative::InitTearOff(XPCWrappedNativeTearOff* aTearOff,
// because we unlocked and called out in the interim and the result of the // because we unlocked and called out in the interim and the result of the
// previous call might not be correct anymore. // previous call might not be correct anymore.
if (!mSet->HasInterface(aInterface) && !ExtendSet(aInterface)) { if (!mSet->HasInterface(aInterface) && !ExtendSet(cx, aInterface)) {
aTearOff->SetInterface(nullptr); aTearOff->SetInterface(nullptr);
return NS_ERROR_NO_INTERFACE; return NS_ERROR_NO_INTERFACE;
} }
@ -1715,7 +1717,7 @@ NS_IMETHODIMP XPCWrappedNative::DebugDump(int16_t depth) {
/***************************************************************************/ /***************************************************************************/
char* XPCWrappedNative::ToString( char* XPCWrappedNative::ToString(
XPCWrappedNativeTearOff* to /* = nullptr */) const { JSContext* cx, XPCWrappedNativeTearOff* to /* = nullptr */) const {
#ifdef DEBUG #ifdef DEBUG
# define FMT_ADDR " @ 0x%p" # define FMT_ADDR " @ 0x%p"
# define FMT_STR(str) str # define FMT_STR(str) str
@ -1740,7 +1742,7 @@ char* XPCWrappedNative::ToString(
} else if (!name) { } else if (!name) {
XPCNativeSet* set = GetSet(); XPCNativeSet* set = GetSet();
XPCNativeInterface** array = set->GetInterfaceArray(); XPCNativeInterface** array = set->GetInterfaceArray();
RefPtr<XPCNativeInterface> isupp = XPCNativeInterface::GetISupports(); RefPtr<XPCNativeInterface> isupp = XPCNativeInterface::GetISupports(cx);
uint16_t count = set->GetInterfaceCount(); uint16_t count = set->GetInterfaceCount();
if (count == 1) { if (count == 1) {

View File

@ -118,7 +118,7 @@ XPCNativeInterface::~XPCNativeInterface() {
// static // static
already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetNewOrUsed( already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetNewOrUsed(
const nsIID* iid) { JSContext* cx, const nsIID* iid) {
RefPtr<XPCNativeInterface> iface; RefPtr<XPCNativeInterface> iface;
XPCJSRuntime* rt = XPCJSRuntime::Get(); XPCJSRuntime* rt = XPCJSRuntime::Get();
@ -138,7 +138,7 @@ already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetNewOrUsed(
return nullptr; return nullptr;
} }
iface = NewInstance(info); iface = NewInstance(cx, info);
if (!iface) { if (!iface) {
return nullptr; return nullptr;
} }
@ -156,7 +156,7 @@ already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetNewOrUsed(
// static // static
already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetNewOrUsed( already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetNewOrUsed(
const nsXPTInterfaceInfo* info) { JSContext* cx, const nsXPTInterfaceInfo* info) {
RefPtr<XPCNativeInterface> iface; RefPtr<XPCNativeInterface> iface;
XPCJSRuntime* rt = XPCJSRuntime::Get(); XPCJSRuntime* rt = XPCJSRuntime::Get();
@ -172,7 +172,7 @@ already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetNewOrUsed(
return iface.forget(); return iface.forget();
} }
iface = NewInstance(info); iface = NewInstance(cx, info);
if (!iface) { if (!iface) {
return nullptr; return nullptr;
} }
@ -190,21 +190,21 @@ already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetNewOrUsed(
// static // static
already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetNewOrUsed( already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetNewOrUsed(
const char* name) { JSContext* cx, const char* name) {
const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByName(name); const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByName(name);
return info ? GetNewOrUsed(info) : nullptr; return info ? GetNewOrUsed(cx, info) : nullptr;
} }
// static // static
already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetISupports() { already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetISupports(
JSContext* cx) {
// XXX We should optimize this to cache this common XPCNativeInterface. // XXX We should optimize this to cache this common XPCNativeInterface.
return GetNewOrUsed(&NS_GET_IID(nsISupports)); return GetNewOrUsed(cx, &NS_GET_IID(nsISupports));
} }
// static // static
already_AddRefed<XPCNativeInterface> XPCNativeInterface::NewInstance( already_AddRefed<XPCNativeInterface> XPCNativeInterface::NewInstance(
const nsXPTInterfaceInfo* aInfo) { JSContext* cx, const nsXPTInterfaceInfo* aInfo) {
AutoJSContext cx;
static const uint16_t MAX_LOCAL_MEMBER_COUNT = 16; static const uint16_t MAX_LOCAL_MEMBER_COUNT = 16;
XPCNativeMember local_members[MAX_LOCAL_MEMBER_COUNT]; XPCNativeMember local_members[MAX_LOCAL_MEMBER_COUNT];
RefPtr<XPCNativeInterface> obj; RefPtr<XPCNativeInterface> obj;
@ -429,6 +429,7 @@ PLDHashNumber XPCNativeSetKey::Hash() const {
PLDHashNumber h = 0; PLDHashNumber h = 0;
if (mBaseSet) { if (mBaseSet) {
// If we ever start using mCx here, adjust the constructors accordingly.
XPCNativeInterface** current = mBaseSet->GetInterfaceArray(); XPCNativeInterface** current = mBaseSet->GetInterfaceArray();
uint16_t count = mBaseSet->GetInterfaceCount(); uint16_t count = mBaseSet->GetInterfaceCount();
for (uint16_t i = 0; i < count; i++) { for (uint16_t i = 0; i < count; i++) {
@ -436,7 +437,7 @@ PLDHashNumber XPCNativeSetKey::Hash() const {
} }
} else { } else {
// A newly created set will contain nsISupports first... // A newly created set will contain nsISupports first...
RefPtr<XPCNativeInterface> isupp = XPCNativeInterface::GetISupports(); RefPtr<XPCNativeInterface> isupp = XPCNativeInterface::GetISupports(mCx);
h ^= HashPointer(isupp); h ^= HashPointer(isupp);
// ...but no more than once. // ...but no more than once.
@ -458,6 +459,7 @@ PLDHashNumber XPCNativeSetKey::Hash() const {
XPCNativeSet::~XPCNativeSet() { XPCNativeSet::~XPCNativeSet() {
// Remove |this| before we clear the interfaces to ensure that the // Remove |this| before we clear the interfaces to ensure that the
// hashtable look up is correct. // hashtable look up is correct.
XPCJSRuntime::Get()->GetNativeSetMap()->Remove(this); XPCJSRuntime::Get()->GetNativeSetMap()->Remove(this);
for (int i = 0; i < mInterfaceCount; i++) { for (int i = 0; i < mInterfaceCount; i++) {
@ -466,13 +468,14 @@ XPCNativeSet::~XPCNativeSet() {
} }
// static // static
already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(const nsIID* iid) { already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(JSContext* cx,
RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(iid); const nsIID* iid) {
RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(cx, iid);
if (!iface) { if (!iface) {
return nullptr; return nullptr;
} }
XPCNativeSetKey key(iface); XPCNativeSetKey key(cx, iface);
XPCJSRuntime* xpcrt = XPCJSRuntime::Get(); XPCJSRuntime* xpcrt = XPCJSRuntime::Get();
NativeSetMap* map = xpcrt->GetNativeSetMap(); NativeSetMap* map = xpcrt->GetNativeSetMap();
@ -486,7 +489,7 @@ already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(const nsIID* iid) {
return set.forget(); return set.forget();
} }
set = NewInstance({iface.forget()}); set = NewInstance(cx, {iface.forget()});
if (!set) { if (!set) {
return nullptr; return nullptr;
} }
@ -501,7 +504,7 @@ already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(const nsIID* iid) {
// static // static
already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed( already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(
nsIClassInfo* classInfo) { JSContext* cx, nsIClassInfo* classInfo) {
XPCJSRuntime* xpcrt = XPCJSRuntime::Get(); XPCJSRuntime* xpcrt = XPCJSRuntime::Get();
ClassInfo2NativeSetMap* map = xpcrt->GetClassInfo2NativeSetMap(); ClassInfo2NativeSetMap* map = xpcrt->GetClassInfo2NativeSetMap();
if (!map) { if (!map) {
@ -527,7 +530,8 @@ already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(
// Try to look up each IID's XPCNativeInterface object. // Try to look up each IID's XPCNativeInterface object.
nsTArray<RefPtr<XPCNativeInterface>> interfaces(iids.Length()); nsTArray<RefPtr<XPCNativeInterface>> interfaces(iids.Length());
for (auto& iid : iids) { for (auto& iid : iids) {
RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(&iid); RefPtr<XPCNativeInterface> iface =
XPCNativeInterface::GetNewOrUsed(cx, &iid);
if (iface) { if (iface) {
interfaces.AppendElement(iface.forget()); interfaces.AppendElement(iface.forget());
} }
@ -535,7 +539,7 @@ already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(
// Build a set from the interfaces specified here. // Build a set from the interfaces specified here.
if (interfaces.Length() > 0) { if (interfaces.Length() > 0) {
set = NewInstance(std::move(interfaces)); set = NewInstance(cx, std::move(interfaces));
if (set) { if (set) {
NativeSetMap* map2 = xpcrt->GetNativeSetMap(); NativeSetMap* map2 = xpcrt->GetNativeSetMap();
if (!map2) { if (!map2) {
@ -556,7 +560,7 @@ already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(
} }
} }
} else { } else {
set = GetNewOrUsed(&NS_GET_IID(nsISupports)); set = GetNewOrUsed(cx, &NS_GET_IID(nsISupports));
} }
if (set) { if (set) {
@ -582,7 +586,7 @@ void XPCNativeSet::ClearCacheEntryForClassInfo(nsIClassInfo* classInfo) {
// static // static
already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed( already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(
XPCNativeSetKey* key) { JSContext* cx, XPCNativeSetKey* key) {
NativeSetMap* map = XPCJSRuntime::Get()->GetNativeSetMap(); NativeSetMap* map = XPCJSRuntime::Get()->GetNativeSetMap();
if (!map) { if (!map) {
return nullptr; return nullptr;
@ -597,7 +601,7 @@ already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(
if (key->GetBaseSet()) { if (key->GetBaseSet()) {
set = NewInstanceMutate(key); set = NewInstanceMutate(key);
} else { } else {
set = NewInstance({key->GetAddition()}); set = NewInstance(cx, {key->GetAddition()});
} }
if (!set) { if (!set) {
@ -614,7 +618,7 @@ already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(
// static // static
already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed( already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(
XPCNativeSet* firstSet, XPCNativeSet* secondSet, JSContext* cx, XPCNativeSet* firstSet, XPCNativeSet* secondSet,
bool preserveFirstSetOrder) { bool preserveFirstSetOrder) {
// Figure out how many interfaces we'll need in the new set. // Figure out how many interfaces we'll need in the new set.
uint32_t uniqueCount = firstSet->mInterfaceCount; uint32_t uniqueCount = firstSet->mInterfaceCount;
@ -649,7 +653,7 @@ already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(
if (!currentSet->HasInterface(iface)) { if (!currentSet->HasInterface(iface)) {
// Create a new augmented set, inserting this interface at the end. // Create a new augmented set, inserting this interface at the end.
XPCNativeSetKey key(currentSet, iface); XPCNativeSetKey key(currentSet, iface);
currentSet = XPCNativeSet::GetNewOrUsed(&key); currentSet = XPCNativeSet::GetNewOrUsed(cx, &key);
if (!currentSet) { if (!currentSet) {
return nullptr; return nullptr;
} }
@ -663,7 +667,7 @@ already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(
// static // static
already_AddRefed<XPCNativeSet> XPCNativeSet::NewInstance( already_AddRefed<XPCNativeSet> XPCNativeSet::NewInstance(
nsTArray<RefPtr<XPCNativeInterface>>&& array) { JSContext* cx, nsTArray<RefPtr<XPCNativeInterface>>&& array) {
if (array.Length() == 0) { if (array.Length() == 0) {
return nullptr; return nullptr;
} }
@ -673,7 +677,7 @@ already_AddRefed<XPCNativeSet> XPCNativeSet::NewInstance(
// This is the place where we impose that rule - even if given inputs // This is the place where we impose that rule - even if given inputs
// that don't exactly follow the rule. // that don't exactly follow the rule.
RefPtr<XPCNativeInterface> isup = XPCNativeInterface::GetISupports(); RefPtr<XPCNativeInterface> isup = XPCNativeInterface::GetISupports(cx);
uint16_t slots = array.Length() + 1; uint16_t slots = array.Length() + 1;
for (auto key = array.begin(); key != array.end(); key++) { for (auto key = array.begin(); key != array.end(); key++) {

View File

@ -43,7 +43,7 @@ static bool ToStringGuts(XPCCallContext& ccx) {
XPCWrappedNative* wrapper = ccx.GetWrapper(); XPCWrappedNative* wrapper = ccx.GetWrapper();
if (wrapper) { if (wrapper) {
sz.reset(wrapper->ToString(ccx.GetTearOff())); sz.reset(wrapper->ToString(ccx, ccx.GetTearOff()));
} else { } else {
sz = JS_smprintf("[xpconnect wrapped native prototype]"); sz = JS_smprintf("[xpconnect wrapped native prototype]");
} }
@ -349,7 +349,7 @@ static bool DefinePropertyIfFound(
break; break;
} }
iface2 = XPCNativeInterface::GetNewOrUsed(name.get()); iface2 = XPCNativeInterface::GetNewOrUsed(ccx, name.get());
if (!iface2) { if (!iface2) {
break; break;
} }

View File

@ -111,7 +111,7 @@ XPCWrappedNativeProto* XPCWrappedNativeProto::GetNewOrUsed(
return proto; return proto;
} }
RefPtr<XPCNativeSet> set = XPCNativeSet::GetNewOrUsed(classInfo); RefPtr<XPCNativeSet> set = XPCNativeSet::GetNewOrUsed(cx, classInfo);
if (!set) { if (!set) {
return nullptr; return nullptr;
} }

View File

@ -1055,11 +1055,13 @@ class XPCNativeInterface final {
NS_INLINE_DECL_REFCOUNTING_WITH_DESTROY(XPCNativeInterface, NS_INLINE_DECL_REFCOUNTING_WITH_DESTROY(XPCNativeInterface,
DestroyInstance(this)) DestroyInstance(this))
static already_AddRefed<XPCNativeInterface> GetNewOrUsed(const nsIID* iid); static already_AddRefed<XPCNativeInterface> GetNewOrUsed(JSContext* cx,
const nsIID* iid);
static already_AddRefed<XPCNativeInterface> GetNewOrUsed( static already_AddRefed<XPCNativeInterface> GetNewOrUsed(
const nsXPTInterfaceInfo* info); JSContext* cx, const nsXPTInterfaceInfo* info);
static already_AddRefed<XPCNativeInterface> GetNewOrUsed(const char* name); static already_AddRefed<XPCNativeInterface> GetNewOrUsed(JSContext* cx,
static already_AddRefed<XPCNativeInterface> GetISupports(); const char* name);
static already_AddRefed<XPCNativeInterface> GetISupports(JSContext* cx);
inline const nsXPTInterfaceInfo* GetInterfaceInfo() const { return mInfo; } inline const nsXPTInterfaceInfo* GetInterfaceInfo() const { return mInfo; }
inline jsid GetName() const { return mName; } inline jsid GetName() const { return mName; }
@ -1083,7 +1085,7 @@ class XPCNativeInterface final {
protected: protected:
static already_AddRefed<XPCNativeInterface> NewInstance( static already_AddRefed<XPCNativeInterface> NewInstance(
const nsXPTInterfaceInfo* aInfo); JSContext* cx, const nsXPTInterfaceInfo* aInfo);
XPCNativeInterface() = delete; XPCNativeInterface() = delete;
XPCNativeInterface(const nsXPTInterfaceInfo* aInfo, jsid aName) XPCNativeInterface(const nsXPTInterfaceInfo* aInfo, jsid aName)
@ -1113,14 +1115,16 @@ class MOZ_STACK_CLASS XPCNativeSetKey final {
public: public:
// This represents an existing set |baseSet|. // This represents an existing set |baseSet|.
explicit XPCNativeSetKey(XPCNativeSet* baseSet) explicit XPCNativeSetKey(XPCNativeSet* baseSet)
: mBaseSet(baseSet), mAddition(nullptr) { : mCx(nullptr), mBaseSet(baseSet), mAddition(nullptr) {
MOZ_ASSERT(baseSet); MOZ_ASSERT(baseSet);
} }
// This represents a new set containing only nsISupports and // This represents a new set containing only nsISupports and
// |addition|. // |addition|. This needs a JSContext because it may need to
explicit XPCNativeSetKey(XPCNativeInterface* addition) // construct some data structures that need one to construct them.
: mBaseSet(nullptr), mAddition(addition) { explicit XPCNativeSetKey(JSContext* cx, XPCNativeInterface* addition)
: mCx(cx), mBaseSet(nullptr), mAddition(addition) {
MOZ_ASSERT(cx);
MOZ_ASSERT(addition); MOZ_ASSERT(addition);
} }
@ -1138,6 +1142,7 @@ class MOZ_STACK_CLASS XPCNativeSetKey final {
// Allow shallow copy // Allow shallow copy
private: private:
JSContext* mCx;
RefPtr<XPCNativeSet> mBaseSet; RefPtr<XPCNativeSet> mBaseSet;
RefPtr<XPCNativeInterface> mAddition; RefPtr<XPCNativeInterface> mAddition;
}; };
@ -1149,9 +1154,12 @@ class XPCNativeSet final {
public: public:
NS_INLINE_DECL_REFCOUNTING_WITH_DESTROY(XPCNativeSet, DestroyInstance(this)) NS_INLINE_DECL_REFCOUNTING_WITH_DESTROY(XPCNativeSet, DestroyInstance(this))
static already_AddRefed<XPCNativeSet> GetNewOrUsed(const nsIID* iid); static already_AddRefed<XPCNativeSet> GetNewOrUsed(JSContext* cx,
static already_AddRefed<XPCNativeSet> GetNewOrUsed(nsIClassInfo* classInfo); const nsIID* iid);
static already_AddRefed<XPCNativeSet> GetNewOrUsed(XPCNativeSetKey* key); static already_AddRefed<XPCNativeSet> GetNewOrUsed(JSContext* cx,
nsIClassInfo* classInfo);
static already_AddRefed<XPCNativeSet> GetNewOrUsed(JSContext* cx,
XPCNativeSetKey* key);
// This generates a union set. // This generates a union set.
// //
@ -1161,7 +1169,7 @@ class XPCNativeSet final {
// |firstSet|, we return |secondSet| without worrying about whether the // |firstSet|, we return |secondSet| without worrying about whether the
// ordering might differ from |firstSet|. // ordering might differ from |firstSet|.
static already_AddRefed<XPCNativeSet> GetNewOrUsed( static already_AddRefed<XPCNativeSet> GetNewOrUsed(
XPCNativeSet* firstSet, XPCNativeSet* secondSet, JSContext* cx, XPCNativeSet* firstSet, XPCNativeSet* secondSet,
bool preserveFirstSetOrder); bool preserveFirstSetOrder);
static void ClearCacheEntryForClassInfo(nsIClassInfo* classInfo); static void ClearCacheEntryForClassInfo(nsIClassInfo* classInfo);
@ -1200,7 +1208,7 @@ class XPCNativeSet final {
protected: protected:
static already_AddRefed<XPCNativeSet> NewInstance( static already_AddRefed<XPCNativeSet> NewInstance(
nsTArray<RefPtr<XPCNativeInterface>>&& array); JSContext* cx, nsTArray<RefPtr<XPCNativeInterface>>&& array);
static already_AddRefed<XPCNativeSet> NewInstanceMutate(XPCNativeSetKey* key); static already_AddRefed<XPCNativeSet> NewInstanceMutate(XPCNativeSetKey* key);
XPCNativeSet() : mMemberCount(0), mInterfaceCount(0) {} XPCNativeSet() : mMemberCount(0), mInterfaceCount(0) {}
@ -1488,7 +1496,7 @@ class XPCWrappedNative final : public nsIXPConnectWrappedNative {
XPCWrappedNativeTearOff* FindTearOff(XPCNativeInterface* aInterface, XPCWrappedNativeTearOff* FindTearOff(XPCNativeInterface* aInterface,
bool needJSObject = false, bool needJSObject = false,
nsresult* pError = nullptr); nsresult* pError = nullptr);
XPCWrappedNativeTearOff* FindTearOff(const nsIID& iid); XPCWrappedNativeTearOff* FindTearOff(JSContext* cx, const nsIID& iid);
void Mark() const {} void Mark() const {}
@ -1521,7 +1529,7 @@ class XPCWrappedNative final : public nsIXPConnectWrappedNative {
// Returns a string that should be freed with js_free, or nullptr on // Returns a string that should be freed with js_free, or nullptr on
// failure. // failure.
char* ToString(XPCWrappedNativeTearOff* to = nullptr) const; char* ToString(JSContext* cx, XPCWrappedNativeTearOff* to = nullptr) const;
static nsIXPCScriptable* GatherProtoScriptable(nsIClassInfo* classInfo); static nsIXPCScriptable* GatherProtoScriptable(nsIClassInfo* classInfo);
@ -1555,7 +1563,7 @@ class XPCWrappedNative final : public nsIXPConnectWrappedNative {
bool Init(nsIXPCScriptable* scriptable); bool Init(nsIXPCScriptable* scriptable);
bool FinishInit(); bool FinishInit();
bool ExtendSet(XPCNativeInterface* aInterface); bool ExtendSet(JSContext* aCx, XPCNativeInterface* aInterface);
nsresult InitTearOff(XPCWrappedNativeTearOff* aTearOff, nsresult InitTearOff(XPCWrappedNativeTearOff* aTearOff,
XPCNativeInterface* aInterface, bool needJSObject); XPCNativeInterface* aInterface, bool needJSObject);

View File

@ -301,7 +301,7 @@ void WrapperFactory::PrepareForWrapping(JSContext* cx, HandleObject scope,
// to do this cleverly in the common case to avoid too much overhead. // to do this cleverly in the common case to avoid too much overhead.
XPCWrappedNative* newwn = XPCWrappedNative::Get(obj); XPCWrappedNative* newwn = XPCWrappedNative::Get(obj);
RefPtr<XPCNativeSet> unionSet = RefPtr<XPCNativeSet> unionSet =
XPCNativeSet::GetNewOrUsed(newwn->GetSet(), wn->GetSet(), false); XPCNativeSet::GetNewOrUsed(cx, newwn->GetSet(), wn->GetSet(), false);
if (!unionSet) { if (!unionSet) {
return; return;
} }