Bug 1547218 - Part 2: Stop special casing pointer types in ParamTraits specialization, r=froydnj

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nika Layzell 2019-05-21 17:04:39 +00:00
Родитель 57a29bfd71
Коммит e71da28e87
21 изменённых файлов: 119 добавлений и 92 удалений

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

@ -889,7 +889,7 @@ void BrowsingContext::DidSetIsActivatedByUserGesture(ContentParent* aSource) {
namespace ipc {
void IPDLParamTraits<dom::BrowsingContext>::Write(
void IPDLParamTraits<dom::BrowsingContext*>::Write(
IPC::Message* aMsg, IProtocol* aActor, dom::BrowsingContext* aParam) {
uint64_t id = aParam ? aParam->Id() : 0;
WriteIPDLParam(aMsg, aActor, id);
@ -902,7 +902,7 @@ void IPDLParamTraits<dom::BrowsingContext>::Write(
}
}
bool IPDLParamTraits<dom::BrowsingContext>::Read(
bool IPDLParamTraits<dom::BrowsingContext*>::Read(
const IPC::Message* aMsg, PickleIterator* aIter, IProtocol* aActor,
RefPtr<dom::BrowsingContext>* aResult) {
uint64_t id = 0;

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

@ -481,7 +481,7 @@ typedef BrowsingContext::Children BrowsingContextChildren;
// Allow sending BrowsingContext objects over IPC.
namespace ipc {
template <>
struct IPDLParamTraits<dom::BrowsingContext> {
struct IPDLParamTraits<dom::BrowsingContext*> {
static void Write(IPC::Message* aMsg, IProtocol* aActor,
dom::BrowsingContext* aParam);
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,

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

@ -287,7 +287,7 @@ nsresult SerializeUntyped(BlobImpl* aBlobImpl, IProtocol* aActor,
} // namespace dom
namespace ipc {
void IPDLParamTraits<mozilla::dom::BlobImpl>::Write(
void IPDLParamTraits<mozilla::dom::BlobImpl*>::Write(
IPC::Message* aMsg, IProtocol* aActor, mozilla::dom::BlobImpl* aParam) {
nsresult rv;
mozilla::dom::IPCBlob ipcblob;
@ -302,7 +302,7 @@ void IPDLParamTraits<mozilla::dom::BlobImpl>::Write(
}
}
bool IPDLParamTraits<mozilla::dom::BlobImpl>::Read(
bool IPDLParamTraits<mozilla::dom::BlobImpl*>::Read(
const IPC::Message* aMsg, PickleIterator* aIter, IProtocol* aActor,
RefPtr<mozilla::dom::BlobImpl>* aResult) {
*aResult = nullptr;

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

@ -258,7 +258,7 @@ namespace ipc {
// sent over the wire. When Read()-ing a BlobImpl,
// __always make sure to handle null!__
template <>
struct IPDLParamTraits<mozilla::dom::BlobImpl> {
struct IPDLParamTraits<mozilla::dom::BlobImpl*> {
static void Write(IPC::Message* aMsg, IProtocol* aActor,
mozilla::dom::BlobImpl* aParam);
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,

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

@ -14,7 +14,7 @@
namespace IPC {
template <>
struct ParamTraits<nsIDOMGeoPositionCoords> {
struct ParamTraits<nsIDOMGeoPositionCoords*> {
// Function to serialize a geoposition
static void Write(Message* aMsg, nsIDOMGeoPositionCoords* aParam) {
bool isNull = !aParam;
@ -89,7 +89,7 @@ struct ParamTraits<nsIDOMGeoPositionCoords> {
};
template <>
struct ParamTraits<nsIDOMGeoPosition> {
struct ParamTraits<nsIDOMGeoPosition*> {
// Function to serialize a geoposition
static void Write(Message* aMsg, nsIDOMGeoPosition* aParam) {
bool isNull = !aParam;

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

@ -10,7 +10,7 @@
namespace IPC {
void ParamTraits<nsIContentSecurityPolicy>::Write(
void ParamTraits<nsIContentSecurityPolicy*>::Write(
Message* aMsg, nsIContentSecurityPolicy* aParam) {
bool isNull = !aParam;
WriteParam(aMsg, isNull);
@ -28,7 +28,7 @@ void ParamTraits<nsIContentSecurityPolicy>::Write(
WriteParam(aMsg, cspString);
}
bool ParamTraits<nsIContentSecurityPolicy>::Read(
bool ParamTraits<nsIContentSecurityPolicy*>::Read(
const Message* aMsg, PickleIterator* aIter,
RefPtr<nsIContentSecurityPolicy>* aResult) {
bool isNull;

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

@ -14,7 +14,7 @@
namespace IPC {
template <>
struct ParamTraits<nsIContentSecurityPolicy> {
struct ParamTraits<nsIContentSecurityPolicy*> {
static void Write(Message* aMsg, nsIContentSecurityPolicy* aParam);
static bool Read(const Message* aMsg, PickleIterator* aIter,
RefPtr<nsIContentSecurityPolicy>* aResult);

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

@ -11,14 +11,14 @@
namespace mozilla {
namespace ipc {
void IPDLParamTraits<nsDocShellLoadState>::Write(IPC::Message* aMsg,
IProtocol* aActor,
nsDocShellLoadState* aParam) {
void IPDLParamTraits<nsDocShellLoadState*>::Write(IPC::Message* aMsg,
IProtocol* aActor,
nsDocShellLoadState* aParam) {
MOZ_RELEASE_ASSERT(aParam);
WriteIPDLParam(aMsg, aActor, aParam->Serialize());
}
bool IPDLParamTraits<nsDocShellLoadState>::Read(
bool IPDLParamTraits<nsDocShellLoadState*>::Read(
const IPC::Message* aMsg, PickleIterator* aIter, IProtocol* aActor,
RefPtr<nsDocShellLoadState>* aResult) {
DocShellLoadStateInit loadState;

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

@ -15,7 +15,7 @@ namespace mozilla {
namespace ipc {
template <>
struct IPDLParamTraits<nsDocShellLoadState> {
struct IPDLParamTraits<nsDocShellLoadState*> {
static void Write(IPC::Message* aMsg, IProtocol* aActor,
nsDocShellLoadState* aParam);
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,

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

@ -11,8 +11,9 @@
namespace mozilla {
namespace ipc {
void IPDLParamTraits<nsIPrincipal>::Write(IPC::Message* aMsg, IProtocol* aActor,
nsIPrincipal* aParam) {
void IPDLParamTraits<nsIPrincipal*>::Write(IPC::Message* aMsg,
IProtocol* aActor,
nsIPrincipal* aParam) {
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
Maybe<PrincipalInfo> info;
@ -25,10 +26,10 @@ void IPDLParamTraits<nsIPrincipal>::Write(IPC::Message* aMsg, IProtocol* aActor,
WriteIPDLParam(aMsg, aActor, info);
}
bool IPDLParamTraits<nsIPrincipal>::Read(const IPC::Message* aMsg,
PickleIterator* aIter,
IProtocol* aActor,
RefPtr<nsIPrincipal>* aResult) {
bool IPDLParamTraits<nsIPrincipal*>::Read(const IPC::Message* aMsg,
PickleIterator* aIter,
IProtocol* aActor,
RefPtr<nsIPrincipal>* aResult) {
Maybe<PrincipalInfo> info;
if (!ReadIPDLParam(aMsg, aIter, aActor, &info)) {
return false;

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

@ -42,7 +42,7 @@ namespace mozilla {
namespace ipc {
template <>
struct IPDLParamTraits<nsIPrincipal> {
struct IPDLParamTraits<nsIPrincipal*> {
static void Write(IPC::Message* aMsg, IProtocol* aActor,
nsIPrincipal* aParam);
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,

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

@ -10,8 +10,8 @@
namespace IPC {
void ParamTraits<nsIReferrerInfo>::Write(Message* aMsg,
nsIReferrerInfo* aParam) {
void ParamTraits<nsIReferrerInfo*>::Write(Message* aMsg,
nsIReferrerInfo* aParam) {
bool isNull = !aParam;
WriteParam(aMsg, isNull);
if (isNull) {
@ -26,9 +26,9 @@ void ParamTraits<nsIReferrerInfo>::Write(Message* aMsg,
WriteParam(aMsg, infoString);
}
bool ParamTraits<nsIReferrerInfo>::Read(const Message* aMsg,
PickleIterator* aIter,
RefPtr<nsIReferrerInfo>* aResult) {
bool ParamTraits<nsIReferrerInfo*>::Read(const Message* aMsg,
PickleIterator* aIter,
RefPtr<nsIReferrerInfo>* aResult) {
bool isNull;
if (!ReadParam(aMsg, aIter, &isNull)) {
return false;

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

@ -14,7 +14,7 @@
namespace IPC {
template <>
struct ParamTraits<nsIReferrerInfo> {
struct ParamTraits<nsIReferrerInfo*> {
static void Write(Message* aMsg, nsIReferrerInfo* aParam);
static bool Read(const Message* aMsg, PickleIterator* aIter,
RefPtr<nsIReferrerInfo>* aResult);

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

@ -384,7 +384,7 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow> {
#ifdef XP_MACOSX
template <>
struct ParamTraits<NPNSString> {
struct ParamTraits<NPNSString*> {
// Empty string writes a length of 0 and no buffer.
// We don't write a nullptr terminating character in buffers.
static void Write(Message* aMsg, NPNSString* aParam) {

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

@ -110,48 +110,20 @@ class MessageIterator {
template <class P>
struct ParamTraits;
// When WriteParam or ReadParam is passed a pointer type like RefPtr<T> or T*,
// we want to invoke Write() on ParamTraits<T>, as the intype is often T*, while
// the ReadParam type may be RefPtr<T>.
namespace detail {
template <typename T>
struct StripPointers {
typedef T Type;
};
template <typename T>
struct StripPointers<T*> {
typedef T Type;
};
template <typename T>
struct StripPointers<RefPtr<T>> {
typedef T Type;
};
template <typename T>
struct StripPointers<nsCOMPtr<T>> {
typedef T Type;
};
} // namespace detail
// NOTE: This helper is also used in IPDLParamTraits.h
template <typename T>
struct ParamTraitsSelector
: public detail::StripPointers<typename mozilla::Decay<T>::Type> {};
template <typename P>
static inline void WriteParam(Message* m, P&& p) {
ParamTraits<typename ParamTraitsSelector<P>::Type>::Write(m,
std::forward<P>(p));
ParamTraits<typename mozilla::Decay<P>::Type>::Write(m, std::forward<P>(p));
}
template <typename P>
static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m,
PickleIterator* iter, P* p) {
return ParamTraits<typename ParamTraitsSelector<P>::Type>::Read(m, iter, p);
return ParamTraits<P>::Read(m, iter, p);
}
template <typename P>
static inline void LogParam(const P& p, std::wstring* l) {
ParamTraits<typename ParamTraitsSelector<P>::Type>::Log(p, l);
ParamTraits<P>::Log(p, l);
}
// Fundamental types.
@ -374,10 +346,8 @@ template <class P>
struct ParamTraitsWindows : ParamTraitsStd<P> {};
#if defined(OS_WIN)
// NOTE: HANDLE is a pointer, which we need to strip off, otherwise we won't
// find this specialization.
template <>
struct ParamTraitsWindows<detail::StripPointers<HANDLE>::Type> {
struct ParamTraitsWindows<HANDLE> {
static_assert(sizeof(HANDLE) == sizeof(intptr_t), "Wrong size for HANDLE?");
static void Write(Message* m, HANDLE p) {
@ -391,10 +361,8 @@ struct ParamTraitsWindows<detail::StripPointers<HANDLE>::Type> {
}
};
// NOTE: HWND is a pointer, which we need to strip off, otherwise we won't find
// this specialization.
template <>
struct ParamTraitsWindows<detail::StripPointers<HWND>::Type> {
struct ParamTraitsWindows<HWND> {
static_assert(sizeof(HWND) == sizeof(intptr_t), "Wrong size for HWND?");
static void Write(Message* m, HWND p) {
@ -484,6 +452,35 @@ struct ParamTraitsMozilla<nsresult> {
}
};
// See comments for the IPDLParamTraits specializations for RefPtr<T> and
// nsCOMPtr<T> for more details.
template <class T>
struct ParamTraitsMozilla<RefPtr<T>> {
static void Write(Message* m, const RefPtr<T>& p) {
ParamTraits<T*>::Write(m, p.get());
}
static bool Read(const Message* m, PickleIterator* iter, RefPtr<T>* r) {
return ParamTraits<T*>::Read(m, iter, r);
}
};
template <class T>
struct ParamTraitsMozilla<nsCOMPtr<T>> {
static void Write(Message* m, const nsCOMPtr<T>& p) {
ParamTraits<T*>::Write(m, p.get());
}
static bool Read(const Message* m, PickleIterator* iter, nsCOMPtr<T>* r) {
RefPtr<T> refptr;
if (!ParamTraits<T*>::Read(m, iter, &refptr)) {
return false;
}
*r = refptr.forget();
return true;
}
};
// Finally, ParamTraits itself.
template <class P>

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

@ -447,9 +447,9 @@ Maybe<IPCStream>& AutoIPCStream::TakeOptionalValue() {
return *mOptionalValue;
}
void IPDLParamTraits<nsIInputStream>::Write(IPC::Message* aMsg,
IProtocol* aActor,
nsIInputStream* aParam) {
void IPDLParamTraits<nsIInputStream*>::Write(IPC::Message* aMsg,
IProtocol* aActor,
nsIInputStream* aParam) {
mozilla::ipc::AutoIPCStream autoStream;
bool ok = false;
bool found = false;
@ -497,10 +497,10 @@ void IPDLParamTraits<nsIInputStream>::Write(IPC::Message* aMsg,
WriteIPDLParam(aMsg, aActor, autoStream.TakeOptionalValue());
}
bool IPDLParamTraits<nsIInputStream>::Read(const IPC::Message* aMsg,
PickleIterator* aIter,
IProtocol* aActor,
RefPtr<nsIInputStream>* aResult) {
bool IPDLParamTraits<nsIInputStream*>::Read(const IPC::Message* aMsg,
PickleIterator* aIter,
IProtocol* aActor,
RefPtr<nsIInputStream>* aResult) {
mozilla::Maybe<mozilla::ipc::IPCStream> ipcStream;
if (!ReadIPDLParam(aMsg, aIter, aActor, &ipcStream)) {
return false;

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

@ -181,7 +181,7 @@ class AutoIPCStream final {
};
template <>
struct IPDLParamTraits<nsIInputStream> {
struct IPDLParamTraits<nsIInputStream*> {
static void Write(IPC::Message* aMsg, IProtocol* aActor,
nsIInputStream* aParam);
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,

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

@ -27,20 +27,12 @@ struct IPDLParamTraits {
// IPDLParamTraits.
template <typename R>
static inline void Write(IPC::Message* aMsg, IProtocol*, R&& aParam) {
static_assert(
IsSame<P, typename IPC::ParamTraitsSelector<R>::Type>::value,
"IPDLParamTraits::Write only forwards calls which work via WriteParam");
IPC::ParamTraits<P>::Write(aMsg, std::forward<R>(aParam));
}
template <typename R>
static inline bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
IProtocol*, R* aResult) {
static_assert(
IsSame<P, typename IPC::ParamTraitsSelector<R>::Type>::value,
"IPDLParamTraits::Read only forwards calls which work via ReadParam");
return IPC::ParamTraits<P>::Read(aMsg, aIter, aResult);
}
};
@ -58,16 +50,15 @@ struct IPDLParamTraits {
template <typename P>
static MOZ_NEVER_INLINE void WriteIPDLParam(IPC::Message* aMsg,
IProtocol* aActor, P&& aParam) {
IPDLParamTraits<typename IPC::ParamTraitsSelector<P>::Type>::Write(
aMsg, aActor, std::forward<P>(aParam));
IPDLParamTraits<typename Decay<P>::Type>::Write(aMsg, aActor,
std::forward<P>(aParam));
}
template <typename P>
static MOZ_NEVER_INLINE bool ReadIPDLParam(const IPC::Message* aMsg,
PickleIterator* aIter,
IProtocol* aActor, P* aResult) {
return IPDLParamTraits<typename IPC::ParamTraitsSelector<P>::Type>::Read(
aMsg, aIter, aActor, aResult);
return IPDLParamTraits<P>::Read(aMsg, aIter, aActor, aResult);
}
constexpr void WriteIPDLParamList(IPC::Message*, IProtocol*) {}
@ -91,6 +82,44 @@ static bool ReadIPDLParamList(const IPC::Message* aMsg, PickleIterator* aIter,
ReadIPDLParamList(aMsg, aIter, aActor, aResults...);
}
// When being passed `RefPtr<T>` or `nsCOMPtr<T>`, forward to a specialization
// for the underlying target type. The parameter type will be passed as `T*`,
// and result as `RefPtr<T>*`.
//
// This is done explicitly to ensure that the deleted `&&` overload for
// `operator T*` is not selected in generic contexts, and to support
// deserializing into `nsCOMPtr<T>`.
template <typename T>
struct IPDLParamTraits<RefPtr<T>> {
static void Write(IPC::Message* aMsg, IProtocol* aActor,
const RefPtr<T>& aParam) {
IPDLParamTraits<T*>::Write(aMsg, aActor, aParam.get());
}
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
IProtocol* aActor, RefPtr<T>* aResult) {
return IPDLParamTraits<T*>::Read(aMsg, aIter, aActor, aResult);
}
};
template <typename T>
struct IPDLParamTraits<nsCOMPtr<T>> {
static void Write(IPC::Message* aMsg, IProtocol* aActor,
const nsCOMPtr<T>& aParam) {
IPDLParamTraits<T*>::Write(aMsg, aActor, aParam.get());
}
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
IProtocol* aActor, nsCOMPtr<T>* aResult) {
RefPtr<T> refptr;
if (!IPDLParamTraits<T*>::Read(aMsg, aIter, aActor, &refptr)) {
return false;
}
*aResult = refptr.forget();
return true;
}
};
// nsTArray support for IPDLParamTraits
template <typename T>
struct IPDLParamTraits<nsTArray<T>> {

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

@ -24,7 +24,7 @@ already_AddRefed<nsIURI> DeserializeURI(const URIParams& aParams);
already_AddRefed<nsIURI> DeserializeURI(const Maybe<URIParams>& aParams);
template <>
struct IPDLParamTraits<nsIURI> {
struct IPDLParamTraits<nsIURI*> {
static void Write(IPC::Message* aMsg, IProtocol* aActor, nsIURI* aParam) {
Maybe<URIParams> params;
SerializeURI(aParam, params);

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

@ -1975,12 +1975,12 @@ class _ParamTraits():
@classmethod
def generateDecl(cls, fortype, write, read, constin=True):
# IPDLParamTraits impls are selected ignoring constness, references,
# and pointers.
# IPDLParamTraits impls are selected ignoring constness, and references.
pt = Class('IPDLParamTraits',
specializes=Type(fortype.name,
T=fortype.T,
inner=fortype.inner),
inner=fortype.inner,
ptr=fortype.ptr),
struct=True)
# typedef T paramType;

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

@ -19,7 +19,7 @@ namespace mozilla {
namespace ipc {
template <>
struct IPDLParamTraits<nsIAlertNotification> {
struct IPDLParamTraits<nsIAlertNotification*> {
static void Write(IPC::Message* aMsg, IProtocol* aActor,
nsIAlertNotification* aParam) {
bool isNull = !aParam;