OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 | 6 |
7 #include <fstream> // NOLINT(readability/streams) | 7 #include <fstream> // NOLINT(readability/streams) |
8 #include <sstream> | 8 #include <sstream> |
9 | 9 |
10 #include "src/v8.h" | 10 #include "src/v8.h" |
(...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1060 code = frame->LookupCode(); | 1060 code = frame->LookupCode(); |
1061 handler_sp = handler->address() + StackHandlerConstants::kSize; | 1061 handler_sp = handler->address() + StackHandlerConstants::kSize; |
1062 offset = Smi::cast(code->handler_table()->get(0))->value(); | 1062 offset = Smi::cast(code->handler_table()->get(0))->value(); |
1063 break; | 1063 break; |
1064 } | 1064 } |
1065 | 1065 |
1066 // For optimized frames we perform a lookup in the handler table. | 1066 // For optimized frames we perform a lookup in the handler table. |
1067 if (frame->is_optimized() && catchable_by_js) { | 1067 if (frame->is_optimized() && catchable_by_js) { |
1068 OptimizedFrame* js_frame = static_cast<OptimizedFrame*>(frame); | 1068 OptimizedFrame* js_frame = static_cast<OptimizedFrame*>(frame); |
1069 int stack_slots = 0; // Will contain stack slot count of frame. | 1069 int stack_slots = 0; // Will contain stack slot count of frame. |
1070 offset = js_frame->LookupExceptionHandlerInTable(&stack_slots); | 1070 offset = js_frame->LookupExceptionHandlerInTable(&stack_slots, NULL); |
1071 if (offset >= 0) { | 1071 if (offset >= 0) { |
1072 // Compute the stack pointer from the frame pointer. This ensures that | 1072 // Compute the stack pointer from the frame pointer. This ensures that |
1073 // argument slots on the stack are dropped as returning would. | 1073 // argument slots on the stack are dropped as returning would. |
1074 Address return_sp = frame->fp() - | 1074 Address return_sp = frame->fp() - |
1075 StandardFrameConstants::kFixedFrameSizeFromFp - | 1075 StandardFrameConstants::kFixedFrameSizeFromFp - |
1076 stack_slots * kPointerSize; | 1076 stack_slots * kPointerSize; |
1077 | 1077 |
1078 // Gather information from the frame. | 1078 // Gather information from the frame. |
1079 code = frame->LookupCode(); | 1079 code = frame->LookupCode(); |
1080 handler_sp = return_sp; | 1080 handler_sp = return_sp; |
1081 handler_fp = frame->fp(); | 1081 handler_fp = frame->fp(); |
1082 break; | 1082 break; |
1083 } | 1083 } |
1084 } | 1084 } |
1085 | 1085 |
1086 // For JavaScript frames we perform a range lookup in the handler table. | 1086 // For JavaScript frames we perform a range lookup in the handler table. |
1087 if (frame->is_java_script() && catchable_by_js) { | 1087 if (frame->is_java_script() && catchable_by_js) { |
1088 JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame); | 1088 JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame); |
1089 int stack_slots = 0; // Will contain operand stack depth of handler. | 1089 int stack_slots = 0; // Will contain operand stack depth of handler. |
1090 offset = js_frame->LookupExceptionHandlerInTable(&stack_slots); | 1090 offset = js_frame->LookupExceptionHandlerInTable(&stack_slots, NULL); |
1091 if (offset >= 0) { | 1091 if (offset >= 0) { |
1092 // Compute the stack pointer from the frame pointer. This ensures that | 1092 // Compute the stack pointer from the frame pointer. This ensures that |
1093 // operand stack slots are dropped for nested statements. Also restore | 1093 // operand stack slots are dropped for nested statements. Also restore |
1094 // correct context for the handler which is pushed within the try-block. | 1094 // correct context for the handler which is pushed within the try-block. |
1095 Address return_sp = frame->fp() - | 1095 Address return_sp = frame->fp() - |
1096 StandardFrameConstants::kFixedFrameSizeFromFp - | 1096 StandardFrameConstants::kFixedFrameSizeFromFp - |
1097 stack_slots * kPointerSize; | 1097 stack_slots * kPointerSize; |
1098 STATIC_ASSERT(TryBlockConstant::kElementCount == 1); | 1098 STATIC_ASSERT(TryBlockConstant::kElementCount == 1); |
1099 context = Context::cast(Memory::Object_at(return_sp - kPointerSize)); | 1099 context = Context::cast(Memory::Object_at(return_sp - kPointerSize)); |
1100 | 1100 |
(...skipping 17 matching lines...) Expand all Loading... |
1118 thread_local_top()->pending_handler_offset_ = offset; | 1118 thread_local_top()->pending_handler_offset_ = offset; |
1119 thread_local_top()->pending_handler_fp_ = handler_fp; | 1119 thread_local_top()->pending_handler_fp_ = handler_fp; |
1120 thread_local_top()->pending_handler_sp_ = handler_sp; | 1120 thread_local_top()->pending_handler_sp_ = handler_sp; |
1121 | 1121 |
1122 // Return and clear pending exception. | 1122 // Return and clear pending exception. |
1123 clear_pending_exception(); | 1123 clear_pending_exception(); |
1124 return exception; | 1124 return exception; |
1125 } | 1125 } |
1126 | 1126 |
1127 | 1127 |
1128 Isolate::CatchType Isolate::PredictExceptionCatcher() { | 1128 Isolate::CatchType Isolate::PredictExceptionCatcher( |
| 1129 Isolate::ExceptionPredictionMode mode) { |
1129 Address external_handler = thread_local_top()->try_catch_handler_address(); | 1130 Address external_handler = thread_local_top()->try_catch_handler_address(); |
1130 Address entry_handler = Isolate::handler(thread_local_top()); | 1131 Address entry_handler = Isolate::handler(thread_local_top()); |
1131 if (IsExternalHandlerOnTop(nullptr)) return CAUGHT_BY_EXTERNAL; | 1132 if (IsExternalHandlerOnTop(nullptr)) return CAUGHT_BY_EXTERNAL; |
1132 | 1133 |
1133 // Search for an exception handler by performing a full walk over the stack. | 1134 // Search for an exception handler by performing a full walk over the stack. |
1134 for (StackFrameIterator iter(this); !iter.done(); iter.Advance()) { | 1135 for (StackFrameIterator iter(this); !iter.done(); iter.Advance()) { |
1135 StackFrame* frame = iter.frame(); | 1136 StackFrame* frame = iter.frame(); |
1136 | 1137 |
1137 // For JSEntryStub frames we update the JS_ENTRY handler. | 1138 // For JSEntryStub frames we update the JS_ENTRY handler. |
1138 if (frame->is_entry() || frame->is_entry_construct()) { | 1139 if (frame->is_entry() || frame->is_entry_construct()) { |
1139 entry_handler = frame->top_handler()->next()->address(); | 1140 entry_handler = frame->top_handler()->next()->address(); |
1140 } | 1141 } |
1141 | 1142 |
1142 // For JavaScript frames we perform a lookup in the handler table. | 1143 // For JavaScript frames we perform a lookup in the handler table. |
1143 if (frame->is_java_script()) { | 1144 if (frame->is_java_script()) { |
1144 JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame); | 1145 JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame); |
1145 int stack_slots = 0; // The computed stack slot count is not used. | 1146 int stack_slots = 0; // The computed stack slot count is not used. |
1146 if (js_frame->LookupExceptionHandlerInTable(&stack_slots) > 0) { | 1147 HandlerTable::CatchPrediction prediction; |
1147 return CAUGHT_BY_JAVASCRIPT; | 1148 if (js_frame->LookupExceptionHandlerInTable(&stack_slots, &prediction) > |
| 1149 0) { |
| 1150 if (mode != CONSERVATIVE_PREDICTION || |
| 1151 prediction != HandlerTable::UNCAUGHT) { |
| 1152 return CAUGHT_BY_JAVASCRIPT; |
| 1153 } |
1148 } | 1154 } |
1149 } | 1155 } |
1150 | 1156 |
1151 // The exception has been externally caught if and only if there is an | 1157 // The exception has been externally caught if and only if there is an |
1152 // external handler which is on top of the top-most JS_ENTRY handler. | 1158 // external handler which is on top of the top-most JS_ENTRY handler. |
1153 if (external_handler != nullptr && !try_catch_handler()->is_verbose_) { | 1159 if (external_handler != nullptr && !try_catch_handler()->is_verbose_) { |
1154 if (entry_handler == nullptr || entry_handler > external_handler) { | 1160 if (entry_handler == nullptr || entry_handler > external_handler) { |
1155 return CAUGHT_BY_EXTERNAL; | 1161 return CAUGHT_BY_EXTERNAL; |
1156 } | 1162 } |
1157 } | 1163 } |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1566 Handle<Object> Isolate::GetPromiseOnStackOnThrow() { | 1572 Handle<Object> Isolate::GetPromiseOnStackOnThrow() { |
1567 Handle<Object> undefined = factory()->undefined_value(); | 1573 Handle<Object> undefined = factory()->undefined_value(); |
1568 ThreadLocalTop* tltop = thread_local_top(); | 1574 ThreadLocalTop* tltop = thread_local_top(); |
1569 if (tltop->promise_on_stack_ == NULL) return undefined; | 1575 if (tltop->promise_on_stack_ == NULL) return undefined; |
1570 Handle<JSFunction> promise_function = tltop->promise_on_stack_->function(); | 1576 Handle<JSFunction> promise_function = tltop->promise_on_stack_->function(); |
1571 // Find the top-most try-catch or try-finally handler. | 1577 // Find the top-most try-catch or try-finally handler. |
1572 if (PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT) return undefined; | 1578 if (PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT) return undefined; |
1573 for (JavaScriptFrameIterator it(this); !it.done(); it.Advance()) { | 1579 for (JavaScriptFrameIterator it(this); !it.done(); it.Advance()) { |
1574 JavaScriptFrame* frame = it.frame(); | 1580 JavaScriptFrame* frame = it.frame(); |
1575 int stack_slots = 0; // The computed stack slot count is not used. | 1581 int stack_slots = 0; // The computed stack slot count is not used. |
1576 if (frame->LookupExceptionHandlerInTable(&stack_slots) > 0) { | 1582 if (frame->LookupExceptionHandlerInTable(&stack_slots, NULL) > 0) { |
1577 // Throwing inside a Promise only leads to a reject if not caught by an | 1583 // Throwing inside a Promise only leads to a reject if not caught by an |
1578 // inner try-catch or try-finally. | 1584 // inner try-catch or try-finally. |
1579 if (frame->function() == *promise_function) { | 1585 if (frame->function() == *promise_function) { |
1580 return tltop->promise_on_stack_->promise(); | 1586 return tltop->promise_on_stack_->promise(); |
1581 } | 1587 } |
1582 return undefined; | 1588 return undefined; |
1583 } | 1589 } |
1584 } | 1590 } |
1585 return undefined; | 1591 return undefined; |
1586 } | 1592 } |
(...skipping 1195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2782 if (prev_ && prev_->Intercept(flag)) return true; | 2788 if (prev_ && prev_->Intercept(flag)) return true; |
2783 // Then check whether this scope intercepts. | 2789 // Then check whether this scope intercepts. |
2784 if ((flag & intercept_mask_)) { | 2790 if ((flag & intercept_mask_)) { |
2785 intercepted_flags_ |= flag; | 2791 intercepted_flags_ |= flag; |
2786 return true; | 2792 return true; |
2787 } | 2793 } |
2788 return false; | 2794 return false; |
2789 } | 2795 } |
2790 | 2796 |
2791 } } // namespace v8::internal | 2797 } } // namespace v8::internal |
OLD | NEW |