Bug 1367679. P2 - overload InvokeCallbackMethod() according to whether promise-chaining is supported. r=gerald

This patch fixes InvokeCallbackMethod() which should return null
if promise-chaining is not supported.

Before this patch, it could return non-null if one of the resolve/reject callbacks
returns a MozPromise while the other not.

MozReview-Commit-ID: 7YKNvRKEHQx

--HG--
extra : rebase_source : 6429d9eef35efa0128e8b5967097850e6f4a4325
extra : intermediate-source : 6f73de7d2d5fb01be19fdf7d7037b506425eab18
extra : source : a1849e24b09b0b4e986ffaef14d2602541c1c6e8
This commit is contained in:
JW Wang 2017-05-31 17:08:08 +08:00
parent b5d3112f74
commit 2bc689b541

View File

@ -521,9 +521,12 @@ protected:
return (aThisVal->*aMethod)(); return (aThisVal->*aMethod)();
} }
template<typename ThisType, typename MethodType, typename ValueType> // Called when promise chaining is supported.
static typename EnableIf<ReturnTypeIs<MethodType, RefPtr<MozPromise>>::value, template<bool SupportChaining,
already_AddRefed<MozPromise>>::Type typename ThisType,
typename MethodType,
typename ValueType>
static typename EnableIf<SupportChaining, already_AddRefed<MozPromise>>::Type
InvokeCallbackMethod(ThisType* aThisVal, InvokeCallbackMethod(ThisType* aThisVal,
MethodType aMethod, MethodType aMethod,
ValueType&& aValue) ValueType&& aValue)
@ -531,9 +534,12 @@ protected:
return InvokeMethod(aThisVal, aMethod, Forward<ValueType>(aValue)).forget(); return InvokeMethod(aThisVal, aMethod, Forward<ValueType>(aValue)).forget();
} }
template<typename ThisType, typename MethodType, typename ValueType> // Called when promise chaining is not supported.
static typename EnableIf<ReturnTypeIs<MethodType, void>::value, template<bool SupportChaining,
already_AddRefed<MozPromise>>::Type typename ThisType,
typename MethodType,
typename ValueType>
static typename EnableIf<!SupportChaining, already_AddRefed<MozPromise>>::Type
InvokeCallbackMethod(ThisType* aThisVal, InvokeCallbackMethod(ThisType* aThisVal,
MethodType aMethod, MethodType aMethod,
ValueType&& aValue) ValueType&& aValue)
@ -593,10 +599,10 @@ protected:
{ {
RefPtr<MozPromise> result; RefPtr<MozPromise> result;
if (aValue.IsResolve()) { if (aValue.IsResolve()) {
result = InvokeCallbackMethod( result = InvokeCallbackMethod<SupportChaining::value>(
mThisVal.get(), mResolveMethod, MaybeMove(aValue.ResolveValue())); mThisVal.get(), mResolveMethod, MaybeMove(aValue.ResolveValue()));
} else { } else {
result = InvokeCallbackMethod( result = InvokeCallbackMethod<SupportChaining::value>(
mThisVal.get(), mRejectMethod, MaybeMove(aValue.RejectValue())); mThisVal.get(), mRejectMethod, MaybeMove(aValue.RejectValue()));
} }
@ -658,7 +664,7 @@ protected:
void DoResolveOrRejectInternal(ResolveOrRejectValue& aValue) override void DoResolveOrRejectInternal(ResolveOrRejectValue& aValue) override
{ {
RefPtr<MozPromise> result = InvokeCallbackMethod( RefPtr<MozPromise> result = InvokeCallbackMethod<SupportChaining::value>(
mThisVal.get(), mResolveRejectMethod, MaybeMove(aValue)); mThisVal.get(), mResolveRejectMethod, MaybeMove(aValue));
// Null out mThisVal after invoking the callback so that any references are // Null out mThisVal after invoking the callback so that any references are
@ -731,13 +737,15 @@ protected:
// just capturing something. // just capturing something.
RefPtr<MozPromise> result; RefPtr<MozPromise> result;
if (aValue.IsResolve()) { if (aValue.IsResolve()) {
result = InvokeCallbackMethod(mResolveFunction.ptr(), result = InvokeCallbackMethod<SupportChaining::value>(
&ResolveFunction::operator(), mResolveFunction.ptr(),
MaybeMove(aValue.ResolveValue())); &ResolveFunction::operator(),
MaybeMove(aValue.ResolveValue()));
} else { } else {
result = InvokeCallbackMethod(mRejectFunction.ptr(), result = InvokeCallbackMethod<SupportChaining::value>(
&RejectFunction::operator(), mRejectFunction.ptr(),
MaybeMove(aValue.RejectValue())); &RejectFunction::operator(),
MaybeMove(aValue.RejectValue()));
} }
// Destroy callbacks after invocation so that any references in closures are // Destroy callbacks after invocation so that any references in closures are
@ -803,10 +811,10 @@ protected:
// classes with ::operator()), since it allows us to share code more easily. // classes with ::operator()), since it allows us to share code more easily.
// We could fix this if need be, though it's quite easy to work around by // We could fix this if need be, though it's quite easy to work around by
// just capturing something. // just capturing something.
RefPtr<MozPromise> result = RefPtr<MozPromise> result = InvokeCallbackMethod<SupportChaining::value>(
InvokeCallbackMethod(mResolveRejectFunction.ptr(), mResolveRejectFunction.ptr(),
&ResolveRejectFunction::operator(), &ResolveRejectFunction::operator(),
MaybeMove(aValue)); MaybeMove(aValue));
// Destroy callbacks after invocation so that any references in closures are // Destroy callbacks after invocation so that any references in closures are
// released predictably on the dispatch thread. Otherwise, they would be // released predictably on the dispatch thread. Otherwise, they would be