Skip to content

Commit

Permalink
Bug 1170760 part 2. Pass in the 'this' value to Promise static method…
Browse files Browse the repository at this point in the history
…s. r=peterv
  • Loading branch information
bzbarsky committed Nov 25, 2015
1 parent 80216f9 commit aa5727d
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 13 deletions.
11 changes: 10 additions & 1 deletion dom/bindings/BindingUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 14 additions & 2 deletions dom/bindings/Codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -5085,12 +5085,19 @@ def handleNull(templateBody, setToNullVar, extraConditionForNull=""):
// 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}
}
Expand Down Expand Up @@ -7054,6 +7061,11 @@ def __init__(self, returnType, arguments, nativeMethodName, static,
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.
Expand Down
12 changes: 6 additions & 6 deletions dom/promise/Promise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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();
Expand All @@ -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());

Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions dom/promise/Promise.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,15 @@ class Promise : public nsISupports,
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>
Resolve(nsIGlobalObject* aGlobal, JSContext* aCx,
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>
Expand All @@ -187,15 +187,15 @@ class Promise : public nsISupports,
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>
All(const GlobalObject& aGlobal,
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);
Expand Down

0 comments on commit aa5727d

Please sign in to comment.