Files
palemoon27/dom/promise/Promise.h
T
roytam1 67e04cfead import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1236750 - Introduce a new unit type CSSTransformedLayerPixel. r=kats (4e9bba3d19)
- Bug 1236750 - Add a ViewAs() overload for casting (with a justification) one typed matrix to another. r=kats (c48e143508)
- Bug 1236750 - Add some specialized typedefs of Matrix4x4 to represent layer transform matrices. r=kats (cc50113c98)
- Bug 1239300 - reject promise with null while creating imagebitmap from empty blob; r=smaug (bff7483bf1)
- Bug 1233056 - Long tapping on a link will select a different link from the page r=tnikkel (3a727b33c1)
- Bug 1245674. Null-check mGlobal before dereferencing it in one more place in Promise code. r=smaug (68cf5312dc)
- Bug 1236750 - Use strongly-typed matrices to represent layer transforms in APZ code. r=kats (63931eb2a1)
- Bug 1236750 - Add typed getters for layer transform matrices. r=kats (baef978fe1)
- Bug 1147673 - Relax the ancestor transform assertion a little. r=kats (ec9ce47ba4)
- Bug 1154161 Initialize WidgetQueryContentEvent::mReply r=smaug (6086291313)
- Bug 1240921 - Use nsAutoTArray in nsStyleSet::RuleNodeWithReplacement. r=bz. (66f6823b46)
- Bug 1229437 part 1 - Add a helper function to get the float containing block of a given frame. r=dbaron (72de452e5d)
- Bug 1229437 part 2 - Reparent floats inside pulled ruby segment. r=dbaron (82cc44632d)
- Bug 1229437 part 3 - Support iterating frames of RubyColumn. r=dholbert (5d43e7f6ff)
- Bug 1229437 part 4 - Reparent floats inside pulled ruby column. r=dbaron (4c1a7ff20b)
- Bug 1229437 part 5 - Add crashtests for this bug. r=dbaron (6afabe1604)
- Bug 1229437 followup - Fix sign-compare error in RubyColumn::Iterator on CLOSED TREE. (e93453d00a)
- Bug 1229437 followup 2 - Fix another sign-compare error in RubyColumn::Iterator on CLOSED TREE. (c0bf6a2a7b)
- Bug 1229437 followup 3 - Fix a mistake in RubyColumn::Iterator::SkipUntilExistingFrame(). a=me (1ce408e194)
- bits of Bug 1072150 - Use the opt-out for various sloppy consumers (29d97c59ca)
- Make test_bug946632 compatible with asynchronous scrolling. (bug 1140293, r=mstange) (e975a8350c)
- fix misspatch of 1072150 (a3e580fa4b)
- Bug 686281 - Implement nsStyleImageLayers; r=dbaron (85bb33c8e6)
- Bug 686281 - Rename *background* to *imagelayer*; r=dbaron. (36d90f112d)
- Bug 1230034 part 4 - Make FramePropertyDescriptor to be a template. r=froydnj,dbaron (271cd19b6e)
- Bug 1230034 part 5 - Convert all frame properties which use DeleteValue and ReleaseValue as destructor to be typesafe. r=dbaron (efc8d63c9d)
- Bug 1230034 part 6 - Convert all frame properties which do not hold pointer to be typed. r=dbaron (b5541775f7)
- Bug 1230034 part 7 - Convert nsIFrame::GenConProperty to be typed. r=dbaron (2b71527b2c)
- Bug 1230034 part 8 - Convert frame properties which assert on destructor to be typed. r=dbaron (0f125a3414)
- Bug 1230034 part 9 - Convert FrameLayerBuilder::LayerManagerDataProperty to be typed. r=dbaron (1147498c2f)
- Bug 1230034 part 10 - Convert remaining frame properties to by typed and remove the unsafe declaring macro. r=dbaron (d59d94eac4)
- Bug 1072501: Unmap file mapping on source surface destruction. r=jrmuizel (19fd63890a)
- Bug 1235613 - Make gfxCriticalError/Note strings in gfx/ unique. r=jrmuizel (780c6ff862)
- Bug 1247535 - Fix -Wunreachable-code warning in mfbt/Poison.cpp. r=froydnj (0e7cf60b6d)
- Bug 1239479: Add comments to mfbt/XorShift128PlusRNG.h from the RNG's designer. DONTBUILD r=Waldo (bb674b07ce)
- Add an assertion message to the assert-is-empty in LinkedList::~LinkedList, to indicate to users who hit it that it's the fault of the caller, not the fault of MFBT code. No bug, rs=froydnj (4cad80874c)
- Bug 1221103 - Add a comment to nsIChannel::securityInfo noting that this info may appear on non-nsHttpChannels and how that may happen. r=bz IGNORE IDL (cd9cebc3f2)
- Bug 1001765 - Make login credentials in Saved Passwords manager editable. r=MattN (09eec4f6f8)
- Bug 1188478 - Add an Import button to the password manager to open the browser migrator. r=dolske (d1126a89fc)
- Bug 1199382 - Rename some strings from "password" to "login" in preferences and the manager. r=markh (60638f5e2a)
- Bug 1207733 - Update @disabled on the Remove Password button when selection changes. r=MattN (64ac9f22f6)
- bits of 1124472 and 1166840 (26e2681183)
- Bug 1219707 - fix argument passing to migration.js, r=jaws (55d332f5c6)
- bug 1215657 - make AccessibleWrap::get_accSelection work with proxies=davidb (4e72111032)
- fix missing telemetry entry (4fcfabb3e6)
and follow-up API changes of TFF#493.
2023-11-09 16:35:18 +08:00

