Bug 974893 - Remove EnterCompartment and keep the global with the value in Promise, r=bz

This commit is contained in:
Andrea Marchesini 2014-04-09 09:30:24 +01:00
parent 423901664f
commit f8f47ff494
5 changed files with 190 additions and 86 deletions

View File

@ -924,6 +924,10 @@ DOMInterfaces = {
'headerFile': 'nsGeolocation.h'
},
'Promise': {
'implicitJSContext': [ 'then', 'catch' ],
},
'PropertyNodeList': {
'headerFile': 'HTMLPropertiesCollection.h',
'resultNotAddRefed': [ 'item' ]

View File

@ -187,15 +187,15 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(Promise)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Promise)
tmp->MaybeReportRejectedOnce();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mResolveCallbacks);
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRejectCallbacks);
NS_IMPL_CYCLE_COLLECTION_UNLINK(mResolveCallbacks)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRejectCallbacks)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Promise)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResolveCallbacks);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRejectCallbacks);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResolveCallbacks)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRejectCallbacks)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -279,17 +279,6 @@ Promise::MaybeReject(JSContext* aCx,
MaybeRejectInternal(aCx, aValue);
}
static void
EnterCompartment(Maybe<JSAutoCompartment>& aAc, JSContext* aCx,
JS::Handle<JS::Value> aValue)
{
// FIXME Bug 878849
if (aValue.isObject()) {
JS::Rooted<JSObject*> rooted(aCx, &aValue.toObject());
aAc.construct(aCx, rooted);
}
}
enum {
SLOT_PROMISE = 0,
SLOT_DATA
@ -507,8 +496,13 @@ Promise::Constructor(const GlobalObject& aGlobal,
JS::Rooted<JS::Value> value(cx);
aRv.StealJSException(cx, &value);
Maybe<JSAutoCompartment> ac;
EnterCompartment(ac, cx, value);
// we want the same behavior as this JS implementation:
// function Promise(arg) { try { arg(a, b); } catch (e) { this.reject(e); }}
if (!JS_WrapValue(cx, &value)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
promise->MaybeRejectInternal(cx, value);
}
@ -576,15 +570,20 @@ Promise::Reject(nsIGlobalObject* aGlobal, JSContext* aCx,
}
already_AddRefed<Promise>
Promise::Then(AnyCallback* aResolveCallback, AnyCallback* aRejectCallback)
Promise::Then(JSContext* aCx, AnyCallback* aResolveCallback,
AnyCallback* aRejectCallback)
{
nsRefPtr<Promise> promise = new Promise(GetParentObject());
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
nsRefPtr<PromiseCallback> resolveCb =
PromiseCallback::Factory(promise, aResolveCallback, PromiseCallback::Resolve);
PromiseCallback::Factory(promise, global, aResolveCallback,
PromiseCallback::Resolve);
nsRefPtr<PromiseCallback> rejectCb =
PromiseCallback::Factory(promise, aRejectCallback, PromiseCallback::Reject);
PromiseCallback::Factory(promise, global, aRejectCallback,
PromiseCallback::Reject);
AppendCallbacks(resolveCb, rejectCb);
@ -592,10 +591,10 @@ Promise::Then(AnyCallback* aResolveCallback, AnyCallback* aRejectCallback)
}
already_AddRefed<Promise>
Promise::Catch(AnyCallback* aRejectCallback)
Promise::Catch(JSContext* aCx, AnyCallback* aRejectCallback)
{
nsRefPtr<AnyCallback> resolveCb;
return Then(resolveCb, aRejectCallback);
return Then(aCx, resolveCb, aRejectCallback);
}
/**
@ -609,11 +608,17 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CountdownHolder)
CountdownHolder(const GlobalObject& aGlobal, Promise* aPromise, uint32_t aCountdown)
CountdownHolder(const GlobalObject& aGlobal, Promise* aPromise,
uint32_t aCountdown)
: mPromise(aPromise), mCountdown(aCountdown)
{
MOZ_ASSERT(aCountdown != 0);
JSContext* cx = aGlobal.GetContext();
// The only time aGlobal.GetContext() and aGlobal.Get() are not
// same-compartment is when we're called via Xrays, and in that situation we
// in fact want to create the array in the callee compartment
JSAutoCompartment ac(cx, aGlobal.Get());
mValues = JS_NewArrayObject(cx, aCountdown);
mozilla::HoldJSObjects(this);
@ -630,10 +635,13 @@ public:
ThreadsafeAutoSafeJSContext cx;
JSAutoCompartment ac(cx, mValues);
{
AutoDontReportUncaught silenceReporting(cx);
if (!JS_DefineElement(cx, mValues, index, aValue, nullptr, nullptr, JSPROP_ENUMERATE)) {
JS::Rooted<JS::Value> value(cx, aValue);
if (!JS_WrapValue(cx, &value) ||
!JS_DefineElement(cx, mValues, index, value, nullptr, nullptr,
JSPROP_ENUMERATE)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
JS::Rooted<JS::Value> exn(cx);
JS_GetPendingException(cx, &exn);
@ -749,7 +757,13 @@ Promise::All(const GlobalObject& aGlobal, JSContext* aCx,
nsRefPtr<CountdownHolder> holder =
new CountdownHolder(aGlobal, promise, aIterable.Length());
nsRefPtr<PromiseCallback> rejectCb = new RejectPromiseCallback(promise);
JS::Rooted<JSObject*> obj(aCx, JS::CurrentGlobalOrNull(aCx));
if (!obj) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsRefPtr<PromiseCallback> rejectCb = new RejectPromiseCallback(promise, obj);
for (uint32_t i = 0; i < aIterable.Length(); ++i) {
JS::Rooted<JS::Value> value(aCx, aIterable.ElementAt(i));
@ -781,9 +795,18 @@ Promise::Race(const GlobalObject& aGlobal, JSContext* aCx,
return nullptr;
}
JS::Rooted<JSObject*> obj(aCx, JS::CurrentGlobalOrNull(aCx));
if (!obj) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsRefPtr<Promise> promise = new Promise(global);
nsRefPtr<PromiseCallback> resolveCb = new ResolvePromiseCallback(promise);
nsRefPtr<PromiseCallback> rejectCb = new RejectPromiseCallback(promise);
nsRefPtr<PromiseCallback> resolveCb =
new ResolvePromiseCallback(promise, obj);
nsRefPtr<PromiseCallback> rejectCb = new RejectPromiseCallback(promise, obj);
for (uint32_t i = 0; i < aIterable.Length(); ++i) {
JS::Rooted<JS::Value> value(aCx, aIterable.ElementAt(i));
@ -997,8 +1020,12 @@ Promise::ResolveInternal(JSContext* aCx,
// If we could mark as called, neither of the callbacks had been called
// when the exception was thrown. So we can reject the Promise.
if (couldMarkAsCalled) {
Maybe<JSAutoCompartment> ac;
EnterCompartment(ac, aCx, exn);
bool ok = JS_WrapValue(aCx, &exn);
MOZ_ASSERT(ok);
if (!ok) {
NS_WARNING("Failed to wrap value into the right compartment.");
}
RejectInternal(aCx, exn, Promise::SyncTask);
}
// At least one of resolveFunc or rejectFunc have been called, so ignore

View File

@ -121,10 +121,11 @@ public:
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
already_AddRefed<Promise>
Then(AnyCallback* aResolveCallback, AnyCallback* aRejectCallback);
Then(JSContext* aCx, AnyCallback* aResolveCallback,
AnyCallback* aRejectCallback);
already_AddRefed<Promise>
Catch(AnyCallback* aRejectCallback);
Catch(JSContext* aCx, AnyCallback* aRejectCallback);
static already_AddRefed<Promise>
All(const GlobalObject& aGlobal, JSContext* aCx,

View File

@ -38,22 +38,25 @@ PromiseCallback::~PromiseCallback()
MOZ_COUNT_DTOR(PromiseCallback);
}
static void
EnterCompartment(Maybe<JSAutoCompartment>& aAc, JSContext* aCx,
JS::Handle<JS::Value> aValue)
{
// FIXME Bug 878849
if (aValue.isObject()) {
JS::Rooted<JSObject*> rooted(aCx, &aValue.toObject());
aAc.construct(aCx, rooted);
}
}
// ResolvePromiseCallback
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(ResolvePromiseCallback,
PromiseCallback,
mPromise)
NS_IMPL_CYCLE_COLLECTION_CLASS(ResolvePromiseCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ResolvePromiseCallback,
PromiseCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPromise)
tmp->mGlobal = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ResolvePromiseCallback,
PromiseCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPromise)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ResolvePromiseCallback)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mGlobal)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ResolvePromiseCallback)
NS_INTERFACE_MAP_END_INHERITING(PromiseCallback)
@ -61,16 +64,21 @@ NS_INTERFACE_MAP_END_INHERITING(PromiseCallback)
NS_IMPL_ADDREF_INHERITED(ResolvePromiseCallback, PromiseCallback)
NS_IMPL_RELEASE_INHERITED(ResolvePromiseCallback, PromiseCallback)
ResolvePromiseCallback::ResolvePromiseCallback(Promise* aPromise)
ResolvePromiseCallback::ResolvePromiseCallback(Promise* aPromise,
JS::Handle<JSObject*> aGlobal)
: mPromise(aPromise)
, mGlobal(aGlobal)
{
MOZ_ASSERT(aPromise);
MOZ_ASSERT(aGlobal);
MOZ_COUNT_CTOR(ResolvePromiseCallback);
HoldJSObjects(this);
}
ResolvePromiseCallback::~ResolvePromiseCallback()
{
MOZ_COUNT_DTOR(ResolvePromiseCallback);
DropJSObjects(this);
}
void
@ -79,34 +87,58 @@ ResolvePromiseCallback::Call(JS::Handle<JS::Value> aValue)
// Run resolver's algorithm with value and the synchronous flag set.
ThreadsafeAutoSafeJSContext cx;
Maybe<JSAutoCompartment> ac;
EnterCompartment(ac, cx, aValue);
JSAutoCompartment ac(cx, mGlobal);
JS::Rooted<JS::Value> value(cx, aValue);
if (!JS_WrapValue(cx, &value)) {
NS_WARNING("Failed to wrap value into the right compartment.");
return;
}
mPromise->ResolveInternal(cx, aValue, Promise::SyncTask);
mPromise->ResolveInternal(cx, value, Promise::SyncTask);
}
// RejectPromiseCallback
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(RejectPromiseCallback,
PromiseCallback,
mPromise)
NS_IMPL_CYCLE_COLLECTION_CLASS(RejectPromiseCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(RejectPromiseCallback,
PromiseCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPromise)
tmp->mGlobal = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(RejectPromiseCallback,
PromiseCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPromise)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(RejectPromiseCallback)
NS_INTERFACE_MAP_END_INHERITING(PromiseCallback)
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(RejectPromiseCallback,
PromiseCallback)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mGlobal)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_ADDREF_INHERITED(RejectPromiseCallback, PromiseCallback)
NS_IMPL_RELEASE_INHERITED(RejectPromiseCallback, PromiseCallback)
RejectPromiseCallback::RejectPromiseCallback(Promise* aPromise)
RejectPromiseCallback::RejectPromiseCallback(Promise* aPromise,
JS::Handle<JSObject*> aGlobal)
: mPromise(aPromise)
, mGlobal(aGlobal)
{
MOZ_ASSERT(aPromise);
MOZ_ASSERT(mGlobal);
MOZ_COUNT_CTOR(RejectPromiseCallback);
HoldJSObjects(this);
}
RejectPromiseCallback::~RejectPromiseCallback()
{
MOZ_COUNT_DTOR(RejectPromiseCallback);
DropJSObjects(this);
}
void
@ -115,17 +147,37 @@ RejectPromiseCallback::Call(JS::Handle<JS::Value> aValue)
// Run resolver's algorithm with value and the synchronous flag set.
ThreadsafeAutoSafeJSContext cx;
Maybe<JSAutoCompartment> ac;
EnterCompartment(ac, cx, aValue);
JSAutoCompartment ac(cx, mGlobal);
JS::Rooted<JS::Value> value(cx, aValue);
if (!JS_WrapValue(cx, &value)) {
NS_WARNING("Failed to wrap value into the right compartment.");
return;
}
mPromise->RejectInternal(cx, aValue, Promise::SyncTask);
mPromise->RejectInternal(cx, value, Promise::SyncTask);
}
// WrapperPromiseCallback
NS_IMPL_CYCLE_COLLECTION_CLASS(WrapperPromiseCallback)
NS_IMPL_CYCLE_COLLECTION_INHERITED_2(WrapperPromiseCallback,
PromiseCallback,
mNextPromise, mCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WrapperPromiseCallback,
PromiseCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNextPromise)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallback)
tmp->mGlobal = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WrapperPromiseCallback,
PromiseCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNextPromise)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(WrapperPromiseCallback)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mGlobal)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(WrapperPromiseCallback)
NS_INTERFACE_MAP_END_INHERITING(PromiseCallback)
@ -134,17 +186,22 @@ NS_IMPL_ADDREF_INHERITED(WrapperPromiseCallback, PromiseCallback)
NS_IMPL_RELEASE_INHERITED(WrapperPromiseCallback, PromiseCallback)
WrapperPromiseCallback::WrapperPromiseCallback(Promise* aNextPromise,
JS::Handle<JSObject*> aGlobal,
AnyCallback* aCallback)
: mNextPromise(aNextPromise)
, mGlobal(aGlobal)
, mCallback(aCallback)
{
MOZ_ASSERT(aNextPromise);
MOZ_ASSERT(aGlobal);
MOZ_COUNT_CTOR(WrapperPromiseCallback);
HoldJSObjects(this);
}
WrapperPromiseCallback::~WrapperPromiseCallback()
{
MOZ_COUNT_DTOR(WrapperPromiseCallback);
DropJSObjects(this);
}
void
@ -152,15 +209,19 @@ WrapperPromiseCallback::Call(JS::Handle<JS::Value> aValue)
{
ThreadsafeAutoSafeJSContext cx;
Maybe<JSAutoCompartment> ac;
EnterCompartment(ac, cx, aValue);
JSAutoCompartment ac(cx, mGlobal);
JS::Rooted<JS::Value> value(cx, aValue);
if (!JS_WrapValue(cx, &value)) {
NS_WARNING("Failed to wrap value into the right compartment.");
return;
}
ErrorResult rv;
// If invoking callback threw an exception, run resolver's reject with the
// thrown exception as argument and the synchronous flag set.
JS::Rooted<JS::Value> value(cx,
mCallback->Call(aValue, rv, CallbackObject::eRethrowExceptions));
JS::Rooted<JS::Value> retValue(cx,
mCallback->Call(value, rv, CallbackObject::eRethrowExceptions));
rv.WouldReportJSException();
@ -168,15 +229,18 @@ WrapperPromiseCallback::Call(JS::Handle<JS::Value> aValue)
JS::Rooted<JS::Value> value(cx);
rv.StealJSException(cx, &value);
Maybe<JSAutoCompartment> ac2;
EnterCompartment(ac2, cx, value);
if (!JS_WrapValue(cx, &value)) {
NS_WARNING("Failed to wrap value into the right compartment.");
return;
}
mNextPromise->RejectInternal(cx, value, Promise::SyncTask);
return;
}
// If the return value is the same as the promise itself, throw TypeError.
if (value.isObject()) {
JS::Rooted<JSObject*> valueObj(cx, &value.toObject());
if (retValue.isObject()) {
JS::Rooted<JSObject*> valueObj(cx, &retValue.toObject());
Promise* returnedPromise;
nsresult r = UNWRAP_OBJECT(Promise, valueObj, returnedPromise);
@ -237,9 +301,12 @@ WrapperPromiseCallback::Call(JS::Handle<JS::Value> aValue)
// Otherwise, run resolver's resolve with value and the synchronous flag
// set.
Maybe<JSAutoCompartment> ac2;
EnterCompartment(ac2, cx, value);
mNextPromise->ResolveInternal(cx, value, Promise::SyncTask);
if (!JS_WrapValue(cx, &retValue)) {
NS_WARNING("Failed to wrap value into the right compartment.");
return;
}
mNextPromise->ResolveInternal(cx, retValue, Promise::SyncTask);
}
// NativePromiseCallback
@ -284,23 +351,23 @@ NativePromiseCallback::Call(JS::Handle<JS::Value> aValue)
}
/* static */ PromiseCallback*
PromiseCallback::Factory(Promise* aNextPromise, AnyCallback* aCallback,
Task aTask)
PromiseCallback::Factory(Promise* aNextPromise, JS::Handle<JSObject*> aGlobal,
AnyCallback* aCallback, Task aTask)
{
MOZ_ASSERT(aNextPromise);
// If we have a callback and a next resolver, we have to exec the callback and
// then propagate the return value to the next resolver->resolve().
if (aCallback) {
return new WrapperPromiseCallback(aNextPromise, aCallback);
return new WrapperPromiseCallback(aNextPromise, aGlobal, aCallback);
}
if (aTask == Resolve) {
return new ResolvePromiseCallback(aNextPromise);
return new ResolvePromiseCallback(aNextPromise, aGlobal);
}
if (aTask == Reject) {
return new RejectPromiseCallback(aNextPromise);
return new RejectPromiseCallback(aNextPromise, aGlobal);
}
MOZ_ASSERT(false, "This should not happen");

View File

@ -33,7 +33,8 @@ public:
// This factory returns a PromiseCallback object with refcount of 0.
static PromiseCallback*
Factory(Promise* aNextPromise, AnyCallback* aCallback, Task aTask);
Factory(Promise* aNextPromise, JS::Handle<JSObject*> aObject,
AnyCallback* aCallback, Task aTask);
};
// WrapperPromiseCallback execs a JS Callback with a value, and then the return
@ -43,16 +44,18 @@ class WrapperPromiseCallback MOZ_FINAL : public PromiseCallback
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(WrapperPromiseCallback,
PromiseCallback)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WrapperPromiseCallback,
PromiseCallback)
void Call(JS::Handle<JS::Value> aValue) MOZ_OVERRIDE;
WrapperPromiseCallback(Promise* aNextPromise, AnyCallback* aCallback);
WrapperPromiseCallback(Promise* aNextPromise, JS::Handle<JSObject*> aGlobal,
AnyCallback* aCallback);
~WrapperPromiseCallback();
private:
nsRefPtr<Promise> mNextPromise;
JS::Heap<JSObject*> mGlobal;
nsRefPtr<AnyCallback> mCallback;
};
@ -62,16 +65,17 @@ class ResolvePromiseCallback MOZ_FINAL : public PromiseCallback
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ResolvePromiseCallback,
PromiseCallback)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ResolvePromiseCallback,
PromiseCallback)
void Call(JS::Handle<JS::Value> aValue) MOZ_OVERRIDE;
ResolvePromiseCallback(Promise* aPromise);
ResolvePromiseCallback(Promise* aPromise, JS::Handle<JSObject*> aGlobal);
~ResolvePromiseCallback();
private:
nsRefPtr<Promise> mPromise;
JS::Heap<JSObject*> mGlobal;
};
// RejectPromiseCallback calls aPromise->RejectFunction() with the value
@ -80,16 +84,17 @@ class RejectPromiseCallback MOZ_FINAL : public PromiseCallback
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(RejectPromiseCallback,
PromiseCallback)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(RejectPromiseCallback,
PromiseCallback)
void Call(JS::Handle<JS::Value> aValue) MOZ_OVERRIDE;
RejectPromiseCallback(Promise* aPromise);
RejectPromiseCallback(Promise* aPromise, JS::Handle<JSObject*> aGlobal);
~RejectPromiseCallback();
private:
nsRefPtr<Promise> mPromise;
JS::Heap<JSObject*> mGlobal;
};
// NativePromiseCallback wraps a NativePromiseHandler.