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 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1018 | 1018 |
1019 Object* Isolate::ReThrow(Object* exception) { | 1019 Object* Isolate::ReThrow(Object* exception) { |
1020 DCHECK(!has_pending_exception()); | 1020 DCHECK(!has_pending_exception()); |
1021 | 1021 |
1022 // Set the exception being re-thrown. | 1022 // Set the exception being re-thrown. |
1023 set_pending_exception(exception); | 1023 set_pending_exception(exception); |
1024 return heap()->exception(); | 1024 return heap()->exception(); |
1025 } | 1025 } |
1026 | 1026 |
1027 | 1027 |
1028 Object* Isolate::FindHandler() { | 1028 Object* Isolate::UnwindAndFindHandler() { |
1029 Object* exception = pending_exception(); | 1029 Object* exception = pending_exception(); |
1030 | 1030 |
1031 Code* code = nullptr; | 1031 Code* code = nullptr; |
1032 Context* context = nullptr; | 1032 Context* context = nullptr; |
1033 intptr_t offset = 0; | 1033 intptr_t offset = 0; |
1034 Address handler_sp = nullptr; | 1034 Address handler_sp = nullptr; |
1035 Address handler_fp = nullptr; | 1035 Address handler_fp = nullptr; |
1036 | 1036 |
1037 // Special handling of termination exceptions, uncatchable by JavaScript code, | 1037 // Special handling of termination exceptions, uncatchable by JavaScript code, |
1038 // we unwind the handlers until the top ENTRY handler is found. | 1038 // we unwind the handlers until the top ENTRY handler is found. |
(...skipping 16 matching lines...) Expand all Loading... |
1055 handler_sp = handler->address() + StackHandlerConstants::kSize; | 1055 handler_sp = handler->address() + StackHandlerConstants::kSize; |
1056 offset = Smi::cast(code->handler_table()->get(0))->value(); | 1056 offset = Smi::cast(code->handler_table()->get(0))->value(); |
1057 break; | 1057 break; |
1058 } | 1058 } |
1059 | 1059 |
1060 // For optimized frames we perform a lookup in the handler table. | 1060 // For optimized frames we perform a lookup in the handler table. |
1061 if (frame->is_optimized() && catchable_by_js) { | 1061 if (frame->is_optimized() && catchable_by_js) { |
1062 OptimizedFrame* js_frame = static_cast<OptimizedFrame*>(frame); | 1062 OptimizedFrame* js_frame = static_cast<OptimizedFrame*>(frame); |
1063 int stack_slots = 0; // Will contain stack slot count of frame. | 1063 int stack_slots = 0; // Will contain stack slot count of frame. |
1064 offset = js_frame->LookupExceptionHandlerInTable(&stack_slots); | 1064 offset = js_frame->LookupExceptionHandlerInTable(&stack_slots); |
1065 if (offset < 0) continue; | 1065 if (offset >= 0) { |
| 1066 // Compute the stack pointer from the frame pointer. This ensures that |
| 1067 // argument slots on the stack are dropped as returning would. |
| 1068 Address return_sp = frame->fp() - |
| 1069 StandardFrameConstants::kFixedFrameSizeFromFp - |
| 1070 stack_slots * kPointerSize; |
1066 | 1071 |
1067 // Compute the stack pointer from the frame pointer. This ensures that | 1072 // Gather information from the frame. |
1068 // argument slots on the stack are dropped as returning would. | 1073 code = frame->LookupCode(); |
1069 Address return_sp = frame->fp() - | 1074 handler_sp = return_sp; |
1070 StandardFrameConstants::kFixedFrameSizeFromFp - | 1075 handler_fp = frame->fp(); |
1071 stack_slots * kPointerSize; | 1076 break; |
1072 | 1077 } |
1073 // Gather information from the frame. | |
1074 code = frame->LookupCode(); | |
1075 handler_sp = return_sp; | |
1076 handler_fp = frame->fp(); | |
1077 break; | |
1078 } | 1078 } |
1079 | 1079 |
1080 // For JavaScript frames we perform a range lookup in the handler table. | 1080 // For JavaScript frames we perform a range lookup in the handler table. |
1081 if (frame->is_java_script() && catchable_by_js) { | 1081 if (frame->is_java_script() && catchable_by_js) { |
1082 JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame); | 1082 JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame); |
1083 int stack_slots = 0; // Will contain operand stack depth of handler. | 1083 int stack_slots = 0; // Will contain operand stack depth of handler. |
1084 offset = js_frame->LookupExceptionHandlerInTable(&stack_slots); | 1084 offset = js_frame->LookupExceptionHandlerInTable(&stack_slots); |
1085 if (offset < 0) continue; | 1085 if (offset >= 0) { |
| 1086 // Compute the stack pointer from the frame pointer. This ensures that |
| 1087 // operand stack slots are dropped for nested statements. Also restore |
| 1088 // correct context for the handler which is pushed within the try-block. |
| 1089 Address return_sp = frame->fp() - |
| 1090 StandardFrameConstants::kFixedFrameSizeFromFp - |
| 1091 stack_slots * kPointerSize; |
| 1092 STATIC_ASSERT(TryBlockConstant::kElementCount == 1); |
| 1093 context = Context::cast(Memory::Object_at(return_sp - kPointerSize)); |
1086 | 1094 |
1087 // Compute the stack pointer from the frame pointer. This ensures that | 1095 // Gather information from the frame. |
1088 // operand stack slots are dropped for nested statements. Also restore | 1096 code = frame->LookupCode(); |
1089 // correct context for the handler which is pushed within the try-block. | 1097 handler_sp = return_sp; |
1090 Address return_sp = frame->fp() - | 1098 handler_fp = frame->fp(); |
1091 StandardFrameConstants::kFixedFrameSizeFromFp - | 1099 break; |
1092 stack_slots * kPointerSize; | 1100 } |
1093 STATIC_ASSERT(TryBlockConstant::kElementCount == 1); | 1101 } |
1094 context = Context::cast(Memory::Object_at(return_sp - kPointerSize)); | |
1095 | 1102 |
1096 // Gather information from the frame. | 1103 RemoveMaterializedObjectsOnUnwind(frame); |
1097 code = frame->LookupCode(); | |
1098 handler_sp = return_sp; | |
1099 handler_fp = frame->fp(); | |
1100 break; | |
1101 } | |
1102 } | 1104 } |
1103 | 1105 |
1104 // Handler must exist. | 1106 // Handler must exist. |
1105 CHECK(code != nullptr); | 1107 CHECK(code != nullptr); |
1106 | 1108 |
1107 // Store information to be consumed by the CEntryStub. | 1109 // Store information to be consumed by the CEntryStub. |
1108 thread_local_top()->pending_handler_context_ = context; | 1110 thread_local_top()->pending_handler_context_ = context; |
1109 thread_local_top()->pending_handler_code_ = code; | 1111 thread_local_top()->pending_handler_code_ = code; |
1110 thread_local_top()->pending_handler_offset_ = offset; | 1112 thread_local_top()->pending_handler_offset_ = offset; |
1111 thread_local_top()->pending_handler_fp_ = handler_fp; | 1113 thread_local_top()->pending_handler_fp_ = handler_fp; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1147 return CAUGHT_BY_EXTERNAL; | 1149 return CAUGHT_BY_EXTERNAL; |
1148 } | 1150 } |
1149 } | 1151 } |
1150 } | 1152 } |
1151 | 1153 |
1152 // Handler not found. | 1154 // Handler not found. |
1153 return NOT_CAUGHT; | 1155 return NOT_CAUGHT; |
1154 } | 1156 } |
1155 | 1157 |
1156 | 1158 |
| 1159 void Isolate::RemoveMaterializedObjectsOnUnwind(StackFrame* frame) { |
| 1160 if (frame->is_optimized()) { |
| 1161 bool removed = materialized_object_store_->Remove(frame->fp()); |
| 1162 USE(removed); |
| 1163 // If there were any materialized objects, the code should be |
| 1164 // marked for deopt. |
| 1165 DCHECK(!removed || frame->LookupCode()->marked_for_deoptimization()); |
| 1166 } |
| 1167 } |
| 1168 |
| 1169 |
1157 Object* Isolate::ThrowIllegalOperation() { | 1170 Object* Isolate::ThrowIllegalOperation() { |
1158 if (FLAG_stack_trace_on_illegal) PrintStack(stdout); | 1171 if (FLAG_stack_trace_on_illegal) PrintStack(stdout); |
1159 return Throw(heap()->illegal_access_string()); | 1172 return Throw(heap()->illegal_access_string()); |
1160 } | 1173 } |
1161 | 1174 |
1162 | 1175 |
1163 void Isolate::ScheduleThrow(Object* exception) { | 1176 void Isolate::ScheduleThrow(Object* exception) { |
1164 // When scheduling a throw we first throw the exception to get the | 1177 // When scheduling a throw we first throw the exception to get the |
1165 // error reporting if it is uncaught before rescheduling it. | 1178 // error reporting if it is uncaught before rescheduling it. |
1166 Throw(exception); | 1179 Throw(exception); |
(...skipping 1589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2756 if (prev_ && prev_->Intercept(flag)) return true; | 2769 if (prev_ && prev_->Intercept(flag)) return true; |
2757 // Then check whether this scope intercepts. | 2770 // Then check whether this scope intercepts. |
2758 if ((flag & intercept_mask_)) { | 2771 if ((flag & intercept_mask_)) { |
2759 intercepted_flags_ |= flag; | 2772 intercepted_flags_ |= flag; |
2760 return true; | 2773 return true; |
2761 } | 2774 } |
2762 return false; | 2775 return false; |
2763 } | 2776 } |
2764 | 2777 |
2765 } } // namespace v8::internal | 2778 } } // namespace v8::internal |
OLD | NEW |