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 1029 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1040 !(Script::cast(script)->source()->IsUndefined())) { | 1040 !(Script::cast(script)->source()->IsUndefined())) { |
1041 int pos = frame->LookupCode()->SourcePosition(frame->pc()); | 1041 int pos = frame->LookupCode()->SourcePosition(frame->pc()); |
1042 // Compute the location from the function and the reloc info. | 1042 // Compute the location from the function and the reloc info. |
1043 Handle<Script> casted_script(Script::cast(script)); | 1043 Handle<Script> casted_script(Script::cast(script)); |
1044 *target = MessageLocation(casted_script, pos, pos + 1); | 1044 *target = MessageLocation(casted_script, pos, pos + 1); |
1045 } | 1045 } |
1046 } | 1046 } |
1047 } | 1047 } |
1048 | 1048 |
1049 | 1049 |
1050 void Isolate::ComputeLocationFromStackTrace(MessageLocation* target, | |
1051 Handle<Object> exception) { | |
1052 *target = MessageLocation(Handle<Script>(heap_.empty_script()), -1, -1); | |
1053 | |
1054 if (!exception->IsJSObject()) return; | |
1055 Handle<Name> key = factory()->stack_trace_symbol(); | |
1056 Handle<Object> property = | |
1057 JSObject::GetDataProperty(Handle<JSObject>::cast(exception), key); | |
1058 if (!property->IsJSArray()) return; | |
1059 Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property); | |
1060 | |
1061 Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements())); | |
1062 int elements_limit = Smi::cast(simple_stack_trace->length())->value(); | |
1063 | |
1064 for (int i = 1; i < elements_limit; i += 4) { | |
1065 Handle<JSFunction> fun = | |
1066 handle(JSFunction::cast(elements->get(i + 1)), this); | |
1067 if (fun->IsFromNativeScript()) continue; | |
1068 Handle<Code> code = handle(Code::cast(elements->get(i + 2)), this); | |
1069 Handle<Smi> offset = handle(Smi::cast(elements->get(i + 3)), this); | |
1070 Address pc = code->address() + offset->value(); | |
1071 | |
1072 Object* script = fun->shared()->script(); | |
1073 if (script->IsScript() && | |
1074 !(Script::cast(script)->source()->IsUndefined())) { | |
1075 int pos = code->SourcePosition(pc); | |
1076 Handle<Script> casted_script(Script::cast(script)); | |
1077 *target = MessageLocation(casted_script, pos, pos + 1); | |
1078 break; | |
1079 } | |
1080 } | |
1081 } | |
1082 | |
1083 | |
1084 bool Isolate::ShouldReportException(bool* can_be_caught_externally, | 1050 bool Isolate::ShouldReportException(bool* can_be_caught_externally, |
1085 bool catchable_by_javascript) { | 1051 bool catchable_by_javascript) { |
1086 // Find the top-most try-catch handler. | 1052 // Find the top-most try-catch handler. |
1087 StackHandler* handler = | 1053 StackHandler* handler = |
1088 StackHandler::FromAddress(Isolate::handler(thread_local_top())); | 1054 StackHandler::FromAddress(Isolate::handler(thread_local_top())); |
1089 while (handler != NULL && !handler->is_catch()) { | 1055 while (handler != NULL && !handler->is_catch()) { |
1090 handler = handler->next(); | 1056 handler = handler->next(); |
1091 } | 1057 } |
1092 | 1058 |
1093 // Get the address of the external handler so we can compare the address to | 1059 // Get the address of the external handler so we can compare the address to |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 } | 1099 } |
1134 return false; | 1100 return false; |
1135 } | 1101 } |
1136 | 1102 |
1137 static int fatal_exception_depth = 0; | 1103 static int fatal_exception_depth = 0; |
1138 | 1104 |
1139 | 1105 |
1140 Handle<JSMessageObject> Isolate::CreateMessage(Handle<Object> exception, | 1106 Handle<JSMessageObject> Isolate::CreateMessage(Handle<Object> exception, |
1141 MessageLocation* location) { | 1107 MessageLocation* location) { |
1142 Handle<JSArray> stack_trace_object; | 1108 Handle<JSArray> stack_trace_object; |
1143 MessageLocation potential_computed_location; | |
1144 if (capture_stack_trace_for_uncaught_exceptions_) { | 1109 if (capture_stack_trace_for_uncaught_exceptions_) { |
1145 if (IsErrorObject(exception)) { | 1110 if (IsErrorObject(exception)) { |
1146 // We fetch the stack trace that corresponds to this error object. | 1111 // We fetch the stack trace that corresponds to this error object. |
1147 // If the lookup fails, the exception is probably not a valid Error | 1112 // If the lookup fails, the exception is probably not a valid Error |
1148 // object. In that case, we fall through and capture the stack trace | 1113 // object. In that case, we fall through and capture the stack trace |
1149 // at this throw site. | 1114 // at this throw site. |
1150 stack_trace_object = | 1115 stack_trace_object = |
1151 GetDetailedStackTrace(Handle<JSObject>::cast(exception)); | 1116 GetDetailedStackTrace(Handle<JSObject>::cast(exception)); |
1152 if (!location) { | |
1153 ComputeLocationFromStackTrace(&potential_computed_location, exception); | |
1154 location = &potential_computed_location; | |
1155 } | |
1156 } | 1117 } |
1157 if (stack_trace_object.is_null()) { | 1118 if (stack_trace_object.is_null()) { |
1158 // Not an error object, we capture stack and location at throw site. | 1119 // Not an error object, we capture at throw site. |
1159 stack_trace_object = CaptureCurrentStackTrace( | 1120 stack_trace_object = CaptureCurrentStackTrace( |
1160 stack_trace_for_uncaught_exceptions_frame_limit_, | 1121 stack_trace_for_uncaught_exceptions_frame_limit_, |
1161 stack_trace_for_uncaught_exceptions_options_); | 1122 stack_trace_for_uncaught_exceptions_options_); |
1162 } | 1123 } |
1163 } | 1124 } |
1164 if (!location) { | |
1165 ComputeLocation(&potential_computed_location); | |
1166 location = &potential_computed_location; | |
1167 } | |
1168 | 1125 |
1169 // If the exception argument is a custom object, turn it into a string | 1126 // If the exception argument is a custom object, turn it into a string |
1170 // before throwing as uncaught exception. Note that the pending | 1127 // before throwing as uncaught exception. Note that the pending |
1171 // exception object to be set later must not be turned into a string. | 1128 // exception object to be set later must not be turned into a string. |
1172 if (exception->IsJSObject() && !IsErrorObject(exception)) { | 1129 if (exception->IsJSObject() && !IsErrorObject(exception)) { |
1173 MaybeHandle<Object> maybe_exception = | 1130 MaybeHandle<Object> maybe_exception = |
1174 Execution::ToDetailString(this, exception); | 1131 Execution::ToDetailString(this, exception); |
1175 if (!maybe_exception.ToHandle(&exception)) { | 1132 if (!maybe_exception.ToHandle(&exception)) { |
1176 exception = | 1133 exception = |
1177 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("exception")); | 1134 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("exception")); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1263 | 1220 |
1264 if (bootstrapper()->IsActive()) { | 1221 if (bootstrapper()->IsActive()) { |
1265 // It's not safe to try to make message objects or collect stack traces | 1222 // It's not safe to try to make message objects or collect stack traces |
1266 // while the bootstrapper is active since the infrastructure may not have | 1223 // while the bootstrapper is active since the infrastructure may not have |
1267 // been properly initialized. | 1224 // been properly initialized. |
1268 ReportBootstrappingException(exception_handle, location); | 1225 ReportBootstrappingException(exception_handle, location); |
1269 } else { | 1226 } else { |
1270 Handle<Object> message_obj = CreateMessage(exception_handle, location); | 1227 Handle<Object> message_obj = CreateMessage(exception_handle, location); |
1271 | 1228 |
1272 thread_local_top()->pending_message_obj_ = *message_obj; | 1229 thread_local_top()->pending_message_obj_ = *message_obj; |
1273 thread_local_top()->pending_message_script_ = *location->script(); | 1230 if (location != NULL) { |
1274 thread_local_top()->pending_message_start_pos_ = location->start_pos(); | 1231 thread_local_top()->pending_message_script_ = *location->script(); |
1275 thread_local_top()->pending_message_end_pos_ = location->end_pos(); | 1232 thread_local_top()->pending_message_start_pos_ = location->start_pos(); |
| 1233 thread_local_top()->pending_message_end_pos_ = location->end_pos(); |
| 1234 } |
1276 | 1235 |
1277 // If the abort-on-uncaught-exception flag is specified, abort on any | 1236 // If the abort-on-uncaught-exception flag is specified, abort on any |
1278 // exception not caught by JavaScript, even when an external handler is | 1237 // exception not caught by JavaScript, even when an external handler is |
1279 // present. This flag is intended for use by JavaScript developers, so | 1238 // present. This flag is intended for use by JavaScript developers, so |
1280 // print a user-friendly stack trace (not an internal one). | 1239 // print a user-friendly stack trace (not an internal one). |
1281 if (fatal_exception_depth == 0 && FLAG_abort_on_uncaught_exception && | 1240 if (fatal_exception_depth == 0 && FLAG_abort_on_uncaught_exception && |
1282 (report_exception || can_be_caught_externally)) { | 1241 (report_exception || can_be_caught_externally)) { |
1283 fatal_exception_depth++; | 1242 fatal_exception_depth++; |
1284 PrintF(stderr, "%s\n\nFROM\n", | 1243 PrintF(stderr, "%s\n\nFROM\n", |
1285 MessageHandler::GetLocalizedMessage(this, message_obj).get()); | 1244 MessageHandler::GetLocalizedMessage(this, message_obj).get()); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1368 } | 1327 } |
1369 if (can_clear_message) clear_pending_message(); | 1328 if (can_clear_message) clear_pending_message(); |
1370 } | 1329 } |
1371 | 1330 |
1372 | 1331 |
1373 MessageLocation Isolate::GetMessageLocation() { | 1332 MessageLocation Isolate::GetMessageLocation() { |
1374 DCHECK(has_pending_exception()); | 1333 DCHECK(has_pending_exception()); |
1375 | 1334 |
1376 if (thread_local_top_.pending_exception_ != heap()->termination_exception() && | 1335 if (thread_local_top_.pending_exception_ != heap()->termination_exception() && |
1377 thread_local_top_.has_pending_message_ && | 1336 thread_local_top_.has_pending_message_ && |
| 1337 !thread_local_top_.pending_message_obj_->IsTheHole() && |
1378 !thread_local_top_.pending_message_obj_->IsTheHole()) { | 1338 !thread_local_top_.pending_message_obj_->IsTheHole()) { |
1379 Handle<Script> script( | 1339 Handle<Script> script( |
1380 Script::cast(thread_local_top_.pending_message_script_)); | 1340 Script::cast(thread_local_top_.pending_message_script_)); |
1381 int start_pos = thread_local_top_.pending_message_start_pos_; | 1341 int start_pos = thread_local_top_.pending_message_start_pos_; |
1382 int end_pos = thread_local_top_.pending_message_end_pos_; | 1342 int end_pos = thread_local_top_.pending_message_end_pos_; |
1383 return MessageLocation(script, start_pos, end_pos); | 1343 return MessageLocation(script, start_pos, end_pos); |
1384 } | 1344 } |
1385 | 1345 |
1386 return MessageLocation(); | 1346 return MessageLocation(); |
1387 } | 1347 } |
(...skipping 1148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2536 if (prev_ && prev_->Intercept(flag)) return true; | 2496 if (prev_ && prev_->Intercept(flag)) return true; |
2537 // Then check whether this scope intercepts. | 2497 // Then check whether this scope intercepts. |
2538 if ((flag & intercept_mask_)) { | 2498 if ((flag & intercept_mask_)) { |
2539 intercepted_flags_ |= flag; | 2499 intercepted_flags_ |= flag; |
2540 return true; | 2500 return true; |
2541 } | 2501 } |
2542 return false; | 2502 return false; |
2543 } | 2503 } |
2544 | 2504 |
2545 } } // namespace v8::internal | 2505 } } // namespace v8::internal |
OLD | NEW |