| Index: src/isolate.cc
|
| diff --git a/src/isolate.cc b/src/isolate.cc
|
| index 2a52c6658a96800965ba0d085e493fbdaa8e0157..cc8c8b6739f2fd6b9739dbc98e699e693d5bcc62 100644
|
| --- a/src/isolate.cc
|
| +++ b/src/isolate.cc
|
| @@ -1296,6 +1296,31 @@ Object* Isolate::UnwindAndFindHandler() {
|
| return exception;
|
| }
|
|
|
| +namespace {
|
| +HandlerTable::CatchPrediction PredictException(JavaScriptFrame* frame) {
|
| + HandlerTable::CatchPrediction prediction;
|
| + if (frame->is_optimized()) {
|
| + if (frame->LookupExceptionHandlerInTable(nullptr, nullptr) > 0) {
|
| + // This optimized frame will catch. It's handler table does not include
|
| + // exception prediction, and we need to use the corresponding handler
|
| + // tables on the unoptimized code objects.
|
| + List<FrameSummary> summaries;
|
| + frame->Summarize(&summaries);
|
| + for (const FrameSummary& summary : summaries) {
|
| + int code_offset = summary.code_offset();
|
| + int index = summary.abstract_code()->LookupRangeInHandlerTable(
|
| + code_offset, nullptr, &prediction);
|
| + if (index <= 0) continue;
|
| + if (prediction == HandlerTable::UNCAUGHT) continue;
|
| + return prediction;
|
| + }
|
| + }
|
| + } else if (frame->LookupExceptionHandlerInTable(nullptr, &prediction) > 0) {
|
| + return prediction;
|
| + }
|
| + return HandlerTable::UNCAUGHT;
|
| +}
|
| +} // anonymous namespace
|
|
|
| Isolate::CatchType Isolate::PredictExceptionCatcher() {
|
| Address external_handler = thread_local_top()->try_catch_handler_address();
|
| @@ -1314,11 +1339,8 @@ Isolate::CatchType Isolate::PredictExceptionCatcher() {
|
| // For JavaScript frames we perform a lookup in the handler table.
|
| if (frame->is_java_script()) {
|
| JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame);
|
| - HandlerTable::CatchPrediction prediction;
|
| - if (js_frame->LookupExceptionHandlerInTable(nullptr, &prediction) > 0) {
|
| - // We are conservative with our prediction: try-finally is considered
|
| - // to always rethrow, to meet the expectation of the debugger.
|
| - if (prediction != HandlerTable::UNCAUGHT) return CAUGHT_BY_JAVASCRIPT;
|
| + if (PredictException(js_frame) != HandlerTable::UNCAUGHT) {
|
| + return CAUGHT_BY_JAVASCRIPT;
|
| }
|
| }
|
|
|
| @@ -1730,15 +1752,13 @@ Handle<Object> Isolate::GetPromiseOnStackOnThrow() {
|
| // Find the top-most try-catch or try-finally handler.
|
| if (PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT) return undefined;
|
| for (JavaScriptFrameIterator it(this); !it.done(); it.Advance()) {
|
| - JavaScriptFrame* frame = it.frame();
|
| - HandlerTable::CatchPrediction prediction;
|
| - if (frame->LookupExceptionHandlerInTable(nullptr, &prediction) > 0) {
|
| - // Throwing inside a Promise only leads to a reject if not caught by an
|
| - // inner try-catch or try-finally.
|
| - if (prediction == HandlerTable::PROMISE) {
|
| + switch (PredictException(it.frame())) {
|
| + case HandlerTable::UNCAUGHT:
|
| + break;
|
| + case HandlerTable::CAUGHT:
|
| + return undefined;
|
| + case HandlerTable::PROMISE:
|
| return tltop->promise_on_stack_->promise();
|
| - }
|
| - return undefined;
|
| }
|
| }
|
| return undefined;
|
|
|