mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 04:41:11 +00:00
Bug 1891541 - [2/2] enforce that MozPromise only accepts static strings r=xpcom-reviewers,media-playback-reviewers,padenot,emilio
All present uses of the call-site arguments to MozPromise's methods supply static strings. However, this is nowhere enforced. Do so. Additionally, since this is the third or fourth time the present author alone has personally implemented such an enforcement mechanism, create a helper class to simplify doing so. No functional changes. Differential Revision: https://phabricator.services.mozilla.com/D207462
This commit is contained in:
parent
53b8555503
commit
e2ee2f11df
@ -65,42 +65,42 @@ FetchServicePromises::GetResponseEndPromise() {
|
||||
}
|
||||
|
||||
void FetchServicePromises::ResolveResponseAvailablePromise(
|
||||
FetchServiceResponse&& aResponse, const char* aMethodName) {
|
||||
FetchServiceResponse&& aResponse, StaticString aMethodName) {
|
||||
if (mAvailablePromise) {
|
||||
mAvailablePromise->Resolve(std::move(aResponse), aMethodName);
|
||||
}
|
||||
}
|
||||
|
||||
void FetchServicePromises::RejectResponseAvailablePromise(
|
||||
const CopyableErrorResult&& aError, const char* aMethodName) {
|
||||
const CopyableErrorResult&& aError, StaticString aMethodName) {
|
||||
if (mAvailablePromise) {
|
||||
mAvailablePromise->Reject(aError, aMethodName);
|
||||
}
|
||||
}
|
||||
|
||||
void FetchServicePromises::ResolveResponseTimingPromise(
|
||||
ResponseTiming&& aTiming, const char* aMethodName) {
|
||||
ResponseTiming&& aTiming, StaticString aMethodName) {
|
||||
if (mTimingPromise) {
|
||||
mTimingPromise->Resolve(std::move(aTiming), aMethodName);
|
||||
}
|
||||
}
|
||||
|
||||
void FetchServicePromises::RejectResponseTimingPromise(
|
||||
const CopyableErrorResult&& aError, const char* aMethodName) {
|
||||
const CopyableErrorResult&& aError, StaticString aMethodName) {
|
||||
if (mTimingPromise) {
|
||||
mTimingPromise->Reject(aError, aMethodName);
|
||||
}
|
||||
}
|
||||
|
||||
void FetchServicePromises::ResolveResponseEndPromise(ResponseEndArgs&& aArgs,
|
||||
const char* aMethodName) {
|
||||
StaticString aMethodName) {
|
||||
if (mEndPromise) {
|
||||
mEndPromise->Resolve(std::move(aArgs), aMethodName);
|
||||
}
|
||||
}
|
||||
|
||||
void FetchServicePromises::RejectResponseEndPromise(
|
||||
const CopyableErrorResult&& aError, const char* aMethodName) {
|
||||
const CopyableErrorResult&& aError, StaticString aMethodName) {
|
||||
if (mEndPromise) {
|
||||
mEndPromise->Reject(aError, aMethodName);
|
||||
}
|
||||
|
@ -48,17 +48,17 @@ class FetchServicePromises final {
|
||||
RefPtr<FetchServiceResponseEndPromise> GetResponseEndPromise();
|
||||
|
||||
void ResolveResponseAvailablePromise(FetchServiceResponse&& aResponse,
|
||||
const char* aMethodName);
|
||||
StaticString aMethodName);
|
||||
void RejectResponseAvailablePromise(const CopyableErrorResult&& aError,
|
||||
const char* aMethodName);
|
||||
StaticString aMethodName);
|
||||
void ResolveResponseTimingPromise(ResponseTiming&& aTiming,
|
||||
const char* aMethodName);
|
||||
StaticString aMethodName);
|
||||
void RejectResponseTimingPromise(const CopyableErrorResult&& aError,
|
||||
const char* aMethodName);
|
||||
StaticString aMethodName);
|
||||
void ResolveResponseEndPromise(ResponseEndArgs&& aArgs,
|
||||
const char* aMethodName);
|
||||
StaticString aMethodName);
|
||||
void RejectResponseEndPromise(const CopyableErrorResult&& aError,
|
||||
const char* aMethodName);
|
||||
StaticString aMethodName);
|
||||
|
||||
private:
|
||||
~FetchServicePromises() = default;
|
||||
|
@ -177,7 +177,7 @@ FileSystemAccessHandle::BeginInit() {
|
||||
|
||||
mLocked = true;
|
||||
|
||||
auto CreateAndRejectInitPromise = [](const char* aFunc, nsresult aRv) {
|
||||
auto CreateAndRejectInitPromise = [](StaticString aFunc, nsresult aRv) {
|
||||
return CreateAndRejectMozPromise<InitPromise>(aFunc, aRv);
|
||||
};
|
||||
|
||||
|
@ -994,7 +994,7 @@ class HTMLMediaElement::MediaStreamRenderer {
|
||||
graph->CreateSourceTrack(MediaSegment::AUDIO));
|
||||
}
|
||||
|
||||
void ResolveAudioDevicePromiseIfExists(const char* aMethodName) {
|
||||
void ResolveAudioDevicePromiseIfExists(StaticString aMethodName) {
|
||||
if (mSetAudioDevicePromise.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -154,12 +154,12 @@ class ExternalEngineStateMachine final
|
||||
mSeekJob = SeekJob();
|
||||
mSeekJob.mTarget = Some(aTarget);
|
||||
}
|
||||
void Resolve(const char* aCallSite) {
|
||||
void Resolve(StaticString aCallSite) {
|
||||
MOZ_ASSERT(mSeekJob.Exists());
|
||||
mSeekJob.Resolve(aCallSite);
|
||||
mSeekJob = SeekJob();
|
||||
}
|
||||
void RejectIfExists(const char* aCallSite) {
|
||||
void RejectIfExists(StaticString aCallSite) {
|
||||
mSeekJob.RejectIfExists(aCallSite);
|
||||
}
|
||||
bool IsSeeking() const { return mSeekRequest.Exists(); }
|
||||
|
@ -552,7 +552,7 @@ class MediaFormatReader final
|
||||
// Rejecting the promise will stop the reader from decoding ahead.
|
||||
virtual bool HasPromise() const = 0;
|
||||
virtual void RejectPromise(const MediaResult& aError,
|
||||
const char* aMethodName) = 0;
|
||||
StaticString aMethodName) = 0;
|
||||
|
||||
// Clear track demuxer related data.
|
||||
void ResetDemuxer() {
|
||||
@ -688,20 +688,20 @@ class MediaFormatReader final
|
||||
|
||||
bool HasPromise() const override { return mHasPromise; }
|
||||
|
||||
RefPtr<DataPromise<Type>> EnsurePromise(const char* aMethodName) {
|
||||
RefPtr<DataPromise<Type>> EnsurePromise(StaticString aMethodName) {
|
||||
MOZ_ASSERT(mOwner->OnTaskQueue());
|
||||
mHasPromise = true;
|
||||
return mPromise.Ensure(aMethodName);
|
||||
}
|
||||
|
||||
void ResolvePromise(Type* aData, const char* aMethodName) {
|
||||
void ResolvePromise(Type* aData, StaticString aMethodName) {
|
||||
MOZ_ASSERT(mOwner->OnTaskQueue());
|
||||
mPromise.Resolve(aData, aMethodName);
|
||||
mHasPromise = false;
|
||||
}
|
||||
|
||||
void RejectPromise(const MediaResult& aError,
|
||||
const char* aMethodName) override {
|
||||
StaticString aMethodName) override {
|
||||
MOZ_ASSERT(mOwner->OnTaskQueue());
|
||||
mPromise.Reject(aError, aMethodName);
|
||||
mHasPromise = false;
|
||||
|
@ -2516,7 +2516,7 @@ void MediaManager::Dispatch(already_AddRefed<Runnable> task) {
|
||||
|
||||
template <typename MozPromiseType, typename FunctionType>
|
||||
/* static */
|
||||
RefPtr<MozPromiseType> MediaManager::Dispatch(const char* aName,
|
||||
RefPtr<MozPromiseType> MediaManager::Dispatch(StaticString aName,
|
||||
FunctionType&& aFunction) {
|
||||
MozPromiseHolder<MozPromiseType> holder;
|
||||
RefPtr<MozPromiseType> promise = holder.Ensure(aName);
|
||||
|
@ -220,7 +220,7 @@ class MediaManager final : public nsIMediaManagerService,
|
||||
* manager thread.
|
||||
*/
|
||||
template <typename MozPromiseType, typename FunctionType>
|
||||
static RefPtr<MozPromiseType> Dispatch(const char* aName,
|
||||
static RefPtr<MozPromiseType> Dispatch(StaticString aName,
|
||||
FunctionType&& aFunction);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -68,12 +68,12 @@ bool MediaTimer::OnMediaTimerThread() {
|
||||
}
|
||||
|
||||
RefPtr<MediaTimerPromise> MediaTimer::WaitFor(const TimeDuration& aDuration,
|
||||
const char* aCallSite) {
|
||||
StaticString aCallSite) {
|
||||
return WaitUntil(TimeStamp::Now() + aDuration, aCallSite);
|
||||
}
|
||||
|
||||
RefPtr<MediaTimerPromise> MediaTimer::WaitUntil(const TimeStamp& aTimeStamp,
|
||||
const char* aCallSite) {
|
||||
StaticString aCallSite) {
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
TIMER_LOG("MediaTimer::WaitUntil %" PRId64, RelativeMicroseconds(aTimeStamp));
|
||||
Entry e(aTimeStamp, aCallSite);
|
||||
|
@ -44,9 +44,9 @@ class MediaTimer {
|
||||
DispatchDestroy());
|
||||
|
||||
RefPtr<MediaTimerPromise> WaitFor(const TimeDuration& aDuration,
|
||||
const char* aCallSite);
|
||||
StaticString aCallSite);
|
||||
RefPtr<MediaTimerPromise> WaitUntil(const TimeStamp& aTimeStamp,
|
||||
const char* aCallSite);
|
||||
StaticString aCallSite);
|
||||
void Cancel(); // Cancel and reject any unresolved promises with false.
|
||||
|
||||
private:
|
||||
@ -81,7 +81,7 @@ class MediaTimer {
|
||||
TimeStamp mTimeStamp;
|
||||
RefPtr<MediaTimerPromise::Private> mPromise;
|
||||
|
||||
explicit Entry(const TimeStamp& aTimeStamp, const char* aCallSite)
|
||||
explicit Entry(const TimeStamp& aTimeStamp, StaticString aCallSite)
|
||||
: mTimeStamp(aTimeStamp),
|
||||
mPromise(new MediaTimerPromise::Private(aCallSite)) {}
|
||||
|
||||
|
@ -18,12 +18,12 @@ bool SeekJob::Exists() const {
|
||||
return mTarget.isSome();
|
||||
}
|
||||
|
||||
void SeekJob::Resolve(const char* aCallSite) {
|
||||
void SeekJob::Resolve(StaticString aCallSite) {
|
||||
mPromise.Resolve(true, aCallSite);
|
||||
mTarget.reset();
|
||||
}
|
||||
|
||||
void SeekJob::RejectIfExists(const char* aCallSite) {
|
||||
void SeekJob::RejectIfExists(StaticString aCallSite) {
|
||||
mTarget.reset();
|
||||
mPromise.RejectIfExists(true, aCallSite);
|
||||
}
|
||||
|
@ -20,8 +20,8 @@ struct SeekJob {
|
||||
~SeekJob();
|
||||
|
||||
bool Exists() const;
|
||||
void Resolve(const char* aCallSite);
|
||||
void RejectIfExists(const char* aCallSite);
|
||||
void Resolve(StaticString aCallSite);
|
||||
void RejectIfExists(StaticString aCallSite);
|
||||
|
||||
Maybe<SeekTarget> mTarget;
|
||||
MozPromiseHolder<MediaDecoder::SeekPromise> mPromise;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "mozilla/EMEUtils.h"
|
||||
#include "mozilla/KeySystemConfig.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/StaticString.h"
|
||||
#include "mozilla/WMFCDMProxyCallback.h"
|
||||
#include "nsString.h"
|
||||
#include "RemoteDecoderManagerChild.h"
|
||||
@ -44,7 +45,7 @@ namespace mozilla {
|
||||
|
||||
#define INVOKE_ASYNC(method, promiseId, param1) \
|
||||
do { \
|
||||
auto callsite = __func__; \
|
||||
StaticString callsite = __func__; \
|
||||
using ParamType = std::remove_reference<decltype(param1)>::type; \
|
||||
mManagerThread->Dispatch(NS_NewRunnableFunction( \
|
||||
callsite, [self = RefPtr{this}, callsite, promiseId, \
|
||||
@ -56,7 +57,7 @@ namespace mozilla {
|
||||
|
||||
#define INVOKE_ASYNC2(method, promiseId, param1, param2) \
|
||||
do { \
|
||||
auto callsite = __func__; \
|
||||
StaticString callsite = __func__; \
|
||||
using ParamType1 = std::remove_reference<decltype(param1)>::type; \
|
||||
using ParamType2 = std::remove_reference<decltype(param2)>::type; \
|
||||
mManagerThread->Dispatch(NS_NewRunnableFunction( \
|
||||
@ -188,7 +189,7 @@ void MFCDMChild::AssertSendable() {
|
||||
|
||||
template <typename PromiseType>
|
||||
already_AddRefed<PromiseType> MFCDMChild::InvokeAsync(
|
||||
std::function<void()>&& aCall, const char* aCallerName,
|
||||
std::function<void()>&& aCall, StaticString aCallerName,
|
||||
MozPromiseHolder<PromiseType>& aPromise) {
|
||||
AssertSendable();
|
||||
|
||||
|
@ -30,7 +30,7 @@ class MFCDMChild final : public PMFCDMChild {
|
||||
|
||||
template <typename PromiseType>
|
||||
already_AddRefed<PromiseType> InvokeAsync(
|
||||
std::function<void()>&& aCall, const char* aCallerName,
|
||||
std::function<void()>&& aCall, StaticString aCallerName,
|
||||
MozPromiseHolder<PromiseType>& aPromise);
|
||||
|
||||
using InitPromise = MozPromise<MFCDMInitIPDL, nsresult, true>;
|
||||
|
@ -94,7 +94,7 @@ class VoidCallback final : public nsIKeyValueVoidCallback {
|
||||
mResultPromise.Reject(NS_ERROR_FAILURE, __func__);
|
||||
return NS_OK;
|
||||
}
|
||||
RefPtr<GenericPromise> Ensure(const char* aMethodName) {
|
||||
RefPtr<GenericPromise> Ensure(StaticString aMethodName) {
|
||||
return mResultPromise.Ensure(aMethodName);
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ void GMPVideoDecoder::Terminated() {
|
||||
}
|
||||
|
||||
void GMPVideoDecoder::ProcessReorderQueue(
|
||||
MozPromiseHolder<DecodePromise>& aPromise, const char* aMethodName) {
|
||||
MozPromiseHolder<DecodePromise>& aPromise, StaticString aMethodName) {
|
||||
if (aPromise.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ class GMPVideoDecoder final : public MediaDataDecoder,
|
||||
virtual GMPUniquePtr<GMPVideoEncodedFrame> CreateFrame(MediaRawData* aSample);
|
||||
virtual const VideoInfo& GetConfig() const;
|
||||
void ProcessReorderQueue(MozPromiseHolder<DecodePromise>& aPromise,
|
||||
const char* aMethodName);
|
||||
StaticString aMethodName);
|
||||
|
||||
private:
|
||||
~GMPVideoDecoder() = default;
|
||||
|
@ -521,14 +521,14 @@ nsTArray<RefPtr<OmxPromiseLayer::BufferData>>* OmxDataDecoder::GetBuffers(
|
||||
return &mOutPortBuffers;
|
||||
}
|
||||
|
||||
void OmxDataDecoder::ResolveInitPromise(const char* aMethodName) {
|
||||
void OmxDataDecoder::ResolveInitPromise(StaticString aMethodName) {
|
||||
MOZ_ASSERT(mOmxTaskQueue->IsCurrentThreadIn());
|
||||
LOG("called from %s", aMethodName);
|
||||
LOG("called from %s", aMethodName.get());
|
||||
mInitPromise.ResolveIfExists(mTrackInfo->GetType(), aMethodName);
|
||||
}
|
||||
|
||||
void OmxDataDecoder::RejectInitPromise(MediaResult aError,
|
||||
const char* aMethodName) {
|
||||
StaticString aMethodName) {
|
||||
MOZ_ASSERT(mOmxTaskQueue->IsCurrentThreadIn());
|
||||
mInitPromise.RejectIfExists(aError, aMethodName);
|
||||
}
|
||||
|
@ -88,9 +88,9 @@ class OmxDataDecoder final : public MediaDataDecoder,
|
||||
protected:
|
||||
void InitializationTask();
|
||||
|
||||
void ResolveInitPromise(const char* aMethodName);
|
||||
void ResolveInitPromise(StaticString aMethodName);
|
||||
|
||||
void RejectInitPromise(MediaResult aError, const char* aMethodName);
|
||||
void RejectInitPromise(MediaResult aError, StaticString aMethodName);
|
||||
|
||||
void OmxStateRunner();
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "js/Value.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/StaticString.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
@ -58,7 +59,7 @@ class MozPromiseRejectOnDestruction final
|
||||
// (Accepting RefPtr<T> instead of T* because compiler fails to implicitly
|
||||
// convert it at call sites)
|
||||
MozPromiseRejectOnDestruction(const RefPtr<T>& aMozPromise,
|
||||
const char* aCallSite)
|
||||
StaticString aCallSite)
|
||||
: mMozPromise(aMozPromise), mCallSite(aCallSite) {
|
||||
MOZ_ASSERT(aMozPromise);
|
||||
}
|
||||
@ -70,7 +71,7 @@ class MozPromiseRejectOnDestruction final
|
||||
}
|
||||
|
||||
RefPtr<T> mMozPromise;
|
||||
const char* mCallSite;
|
||||
StaticString mCallSite;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
@ -38,18 +38,18 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
RefPtr<BoolPromise> CreateAndRejectBoolPromise(const char* aFunc,
|
||||
RefPtr<BoolPromise> CreateAndRejectBoolPromise(StaticString aFunc,
|
||||
nsresult aRv) {
|
||||
return CreateAndRejectMozPromise<BoolPromise>(aFunc, aRv);
|
||||
}
|
||||
|
||||
RefPtr<Int64Promise> CreateAndRejectInt64Promise(const char* aFunc,
|
||||
RefPtr<Int64Promise> CreateAndRejectInt64Promise(StaticString aFunc,
|
||||
nsresult aRv) {
|
||||
return CreateAndRejectMozPromise<Int64Promise>(aFunc, aRv);
|
||||
}
|
||||
|
||||
RefPtr<BoolPromise> CreateAndRejectBoolPromiseFromQMResult(
|
||||
const char* aFunc, const QMResult& aRv) {
|
||||
StaticString aFunc, const QMResult& aRv) {
|
||||
return CreateAndRejectMozPromise<BoolPromise>(aFunc, aRv);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "mozilla/MacroArgs.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "mozilla/StaticString.h"
|
||||
#include "mozilla/Try.h"
|
||||
#if defined(QM_LOG_ERROR_ENABLED) && defined(QM_ERROR_STACKS_ENABLED)
|
||||
# include "mozilla/Variant.h"
|
||||
@ -1133,7 +1134,7 @@ auto ErrToDefaultOk(const nsresult aValue) -> Result<V, nsresult> {
|
||||
}
|
||||
|
||||
template <typename MozPromiseType, typename RejectValueT = nsresult>
|
||||
auto CreateAndRejectMozPromise(const char* aFunc, const RejectValueT& aRv)
|
||||
auto CreateAndRejectMozPromise(StaticString aFunc, const RejectValueT& aRv)
|
||||
-> decltype(auto) {
|
||||
if constexpr (std::is_same_v<RejectValueT, nsresult>) {
|
||||
return MozPromiseType::CreateAndReject(aRv, aFunc);
|
||||
@ -1142,12 +1143,13 @@ auto CreateAndRejectMozPromise(const char* aFunc, const RejectValueT& aRv)
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<BoolPromise> CreateAndRejectBoolPromise(const char* aFunc, nsresult aRv);
|
||||
RefPtr<BoolPromise> CreateAndRejectBoolPromise(StaticString aFunc,
|
||||
nsresult aRv);
|
||||
|
||||
RefPtr<Int64Promise> CreateAndRejectInt64Promise(const char* aFunc,
|
||||
RefPtr<Int64Promise> CreateAndRejectInt64Promise(StaticString aFunc,
|
||||
nsresult aRv);
|
||||
|
||||
RefPtr<BoolPromise> CreateAndRejectBoolPromiseFromQMResult(const char* aFunc,
|
||||
RefPtr<BoolPromise> CreateAndRejectBoolPromiseFromQMResult(StaticString aFunc,
|
||||
const QMResult& aRv);
|
||||
|
||||
// Like Rust's collect with a step function, not a generic iterator/range.
|
||||
|
@ -603,7 +603,7 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
|
||||
RefPtr<dom::ContentParent> mContentParent;
|
||||
|
||||
void RejectOpenPromise(nsresult aStatus, nsresult aLoadGroupStatus,
|
||||
bool aContinueNavigating, const char* aLocation) {
|
||||
bool aContinueNavigating, StaticString aLocation) {
|
||||
// It is possible for mOpenPromise to not be set if AsyncOpen failed and
|
||||
// the DocumentChannel got canceled.
|
||||
if (!mOpenPromiseResolved && mOpenPromise) {
|
||||
|
@ -72,7 +72,8 @@ class ScaffoldingCallHandler {
|
||||
|
||||
// Create a second promise that gets resolved by a background task that
|
||||
// calls the scaffolding function
|
||||
RefPtr taskPromise = new typename TaskPromiseType::Private(aFuncName.get());
|
||||
RefPtr taskPromise =
|
||||
new typename TaskPromiseType::Private(StaticString(aFuncName));
|
||||
nsresult dispatchResult = NS_DispatchBackgroundTask(
|
||||
NS_NewRunnableFunction(aFuncName.get(),
|
||||
[args = std::move(convertedArgs), taskPromise,
|
||||
@ -80,16 +81,16 @@ class ScaffoldingCallHandler {
|
||||
auto callResult = CallScaffoldingFunc(
|
||||
aScaffoldingFunc, std::move(args));
|
||||
taskPromise->Resolve(std::move(callResult),
|
||||
aFuncName.get());
|
||||
StaticString(aFuncName));
|
||||
}),
|
||||
NS_DISPATCH_EVENT_MAY_BLOCK);
|
||||
if (NS_FAILED(dispatchResult)) {
|
||||
taskPromise->Reject(dispatchResult, aFuncName.get());
|
||||
taskPromise->Reject(dispatchResult, StaticString(aFuncName));
|
||||
}
|
||||
|
||||
// When the background task promise completes, resolve the JS promise
|
||||
taskPromise->Then(
|
||||
GetCurrentSerialEventTarget(), aFuncName.get(),
|
||||
GetCurrentSerialEventTarget(), StaticString(aFuncName),
|
||||
[xpcomGlobal, returnPromise,
|
||||
aFuncName](typename TaskPromiseType::ResolveOrRejectValue&& aResult) {
|
||||
if (!aResult.IsResolve()) {
|
||||
|
@ -409,7 +409,7 @@ RefPtr<ModulesTrustPromise> UntrustedModulesProcessor::GetModulesTrust(
|
||||
RefPtr<ModulesTrustPromise::Private> p(
|
||||
new ModulesTrustPromise::Private(__func__));
|
||||
nsCOMPtr<nsISerialEventTarget> evtTarget(mThread);
|
||||
const char* source = __func__;
|
||||
StaticString source = __func__;
|
||||
|
||||
auto runWrap = [evtTarget = std::move(evtTarget), p, source,
|
||||
run = std::move(run)]() mutable -> void {
|
||||
@ -441,7 +441,7 @@ UntrustedModulesProcessor::GetProcessedDataInternal() {
|
||||
}
|
||||
|
||||
RefPtr<UntrustedModulesPromise> UntrustedModulesProcessor::GetAllProcessedData(
|
||||
const char* aSource) {
|
||||
StaticString aSource) {
|
||||
AssertRunningOnLazyIdleThread();
|
||||
|
||||
UntrustedModulesData result;
|
||||
@ -471,7 +471,7 @@ UntrustedModulesProcessor::GetProcessedDataInternalChildProcess() {
|
||||
new UntrustedModulesPromise::Private(__func__));
|
||||
nsCOMPtr<nsISerialEventTarget> evtTarget(mThread);
|
||||
|
||||
const char* source = __func__;
|
||||
StaticString source = __func__;
|
||||
auto completionRoutine = [evtTarget = std::move(evtTarget), p,
|
||||
self = std::move(self), source,
|
||||
whenProcessed = std::move(whenProcessed)]() {
|
||||
@ -570,7 +570,7 @@ void UntrustedModulesProcessor::BackgroundProcessModuleLoadQueueChildProcess() {
|
||||
RefPtr<UntrustedModulesProcessor> self(this);
|
||||
nsCOMPtr<nsISerialEventTarget> evtTarget(mThread);
|
||||
|
||||
const char* source = __func__;
|
||||
constexpr StaticString const source = __func__;
|
||||
auto completionRoutine = [evtTarget = std::move(evtTarget),
|
||||
self = std::move(self), source,
|
||||
whenProcessed = std::move(whenProcessed)]() {
|
||||
|
@ -149,7 +149,7 @@ class UntrustedModulesProcessor final : public nsIObserver,
|
||||
Priority aPriority);
|
||||
|
||||
void CompleteProcessing(ModulesMapResultWithLoads&& aModulesAndLoads);
|
||||
RefPtr<UntrustedModulesPromise> GetAllProcessedData(const char* aSource);
|
||||
RefPtr<UntrustedModulesPromise> GetAllProcessedData(StaticString aSource);
|
||||
|
||||
private:
|
||||
RefPtr<LazyIdleThread> mThread;
|
||||
|
@ -58,8 +58,8 @@ gfxPoint nsIDeviceContextSpec::GetPrintingTranslate() {
|
||||
}
|
||||
|
||||
RefPtr<PrintEndDocumentPromise>
|
||||
nsIDeviceContextSpec::EndDocumentPromiseFromResult(nsresult aResult,
|
||||
const char* aSite) {
|
||||
nsIDeviceContextSpec::EndDocumentPromiseFromResult(
|
||||
nsresult aResult, mozilla::StaticString aSite) {
|
||||
return NS_SUCCEEDED(aResult)
|
||||
? PrintEndDocumentPromise::CreateAndResolve(true, aSite)
|
||||
: PrintEndDocumentPromise::CreateAndReject(aResult, aSite);
|
||||
|
@ -95,7 +95,7 @@ class nsIDeviceContextSpec : public nsISupports {
|
||||
const char* aCallSite, AsyncEndDocumentFunction aFunction);
|
||||
|
||||
static RefPtr<mozilla::gfx::PrintEndDocumentPromise>
|
||||
EndDocumentPromiseFromResult(nsresult aResult, const char* aSite);
|
||||
EndDocumentPromiseFromResult(nsresult aResult, mozilla::StaticString aSite);
|
||||
|
||||
nsCOMPtr<nsIPrintSettings> mPrintSettings;
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define nsTLiteralString_h
|
||||
|
||||
#include "nsTStringRepr.h"
|
||||
#include "mozilla/StaticString.h"
|
||||
|
||||
/**
|
||||
* nsTLiteralString_CharT
|
||||
@ -78,8 +79,10 @@ class nsTLiteralString : public mozilla::detail::nsTStringRepr<T> {
|
||||
* Prohibit get() on temporaries as in "x"_ns.get().
|
||||
* These should be written as just "x", using a string literal directly.
|
||||
*/
|
||||
const typename raw_type<T, int>::type get() const&& = delete;
|
||||
const typename raw_type<T, int>::type get() const& { return this->mData; }
|
||||
constexpr const typename raw_type<T, int>::type get() const&& = delete;
|
||||
constexpr const typename raw_type<T, int>::type get() const& {
|
||||
return this->mData;
|
||||
}
|
||||
|
||||
// At least older gcc versions do not accept these friend declarations,
|
||||
// complaining about an "invalid argument list" here, but not where the actual
|
||||
@ -110,4 +113,9 @@ class nsTLiteralString : public mozilla::detail::nsTStringRepr<T> {
|
||||
extern template class nsTLiteralString<char>;
|
||||
extern template class nsTLiteralString<char16_t>;
|
||||
|
||||
namespace mozilla {
|
||||
constexpr MOZ_IMPLICIT StaticString::StaticString(nsLiteralCString const& str)
|
||||
: mStr(str.get()) {}
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/StaticString.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Variant.h"
|
||||
#include "nsIDirectTaskDispatcher.h"
|
||||
@ -231,7 +232,7 @@ class MozPromise : public MozPromiseBase {
|
||||
protected:
|
||||
// MozPromise is the public type, and never constructed directly. Construct
|
||||
// a MozPromise::Private, defined below.
|
||||
MozPromise(const char* aCreationSite, bool aIsCompletionPromise)
|
||||
MozPromise(StaticString aCreationSite, bool aIsCompletionPromise)
|
||||
: mCreationSite(aCreationSite),
|
||||
mMutex("MozPromise Mutex"),
|
||||
mHaveRequest(false),
|
||||
@ -241,7 +242,7 @@ class MozPromise : public MozPromiseBase {
|
||||
mMagic4(&mMutex)
|
||||
#endif
|
||||
{
|
||||
PROMISE_LOG("%s creating MozPromise (%p)", mCreationSite, this);
|
||||
PROMISE_LOG("%s creating MozPromise (%p)", mCreationSite.get(), this);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -257,7 +258,7 @@ class MozPromise : public MozPromiseBase {
|
||||
|
||||
template <typename ResolveValueType_>
|
||||
[[nodiscard]] static RefPtr<MozPromise> CreateAndResolve(
|
||||
ResolveValueType_&& aResolveValue, const char* aResolveSite) {
|
||||
ResolveValueType_&& aResolveValue, StaticString aResolveSite) {
|
||||
static_assert(std::is_convertible_v<ResolveValueType_, ResolveValueT>,
|
||||
"Resolve() argument must be implicitly convertible to "
|
||||
"MozPromise's ResolveValueT");
|
||||
@ -269,7 +270,7 @@ class MozPromise : public MozPromiseBase {
|
||||
|
||||
template <typename RejectValueType_>
|
||||
[[nodiscard]] static RefPtr<MozPromise> CreateAndReject(
|
||||
RejectValueType_&& aRejectValue, const char* aRejectSite) {
|
||||
RejectValueType_&& aRejectValue, StaticString aRejectSite) {
|
||||
static_assert(std::is_convertible_v<RejectValueType_, RejectValueT>,
|
||||
"Reject() argument must be implicitly convertible to "
|
||||
"MozPromise's RejectValueT");
|
||||
@ -281,7 +282,7 @@ class MozPromise : public MozPromiseBase {
|
||||
|
||||
template <typename ResolveOrRejectValueType_>
|
||||
[[nodiscard]] static RefPtr<MozPromise> CreateAndResolveOrReject(
|
||||
ResolveOrRejectValueType_&& aValue, const char* aSite) {
|
||||
ResolveOrRejectValueType_&& aValue, StaticString aSite) {
|
||||
RefPtr<typename MozPromise::Private> p = new MozPromise::Private(aSite);
|
||||
p->ResolveOrReject(std::forward<ResolveOrRejectValueType_>(aValue), aSite);
|
||||
return p;
|
||||
@ -497,7 +498,7 @@ class MozPromise : public MozPromiseBase {
|
||||
RefPtr<MozPromise> mPromise;
|
||||
};
|
||||
|
||||
ThenValueBase(nsISerialEventTarget* aResponseTarget, const char* aCallSite)
|
||||
ThenValueBase(nsISerialEventTarget* aResponseTarget, StaticString aCallSite)
|
||||
: mResponseTarget(aResponseTarget), mCallSite(aCallSite) {
|
||||
MOZ_ASSERT(aResponseTarget);
|
||||
}
|
||||
@ -526,7 +527,7 @@ class MozPromise : public MozPromiseBase {
|
||||
MOZ_CRASH_UNSAFE_PRINTF(
|
||||
"MozPromise::ThenValue created from '%s' destroyed without being "
|
||||
"either disconnected, resolved, or rejected (dispatchRv: %s)",
|
||||
mCallSite,
|
||||
mCallSite.get(),
|
||||
mDispatchRv ? GetStaticErrorName(*mDispatchRv)
|
||||
: "not dispatched");
|
||||
}
|
||||
@ -543,8 +544,8 @@ class MozPromise : public MozPromiseBase {
|
||||
PROMISE_LOG(
|
||||
"%s Then() call made from %s [Runnable=%p, Promise=%p, ThenValue=%p] "
|
||||
"%s dispatch",
|
||||
aPromise->mValue.IsResolve() ? "Resolving" : "Rejecting", mCallSite,
|
||||
r.get(), aPromise, this,
|
||||
aPromise->mValue.IsResolve() ? "Resolving" : "Rejecting",
|
||||
mCallSite.get(), r.get(), aPromise, this,
|
||||
aPromise->mUseSynchronousTaskDispatch ? "synchronous"
|
||||
: aPromise->mUseDirectTaskDispatch ? "directtask"
|
||||
: "normal");
|
||||
@ -631,7 +632,7 @@ class MozPromise : public MozPromiseBase {
|
||||
#ifdef PROMISE_DEBUG
|
||||
uint32_t mMagic1 = sMagic;
|
||||
#endif
|
||||
const char* mCallSite;
|
||||
StaticString mCallSite;
|
||||
#ifdef PROMISE_DEBUG
|
||||
uint32_t mMagic2 = sMagic;
|
||||
#endif
|
||||
@ -706,7 +707,7 @@ class MozPromise : public MozPromiseBase {
|
||||
public:
|
||||
ThenValue(nsISerialEventTarget* aResponseTarget, ThisType* aThisVal,
|
||||
ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod,
|
||||
const char* aCallSite)
|
||||
StaticString aCallSite)
|
||||
: ThenValueBase(aResponseTarget, aCallSite),
|
||||
mThisVal(aThisVal),
|
||||
mResolveMethod(aResolveMethod),
|
||||
@ -767,7 +768,7 @@ class MozPromise : public MozPromiseBase {
|
||||
public:
|
||||
ThenValue(nsISerialEventTarget* aResponseTarget, ThisType* aThisVal,
|
||||
ResolveRejectMethodType aResolveRejectMethod,
|
||||
const char* aCallSite)
|
||||
StaticString aCallSite)
|
||||
: ThenValueBase(aResponseTarget, aCallSite),
|
||||
mThisVal(aThisVal),
|
||||
mResolveRejectMethod(aResolveRejectMethod) {}
|
||||
@ -824,7 +825,7 @@ class MozPromise : public MozPromiseBase {
|
||||
public:
|
||||
ThenValue(nsISerialEventTarget* aResponseTarget,
|
||||
ResolveFunction&& aResolveFunction,
|
||||
RejectFunction&& aRejectFunction, const char* aCallSite)
|
||||
RejectFunction&& aRejectFunction, StaticString aCallSite)
|
||||
: ThenValueBase(aResponseTarget, aCallSite) {
|
||||
mResolveFunction.emplace(std::move(aResolveFunction));
|
||||
mRejectFunction.emplace(std::move(aRejectFunction));
|
||||
@ -892,7 +893,7 @@ class MozPromise : public MozPromiseBase {
|
||||
public:
|
||||
ThenValue(nsISerialEventTarget* aResponseTarget,
|
||||
ResolveRejectFunction&& aResolveRejectFunction,
|
||||
const char* aCallSite)
|
||||
StaticString aCallSite)
|
||||
: ThenValueBase(aResponseTarget, aCallSite) {
|
||||
mResolveRejectFunction.emplace(std::move(aResolveRejectFunction));
|
||||
}
|
||||
@ -945,7 +946,7 @@ class MozPromise : public MozPromiseBase {
|
||||
|
||||
public:
|
||||
explicit MapValue(nsISerialEventTarget* aResponseTarget,
|
||||
ResolveFunction&& f, const char* aCallSite)
|
||||
ResolveFunction&& f, StaticString aCallSite)
|
||||
: ThenValueBase(aResponseTarget, aCallSite),
|
||||
mResolveFunction(Some(std::forward<ResolveFunction>(f))) {}
|
||||
|
||||
@ -991,7 +992,7 @@ class MozPromise : public MozPromiseBase {
|
||||
|
||||
public:
|
||||
explicit MapErrValue(nsISerialEventTarget* aResponseTarget,
|
||||
RejectFunction&& f, const char* aCallSite)
|
||||
RejectFunction&& f, StaticString aCallSite)
|
||||
: ThenValueBase(aResponseTarget, aCallSite),
|
||||
mRejectFunction(Some(std::forward<RejectFunction>(f))) {}
|
||||
|
||||
@ -1030,7 +1031,7 @@ class MozPromise : public MozPromiseBase {
|
||||
|
||||
public:
|
||||
void ThenInternal(already_AddRefed<ThenValueBase> aThenValue,
|
||||
const char* aCallSite) {
|
||||
StaticString aCallSite) {
|
||||
PROMISE_ASSERT(mMagic1 == sMagic && mMagic2 == sMagic &&
|
||||
mMagic3 == sMagic && mMagic4 == &mMutex);
|
||||
RefPtr<ThenValueBase> thenValue = aThenValue;
|
||||
@ -1040,7 +1041,7 @@ class MozPromise : public MozPromiseBase {
|
||||
"Using an exclusive promise in a non-exclusive fashion");
|
||||
mHaveRequest = true;
|
||||
PROMISE_LOG("%s invoking Then() [this=%p, aThenValue=%p, isPending=%d]",
|
||||
aCallSite, this, thenValue.get(), (int)IsPending());
|
||||
aCallSite.get(), this, thenValue.get(), (int)IsPending());
|
||||
if (!IsPending()) {
|
||||
thenValue->Dispatch(this);
|
||||
} else {
|
||||
@ -1072,7 +1073,7 @@ class MozPromise : public MozPromiseBase {
|
||||
using PromiseType = typename ThenValueType::PromiseType;
|
||||
using Private = typename PromiseType::Private;
|
||||
|
||||
ThenCommand(const char* aCallSite,
|
||||
ThenCommand(StaticString aCallSite,
|
||||
already_AddRefed<ThenValueType> aThenValue,
|
||||
MozPromise* aReceiver)
|
||||
: mCallSite(aCallSite), mThenValue(aThenValue), mReceiver(aReceiver) {}
|
||||
@ -1137,7 +1138,7 @@ class MozPromise : public MozPromiseBase {
|
||||
ThenCommand* operator->() { return this; }
|
||||
|
||||
private:
|
||||
const char* mCallSite;
|
||||
StaticString mCallSite;
|
||||
RefPtr<ThenValueType> mThenValue;
|
||||
RefPtr<MozPromise> mReceiver;
|
||||
};
|
||||
@ -1146,7 +1147,7 @@ class MozPromise : public MozPromiseBase {
|
||||
template <typename ThisType, typename... Methods,
|
||||
typename ThenValueType = ThenValue<ThisType*, Methods...>,
|
||||
typename ReturnType = ThenCommand<ThenValueType>>
|
||||
ReturnType Then(nsISerialEventTarget* aResponseTarget, const char* aCallSite,
|
||||
ReturnType Then(nsISerialEventTarget* aResponseTarget, StaticString aCallSite,
|
||||
ThisType* aThisVal, Methods... aMethods) {
|
||||
RefPtr<ThenValueType> thenValue =
|
||||
new ThenValueType(aResponseTarget, aThisVal, aMethods..., aCallSite);
|
||||
@ -1156,7 +1157,7 @@ class MozPromise : public MozPromiseBase {
|
||||
template <typename... Functions,
|
||||
typename ThenValueType = ThenValue<Functions...>,
|
||||
typename ReturnType = ThenCommand<ThenValueType>>
|
||||
ReturnType Then(nsISerialEventTarget* aResponseTarget, const char* aCallSite,
|
||||
ReturnType Then(nsISerialEventTarget* aResponseTarget, StaticString aCallSite,
|
||||
Functions&&... aFunctions) {
|
||||
RefPtr<ThenValueType> thenValue =
|
||||
new ThenValueType(aResponseTarget, std::move(aFunctions)..., aCallSite);
|
||||
@ -1166,7 +1167,7 @@ class MozPromise : public MozPromiseBase {
|
||||
// Shorthand for a `Then` which simply forwards the reject-value, but performs
|
||||
// some additional work with the resolve-value.
|
||||
template <typename Function>
|
||||
auto Map(nsISerialEventTarget* aResponseTarget, const char* aCallSite,
|
||||
auto Map(nsISerialEventTarget* aResponseTarget, StaticString aCallSite,
|
||||
Function&& function) {
|
||||
RefPtr<MapValue<Function>> thenValue = new MapValue<Function>(
|
||||
aResponseTarget, std::forward<Function>(function), aCallSite);
|
||||
@ -1176,7 +1177,7 @@ class MozPromise : public MozPromiseBase {
|
||||
// Shorthand for a `Then` which simply forwards the resolve-value, but
|
||||
// performs some additional work with the reject-value.
|
||||
template <typename Function>
|
||||
auto MapErr(nsISerialEventTarget* aResponseTarget, const char* aCallSite,
|
||||
auto MapErr(nsISerialEventTarget* aResponseTarget, StaticString aCallSite,
|
||||
Function&& function) {
|
||||
RefPtr<MapErrValue<Function>> thenValue = new MapErrValue<Function>(
|
||||
aResponseTarget, std::forward<Function>(function), aCallSite);
|
||||
@ -1185,7 +1186,7 @@ class MozPromise : public MozPromiseBase {
|
||||
}
|
||||
|
||||
void ChainTo(already_AddRefed<Private> aChainedPromise,
|
||||
const char* aCallSite) {
|
||||
StaticString aCallSite) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
!IsExclusive || !mHaveRequest,
|
||||
@ -1194,7 +1195,7 @@ class MozPromise : public MozPromiseBase {
|
||||
RefPtr<Private> chainedPromise = aChainedPromise;
|
||||
PROMISE_LOG(
|
||||
"%s invoking Chain() [this=%p, chainedPromise=%p, isPending=%d]",
|
||||
aCallSite, this, chainedPromise.get(), (int)IsPending());
|
||||
aCallSite.get(), this, chainedPromise.get(), (int)IsPending());
|
||||
|
||||
// We want to use the same type of dispatching method with the chained
|
||||
// promises.
|
||||
@ -1305,7 +1306,7 @@ class MozPromise : public MozPromiseBase {
|
||||
#endif
|
||||
};
|
||||
|
||||
const char* mCreationSite; // For logging
|
||||
StaticString mCreationSite; // For logging
|
||||
Mutex mMutex MOZ_UNANNOTATED;
|
||||
ResolveOrRejectValue mValue;
|
||||
bool mUseSynchronousTaskDispatch = false;
|
||||
@ -1335,21 +1336,22 @@ template <typename ResolveValueT, typename RejectValueT, bool IsExclusive>
|
||||
class MozPromise<ResolveValueT, RejectValueT, IsExclusive>::Private
|
||||
: public MozPromise<ResolveValueT, RejectValueT, IsExclusive> {
|
||||
public:
|
||||
explicit Private(const char* aCreationSite, bool aIsCompletionPromise = false)
|
||||
explicit Private(StaticString aCreationSite,
|
||||
bool aIsCompletionPromise = false)
|
||||
: MozPromise(aCreationSite, aIsCompletionPromise) {}
|
||||
|
||||
template <typename ResolveValueT_>
|
||||
void Resolve(ResolveValueT_&& aResolveValue, const char* aResolveSite) {
|
||||
void Resolve(ResolveValueT_&& aResolveValue, StaticString aResolveSite) {
|
||||
PROMISE_ASSERT(mMagic1 == sMagic && mMagic2 == sMagic &&
|
||||
mMagic3 == sMagic && mMagic4 == &mMutex);
|
||||
MutexAutoLock lock(mMutex);
|
||||
PROMISE_LOG("%s resolving MozPromise (%p created at %s)", aResolveSite,
|
||||
this, mCreationSite);
|
||||
PROMISE_LOG("%s resolving MozPromise (%p created at %s)",
|
||||
aResolveSite.get(), this, mCreationSite.get());
|
||||
if (!IsPending()) {
|
||||
PROMISE_LOG(
|
||||
"%s ignored already resolved or rejected MozPromise (%p created at "
|
||||
"%s)",
|
||||
aResolveSite, this, mCreationSite);
|
||||
aResolveSite.get(), this, mCreationSite.get());
|
||||
return;
|
||||
}
|
||||
mValue.SetResolve(std::forward<ResolveValueT_>(aResolveValue));
|
||||
@ -1357,17 +1359,17 @@ class MozPromise<ResolveValueT, RejectValueT, IsExclusive>::Private
|
||||
}
|
||||
|
||||
template <typename RejectValueT_>
|
||||
void Reject(RejectValueT_&& aRejectValue, const char* aRejectSite) {
|
||||
void Reject(RejectValueT_&& aRejectValue, StaticString aRejectSite) {
|
||||
PROMISE_ASSERT(mMagic1 == sMagic && mMagic2 == sMagic &&
|
||||
mMagic3 == sMagic && mMagic4 == &mMutex);
|
||||
MutexAutoLock lock(mMutex);
|
||||
PROMISE_LOG("%s rejecting MozPromise (%p created at %s)", aRejectSite, this,
|
||||
mCreationSite);
|
||||
PROMISE_LOG("%s rejecting MozPromise (%p created at %s)", aRejectSite.get(),
|
||||
this, mCreationSite.get());
|
||||
if (!IsPending()) {
|
||||
PROMISE_LOG(
|
||||
"%s ignored already resolved or rejected MozPromise (%p created at "
|
||||
"%s)",
|
||||
aRejectSite, this, mCreationSite);
|
||||
aRejectSite.get(), this, mCreationSite.get());
|
||||
return;
|
||||
}
|
||||
mValue.SetReject(std::forward<RejectValueT_>(aRejectValue));
|
||||
@ -1375,17 +1377,17 @@ class MozPromise<ResolveValueT, RejectValueT, IsExclusive>::Private
|
||||
}
|
||||
|
||||
template <typename ResolveOrRejectValue_>
|
||||
void ResolveOrReject(ResolveOrRejectValue_&& aValue, const char* aSite) {
|
||||
void ResolveOrReject(ResolveOrRejectValue_&& aValue, StaticString aSite) {
|
||||
PROMISE_ASSERT(mMagic1 == sMagic && mMagic2 == sMagic &&
|
||||
mMagic3 == sMagic && mMagic4 == &mMutex);
|
||||
MutexAutoLock lock(mMutex);
|
||||
PROMISE_LOG("%s resolveOrRejecting MozPromise (%p created at %s)", aSite,
|
||||
this, mCreationSite);
|
||||
PROMISE_LOG("%s resolveOrRejecting MozPromise (%p created at %s)",
|
||||
aSite.get(), this, mCreationSite.get());
|
||||
if (!IsPending()) {
|
||||
PROMISE_LOG(
|
||||
"%s ignored already resolved or rejected MozPromise (%p created at "
|
||||
"%s)",
|
||||
aSite, this, mCreationSite);
|
||||
aSite.get(), this, mCreationSite.get());
|
||||
return;
|
||||
}
|
||||
mValue = std::forward<ResolveOrRejectValue_>(aValue);
|
||||
@ -1403,7 +1405,7 @@ class MozPromise<ResolveValueT, RejectValueT, IsExclusive>::Private
|
||||
mMagic3 == sMagic && mMagic4 == &mMutex);
|
||||
MutexAutoLock lock(mMutex);
|
||||
PROMISE_LOG("%s UseSynchronousTaskDispatch MozPromise (%p created at %s)",
|
||||
aSite, this, mCreationSite);
|
||||
aSite, this, mCreationSite.get());
|
||||
MOZ_ASSERT(IsPending(),
|
||||
"A Promise must not have been already resolved or rejected to "
|
||||
"set dispatch state");
|
||||
@ -1420,7 +1422,7 @@ class MozPromise<ResolveValueT, RejectValueT, IsExclusive>::Private
|
||||
mMagic3 == sMagic && mMagic4 == &mMutex);
|
||||
MutexAutoLock lock(mMutex);
|
||||
PROMISE_LOG("%s UseDirectTaskDispatch MozPromise (%p created at %s)", aSite,
|
||||
this, mCreationSite);
|
||||
this, mCreationSite.get());
|
||||
MOZ_ASSERT(IsPending(),
|
||||
"A Promise must not have been already resolved or rejected to "
|
||||
"set dispatch state");
|
||||
@ -1437,7 +1439,7 @@ class MozPromise<ResolveValueT, RejectValueT, IsExclusive>::Private
|
||||
mMagic3 == sMagic && mMagic4 == &mMutex);
|
||||
MutexAutoLock lock(mMutex);
|
||||
PROMISE_LOG("%s TaskPriority MozPromise (%p created at %s)", aSite, this,
|
||||
mCreationSite);
|
||||
mCreationSite.get());
|
||||
MOZ_ASSERT(IsPending(),
|
||||
"A Promise must not have been already resolved or rejected to "
|
||||
"set dispatch state");
|
||||
@ -1478,7 +1480,7 @@ class MozPromiseHolderBase {
|
||||
|
||||
~MozPromiseHolderBase() { MOZ_ASSERT(!mPromise); }
|
||||
|
||||
already_AddRefed<PromiseType> Ensure(const char* aMethodName) {
|
||||
already_AddRefed<PromiseType> Ensure(StaticString aMethodName) {
|
||||
static_cast<ImplType*>(this)->Check();
|
||||
if (!mPromise) {
|
||||
mPromise = new (typename PromiseType::Private)(aMethodName);
|
||||
@ -1498,7 +1500,7 @@ class MozPromiseHolderBase {
|
||||
}
|
||||
|
||||
template <typename ResolveValueType_>
|
||||
void Resolve(ResolveValueType_&& aResolveValue, const char* aMethodName) {
|
||||
void Resolve(ResolveValueType_&& aResolveValue, StaticString aMethodName) {
|
||||
static_assert(std::is_convertible_v<ResolveValueType_,
|
||||
typename PromiseType::ResolveValueType>,
|
||||
"Resolve() argument must be implicitly convertible to "
|
||||
@ -1513,14 +1515,14 @@ class MozPromiseHolderBase {
|
||||
|
||||
template <typename ResolveValueType_>
|
||||
void ResolveIfExists(ResolveValueType_&& aResolveValue,
|
||||
const char* aMethodName) {
|
||||
StaticString aMethodName) {
|
||||
if (!IsEmpty()) {
|
||||
Resolve(std::forward<ResolveValueType_>(aResolveValue), aMethodName);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename RejectValueType_>
|
||||
void Reject(RejectValueType_&& aRejectValue, const char* aMethodName) {
|
||||
void Reject(RejectValueType_&& aRejectValue, StaticString aMethodName) {
|
||||
static_assert(std::is_convertible_v<RejectValueType_,
|
||||
typename PromiseType::RejectValueType>,
|
||||
"Reject() argument must be implicitly convertible to "
|
||||
@ -1534,7 +1536,7 @@ class MozPromiseHolderBase {
|
||||
|
||||
template <typename RejectValueType_>
|
||||
void RejectIfExists(RejectValueType_&& aRejectValue,
|
||||
const char* aMethodName) {
|
||||
StaticString aMethodName) {
|
||||
if (!IsEmpty()) {
|
||||
Reject(std::forward<RejectValueType_>(aRejectValue), aMethodName);
|
||||
}
|
||||
@ -1542,7 +1544,7 @@ class MozPromiseHolderBase {
|
||||
|
||||
template <typename ResolveOrRejectValueType_>
|
||||
void ResolveOrReject(ResolveOrRejectValueType_&& aValue,
|
||||
const char* aMethodName) {
|
||||
StaticString aMethodName) {
|
||||
static_cast<ImplType*>(this)->Check();
|
||||
MOZ_ASSERT(mPromise);
|
||||
mPromise->ResolveOrReject(std::forward<ResolveOrRejectValueType_>(aValue),
|
||||
@ -1552,7 +1554,7 @@ class MozPromiseHolderBase {
|
||||
|
||||
template <typename ResolveOrRejectValueType_>
|
||||
void ResolveOrRejectIfExists(ResolveOrRejectValueType_&& aValue,
|
||||
const char* aMethodName) {
|
||||
StaticString aMethodName) {
|
||||
if (!IsEmpty()) {
|
||||
ResolveOrReject(std::forward<ResolveOrRejectValueType_>(aValue),
|
||||
aMethodName);
|
||||
@ -1718,7 +1720,7 @@ class ProxyRunnable : public CancelableRunnable {
|
||||
template <typename... Storages, typename PromiseType, typename ThisType,
|
||||
typename... ArgTypes, typename... ActualArgTypes>
|
||||
static RefPtr<PromiseType> InvokeAsyncImpl(
|
||||
nsISerialEventTarget* aTarget, ThisType* aThisVal, const char* aCallerName,
|
||||
nsISerialEventTarget* aTarget, ThisType* aThisVal, StaticString aCallerName,
|
||||
RefPtr<PromiseType> (ThisType::*aMethod)(ArgTypes...),
|
||||
ActualArgTypes&&... aArgs) {
|
||||
MOZ_ASSERT(aTarget);
|
||||
@ -1758,7 +1760,7 @@ template <typename... Storages, typename PromiseType, typename ThisType,
|
||||
typename... ArgTypes, typename... ActualArgTypes,
|
||||
std::enable_if_t<sizeof...(Storages) != 0, int> = 0>
|
||||
static RefPtr<PromiseType> InvokeAsync(
|
||||
nsISerialEventTarget* aTarget, ThisType* aThisVal, const char* aCallerName,
|
||||
nsISerialEventTarget* aTarget, ThisType* aThisVal, StaticString aCallerName,
|
||||
RefPtr<PromiseType> (ThisType::*aMethod)(ArgTypes...),
|
||||
ActualArgTypes&&... aArgs) {
|
||||
static_assert(
|
||||
@ -1777,7 +1779,7 @@ template <typename... Storages, typename PromiseType, typename ThisType,
|
||||
typename... ArgTypes, typename... ActualArgTypes,
|
||||
std::enable_if_t<sizeof...(Storages) == 0, int> = 0>
|
||||
static RefPtr<PromiseType> InvokeAsync(
|
||||
nsISerialEventTarget* aTarget, ThisType* aThisVal, const char* aCallerName,
|
||||
nsISerialEventTarget* aTarget, ThisType* aThisVal, StaticString aCallerName,
|
||||
RefPtr<PromiseType> (ThisType::*aMethod)(ArgTypes...),
|
||||
ActualArgTypes&&... aArgs) {
|
||||
static_assert(
|
||||
@ -1831,7 +1833,7 @@ constexpr static bool IsRefPtrMozPromise<RefPtr<MozPromise<T, U, B>>> = true;
|
||||
// Invoke a function object (e.g., lambda) asynchronously.
|
||||
// Return a promise that the function should eventually resolve or reject.
|
||||
template <typename Function>
|
||||
static auto InvokeAsync(nsISerialEventTarget* aTarget, const char* aCallerName,
|
||||
static auto InvokeAsync(nsISerialEventTarget* aTarget, StaticString aCallerName,
|
||||
Function&& aFunction) -> decltype(aFunction()) {
|
||||
static_assert(!std::is_lvalue_reference_v<Function>,
|
||||
"Function object must not be passed by lvalue-ref (to avoid "
|
||||
|
102
xpcom/threads/StaticString.h
Normal file
102
xpcom/threads/StaticString.h
Normal file
@ -0,0 +1,102 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef XPCOM_THREADS_STATICSTRING_H_
|
||||
#define XPCOM_THREADS_STATICSTRING_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
// from "nsStringFwd.h"
|
||||
template <typename T>
|
||||
class nsTLiteralString;
|
||||
using nsLiteralCString = nsTLiteralString<char>;
|
||||
|
||||
namespace mozilla {
|
||||
// class StaticString
|
||||
//
|
||||
// Wrapper type containing a C-style string which is guaranteed[*] to have been
|
||||
// created (potentially indirectly) from static data. Primarily intended for
|
||||
// text that may eventually be sent up via telemetry, to avoid the possibility
|
||||
// of accidentally exfiltrating PII.
|
||||
//
|
||||
// `StaticString`, like `template <size_t N> const char (&str)[N]`, can be
|
||||
// freely and implicitly converted to `const char *`, to simplify its use as a
|
||||
// drop-in replacement when detemplatizing functions.
|
||||
//
|
||||
// ### Comparison/contrast with `nsLiteralCString`
|
||||
//
|
||||
// Concretely, `StaticString` is smaller than `nsLiteralCString`, as it does not
|
||||
// store the string-length. It's also trivial to construct a `StaticString` from
|
||||
// the variable `__func__` or the preprocessor token `__FILE__`, which would
|
||||
// require additional work to be used with the latter's `_ns` constructor.
|
||||
//
|
||||
// Conventionally, the primary intended use case of `StaticString` is subtly
|
||||
// different from that of `nsLiteralCString`:
|
||||
// * `StaticString` is intended for correctness (etc.) in contexts where the
|
||||
// consumer of the string requires that it be static.
|
||||
// * `nsLiteralCString` is more for efficiency in contexts where the source
|
||||
// string _happens to be_ static, but in which the consumer does not care
|
||||
// (and so accepts `nsACString const &` or similar).
|
||||
//
|
||||
// This is not a hard rule, however, and is notably bent in dom::Promise. (See
|
||||
// comments below.)
|
||||
//
|
||||
// Both are trivially-copyable/-movable/-destructible, guaranteed non-null, and
|
||||
// can only contain static data.
|
||||
//
|
||||
// #### Footnotes
|
||||
//
|
||||
// [*] ```
|
||||
// CHORUS: "What, never?"
|
||||
// CAPTAIN: "Well... hardly ever!"
|
||||
// CHORUS: "He's hardly ever sick of C!"
|
||||
// -- Gilbert & Sullivan, _H.M.S. Pinafore_ (emended)
|
||||
// ```
|
||||
//
|
||||
class StaticString {
|
||||
/* TODO(C++20): convert `constexpr` to `consteval` wherever possible. */
|
||||
const char* mStr; // guaranteed nonnull
|
||||
|
||||
public:
|
||||
template <size_t N>
|
||||
constexpr MOZ_IMPLICIT StaticString(const char (&str)[N]) : mStr(str) {}
|
||||
|
||||
// `nsLiteralCString` has the same guarantees as `StaticString` (both in being
|
||||
// nonnull and containing only static data), so it's safe to construct either
|
||||
// from the other.
|
||||
//
|
||||
// At present we only support construction of a `StaticString` from an
|
||||
// `nsLiteralCString`, since this is zero-cost (the converse would not be),
|
||||
// and is probably the simplest way to support dom::Promise's interoperation
|
||||
// with MozPromise.
|
||||
//
|
||||
// (A more principled approach, in some sense, would be to create a third type
|
||||
// `StaticStringWithLength` (or whatever) acting as the lattice-join of the
|
||||
// two, which could then decay to either one as necessary. This is overkill
|
||||
// for our current goals... but might be worthwhile if, _e.g._, you really
|
||||
// need to get `__func__` into an `nsLiteralCString` rather than just an
|
||||
// `nsDependentCString` for some reason.)
|
||||
//
|
||||
constexpr explicit StaticString(nsLiteralCString const& str);
|
||||
|
||||
constexpr StaticString(StaticString const&) = default;
|
||||
constexpr StaticString(StaticString&&) = default;
|
||||
~StaticString() = default;
|
||||
|
||||
constexpr MOZ_IMPLICIT operator const char*() const { return mStr; }
|
||||
|
||||
// Not normally needed, but useful for variadic logging functions.
|
||||
constexpr const char* get() const { return mStr; }
|
||||
};
|
||||
|
||||
// Under the covers, StaticString is as lightweight as a single pointer: it does
|
||||
// not store the length of its deta.
|
||||
static_assert(sizeof(StaticString) == sizeof(const char*));
|
||||
static_assert(alignof(StaticString) == alignof(const char*));
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -70,6 +70,7 @@ EXPORTS.mozilla += [
|
||||
"SpinEventLoopUntil.h",
|
||||
"StateMirroring.h",
|
||||
"StateWatching.h",
|
||||
"StaticString.h",
|
||||
"SynchronizedEventQueue.h",
|
||||
"SyncRunnable.h",
|
||||
"TaskController.h",
|
||||
|
Loading…
Reference in New Issue
Block a user