533 lines
18 KiB
C++

/* -*- 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 mozilla_dom_Promise_h
#define mozilla_dom_Promise_h
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/TypeTraits.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/dom/PromiseBinding.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/WeakPtr.h"
#include "nsWrapperCache.h"
#include "nsAutoPtr.h"
#include "js/TypeDecls.h"
#include "jspubtd.h"
// Bug 1083361 introduces a new mechanism for tracking uncaught
// rejections. This #define serves to track down the parts of code
// that need to be removed once clients have been put together
// to take advantage of the new mechanism. New code should not
// depend on code #ifdefed to this #define.
#define DOM_PROMISE_DEPRECATED_REPORTING 1
#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
#include "mozilla/dom/workers/bindings/WorkerFeature.h"
#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
class nsIGlobalObject;
namespace mozilla {
namespace dom {
class AnyCallback;
class DOMError;
class MediaStreamError;
class PromiseCallback;
class PromiseInit;
class PromiseNativeHandler;
class PromiseDebugging;
class Promise;
#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
class PromiseReportRejectFeature : public workers::WorkerFeature
{
// PromiseReportRejectFeature is held by an nsAutoPtr on the Promise which
// means that this object will be destroyed before the Promise is destroyed.
Promise* MOZ_NON_OWNING_REF mPromise;
public:
explicit PromiseReportRejectFeature(Promise* aPromise)
: mPromise(aPromise)
{
MOZ_ASSERT(mPromise);
}
virtual bool
Notify(JSContext* aCx, workers::Status aStatus) override;
};
#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
#define NS_PROMISE_IID \
{ 0x1b8d6215, 0x3e67, 0x43ba, \
{ 0x8a, 0xf9, 0x31, 0x5e, 0x8f, 0xce, 0x75, 0x65 } }
class Promise : public nsISupports,
#ifndef SPIDERMONKEY_PROMISE
// Only wrappercached when we're not using SpiderMonkey
// promises, because those don't have a useful object moved
// hook, which wrappercache needs.
public nsWrapperCache,
#endif // SPIDERMONKEY_PROMISE
public SupportsWeakPtr<Promise>
{
friend class NativePromiseCallback;
friend class PromiseReactionJob;
friend class PromiseResolverTask;
friend class PromiseTask;
#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
friend class PromiseReportRejectFeature;
#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
friend class PromiseWorkerProxy;
friend class PromiseWorkerProxyRunnable;
friend class RejectPromiseCallback;
friend class ResolvePromiseCallback;
friend class PromiseResolveThenableJob;
friend class FastPromiseResolveThenableJob;
friend class WrapperPromiseCallback;
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_PROMISE_IID)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
#ifdef SPIDERMONKEY_PROMISE
// We're not skippable, since we're not owned from JS to start with.
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Promise)
#else // SPIDERMONKEY_PROMISE
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(Promise)
#endif // SPIDERMONKEY_PROMISE
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(Promise)
// Promise creation tries to create a JS reflector for the Promise, so is
// fallible. Furthermore, we don't want to do JS-wrapping on a 0-refcount
// object, so we addref before doing that and return the addrefed pointer
// here.
#ifdef SPIDERMONKEY_PROMISE
static already_AddRefed<Promise>
Create(nsIGlobalObject* aGlobal, ErrorResult& aRv);
#else
static already_AddRefed<Promise>
Create(nsIGlobalObject* aGlobal, ErrorResult& aRv,
// Passing null for aDesiredProto will use Promise.prototype.
JS::Handle<JSObject*> aDesiredProto = nullptr);
#endif // SPIDERMONKEY_PROMISE
typedef void (Promise::*MaybeFunc)(JSContext* aCx,
JS::Handle<JS::Value> aValue);
void MaybeResolve(JSContext* aCx,
JS::Handle<JS::Value> aValue);
void MaybeReject(JSContext* aCx,
JS::Handle<JS::Value> aValue);
// Helpers for using Promise from C++.
// Most DOM objects are handled already. To add a new type T, add a
// ToJSValue overload in ToJSValue.h.
// aArg is a const reference so we can pass rvalues like integer constants
template <typename T>
void MaybeResolve(const T& aArg) {
MaybeSomething(aArg, &Promise::MaybeResolve);
}
inline void MaybeReject(nsresult aArg) {
MOZ_ASSERT(NS_FAILED(aArg));
MaybeSomething(aArg, &Promise::MaybeReject);
}
inline void MaybeReject(ErrorResult& aArg) {
MOZ_ASSERT(aArg.Failed());
MaybeSomething(aArg, &Promise::MaybeReject);
}
void MaybeReject(const RefPtr<MediaStreamError>& aArg);
void MaybeRejectWithNull();
// DO NOT USE MaybeRejectBrokenly with in new code. Promises should be
// rejected with Error instances.
// Note: MaybeRejectBrokenly is a template so we can use it with DOMError
// without instantiating the DOMError specialization of MaybeSomething in
// every translation unit that includes this header, because that would
// require use to include DOMError.h either here or in all those translation
// units.
template<typename T>
void MaybeRejectBrokenly(const T& aArg); // Not implemented by default; see
// specializations in the .cpp for
// the T values we support.
// Called by DOM to let us execute our callbacks. May be called recursively.
// Returns true if at least one microtask was processed.
static bool PerformMicroTaskCheckpoint();
// WebIDL
nsIGlobalObject* GetParentObject() const
{
return mGlobal;
}
#ifdef SPIDERMONKEY_PROMISE
bool
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto,
JS::MutableHandle<JSObject*> aWrapper);
// Do the equivalent of Promise.resolve in the current compartment of aCx.
// Errorrs are reported on the ErrorResult; if aRv comes back !Failed(), this
// function MUST return a non-null value.
static already_AddRefed<Promise>
Resolve(nsIGlobalObject* aGlobal, JSContext* aCx,
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
// Do the equivalent of Promise.reject in the current compartment of aCx.
// Errorrs are reported on the ErrorResult; if aRv comes back !Failed(), this
// function MUST return a non-null value.
static already_AddRefed<Promise>
Reject(nsIGlobalObject* aGlobal, JSContext* aCx,
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
static already_AddRefed<Promise>
All(const GlobalObject& aGlobal,
const nsTArray<RefPtr<Promise>>& aPromiseList, ErrorResult& aRv);
void
Then(JSContext* aCx,
// aCalleeGlobal may not be in the compartment of aCx, when called over
// Xrays.
JS::Handle<JSObject*> aCalleeGlobal,
AnyCallback* aResolveCallback, AnyCallback* aRejectCallback,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aRv);
JSObject* PromiseObj() const
{
if (mPromiseObj) {
JS::ExposeObjectToActiveJS(mPromiseObj);
}
return mPromiseObj;
}
#else // SPIDERMONKEY_PROMISE
JSObject* PromiseObj()
{
return GetWrapper();
}
virtual JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<Promise>
Constructor(const GlobalObject& aGlobal, PromiseInit& aInit,
ErrorResult& aRv, JS::Handle<JSObject*> aDesiredProto);
static void
Resolve(const GlobalObject& aGlobal, JS::Handle<JS::Value> aThisv,
JS::Handle<JS::Value> aValue,
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aRv);
static already_AddRefed<Promise>
Resolve(nsIGlobalObject* aGlobal, JSContext* aCx,
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
static void
Reject(const GlobalObject& aGlobal, JS::Handle<JS::Value> aThisv,
JS::Handle<JS::Value> aValue,
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aRv);
static already_AddRefed<Promise>
Reject(nsIGlobalObject* aGlobal, JSContext* aCx,
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
void
Then(JSContext* aCx,
// aCalleeGlobal may not be in the compartment of aCx, when called over
// Xrays.
JS::Handle<JSObject*> aCalleeGlobal,
AnyCallback* aResolveCallback, AnyCallback* aRejectCallback,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aRv);
void
Catch(JSContext* aCx,
AnyCallback* aRejectCallback,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aRv);
static void
All(const GlobalObject& aGlobal, JS::Handle<JS::Value> aThisv,
JS::Handle<JS::Value> aIterable, JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aRv);
static already_AddRefed<Promise>
All(const GlobalObject& aGlobal,
const nsTArray<RefPtr<Promise>>& aPromiseList, ErrorResult& aRv);
static void
Race(const GlobalObject& aGlobal, JS::Handle<JS::Value> aThisv,
JS::Handle<JS::Value> aIterable, JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aRv);
static bool
PromiseSpecies(JSContext* aCx, unsigned aArgc, JS::Value* aVp);
#endif // SPIDERMONKEY_PROMISE
void AppendNativeHandler(PromiseNativeHandler* aRunnable);
JSObject* GlobalJSObject() const;
JSCompartment* Compartment() const;
#ifndef SPIDERMONKEY_PROMISE
// Return a unique-to-the-process identifier for this Promise.
uint64_t GetID();
#endif // SPIDERMONKEY_PROMISE
// Queue an async microtask to current main or worker thread.
static void
DispatchToMicroTask(nsIRunnable* aRunnable);
#ifndef SPIDERMONKEY_PROMISE
enum JSCallbackSlots {
SLOT_PROMISE = 0,
SLOT_DATA
};
#endif // SPIDERMONKEY_PROMISE
#ifdef SPIDERMONKEY_PROMISE
// Create a dom::Promise from a given SpiderMonkey Promise object.
// aPromiseObj MUST be in the compartment of aGlobal's global JS object.
static already_AddRefed<Promise>
CreateFromExisting(nsIGlobalObject* aGlobal,
JS::Handle<JSObject*> aPromiseObj);
#endif // SPIDERMONKEY_PROMISE
protected:
struct PromiseCapability;
// Do NOT call this unless you're Promise::Create or
// Promise::CreateFromExisting. I wish we could enforce that from inside this
// class too, somehow.
explicit Promise(nsIGlobalObject* aGlobal);
virtual ~Promise();
// Do JS-wrapping after Promise creation. Passing null for aDesiredProto will
// use the default prototype for the sort of Promise we have.
void CreateWrapper(JS::Handle<JSObject*> aDesiredProto, ErrorResult& aRv);
#ifndef SPIDERMONKEY_PROMISE
// Create the JS resolving functions of resolve() and reject(). And provide
// references to the two functions by calling PromiseInit passed from Promise
// constructor.
void CallInitFunction(const GlobalObject& aGlobal, PromiseInit& aInit,
ErrorResult& aRv);
// The NewPromiseCapability function from
// <http://www.ecma-international.org/ecma-262/6.0/#sec-newpromisecapability>.
// Errors are communicated via aRv. If aForceCallbackCreation is
// true, then this function will ensure that aCapability has a
// useful mResolve/mReject even if mNativePromise is non-null.
static void NewPromiseCapability(JSContext* aCx, nsIGlobalObject* aGlobal,
JS::Handle<JS::Value> aConstructor,
bool aForceCallbackCreation,
PromiseCapability& aCapability,
ErrorResult& aRv);
bool IsPending()
{
return mResolvePending;
}
void GetDependentPromises(nsTArray<RefPtr<Promise>>& aPromises);
bool IsLastInChain() const
{
return mIsLastInChain;
}
void SetNotifiedAsUncaught()
{
mWasNotifiedAsUncaught = true;
}
bool WasNotifiedAsUncaught() const
{
return mWasNotifiedAsUncaught;
}
#endif // SPIDERMONKEY_PROMISE
private:
enum PromiseState {
Pending,
Resolved,
Rejected
};
#ifndef SPIDERMONKEY_PROMISE
friend class PromiseDebugging;
void SetState(PromiseState aState)
{
MOZ_ASSERT(mState == Pending);
MOZ_ASSERT(aState != Pending);
mState = aState;
}
void SetResult(JS::Handle<JS::Value> aValue)
{
mResult = aValue;
}
// This method enqueues promise's resolve/reject callbacks with promise's
// result. It's executed when the resolver.resolve() or resolver.reject() is
// called or when the promise already has a result and new callbacks are
// appended by then() or catch().
void TriggerPromiseReactions();
void Settle(JS::Handle<JS::Value> aValue, Promise::PromiseState aState);
void MaybeSettle(JS::Handle<JS::Value> aValue, Promise::PromiseState aState);
void AppendCallbacks(PromiseCallback* aResolveCallback,
PromiseCallback* aRejectCallback);
#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
// If we have been rejected and our mResult is a JS exception,
// report it to the error console.
// Use MaybeReportRejectedOnce() for actual calls.
void MaybeReportRejected();
void MaybeReportRejectedOnce() {
MaybeReportRejected();
RemoveFeature();
mResult.setUndefined();
}
#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
void MaybeResolveInternal(JSContext* aCx,
JS::Handle<JS::Value> aValue);
void MaybeRejectInternal(JSContext* aCx,
JS::Handle<JS::Value> aValue);
void ResolveInternal(JSContext* aCx,
JS::Handle<JS::Value> aValue);
void RejectInternal(JSContext* aCx,
JS::Handle<JS::Value> aValue);
#endif // SPIDERMONKEY_PROMISE
template <typename T>
void MaybeSomething(T& aArgument, MaybeFunc aFunc) {
ThreadsafeAutoJSContext cx;
JSObject* wrapper = PromiseObj();
MOZ_ASSERT(wrapper); // We preserved it!
JSAutoCompartment ac(cx, wrapper);
JS::Rooted<JS::Value> val(cx);
if (!ToJSValue(cx, aArgument, &val)) {
HandleException(cx);
return;
}
(this->*aFunc)(cx, val);
}
#ifndef SPIDERMONKEY_PROMISE
// Static methods for the PromiseInit functions.
static bool
JSCallback(JSContext *aCx, unsigned aArgc, JS::Value *aVp);
static bool
ThenableResolverCommon(JSContext* aCx, uint32_t /* PromiseCallback::Task */ aTask,
unsigned aArgc, JS::Value* aVp);
static bool
JSCallbackThenableResolver(JSContext *aCx, unsigned aArgc, JS::Value *aVp);
static bool
JSCallbackThenableRejecter(JSContext *aCx, unsigned aArgc, JS::Value *aVp);
static JSObject*
CreateFunction(JSContext* aCx, Promise* aPromise, int32_t aTask);
static JSObject*
CreateThenableFunction(JSContext* aCx, Promise* aPromise, uint32_t aTask);
#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
void RemoveFeature();
#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
// Capture the current stack and store it in aTarget. If false is
// returned, an exception is presumably pending on aCx.
bool CaptureStack(JSContext* aCx, JS::Heap<JSObject*>& aTarget);
#endif // SPIDERMONKEY_PROMISE
void HandleException(JSContext* aCx);
RefPtr<nsIGlobalObject> mGlobal;
#ifndef SPIDERMONKEY_PROMISE
nsTArray<RefPtr<PromiseCallback> > mResolveCallbacks;
nsTArray<RefPtr<PromiseCallback> > mRejectCallbacks;
JS::Heap<JS::Value> mResult;
// A stack that shows where this promise was allocated, if there was
// JS running at the time. Otherwise null.
JS::Heap<JSObject*> mAllocationStack;
// mRejectionStack is only set when the promise is rejected directly from
// script, by calling Promise.reject() or the rejection callback we pass to
// the PromiseInit function. Promises that are rejected internally do not
// have a rejection stack.
JS::Heap<JSObject*> mRejectionStack;
// mFullfillmentStack is only set when the promise is fulfilled directly from
// script, by calling Promise.resolve() or the fulfillment callback we pass to
// the PromiseInit function. Promises that are fulfilled internally do not
// have a fulfillment stack.
JS::Heap<JSObject*> mFullfillmentStack;
PromiseState mState;
#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
bool mHadRejectCallback;
// If a rejected promise on a worker has no reject callbacks attached, it
// needs to know when the worker is shutting down, to report the error on the
// console before the worker's context is deleted. This feature is used for
// that purpose.
nsAutoPtr<PromiseReportRejectFeature> mFeature;
#endif // defined(DOM_PROMISE_DEPRECATED_REPORTING)
bool mTaskPending;
bool mResolvePending;
// `true` if this Promise is the last in the chain, or `false` if
// another Promise has been created from this one by a call to
// `then`, `all`, `race`, etc.
bool mIsLastInChain;
// `true` if PromiseDebugging has already notified at least one observer that
// this promise was left uncaught, `false` otherwise.
bool mWasNotifiedAsUncaught;
// The time when this promise was created.
TimeStamp mCreationTimestamp;
// The time when this promise transitioned out of the pending state.
TimeStamp mSettlementTimestamp;
// Once `GetID()` has been called, a unique-to-the-process identifier for this
// promise. Until then, `0`.
uint64_t mID;
#else // SPIDERMONKEY_PROMISE
JS::Heap<JSObject*> mPromiseObj;
#endif // SPIDERMONKEY_PROMISE
};
NS_DEFINE_STATIC_IID_ACCESSOR(Promise, NS_PROMISE_IID)
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_Promise_h