Bug 1170760 part 2. Pass in the 'this' value to Promise static methods. r=peterv

This commit is contained in:
Boris Zbarsky 2015-11-25 15:48:08 -05:00
Родитель 1e0e4345bd
Коммит b4cbee7794
4 изменённых файлов: 34 добавлений и 13 удалений

Просмотреть файл

@ -2761,8 +2761,17 @@ ConvertExceptionToPromise(JSContext* cx,
}
JS_ClearPendingException(cx);
nsCOMPtr<nsIGlobalObject> globalObj =
do_QueryInterface(global.GetAsSupports());
if (!globalObj) {
ErrorResult rv;
rv.Throw(NS_ERROR_UNEXPECTED);
return !rv.MaybeSetPendingException(cx);
}
ErrorResult rv;
RefPtr<Promise> promise = Promise::Reject(global, exn, rv);
RefPtr<Promise> promise = Promise::Reject(globalObj, cx, exn, rv);
if (rv.MaybeSetPendingException(cx)) {
// We just give up. We put the exception from the ErrorResult on
// the JSContext just to make sure to not leak memory on the

Просмотреть файл

@ -5085,12 +5085,19 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
// Might as well use CurrentGlobalOrNull here; that will at
// least give us the same behavior as if the caller just called
// Promise.resolve() themselves.
GlobalObject promiseGlobal(cx, JS::CurrentGlobalOrNull(cx));
JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
GlobalObject promiseGlobal(cx, globalObj);
if (promiseGlobal.Failed()) {
$*{exceptionCode}
}
ErrorResult promiseRv;
$${declName} = Promise::Resolve(promiseGlobal, $${val}, promiseRv);
JS::Handle<JSObject*> promiseCtor =
PromiseBinding::GetConstructorObjectHandle(cx, globalObj);
if (!promiseCtor) {
$*{exceptionCode}
}
JS::Rooted<JS::Value> resolveThisv(cx, JS::ObjectValue(*promiseCtor));
$${declName} = Promise::Resolve(promiseGlobal, resolveThisv, $${val}, promiseRv);
if (promiseRv.MaybeSetPendingException(cx)) {
$*{exceptionCode}
}
@ -7054,6 +7061,11 @@ class CGPerSignatureCall(CGThing):
needsUnwrappedVar = True
argsPre.append("unwrappedObj ? *unwrappedObj : obj")
if static and not isConstructor and descriptor.name == "Promise":
# Hack for Promise for now: pass in the "this" value to
# Promise static methods.
argsPre.append("args.thisv()")
if needsUnwrap and needsUnwrappedVar:
# We cannot assign into obj because it's a Handle, not a
# MutableHandle, so we need a separate Rooted.

Просмотреть файл

@ -813,7 +813,7 @@ Promise::CallInitFunction(const GlobalObject& aGlobal,
}
/* static */ already_AddRefed<Promise>
Promise::Resolve(const GlobalObject& aGlobal,
Promise::Resolve(const GlobalObject& aGlobal, JS::Handle<JS::Value> aThisv,
JS::Handle<JS::Value> aValue, ErrorResult& aRv)
{
// If a Promise was passed, just return it.
@ -856,7 +856,7 @@ Promise::Resolve(nsIGlobalObject* aGlobal, JSContext* aCx,
}
/* static */ already_AddRefed<Promise>
Promise::Reject(const GlobalObject& aGlobal,
Promise::Reject(const GlobalObject& aGlobal, JS::Handle<JS::Value> aThisv,
JS::Handle<JS::Value> aValue, ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global =
@ -1057,7 +1057,7 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION(AllResolveElementFunction, mCountdownHolder)
/* static */ already_AddRefed<Promise>
Promise::All(const GlobalObject& aGlobal,
Promise::All(const GlobalObject& aGlobal, JS::Handle<JS::Value> aThisv,
const Sequence<JS::Value>& aIterable, ErrorResult& aRv)
{
JSContext* cx = aGlobal.Context();
@ -1066,7 +1066,7 @@ Promise::All(const GlobalObject& aGlobal,
for (uint32_t i = 0; i < aIterable.Length(); ++i) {
JS::Rooted<JS::Value> value(cx, aIterable.ElementAt(i));
RefPtr<Promise> nextPromise = Promise::Resolve(aGlobal, value, aRv);
RefPtr<Promise> nextPromise = Promise::Resolve(aGlobal, aThisv, value, aRv);
MOZ_ASSERT(!aRv.Failed());
@ -1132,7 +1132,7 @@ Promise::All(const GlobalObject& aGlobal,
}
/* static */ already_AddRefed<Promise>
Promise::Race(const GlobalObject& aGlobal,
Promise::Race(const GlobalObject& aGlobal, JS::Handle<JS::Value> aThisv,
const Sequence<JS::Value>& aIterable, ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global =
@ -1162,7 +1162,7 @@ Promise::Race(const GlobalObject& aGlobal,
for (uint32_t i = 0; i < aIterable.Length(); ++i) {
JS::Rooted<JS::Value> value(cx, aIterable.ElementAt(i));
RefPtr<Promise> nextPromise = Promise::Resolve(aGlobal, value, aRv);
RefPtr<Promise> nextPromise = Promise::Resolve(aGlobal, aThisv, value, aRv);
// According to spec, Resolve can throw, but our implementation never does.
// Well it does when window isn't passed on the main thread, but that is an
// implementation detail which should never be reached since we are checking

Просмотреть файл

@ -164,7 +164,7 @@ public:
ErrorResult& aRv, JS::Handle<JSObject*> aDesiredProto);
static already_AddRefed<Promise>
Resolve(const GlobalObject& aGlobal,
Resolve(const GlobalObject& aGlobal, JS::Handle<JS::Value> aThisv,
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
static already_AddRefed<Promise>
@ -172,7 +172,7 @@ public:
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
static already_AddRefed<Promise>
Reject(const GlobalObject& aGlobal,
Reject(const GlobalObject& aGlobal, JS::Handle<JS::Value> aThisv,
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
static already_AddRefed<Promise>
@ -187,7 +187,7 @@ public:
Catch(JSContext* aCx, AnyCallback* aRejectCallback, ErrorResult& aRv);
static already_AddRefed<Promise>
All(const GlobalObject& aGlobal,
All(const GlobalObject& aGlobal, JS::Handle<JS::Value> aThisv,
const Sequence<JS::Value>& aIterable, ErrorResult& aRv);
static already_AddRefed<Promise>
@ -195,7 +195,7 @@ public:
const nsTArray<RefPtr<Promise>>& aPromiseList, ErrorResult& aRv);
static already_AddRefed<Promise>
Race(const GlobalObject& aGlobal,
Race(const GlobalObject& aGlobal, JS::Handle<JS::Value> aThisv,
const Sequence<JS::Value>& aIterable, ErrorResult& aRv);
void AppendNativeHandler(PromiseNativeHandler* aRunnable);