author | Sebastian Hengst <archaeopteryx@coole-files.de> |
Fri, 03 Mar 2017 15:43:24 +0100 | |
changeset 345902 | 4dbbd735c27d7a4a2968c819c5022d31e71b2dc8 |
parent 345901 | c3e6f013c7718a829dbd34f2941708fb86bca4b5 |
child 345903 | e090bd2b732cfb91b4b84ac7803a2e3160ef0615 |
push id | 38337 |
push user | kwierso@gmail.com |
push date | Sat, 04 Mar 2017 01:30:14 +0000 |
treeherder | autoland@b691557cb7a3 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | backout |
bugs | 1339999 |
milestone | 54.0a1 |
backs out | cfd2fd77ff046cfbe2d1693858f093df9af41d74 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/src/builtin/Promise.cpp | file | annotate | diff | comparison | revisions | |
js/src/jit-test/tests/promise/handling-oom-during-exception-throwing.js | file | annotate | diff | comparison | revisions |
--- a/js/src/builtin/Promise.cpp +++ b/js/src/builtin/Promise.cpp @@ -126,44 +126,34 @@ NewPromiseAllDataHolder(JSContext* cx, H dataHolder->setFixedSlot(PromiseAllDataHolderSlot_Promise, ObjectValue(*resultPromise)); dataHolder->setFixedSlot(PromiseAllDataHolderSlot_RemainingElements, Int32Value(1)); dataHolder->setFixedSlot(PromiseAllDataHolderSlot_ValuesArray, valuesArray); dataHolder->setFixedSlot(PromiseAllDataHolderSlot_ResolveFunction, ObjectValue(*resolve)); 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); // ES2016, 25.4.1.1.1, Steps 1.a-b. // Extracting all of this internal spec algorithm into a helper function would // be tedious, so the check in step 1 and the entirety of step 2 aren't // included. 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 (!MaybeGetAndClearException(cx, &reason)) + if (!GetAndClearException(cx, &reason)) return false; if (!RunResolutionFunction(cx, reject, reason, RejectMode, promiseObj)) return false; // Step 1.b. args.rval().setObject(*promiseObj); return true; @@ -356,31 +346,30 @@ ResolvePromiseInternal(JSContext* cx, Ha RootedObject resolution(cx, &resolutionVal.toObject()); // Step 6. if (resolution == promise) { // Step 6.a. JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF); RootedValue selfResolutionError(cx); - if (!MaybeGetAndClearException(cx, &selfResolutionError)) - return false; + MOZ_ALWAYS_TRUE(GetAndClearException(cx, &selfResolutionError)); // Step 6.b. return RejectMaybeWrappedPromise(cx, promise, selfResolutionError); } // Step 8. RootedValue thenVal(cx); bool status = GetProperty(cx, resolution, resolution, cx->names().then, &thenVal); // Step 9. if (!status) { RootedValue error(cx); - if (!MaybeGetAndClearException(cx, &error)) + if (!GetAndClearException(cx, &error)) return false; return RejectMaybeWrappedPromise(cx, promise, error); } // Step 10 (implicit). // Step 11. @@ -905,17 +894,19 @@ PromiseReactionJob(JSContext* cx, unsign handlerResult = argument; } } else { // Step 6. FixedInvokeArgs<1> args2(cx); args2[0].set(argument); if (!Call(cx, handlerVal, UndefinedHandleValue, args2, &handlerResult)) { resolutionMode = RejectMode; - if (!MaybeGetAndClearException(cx, &handlerResult)) + // Not much we can do about uncatchable exceptions, so just bail + // for those. + if (!cx->isExceptionPending() || !GetAndClearException(cx, &handlerResult)) return false; } } // Steps 7-9. size_t hookSlot = resolutionMode == RejectMode ? ReactionRecordSlot_Reject : ReactionRecordSlot_Resolve; @@ -982,17 +973,17 @@ PromiseResolveThenableJob(JSContext* cx, args2[1].set(rejectVal); RootedValue rval(cx); // In difference to the usual pattern, we return immediately on success. if (Call(cx, then, thenable, args2, &rval)) return true; - if (!MaybeGetAndClearException(cx, &rval)) + if (!GetAndClearException(cx, &rval)) return false; FixedInvokeArgs<1> rejectArgs(cx); rejectArgs[0].set(rval); return Call(cx, rejectVal, UndefinedHandleValue, rejectArgs, &rval); } @@ -1325,17 +1316,19 @@ PromiseObject::create(JSContext* cx, Han RootedValue calleeOrRval(cx, ObjectValue(*executor)); success = Call(cx, calleeOrRval, UndefinedHandleValue, args, &calleeOrRval); } // Step 10. if (!success) { RootedValue exceptionVal(cx); - if (!MaybeGetAndClearException(cx, &exceptionVal)) + // Not much we can do about uncatchable exceptions, so just bail + // for those. + if (!cx->isExceptionPending() || !GetAndClearException(cx, &exceptionVal)) return nullptr; FixedInvokeArgs<1> args(cx); args[0].set(exceptionVal); // |rejectVal| is unused after this, so we can safely write to it. if (!Call(cx, rejectVal, UndefinedHandleValue, args, &rejectVal)) @@ -2127,19 +2120,23 @@ js::CreatePromiseObjectForAsync(JSContex promise->setFixedSlot(PromiseSlot_AwaitGenerator, generatorVal); return promise; } // Async Functions proposal 2.2 steps 3.f, 3.g. 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 (!MaybeGetAndClearException(cx, &exc)) + if (!GetAndClearException(cx, &exc)) return false; if (!RejectMaybeWrappedPromise(cx, resultPromise, exc)) return false; // Step 3.g. return true; }
deleted file mode 100644 --- a/js/src/jit-test/tests/promise/handling-oom-during-exception-throwing.js +++ /dev/null @@ -1,12 +0,0 @@ -// |jit-test| error: out of memory -var y = { - then: function(m) { - throw 0; - } -}; -Promise.resolve(y); - -g = newGlobal(); -g.parent = this; -g.eval("Debugger(parent).onExceptionUnwind = function(fr, e) {return {throw:e}};"); -gcparam("maxBytes", gcparam("gcBytes"));