Skip to content
This repository has been archived by the owner on Aug 4, 2022. It is now read-only.

Commit

Permalink
Bug 1339999 - Properly handle OOM during exception throwing in all Pr…
Browse files Browse the repository at this point in the history
…omise code. r=arai

MozReview-Commit-ID: 2uZgTZAKYnK
  • Loading branch information
tschneidereit committed Mar 26, 2017
1 parent 669ee79 commit e810f88
Showing 1 changed file with 22 additions and 19 deletions.
41 changes: 22 additions & 19 deletions js/src/builtin/Promise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,20 @@ NewPromiseAllDataHolder(JSContext* cx, HandleObject resultPromise, HandleValue v
return dataHolder;
}

/**
* Wrapper for GetAndClearException that handles cases where no exception is
* pending, but an error occurred. This can be the case if an OOM was
* encountered while throwing the error.
*/
static bool
MaybeGetAndClearException(JSContext* cx, MutableHandleValue rval)
{
if (!cx->isExceptionPending())
return false;

return GetAndClearException(cx, rval);
}

static MOZ_MUST_USE bool RunResolutionFunction(JSContext *cx, HandleObject resolutionFun,
HandleValue result, ResolutionMode mode,
HandleObject promiseObj);
Expand All @@ -142,13 +156,9 @@ static MOZ_MUST_USE bool RunResolutionFunction(JSContext *cx, HandleObject resol
static bool
AbruptRejectPromise(JSContext *cx, CallArgs& args, HandleObject promiseObj, HandleObject reject)
{
// Not much we can do about uncatchable exceptions, so just bail.
if (!cx->isExceptionPending())
return false;

// Step 1.a.
RootedValue reason(cx);
if (!GetAndClearException(cx, &reason))
if (!MaybeGetAndClearException(cx, &reason))
return false;

if (!RunResolutionFunction(cx, reject, reason, RejectMode, promiseObj))
Expand Down Expand Up @@ -351,7 +361,8 @@ ResolvePromiseInternal(JSContext* cx, HandleObject promise, HandleValue resoluti
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF);
RootedValue selfResolutionError(cx);
MOZ_ALWAYS_TRUE(GetAndClearException(cx, &selfResolutionError));
if (!MaybeGetAndClearException(cx, &selfResolutionError))
return false;

// Step 6.b.
return RejectMaybeWrappedPromise(cx, promise, selfResolutionError);
Expand All @@ -364,7 +375,7 @@ ResolvePromiseInternal(JSContext* cx, HandleObject promise, HandleValue resoluti
// Step 9.
if (!status) {
RootedValue error(cx);
if (!GetAndClearException(cx, &error))
if (!MaybeGetAndClearException(cx, &error))
return false;

return RejectMaybeWrappedPromise(cx, promise, error);
Expand Down Expand Up @@ -899,9 +910,7 @@ PromiseReactionJob(JSContext* cx, unsigned argc, Value* vp)
args2[0].set(argument);
if (!Call(cx, handlerVal, UndefinedHandleValue, args2, &handlerResult)) {
resolutionMode = RejectMode;
// Not much we can do about uncatchable exceptions, so just bail
// for those.
if (!cx->isExceptionPending() || !GetAndClearException(cx, &handlerResult))
if (!MaybeGetAndClearException(cx, &handlerResult))
return false;
}
}
Expand Down Expand Up @@ -978,7 +987,7 @@ PromiseResolveThenableJob(JSContext* cx, unsigned argc, Value* vp)
if (Call(cx, then, thenable, args2, &rval))
return true;

if (!GetAndClearException(cx, &rval))
if (!MaybeGetAndClearException(cx, &rval))
return false;

FixedInvokeArgs<1> rejectArgs(cx);
Expand Down Expand Up @@ -1321,9 +1330,7 @@ PromiseObject::create(JSContext* cx, HandleObject executor, HandleObject proto /
// Step 10.
if (!success) {
RootedValue exceptionVal(cx);
// Not much we can do about uncatchable exceptions, so just bail
// for those.
if (!cx->isExceptionPending() || !GetAndClearException(cx, &exceptionVal))
if (!MaybeGetAndClearException(cx, &exceptionVal))
return nullptr;

FixedInvokeArgs<1> args(cx);
Expand Down Expand Up @@ -2125,13 +2132,9 @@ js::CreatePromiseObjectForAsync(JSContext* cx, HandleValue generatorVal)
MOZ_MUST_USE bool
js::AsyncFunctionThrown(JSContext* cx, Handle<PromiseObject*> resultPromise)
{
// Not much we can do about uncatchable exceptions, so just bail.
if (!cx->isExceptionPending())
return false;

// Step 3.f.
RootedValue exc(cx);
if (!GetAndClearException(cx, &exc))
if (!MaybeGetAndClearException(cx, &exc))
return false;

if (!RejectMaybeWrappedPromise(cx, resultPromise, exc))
Expand Down

0 comments on commit e810f88

Please sign in to comment.