| 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 |