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.
RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(iid);
RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(cx, iid);
if (!iface) {
return false;
}

View File

@ -201,7 +201,7 @@ inline size_t XPCNativeInterface::OffsetOfMembers() {
inline XPCNativeSetKey::XPCNativeSetKey(XPCNativeSet* baseSet,
XPCNativeInterface* addition)
: mBaseSet(baseSet), mAddition(addition) {
: mCx(nullptr), mBaseSet(baseSet), mAddition(addition) {
MOZ_ASSERT(mBaseSet);
MOZ_ASSERT(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
// really care if it fails.
if (IS_WN_REFLECTOR(obj)) {
(void)XPCWrappedNative::Get(obj)->FindTearOff(*iid);
(void)XPCWrappedNative::Get(obj)->FindTearOff(cx, *iid);
}
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
// to exist for everything, so we just follow along.
RefPtr<XPCNativeInterface> iface =
XPCNativeInterface::GetNewOrUsed(&NS_GET_IID(nsISupports));
XPCNativeInterface::GetNewOrUsed(cx, &NS_GET_IID(nsISupports));
MOZ_ASSERT(iface);
nsresult status;
success = wrapper->FindTearOff(iface, false, &status);
@ -412,11 +412,11 @@ nsresult XPCWrappedNative::GetNewOrUsed(xpcObjectHelper& helper,
} else {
RefPtr<XPCNativeInterface> iface = Interface;
if (!iface) {
iface = XPCNativeInterface::GetISupports();
iface = XPCNativeInterface::GetISupports(cx);
}
XPCNativeSetKey key(iface);
RefPtr<XPCNativeSet> set = XPCNativeSet::GetNewOrUsed(&key);
XPCNativeSetKey key(cx, iface);
RefPtr<XPCNativeSet> set = XPCNativeSet::GetNewOrUsed(cx, &key);
if (!set) {
return NS_ERROR_FAILURE;
@ -854,10 +854,11 @@ class MOZ_STACK_CLASS AutoClonePrivateGuard {
RootedObject mNewReflector;
};
bool XPCWrappedNative::ExtendSet(XPCNativeInterface* aInterface) {
bool XPCWrappedNative::ExtendSet(JSContext* aCx,
XPCNativeInterface* aInterface) {
if (!mSet->HasInterface(aInterface)) {
XPCNativeSetKey key(mSet, aInterface);
RefPtr<XPCNativeSet> newSet = XPCNativeSet::GetNewOrUsed(&key);
RefPtr<XPCNativeSet> newSet = XPCNativeSet::GetNewOrUsed(aCx, &key);
if (!newSet) {
return false;
}
@ -927,8 +928,9 @@ XPCWrappedNativeTearOff* XPCWrappedNative::FindTearOff(
return to;
}
XPCWrappedNativeTearOff* XPCWrappedNative::FindTearOff(const nsIID& iid) {
RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(&iid);
XPCWrappedNativeTearOff* XPCWrappedNative::FindTearOff(JSContext* cx,
const nsIID& iid) {
RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(cx, &iid);
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
// previous call might not be correct anymore.
if (!mSet->HasInterface(aInterface) && !ExtendSet(aInterface)) {
if (!mSet->HasInterface(aInterface) && !ExtendSet(cx, aInterface)) {
aTearOff->SetInterface(nullptr);
return NS_ERROR_NO_INTERFACE;
}
@ -1715,7 +1717,7 @@ NS_IMETHODIMP XPCWrappedNative::DebugDump(int16_t depth) {
/***************************************************************************/
char* XPCWrappedNative::ToString(
XPCWrappedNativeTearOff* to /* = nullptr */) const {
JSContext* cx, XPCWrappedNativeTearOff* to /* = nullptr */) const {
#ifdef DEBUG
# define FMT_ADDR " @ 0x%p"
# define FMT_STR(str) str
@ -1740,7 +1742,7 @@ char* XPCWrappedNative::ToString(
} else if (!name) {
XPCNativeSet* set = GetSet();
XPCNativeInterface** array = set->GetInterfaceArray();
RefPtr<XPCNativeInterface> isupp = XPCNativeInterface::GetISupports();
RefPtr<XPCNativeInterface> isupp = XPCNativeInterface::GetISupports(cx);
uint16_t count = set->GetInterfaceCount();
if (count == 1) {

View File

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

View File

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

View File

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

View File

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