mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 12:35:58 +00:00
Bug 995163 - wrap the Promise value in NativePromiseCallback, r=bz
This commit is contained in:
parent
a847cfea9d
commit
fc5fc8f292
@ -865,11 +865,20 @@ Promise::RunTask()
|
||||
mResolveCallbacks.Clear();
|
||||
mRejectCallbacks.Clear();
|
||||
|
||||
ThreadsafeAutoJSContext cx; // Just for rooting.
|
||||
ThreadsafeAutoJSContext cx;
|
||||
JS::Rooted<JS::Value> value(cx, mResult);
|
||||
JS::Rooted<JSObject*> wrapper(cx, GetOrCreateWrapper(cx));
|
||||
if (!wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
JSAutoCompartment ac(cx, wrapper);
|
||||
if (!MaybeWrapValue(cx, &value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < callbacks.Length(); ++i) {
|
||||
callbacks[i]->Call(value);
|
||||
callbacks[i]->Call(cx, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,19 +82,19 @@ ResolvePromiseCallback::~ResolvePromiseCallback()
|
||||
}
|
||||
|
||||
void
|
||||
ResolvePromiseCallback::Call(JS::Handle<JS::Value> aValue)
|
||||
ResolvePromiseCallback::Call(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
// Run resolver's algorithm with value and the synchronous flag set.
|
||||
ThreadsafeAutoSafeJSContext cx;
|
||||
|
||||
JSAutoCompartment ac(cx, mGlobal);
|
||||
JS::Rooted<JS::Value> value(cx, aValue);
|
||||
if (!JS_WrapValue(cx, &value)) {
|
||||
JSAutoCompartment ac(aCx, mGlobal);
|
||||
JS::Rooted<JS::Value> value(aCx, aValue);
|
||||
if (!JS_WrapValue(aCx, &value)) {
|
||||
NS_WARNING("Failed to wrap value into the right compartment.");
|
||||
return;
|
||||
}
|
||||
|
||||
mPromise->ResolveInternal(cx, value, Promise::SyncTask);
|
||||
mPromise->ResolveInternal(aCx, value, Promise::SyncTask);
|
||||
}
|
||||
|
||||
// RejectPromiseCallback
|
||||
@ -142,20 +142,20 @@ RejectPromiseCallback::~RejectPromiseCallback()
|
||||
}
|
||||
|
||||
void
|
||||
RejectPromiseCallback::Call(JS::Handle<JS::Value> aValue)
|
||||
RejectPromiseCallback::Call(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
// Run resolver's algorithm with value and the synchronous flag set.
|
||||
ThreadsafeAutoSafeJSContext cx;
|
||||
|
||||
JSAutoCompartment ac(cx, mGlobal);
|
||||
JS::Rooted<JS::Value> value(cx, aValue);
|
||||
if (!JS_WrapValue(cx, &value)) {
|
||||
JSAutoCompartment ac(aCx, mGlobal);
|
||||
JS::Rooted<JS::Value> value(aCx, aValue);
|
||||
if (!JS_WrapValue(aCx, &value)) {
|
||||
NS_WARNING("Failed to wrap value into the right compartment.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
mPromise->RejectInternal(cx, value, Promise::SyncTask);
|
||||
mPromise->RejectInternal(aCx, value, Promise::SyncTask);
|
||||
}
|
||||
|
||||
// WrapperPromiseCallback
|
||||
@ -205,13 +205,12 @@ WrapperPromiseCallback::~WrapperPromiseCallback()
|
||||
}
|
||||
|
||||
void
|
||||
WrapperPromiseCallback::Call(JS::Handle<JS::Value> aValue)
|
||||
WrapperPromiseCallback::Call(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
ThreadsafeAutoSafeJSContext cx;
|
||||
|
||||
JSAutoCompartment ac(cx, mGlobal);
|
||||
JS::Rooted<JS::Value> value(cx, aValue);
|
||||
if (!JS_WrapValue(cx, &value)) {
|
||||
JSAutoCompartment ac(aCx, mGlobal);
|
||||
JS::Rooted<JS::Value> value(aCx, aValue);
|
||||
if (!JS_WrapValue(aCx, &value)) {
|
||||
NS_WARNING("Failed to wrap value into the right compartment.");
|
||||
return;
|
||||
}
|
||||
@ -220,27 +219,27 @@ WrapperPromiseCallback::Call(JS::Handle<JS::Value> aValue)
|
||||
|
||||
// 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> retValue(cx,
|
||||
JS::Rooted<JS::Value> retValue(aCx,
|
||||
mCallback->Call(value, rv, CallbackObject::eRethrowExceptions));
|
||||
|
||||
rv.WouldReportJSException();
|
||||
|
||||
if (rv.Failed() && rv.IsJSException()) {
|
||||
JS::Rooted<JS::Value> value(cx);
|
||||
rv.StealJSException(cx, &value);
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
rv.StealJSException(aCx, &value);
|
||||
|
||||
if (!JS_WrapValue(cx, &value)) {
|
||||
if (!JS_WrapValue(aCx, &value)) {
|
||||
NS_WARNING("Failed to wrap value into the right compartment.");
|
||||
return;
|
||||
}
|
||||
|
||||
mNextPromise->RejectInternal(cx, value, Promise::SyncTask);
|
||||
mNextPromise->RejectInternal(aCx, value, Promise::SyncTask);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the return value is the same as the promise itself, throw TypeError.
|
||||
if (retValue.isObject()) {
|
||||
JS::Rooted<JSObject*> valueObj(cx, &retValue.toObject());
|
||||
JS::Rooted<JSObject*> valueObj(aCx, &retValue.toObject());
|
||||
Promise* returnedPromise;
|
||||
nsresult r = UNWRAP_OBJECT(Promise, valueObj, returnedPromise);
|
||||
|
||||
@ -250,63 +249,63 @@ WrapperPromiseCallback::Call(JS::Handle<JS::Value> aValue)
|
||||
|
||||
// Try to get some information about the callback to report a sane error,
|
||||
// but don't try too hard (only deals with scripted functions).
|
||||
JS::Rooted<JSObject*> unwrapped(cx,
|
||||
JS::Rooted<JSObject*> unwrapped(aCx,
|
||||
js::CheckedUnwrap(mCallback->Callback()));
|
||||
|
||||
if (unwrapped) {
|
||||
JSAutoCompartment ac(cx, unwrapped);
|
||||
if (JS_ObjectIsFunction(cx, unwrapped)) {
|
||||
JS::Rooted<JS::Value> asValue(cx, JS::ObjectValue(*unwrapped));
|
||||
JS::Rooted<JSFunction*> func(cx, JS_ValueToFunction(cx, asValue));
|
||||
JSAutoCompartment ac(aCx, unwrapped);
|
||||
if (JS_ObjectIsFunction(aCx, unwrapped)) {
|
||||
JS::Rooted<JS::Value> asValue(aCx, JS::ObjectValue(*unwrapped));
|
||||
JS::Rooted<JSFunction*> func(aCx, JS_ValueToFunction(aCx, asValue));
|
||||
|
||||
MOZ_ASSERT(func);
|
||||
JSScript* script = JS_GetFunctionScript(cx, func);
|
||||
JSScript* script = JS_GetFunctionScript(aCx, func);
|
||||
if (script) {
|
||||
fileName = JS_GetScriptFilename(script);
|
||||
lineNumber = JS_GetScriptBaseLineNumber(cx, script);
|
||||
lineNumber = JS_GetScriptBaseLineNumber(aCx, script);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We're back in aValue's compartment here.
|
||||
JS::Rooted<JSString*> stack(cx, JS_GetEmptyString(JS_GetRuntime(cx)));
|
||||
JS::Rooted<JSString*> fn(cx, JS_NewStringCopyZ(cx, fileName));
|
||||
JS::Rooted<JSString*> stack(aCx, JS_GetEmptyString(JS_GetRuntime(aCx)));
|
||||
JS::Rooted<JSString*> fn(aCx, JS_NewStringCopyZ(aCx, fileName));
|
||||
if (!fn) {
|
||||
// Out of memory. Promise will stay unresolved.
|
||||
JS_ClearPendingException(cx);
|
||||
JS_ClearPendingException(aCx);
|
||||
return;
|
||||
}
|
||||
|
||||
JS::Rooted<JSString*> message(cx,
|
||||
JS_NewStringCopyZ(cx,
|
||||
JS::Rooted<JSString*> message(aCx,
|
||||
JS_NewStringCopyZ(aCx,
|
||||
"then() cannot return same Promise that it resolves."));
|
||||
if (!message) {
|
||||
// Out of memory. Promise will stay unresolved.
|
||||
JS_ClearPendingException(cx);
|
||||
JS_ClearPendingException(aCx);
|
||||
return;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> typeError(cx);
|
||||
if (!JS::CreateTypeError(cx, stack, fn, lineNumber, 0,
|
||||
JS::Rooted<JS::Value> typeError(aCx);
|
||||
if (!JS::CreateTypeError(aCx, stack, fn, lineNumber, 0,
|
||||
nullptr, message, &typeError)) {
|
||||
// Out of memory. Promise will stay unresolved.
|
||||
JS_ClearPendingException(cx);
|
||||
JS_ClearPendingException(aCx);
|
||||
return;
|
||||
}
|
||||
|
||||
mNextPromise->RejectInternal(cx, typeError, Promise::SyncTask);
|
||||
mNextPromise->RejectInternal(aCx, typeError, Promise::SyncTask);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, run resolver's resolve with value and the synchronous flag
|
||||
// set.
|
||||
if (!JS_WrapValue(cx, &retValue)) {
|
||||
if (!JS_WrapValue(aCx, &retValue)) {
|
||||
NS_WARNING("Failed to wrap value into the right compartment.");
|
||||
return;
|
||||
}
|
||||
|
||||
mNextPromise->ResolveInternal(cx, retValue, Promise::SyncTask);
|
||||
mNextPromise->ResolveInternal(aCx, retValue, Promise::SyncTask);
|
||||
}
|
||||
|
||||
// NativePromiseCallback
|
||||
@ -335,7 +334,8 @@ NativePromiseCallback::~NativePromiseCallback()
|
||||
}
|
||||
|
||||
void
|
||||
NativePromiseCallback::Call(JS::Handle<JS::Value> aValue)
|
||||
NativePromiseCallback::Call(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
if (mState == Promise::Resolved) {
|
||||
mHandler->ResolvedCallback(aValue);
|
||||
|
@ -24,7 +24,8 @@ public:
|
||||
PromiseCallback();
|
||||
virtual ~PromiseCallback();
|
||||
|
||||
virtual void Call(JS::Handle<JS::Value> aValue) = 0;
|
||||
virtual void Call(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue) = 0;
|
||||
|
||||
enum Task {
|
||||
Resolve,
|
||||
@ -47,7 +48,8 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WrapperPromiseCallback,
|
||||
PromiseCallback)
|
||||
|
||||
void Call(JS::Handle<JS::Value> aValue) MOZ_OVERRIDE;
|
||||
void Call(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue) MOZ_OVERRIDE;
|
||||
|
||||
WrapperPromiseCallback(Promise* aNextPromise, JS::Handle<JSObject*> aGlobal,
|
||||
AnyCallback* aCallback);
|
||||
@ -68,7 +70,8 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ResolvePromiseCallback,
|
||||
PromiseCallback)
|
||||
|
||||
void Call(JS::Handle<JS::Value> aValue) MOZ_OVERRIDE;
|
||||
void Call(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue) MOZ_OVERRIDE;
|
||||
|
||||
ResolvePromiseCallback(Promise* aPromise, JS::Handle<JSObject*> aGlobal);
|
||||
~ResolvePromiseCallback();
|
||||
@ -87,7 +90,8 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(RejectPromiseCallback,
|
||||
PromiseCallback)
|
||||
|
||||
void Call(JS::Handle<JS::Value> aValue) MOZ_OVERRIDE;
|
||||
void Call(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue) MOZ_OVERRIDE;
|
||||
|
||||
RejectPromiseCallback(Promise* aPromise, JS::Handle<JSObject*> aGlobal);
|
||||
~RejectPromiseCallback();
|
||||
@ -105,7 +109,8 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(NativePromiseCallback,
|
||||
PromiseCallback)
|
||||
|
||||
void Call(JS::Handle<JS::Value> aValue) MOZ_OVERRIDE;
|
||||
void Call(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue) MOZ_OVERRIDE;
|
||||
|
||||
NativePromiseCallback(PromiseNativeHandler* aHandler,
|
||||
Promise::PromiseState aState);
|
||||
|
Loading…
x
Reference in New Issue
Block a user