Index: src/isolate.cc |
diff --git a/src/isolate.cc b/src/isolate.cc |
index 1b96583cb093cd44eb2022945e59b2a6bc185322..b9c35b7fae1abc8f9c874f604a5d547b1ace8b03 100644 |
--- a/src/isolate.cc |
+++ b/src/isolate.cc |
@@ -1703,29 +1703,59 @@ void Isolate::PopPromise() { |
global_handles()->Destroy(global_promise.location()); |
} |
+bool Isolate::PromiseHasUserDefinedRejectHandler(Handle<Object> promise) { |
+ Handle<JSFunction> fun = promise_has_user_defined_reject_handler(); |
+ Handle<Object> has_reject_handler; |
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(this, has_reject_handler, |
jgruber
2016/09/12 10:27:31
We need to handle thrown exceptions, either by cle
Dan Ehrenberg
2016/09/12 22:12:11
I think it's OK to handle the exceptions like this
jgruber
2016/09/13 08:17:20
If we don't care about any thrown exceptions in pr
Dan Ehrenberg
2016/09/13 22:34:55
Done
adamk
2016/09/15 00:11:07
Would Execution::TryCall() work instead of calling
Dan Ehrenberg
2016/09/15 00:37:40
Done
|
+ Execution::Call(this, fun, promise, 0, NULL), |
+ false); |
+ return has_reject_handler->IsTrue(this); |
+} |
Handle<Object> Isolate::GetPromiseOnStackOnThrow() { |
- Handle<Object> undefined = factory()->undefined_value(); |
+ Handle<Object> retval = factory()->undefined_value(); |
ThreadLocalTop* tltop = thread_local_top(); |
- if (tltop->promise_on_stack_ == NULL) return undefined; |
+ if (tltop->promise_on_stack_ == NULL) return retval; |
kozy
2016/09/12 18:13:56
Can we return factory()->undefined_value() here..
Dan Ehrenberg
2016/09/12 22:12:11
Done
|
// Find the top-most try-catch or try-finally handler. |
CatchType prediction = PredictExceptionCatcher(); |
if (prediction == NOT_CAUGHT || prediction == CAUGHT_BY_EXTERNAL) { |
- return undefined; |
+ return retval; |
kozy
2016/09/12 18:13:56
..and here, and then introduce retval variable.
Dan Ehrenberg
2016/09/12 22:12:11
Done
|
} |
+ PromiseOnStack* promise_on_stack = tltop->promise_on_stack_; |
for (JavaScriptFrameIterator it(this); !it.done(); it.Advance()) { |
switch (PredictException(it.frame())) { |
case HandlerTable::UNCAUGHT: |
- case HandlerTable::ASYNC_AWAIT: |
- break; |
+ continue; |
case HandlerTable::CAUGHT: |
case HandlerTable::DESUGARING: |
- return undefined; |
+ if (retval->IsJSObject()) { |
jgruber
2016/09/12 10:27:31
Would a DCHECK(retval->IsJSPromise()) work here?
Dan Ehrenberg
2016/09/12 22:12:11
No, as this may be occurring in a case that has no
jgruber
2016/09/13 08:17:20
I meant
if (retval->IsJSObject()) {
DCHECK(ret
Dan Ehrenberg
2016/09/13 22:34:55
Done
|
+ // Caught the result of an inner async/await invocation. |
+ // Mark the inner promise as caught in the "synchronous case" so |
+ // that Debug::OnException will see. |
+ Handle<Symbol> key = factory()->promise_handled_hint_symbol(); |
jgruber
2016/09/12 10:27:31
Which case is this so that the promise isn't marke
Dan Ehrenberg
2016/09/12 22:12:11
I added more comment text to try to explain. This
|
+ JSObject::SetProperty(Handle<JSObject>::cast(retval), key, |
+ factory()->true_value(), STRICT) |
+ .Assert(); |
+ } |
+ return retval; |
case HandlerTable::PROMISE: |
- return tltop->promise_on_stack_->promise(); |
+ return promise_on_stack->promise(); |
+ case HandlerTable::ASYNC_AWAIT: { |
+ // If in the initial portion of async/await, continue the loop to pop up |
+ // successive async/await stack frames until an asynchronous one with |
+ // dependents is found, or a non-async stack frame is encountered, in |
+ // order to handle the synchronous async/await catch prediction case: |
+ // assume that async function calls are awaited. |
+ retval = promise_on_stack->promise(); |
+ if (PromiseHasUserDefinedRejectHandler(retval)) { |
+ return retval; |
+ } |
+ promise_on_stack = promise_on_stack->prev(); |
+ continue; |
+ } |
} |
} |
- return undefined; |
+ return retval; |
} |