Bug 1526382 - Part 2: Make nsIClassInfo use Array<nsIIDRef> for 'interfaces', r=mccr8

This is a follow-up to the previous part, which actually changes one of
these callers to use Array<nsIIDRef> instead of [array] nsIIDPtr.

From doing this patch, it seems like we should consider changing
the type `nsIIDRef` to instead simply be `nsIID`, and treat it more like
the `AString` types from the POV of XPIDL. `nsIIDPtr` would then
continue to exist for backwards compatibility, but we can probably
remove almost all current consumers over time.

Depends on D19175

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nika Layzell 2019-02-13 21:42:08 +00:00
Родитель 1c2a9c2b07
Коммит dbec7d4975
22 изменённых файлов: 141 добавлений и 224 удалений

Просмотреть файл

@ -166,9 +166,8 @@ BlobURL::Mutate(nsIURIMutator** aMutator) {
// nsIClassInfo methods:
NS_IMETHODIMP
BlobURL::GetInterfaces(uint32_t* count, nsIID*** array) {
*count = 0;
*array = nullptr;
BlobURL::GetInterfaces(nsTArray<nsIID>& array) {
array.Clear();
return NS_OK;
}

Просмотреть файл

@ -118,13 +118,9 @@ class nsXPCComponents_Interfaces final : public nsIXPCComponents_Interfaces,
};
NS_IMETHODIMP
nsXPCComponents_Interfaces::GetInterfaces(uint32_t* aCount, nsIID*** aArray) {
*aCount = 2;
nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
*aArray = array;
array[0] = NS_GET_IID(nsIXPCComponents_Interfaces).Clone();
array[1] = NS_GET_IID(nsIXPCScriptable).Clone();
nsXPCComponents_Interfaces::GetInterfaces(nsTArray<nsIID>& aArray) {
aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCComponents_Interfaces),
NS_GET_IID(nsIXPCScriptable)};
return NS_OK;
}
@ -275,13 +271,9 @@ class nsXPCComponents_Classes final : public nsIXPCComponents_Classes,
/***************************************************************************/
NS_IMETHODIMP
nsXPCComponents_Classes::GetInterfaces(uint32_t* aCount, nsIID*** aArray) {
*aCount = 2;
nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
*aArray = array;
array[0] = NS_GET_IID(nsIXPCComponents_Classes).Clone();
array[1] = NS_GET_IID(nsIXPCScriptable).Clone();
nsXPCComponents_Classes::GetInterfaces(nsTArray<nsIID>& aArray) {
aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCComponents_Classes),
NS_GET_IID(nsIXPCScriptable)};
return NS_OK;
}
@ -432,13 +424,9 @@ class nsXPCComponents_Results final : public nsIXPCComponents_Results,
/***************************************************************************/
NS_IMETHODIMP
nsXPCComponents_Results::GetInterfaces(uint32_t* aCount, nsIID*** aArray) {
*aCount = 2;
nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
*aArray = array;
array[0] = NS_GET_IID(nsIXPCComponents_Results).Clone();
array[1] = NS_GET_IID(nsIXPCScriptable).Clone();
nsXPCComponents_Results::GetInterfaces(nsTArray<nsIID>& aArray) {
aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCComponents_Results),
NS_GET_IID(nsIXPCScriptable)};
return NS_OK;
}
@ -577,13 +565,9 @@ class nsXPCComponents_ID final : public nsIXPCComponents_ID,
/***************************************************************************/
NS_IMETHODIMP
nsXPCComponents_ID::GetInterfaces(uint32_t* aCount, nsIID*** aArray) {
*aCount = 2;
nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
*aArray = array;
array[0] = NS_GET_IID(nsIXPCComponents_ID).Clone();
array[1] = NS_GET_IID(nsIXPCScriptable).Clone();
nsXPCComponents_ID::GetInterfaces(nsTArray<nsIID>& aArray) {
aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCComponents_ID),
NS_GET_IID(nsIXPCScriptable)};
return NS_OK;
}
@ -732,13 +716,9 @@ class nsXPCComponents_Exception final : public nsIXPCComponents_Exception,
/***************************************************************************/
NS_IMETHODIMP
nsXPCComponents_Exception::GetInterfaces(uint32_t* aCount, nsIID*** aArray) {
*aCount = 2;
nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
*aArray = array;
array[0] = NS_GET_IID(nsIXPCComponents_Exception).Clone();
array[1] = NS_GET_IID(nsIXPCScriptable).Clone();
nsXPCComponents_Exception::GetInterfaces(nsTArray<nsIID>& aArray) {
aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCComponents_Exception),
NS_GET_IID(nsIXPCScriptable)};
return NS_OK;
}
@ -1027,13 +1007,9 @@ class nsXPCComponents_Constructor final : public nsIXPCComponents_Constructor,
/***************************************************************************/
NS_IMETHODIMP
nsXPCComponents_Constructor::GetInterfaces(uint32_t* aCount, nsIID*** aArray) {
*aCount = 2;
nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
*aArray = array;
array[0] = NS_GET_IID(nsIXPCComponents_Constructor).Clone();
array[1] = NS_GET_IID(nsIXPCScriptable).Clone();
nsXPCComponents_Constructor::GetInterfaces(nsTArray<nsIID>& aArray) {
aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCComponents_Constructor),
NS_GET_IID(nsIXPCScriptable)};
return NS_OK;
}

