Bug 1366511: Part 1 - Allow packing Result<T, nsresult> values into a single word. r?ehsan,nbp
When used as an error value, nsresult should never be NS_OK, which means that
we should be able to safely pack simple nsresult Result values into a single
word.
MozReview-Commit-ID: GJvnyTPjynk
--- a/mfbt/Result.h
+++ b/mfbt/Result.h
@@ -90,16 +90,37 @@ public:
explicit ResultImplementation(E& aErrorValue) : mErrorValue(&aErrorValue) {}
bool isOk() const { return mErrorValue == nullptr; }
V unwrap() const { return V(); }
E& unwrapErr() const { return *mErrorValue; }
};
+template <typename V, typename E>
+class ResultImplementation<V, E, PackingStrategy::NullIsOk>
+{
+ static constexpr E NullValue = E(0);
+
+ E mErrorValue;
+
+public:
+ explicit ResultImplementation(V) : mErrorValue(NullValue) {}
+ explicit ResultImplementation(E aErrorValue) : mErrorValue(aErrorValue)
+ {
+ MOZ_ASSERT(aErrorValue != NullValue);
+ }
+
+ bool isOk() const { return mErrorValue == NullValue; }
+
+ V unwrap() const { return V(); }
+ E unwrapErr() const { return mErrorValue; }
+};
+
+
/**
* Specialization for when alignment permits using the least significant bit as
* a tag bit.
*/
template <typename V, typename E>
class ResultImplementation<V*, E&, PackingStrategy::LowBitTagIsError>
{
uintptr_t mBits;
--- a/xpcom/base/nscore.h
+++ b/xpcom/base/nscore.h
@@ -189,16 +189,36 @@
/**
* Generic XPCOM result data type
*/
#include "nsError.h"
typedef MozRefCountType nsrefcnt;
+namespace mozilla {
+// Extensions to the mozilla::Result type for handling of nsresult values.
+//
+// Note that these specializations need to be defined before Result.h is
+// included, or we run into explicit specialization after instantiation errors,
+// especially if Result.h is used in multiple sources in a unified compile.
+
+namespace detail {
+// When used as an error value, nsresult should never be NS_OK.
+// This specialization allows us to pack Result<Ok, nsresult> into a
+// nsresult-sized value.
+template<typename T> struct UnusedZero;
+template<>
+struct UnusedZero<nsresult>
+{
+ static const bool value = true;
+};
+} // namespace detail
+} // namespace mozilla
+
/*
* Use these macros to do 64bit safe pointer conversions.
*/
#define NS_PTR_TO_INT32(x) ((int32_t)(intptr_t)(x))
#define NS_PTR_TO_UINT32(x) ((uint32_t)(intptr_t)(x))
#define NS_INT32_TO_PTR(x) ((void*)(intptr_t)(x))