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