Просмотреть файл

@ -71,13 +71,9 @@ BackstagePass::NewEnumerate(nsIXPConnectWrappedNative* wrapper, JSContext* cx,
/***************************************************************************/
NS_IMETHODIMP
BackstagePass::GetInterfaces(uint32_t* aCount, nsIID*** aArray) {
*aCount = 2;
nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
*aArray = array;
array[0] = NS_GET_IID(nsIXPCScriptable).Clone();
array[1] = NS_GET_IID(nsIScriptObjectPrincipal).Clone();
BackstagePass::GetInterfaces(nsTArray<nsIID>& aArray) {
aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCScriptable),
NS_GET_IID(nsIScriptObjectPrincipal)};
return NS_OK;
}

Просмотреть файл

@ -513,71 +513,50 @@ already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(
return set.forget();
}
nsIID** iidArray = nullptr;
uint32_t iidCount = 0;
if (NS_FAILED(classInfo->GetInterfaces(&iidCount, &iidArray))) {
AutoTArray<nsIID, 4> iids;
if (NS_FAILED(classInfo->GetInterfaces(iids))) {
// Note: I'm making it OK for this call to fail so that one can add
// nsIClassInfo to classes implemented in script without requiring this
// method to be implemented.
// Make sure these are set correctly...
iidArray = nullptr;
iidCount = 0;
iids.Clear();
}
MOZ_ASSERT((iidCount && iidArray) || !(iidCount || iidArray),
"GetInterfaces returned bad array");
// !!! from here on we only exit through the 'out' label !!!
if (iidCount) {
nsTArray<RefPtr<XPCNativeInterface>> interfaceArray(iidCount);
nsIID** currentIID = iidArray;
for (uint32_t i = 0; i < iidCount; i++) {
nsIID* iid = *(currentIID++);
if (!iid) {
NS_ERROR("Null found in classinfo interface list");
continue;
}
RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(iid);
if (!iface) {
// XXX warn here
continue;
}
interfaceArray.AppendElement(iface.forget());
// 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);
if (iface) {
interfaces.AppendElement(iface.forget());
}
}
if (interfaceArray.Length() > 0) {
set = NewInstance(std::move(interfaceArray));
if (set) {
NativeSetMap* map2 = xpcrt->GetNativeSetMap();
if (!map2) {
goto out;
}
XPCNativeSetKey key(set);
XPCNativeSet* set2 = map2->Add(&key, set);
if (!set2) {
NS_ERROR("failed to add our set!");
set = nullptr;
goto out;
}
// It is okay to find an existing entry here because
// we did not look for one before we called Add().
if (set2 != set) {
set = set2;
}
// Build a set from the interfaces specified here.
if (interfaces.Length() > 0) {
set = NewInstance(std::move(interfaces));
if (set) {
NativeSetMap* map2 = xpcrt->GetNativeSetMap();
if (!map2) {
return set.forget();
}
} else
set = GetNewOrUsed(&NS_GET_IID(nsISupports));
} else
XPCNativeSetKey key(set);
XPCNativeSet* set2 = map2->Add(&key, set);
if (!set2) {
NS_ERROR("failed to add our set");
return nullptr;
}
// It is okay to find an existing entry here because
// we did not look for one before we called Add().
if (set2 != set) {
set = set2;
}
}
} else {
set = GetNewOrUsed(&NS_GET_IID(nsISupports));
}
if (set) {
#ifdef DEBUG
@ -588,11 +567,6 @@ already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(
MOZ_ASSERT(set2 == set, "hashtables inconsistent!");
}
out:
if (iidArray) {
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(iidCount, iidArray);
}
return set.forget();
}

Просмотреть файл

@ -59,11 +59,7 @@ BlobComponent.prototype =
// nsIClassInfo
flags: 0,
getInterfaces: function getInterfaces(aCount) {
var interfaces = [Ci.nsIClassInfo];
aCount.value = interfaces.length;
return interfaces;
},
interfaces: [Ci.nsIClassInfo],
getScriptableHelper: function getScriptableHelper() {
return null;

Просмотреть файл

@ -90,11 +90,7 @@ FileComponent.prototype =
// nsIClassInfo
flags: 0,
getInterfaces: function getInterfaces(aCount) {
var interfaces = [Ci.nsIClassInfo];
aCount.value = interfaces.length;
return interfaces;
},
interfaces: [Ci.nsIClassInfo],
getScriptableHelper: function getScriptableHelper() {
return null;

Просмотреть файл

@ -17,9 +17,8 @@ FooComponent.prototype =
// nsIClassInfo
flags: 0,
getInterfaces: function getInterfaces(aCount) {
get interfaces() {
var interfaces = [Ci.nsIClassInfo];
aCount.value = interfaces.length;
// Guerilla test for line numbers hiding in this method
var threw = true;
@ -27,7 +26,7 @@ FooComponent.prototype =
thereIsNoSuchIdentifier;
threw = false;
} catch (ex) {
Assert.ok(ex.lineNumber == 27);
Assert.ok(ex.lineNumber == 26);
}
Assert.ok(threw);
@ -60,11 +59,7 @@ BarComponent.prototype =
// nsIClassInfo
flags: 0,
getInterfaces: function getInterfaces(aCount) {
var interfaces = [Ci.nsIClassInfo];
aCount.value = interfaces.length;
return interfaces;
},
interfaces: [Ci.nsIClassInfo],
getScriptableHelper: function getScriptableHelper() {
return null;

Просмотреть файл

@ -75,10 +75,10 @@ function run_test() {
// Call getInterfaces to test line numbers in JS components. But as long as
// we're doing that, why not test what it returns too?
// Kind of odd that this is not returning an array containing the
// number... Or for that matter not returning an array containing an object?
var interfaces = foo.getInterfaces({});
Assert.equal(interfaces, Ci.nsIClassInfo.number);
var interfaces = foo.interfaces;
Assert.ok(Array.isArray(interfaces));
Assert.equal(interfaces.length, 1);
Assert.ok(interfaces[0].equals(Ci.nsIClassInfo))
// try to create another component which doesn't directly implement QI
Assert.ok((contractID + "2") in Cc);

Просмотреть файл

@ -136,9 +136,8 @@ nsJARURI::Write(nsIObjectOutputStream *aOutputStream) {
// nsIClassInfo methods:
NS_IMETHODIMP
nsJARURI::GetInterfaces(uint32_t *count, nsIID ***array) {
*count = 0;
*array = nullptr;
nsJARURI::GetInterfaces(nsTArray<nsIID> &array) {
array.Clear();
return NS_OK;
}

Просмотреть файл

@ -607,9 +607,8 @@ nsSimpleURI::GetAsciiHost(nsACString &result) {
//----------------------------------------------------------------------------
NS_IMETHODIMP
nsSimpleURI::GetInterfaces(uint32_t *count, nsIID ***array) {
*count = 0;
*array = nullptr;
nsSimpleURI::GetInterfaces(nsTArray<nsIID> &array) {
array.Clear();
return NS_OK;
}

Просмотреть файл

@ -2944,8 +2944,8 @@ nsSocketTransport::GetInterface(const nsIID &iid, void **result) {
}
NS_IMETHODIMP
nsSocketTransport::GetInterfaces(uint32_t *count, nsIID ***array) {
return NS_CI_INTERFACE_GETTER_NAME(nsSocketTransport)(count, array);
nsSocketTransport::GetInterfaces(nsTArray<nsIID>& array) {
return NS_CI_INTERFACE_GETTER_NAME(nsSocketTransport)(array);
}
NS_IMETHODIMP

Просмотреть файл

@ -3447,9 +3447,8 @@ bool nsStandardURL::Deserialize(const URIParams &aParams) {
//----------------------------------------------------------------------------
NS_IMETHODIMP
nsStandardURL::GetInterfaces(uint32_t *count, nsIID ***array) {
*count = 0;
*array = nullptr;
nsStandardURL::GetInterfaces(nsTArray<nsIID> &array) {
array.Clear();
return NS_OK;
}

Просмотреть файл

@ -516,9 +516,8 @@ TransportSecurityInfo::Read(nsIObjectInputStream* aStream) {
}
NS_IMETHODIMP
TransportSecurityInfo::GetInterfaces(uint32_t* count, nsIID*** array) {
*count = 0;
*array = nullptr;
TransportSecurityInfo::GetInterfaces(nsTArray<nsIID>& array) {
array.Clear();
return NS_OK;
}

Просмотреть файл

@ -1227,9 +1227,8 @@ nsNSSCertificate::Read(nsIObjectInputStream* aStream) {
}
NS_IMETHODIMP
nsNSSCertificate::GetInterfaces(uint32_t* count, nsIID*** array) {
*count = 0;
*array = nullptr;
nsNSSCertificate::GetInterfaces(nsTArray<nsIID>& array) {
array.Clear();
return NS_OK;
}

Просмотреть файл

@ -45,8 +45,8 @@ class AsyncStatementClassInfo : public nsIClassInfo {
NS_DECL_ISUPPORTS_INHERITED
NS_IMETHOD
GetInterfaces(uint32_t *_count, nsIID ***_array) override {
return NS_CI_INTERFACE_GETTER_NAME(AsyncStatement)(_count, _array);
GetInterfaces(nsTArray<nsIID> &_array) override {
return NS_CI_INTERFACE_GETTER_NAME(AsyncStatement)(_array);
}
NS_IMETHOD

Просмотреть файл

@ -47,8 +47,8 @@ class StatementClassInfo : public nsIClassInfo {
NS_DECL_ISUPPORTS_INHERITED
NS_IMETHOD
GetInterfaces(uint32_t *_count, nsIID ***_array) override {
return NS_CI_INTERFACE_GETTER_NAME(Statement)(_count, _array);
GetInterfaces(nsTArray<nsIID> &_array) override {
return NS_CI_INTERFACE_GETTER_NAME(Statement)(_array);
}
NS_IMETHOD

Просмотреть файл

@ -3562,11 +3562,7 @@ function UpdatePrompt(aCallback) {
UpdatePrompt.prototype = {
flags: Ci.nsIClassInfo.SINGLETON,
getScriptableHelper: () => null,
getInterfaces(aCount) {
let interfaces = [Ci.nsISupports, Ci.nsIUpdatePrompt];
aCount.value = interfaces.length;
return interfaces;
},
interfaces: [Ci.nsISupports, Ci.nsIUpdatePrompt],
QueryInterface: ChromeUtils.generateQI([Ci.nsIClassInfo, Ci.nsIUpdatePrompt]),
};

Просмотреть файл

@ -16,8 +16,8 @@ GenericClassInfo::Release() { return 1; }
NS_IMPL_QUERY_INTERFACE(GenericClassInfo, nsIClassInfo)
NS_IMETHODIMP
GenericClassInfo::GetInterfaces(uint32_t* aCount, nsIID*** aArray) {
return mData->getinterfaces(aCount, aArray);
GenericClassInfo::GetInterfaces(nsTArray<nsIID>& aArray) {
return mData->getinterfaces(aArray);
}
NS_IMETHODIMP

Просмотреть файл

@ -89,8 +89,7 @@ class GenericClassInfo : public nsIClassInfo {
struct ClassInfoData {
// This function pointer uses NS_CALLBACK_ because it's always set to an
// NS_IMETHOD function, which uses __stdcall on Win32.
typedef NS_CALLBACK_(nsresult, GetInterfacesProc)(uint32_t* aCountP,
nsIID*** aArray);
typedef NS_CALLBACK_(nsresult, GetInterfacesProc)(nsTArray<nsIID>& aArray);
GetInterfacesProc getinterfaces;
// This function pointer doesn't use NS_CALLBACK_ because it's always set to
@ -113,8 +112,9 @@ class GenericClassInfo : public nsIClassInfo {
#define NS_CLASSINFO_NAME(_class) g##_class##_classInfoGlobal
#define NS_CI_INTERFACE_GETTER_NAME(_class) _class##_GetInterfacesHelper
#define NS_DECL_CI_INTERFACE_GETTER(_class) \
extern NS_IMETHODIMP NS_CI_INTERFACE_GETTER_NAME(_class)(uint32_t*, nsIID***);
#define NS_DECL_CI_INTERFACE_GETTER(_class) \
extern NS_IMETHODIMP NS_CI_INTERFACE_GETTER_NAME(_class)(nsTArray<nsIID> & \
array);
#define NS_IMPL_CLASSINFO(_class, _getscriptablehelper, _flags, _cid) \
NS_DECL_CI_INTERFACE_GETTER(_class) \
@ -135,19 +135,17 @@ class GenericClassInfo : public nsIClassInfo {
foundInterface = NS_CLASSINFO_NAME(_class); \
} else
#define NS_CLASSINFO_HELPER_BEGIN(_class, _c) \
NS_IMETHODIMP \
NS_CI_INTERFACE_GETTER_NAME(_class)(uint32_t * count, nsIID * **array) { \
*count = _c; \
*array = (nsIID**)moz_xmalloc(sizeof(nsIID*) * _c); \
uint32_t i = 0;
#define NS_CLASSINFO_HELPER_BEGIN(_class, _c) \
NS_IMETHODIMP \
NS_CI_INTERFACE_GETTER_NAME(_class)(nsTArray<nsIID> & array) { \
array.Clear(); \
array.SetCapacity(_c);
#define NS_CLASSINFO_HELPER_ENTRY(_interface) \
(*array)[i++] = NS_GET_IID(_interface).Clone();
array.AppendElement(NS_GET_IID(_interface));
#define NS_CLASSINFO_HELPER_END \
MOZ_ASSERT(i == *count, "Incorrent number of entries"); \
return NS_OK; \
#define NS_CLASSINFO_HELPER_END \
return NS_OK; \
}
#define NS_IMPL_CI_INTERFACE_GETTER(aClass, ...) \

Просмотреть файл

@ -1247,45 +1247,45 @@ class Runnable;
* Macro to generate nsIClassInfo methods for classes which do not have
* corresponding nsIFactory implementations.
*/
#define NS_IMPL_THREADSAFE_CI(_class) \
NS_IMETHODIMP \
_class::GetInterfaces(uint32_t* _count, nsIID*** _array) { \
return NS_CI_INTERFACE_GETTER_NAME(_class)(_count, _array); \
} \
\
NS_IMETHODIMP \
_class::GetScriptableHelper(nsIXPCScriptable** _retval) { \
*_retval = nullptr; \
return NS_OK; \
} \
\
NS_IMETHODIMP \
_class::GetContractID(nsACString& _contractID) { \
_contractID.SetIsVoid(true); \
return NS_OK; \
} \
\
NS_IMETHODIMP \
_class::GetClassDescription(nsACString& _classDescription) { \
_classDescription.SetIsVoid(true); \
return NS_OK; \
} \
\
NS_IMETHODIMP \
_class::GetClassID(nsCID** _classID) { \
*_classID = nullptr; \
return NS_OK; \
} \
\
NS_IMETHODIMP \
_class::GetFlags(uint32_t* _flags) { \
*_flags = nsIClassInfo::THREADSAFE; \
return NS_OK; \
} \
\
NS_IMETHODIMP \
_class::GetClassIDNoAlloc(nsCID* _classIDNoAlloc) { \
return NS_ERROR_NOT_AVAILABLE; \
#define NS_IMPL_THREADSAFE_CI(_class) \
NS_IMETHODIMP \
_class::GetInterfaces(nsTArray<nsIID>& _array) { \
return NS_CI_INTERFACE_GETTER_NAME(_class)(_array); \
} \
\
NS_IMETHODIMP \
_class::GetScriptableHelper(nsIXPCScriptable** _retval) { \
*_retval = nullptr; \
return NS_OK; \
} \
\
NS_IMETHODIMP \
_class::GetContractID(nsACString& _contractID) { \
_contractID.SetIsVoid(true); \
return NS_OK; \
} \
\
NS_IMETHODIMP \
_class::GetClassDescription(nsACString& _classDescription) { \
_classDescription.SetIsVoid(true); \
return NS_OK; \
} \
\
NS_IMETHODIMP \
_class::GetClassID(nsCID** _classID) { \
*_classID = nullptr; \
return NS_OK; \
} \
\
NS_IMETHODIMP \
_class::GetFlags(uint32_t* _flags) { \
*_flags = nsIClassInfo::THREADSAFE; \
return NS_OK; \
} \
\
NS_IMETHODIMP \
_class::GetClassIDNoAlloc(nsCID* _classIDNoAlloc) { \
return NS_ERROR_NOT_AVAILABLE; \
}
#endif

Просмотреть файл

@ -18,15 +18,11 @@ interface nsIXPCScriptable;
interface nsIClassInfo : nsISupports
{
/**
* Get an ordered list of the interface ids that instances of the class
* promise to implement. Note that nsISupports is an implicit member
* of any such list and need not be included.
*
* Should set *count = 0 and *array = null and return NS_OK if getting the
* list is not supported.
* Returns a list of the interfaces which instances of this class promise
* to implement. Note that nsISupports is an implicit member of any such
* list, and need not be included.
*/
void getInterfaces(out uint32_t count,
[array, size_is(count), retval] out nsIIDPtr array);
readonly attribute Array<nsIIDRef> interfaces;
/**
* Return an object to assist XPConnect in supplying JavaScript-specific

Просмотреть файл

@ -140,8 +140,8 @@ nsThreadClassInfo::Release() { return 1; }
NS_IMPL_QUERY_INTERFACE(nsThreadClassInfo, nsIClassInfo)
NS_IMETHODIMP
nsThreadClassInfo::GetInterfaces(uint32_t* aCount, nsIID*** aArray) {
return NS_CI_INTERFACE_GETTER_NAME(nsThread)(aCount, aArray);
nsThreadClassInfo::GetInterfaces(nsTArray<nsIID>& aArray) {
return NS_CI_INTERFACE_GETTER_NAME(nsThread)(aArray);
}
NS_IMETHODIMP