mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 974893 - Remove EnterCompartment and keep the global with the value in Promise, r=bz
This commit is contained in:
parent
423901664f
commit
f8f47ff494
@ -924,6 +924,10 @@ DOMInterfaces = {
|
||||
'headerFile': 'nsGeolocation.h'
|
||||
},
|
||||
|
||||
'Promise': {
|
||||
'implicitJSContext': [ 'then', 'catch' ],
|
||||
},
|
||||
|
||||
'PropertyNodeList': {
|
||||
'headerFile': 'HTMLPropertiesCollection.h',
|
||||
'resultNotAddRefed': [ 'item' ]
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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");
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user