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 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 PrintF("%c", character); | 927 PrintF("%c", character); |
928 if (character == '\n' && i < len - 2) { | 928 if (character == '\n' && i < len - 2) { |
929 PrintF("%5d: ", ++line_number); | 929 PrintF("%5d: ", ++line_number); |
930 } | 930 } |
931 } | 931 } |
932 } | 932 } |
933 #endif | 933 #endif |
934 } | 934 } |
935 | 935 |
936 | 936 |
| 937 namespace { |
| 938 |
| 939 // Only use by Isolate::Throw for --abort-on-uncaught-exception. |
| 940 int fatal_exception_depth = 0; |
| 941 |
| 942 } // namespace |
| 943 |
| 944 |
937 Object* Isolate::Throw(Object* exception, MessageLocation* location) { | 945 Object* Isolate::Throw(Object* exception, MessageLocation* location) { |
938 DCHECK(!has_pending_exception()); | 946 DCHECK(!has_pending_exception()); |
939 | 947 |
940 HandleScope scope(this); | 948 HandleScope scope(this); |
941 Handle<Object> exception_handle(exception, this); | 949 Handle<Object> exception_handle(exception, this); |
942 | 950 |
943 // Determine whether a message needs to be created for the given exception | 951 // Determine reporting and whether the exception is caught externally. |
944 // depending on the following criteria: | 952 bool catchable_by_javascript = is_catchable_by_javascript(exception); |
945 // 1) External v8::TryCatch missing: Always create a message because any | 953 bool can_be_caught_externally = false; |
946 // JavaScript handler for a finally-block might re-throw to top-level. | 954 bool should_report_exception = |
947 // 2) External v8::TryCatch exists: Only create a message if the handler | 955 ShouldReportException(&can_be_caught_externally, catchable_by_javascript); |
948 // captures messages or is verbose (which reports despite the catch). | 956 bool report_exception = catchable_by_javascript && should_report_exception; |
949 // 3) ReThrow from v8::TryCatch: The message from a previous throw still | 957 bool try_catch_needs_message = |
950 // exists and we preserve it instead of creating a new message. | 958 can_be_caught_externally && try_catch_handler()->capture_message_; |
951 bool requires_message = try_catch_handler() == nullptr || | |
952 try_catch_handler()->is_verbose_ || | |
953 try_catch_handler()->capture_message_; | |
954 bool rethrowing_message = thread_local_top()->rethrowing_message_; | 959 bool rethrowing_message = thread_local_top()->rethrowing_message_; |
955 | 960 |
956 thread_local_top()->rethrowing_message_ = false; | 961 thread_local_top()->rethrowing_message_ = false; |
957 | 962 |
958 // Notify debugger of exception. | 963 // Notify debugger of exception. |
959 if (is_catchable_by_javascript(exception)) { | 964 if (catchable_by_javascript) { |
960 debug()->OnThrow(exception_handle); | 965 debug()->OnThrow(exception_handle, report_exception); |
961 } | 966 } |
962 | 967 |
963 // Generate the message if required. | 968 // Generate the message if required. |
964 if (requires_message && !rethrowing_message) { | 969 if (!rethrowing_message && (report_exception || try_catch_needs_message)) { |
965 MessageLocation potential_computed_location; | 970 MessageLocation potential_computed_location; |
966 if (location == NULL) { | 971 if (location == NULL) { |
967 // If no location was specified we use a computed one instead. | 972 // If no location was specified we use a computed one instead. |
968 ComputeLocation(&potential_computed_location); | 973 ComputeLocation(&potential_computed_location); |
969 location = &potential_computed_location; | 974 location = &potential_computed_location; |
970 } | 975 } |
971 | 976 |
972 if (bootstrapper()->IsActive()) { | 977 if (bootstrapper()->IsActive()) { |
973 // It's not safe to try to make message objects or collect stack traces | 978 // It's not safe to try to make message objects or collect stack traces |
974 // while the bootstrapper is active since the infrastructure may not have | 979 // while the bootstrapper is active since the infrastructure may not have |
975 // been properly initialized. | 980 // been properly initialized. |
976 ReportBootstrappingException(exception_handle, location); | 981 ReportBootstrappingException(exception_handle, location); |
977 } else { | 982 } else { |
978 Handle<Object> message_obj = CreateMessage(exception_handle, location); | 983 Handle<Object> message_obj = CreateMessage(exception_handle, location); |
| 984 |
979 thread_local_top()->pending_message_obj_ = *message_obj; | 985 thread_local_top()->pending_message_obj_ = *message_obj; |
980 | 986 |
981 // If the abort-on-uncaught-exception flag is specified, abort on any | 987 // If the abort-on-uncaught-exception flag is specified, abort on any |
982 // exception not caught by JavaScript, even when an external handler is | 988 // exception not caught by JavaScript, even when an external handler is |
983 // present. This flag is intended for use by JavaScript developers, so | 989 // present. This flag is intended for use by JavaScript developers, so |
984 // print a user-friendly stack trace (not an internal one). | 990 // print a user-friendly stack trace (not an internal one). |
985 if (FLAG_abort_on_uncaught_exception && | 991 if (fatal_exception_depth == 0 && FLAG_abort_on_uncaught_exception && |
986 !PredictWhetherExceptionIsCaught(*exception_handle)) { | 992 (report_exception || can_be_caught_externally)) { |
987 FLAG_abort_on_uncaught_exception = false; // Prevent endless recursion. | 993 fatal_exception_depth++; |
988 PrintF(stderr, "%s\n\nFROM\n", | 994 PrintF(stderr, "%s\n\nFROM\n", |
989 MessageHandler::GetLocalizedMessage(this, message_obj).get()); | 995 MessageHandler::GetLocalizedMessage(this, message_obj).get()); |
990 PrintCurrentStackTrace(stderr); | 996 PrintCurrentStackTrace(stderr); |
991 base::OS::Abort(); | 997 base::OS::Abort(); |
992 } | 998 } |
993 } | 999 } |
994 } | 1000 } |
995 | 1001 |
996 // Set the exception being thrown. | 1002 // Set the exception being thrown. |
997 set_pending_exception(*exception_handle); | 1003 set_pending_exception(*exception_handle); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 bool catchable_by_js = is_catchable_by_javascript(exception); | 1040 bool catchable_by_js = is_catchable_by_javascript(exception); |
1035 | 1041 |
1036 // Compute handler and stack unwinding information by performing a full walk | 1042 // Compute handler and stack unwinding information by performing a full walk |
1037 // over the stack and dispatching according to the frame type. | 1043 // over the stack and dispatching according to the frame type. |
1038 for (StackFrameIterator iter(this); !iter.done(); iter.Advance()) { | 1044 for (StackFrameIterator iter(this); !iter.done(); iter.Advance()) { |
1039 StackFrame* frame = iter.frame(); | 1045 StackFrame* frame = iter.frame(); |
1040 | 1046 |
1041 // For JSEntryStub frames we always have a handler. | 1047 // For JSEntryStub frames we always have a handler. |
1042 if (frame->is_entry() || frame->is_entry_construct()) { | 1048 if (frame->is_entry() || frame->is_entry_construct()) { |
1043 StackHandler* handler = frame->top_handler(); | 1049 StackHandler* handler = frame->top_handler(); |
| 1050 DCHECK_EQ(StackHandler::JS_ENTRY, handler->kind()); |
1044 DCHECK_EQ(0, handler->index()); | 1051 DCHECK_EQ(0, handler->index()); |
1045 | 1052 |
1046 // Restore the next handler. | 1053 // Restore the next handler. |
1047 thread_local_top()->handler_ = handler->next()->address(); | 1054 thread_local_top()->handler_ = handler->next()->address(); |
1048 | 1055 |
1049 // Gather information from the handler. | 1056 // Gather information from the handler. |
1050 code = frame->LookupCode(); | 1057 code = frame->LookupCode(); |
1051 handler_sp = handler->address() + StackHandlerConstants::kSize; | 1058 handler_sp = handler->address() + StackHandlerConstants::kSize; |
1052 offset = Smi::cast(code->handler_table()->get(0))->value(); | 1059 offset = Smi::cast(code->handler_table()->get(0))->value(); |
1053 break; | 1060 break; |
1054 } | 1061 } |
1055 | 1062 |
1056 // For JavaScript frames which have a handler, we use the handler. | 1063 // For JavaScript frames which have a handler, we use the handler. |
1057 if (frame->is_java_script() && catchable_by_js && frame->HasHandler()) { | 1064 if (frame->is_java_script() && catchable_by_js && frame->HasHandler()) { |
1058 StackHandler* handler = frame->top_handler(); | 1065 StackHandler* handler = frame->top_handler(); |
| 1066 DCHECK_NE(StackHandler::JS_ENTRY, handler->kind()); |
1059 | 1067 |
1060 // Restore the next handler. | 1068 // Restore the next handler. |
1061 thread_local_top()->handler_ = handler->next()->address(); | 1069 thread_local_top()->handler_ = handler->next()->address(); |
1062 | 1070 |
1063 // Gather information from the handler. | 1071 // Gather information from the handler. |
1064 code = frame->LookupCode(); | 1072 code = frame->LookupCode(); |
1065 context = handler->context(); | 1073 context = handler->context(); |
1066 offset = Smi::cast(code->handler_table()->get(handler->index()))->value(); | 1074 offset = Smi::cast(code->handler_table()->get(handler->index()))->value(); |
1067 handler_sp = handler->address() + StackHandlerConstants::kSize; | 1075 handler_sp = handler->address() + StackHandlerConstants::kSize; |
1068 handler_fp = frame->fp(); | 1076 handler_fp = frame->fp(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1101 thread_local_top()->pending_handler_offset_ = offset; | 1109 thread_local_top()->pending_handler_offset_ = offset; |
1102 thread_local_top()->pending_handler_fp_ = handler_fp; | 1110 thread_local_top()->pending_handler_fp_ = handler_fp; |
1103 thread_local_top()->pending_handler_sp_ = handler_sp; | 1111 thread_local_top()->pending_handler_sp_ = handler_sp; |
1104 | 1112 |
1105 // Return and clear pending exception. | 1113 // Return and clear pending exception. |
1106 clear_pending_exception(); | 1114 clear_pending_exception(); |
1107 return exception; | 1115 return exception; |
1108 } | 1116 } |
1109 | 1117 |
1110 | 1118 |
1111 // TODO(mstarzinger): We shouldn't need the exception object here. | |
1112 bool Isolate::PredictWhetherExceptionIsCaught(Object* exception) { | |
1113 if (IsExternalHandlerOnTop(exception)) return true; | |
1114 | |
1115 // Search for a JavaScript handler by performing a full walk over the stack | |
1116 // and dispatching according to the frame type. | |
1117 for (StackFrameIterator iter(this); !iter.done(); iter.Advance()) { | |
1118 StackFrame* frame = iter.frame(); | |
1119 | |
1120 // For JavaScript frames which have a handler, we use the handler. | |
1121 if (frame->is_java_script() && frame->HasHandler()) { | |
1122 return true; | |
1123 } | |
1124 | |
1125 // For optimized frames we perform a lookup in the handler table. | |
1126 if (frame->is_optimized()) { | |
1127 Code* frame_code = frame->LookupCode(); | |
1128 DCHECK(frame_code->is_optimized_code()); | |
1129 int pc_offset = static_cast<int>(frame->pc() - frame_code->entry()); | |
1130 int handler_offset = LookupInHandlerTable(frame_code, pc_offset); | |
1131 if (handler_offset < 0) continue; | |
1132 return true; | |
1133 } | |
1134 } | |
1135 | |
1136 // Handler not found. | |
1137 return false; | |
1138 } | |
1139 | |
1140 | |
1141 Object* Isolate::ThrowIllegalOperation() { | 1119 Object* Isolate::ThrowIllegalOperation() { |
1142 if (FLAG_stack_trace_on_illegal) PrintStack(stdout); | 1120 if (FLAG_stack_trace_on_illegal) PrintStack(stdout); |
1143 return Throw(heap()->illegal_access_string()); | 1121 return Throw(heap_.illegal_access_string()); |
1144 } | 1122 } |
1145 | 1123 |
1146 | 1124 |
1147 void Isolate::ScheduleThrow(Object* exception) { | 1125 void Isolate::ScheduleThrow(Object* exception) { |
1148 // When scheduling a throw we first throw the exception to get the | 1126 // When scheduling a throw we first throw the exception to get the |
1149 // error reporting if it is uncaught before rescheduling it. | 1127 // error reporting if it is uncaught before rescheduling it. |
1150 Throw(exception); | 1128 Throw(exception); |
1151 PropagatePendingExceptionToExternalTryCatch(); | 1129 PropagatePendingExceptionToExternalTryCatch(); |
1152 if (has_pending_exception()) { | 1130 if (has_pending_exception()) { |
1153 thread_local_top()->scheduled_exception_ = pending_exception(); | 1131 thread_local_top()->scheduled_exception_ = pending_exception(); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 int pos = code->SourcePosition(pc); | 1262 int pos = code->SourcePosition(pc); |
1285 Handle<Script> casted_script(Script::cast(script)); | 1263 Handle<Script> casted_script(Script::cast(script)); |
1286 *target = MessageLocation(casted_script, pos, pos + 1); | 1264 *target = MessageLocation(casted_script, pos, pos + 1); |
1287 return true; | 1265 return true; |
1288 } | 1266 } |
1289 } | 1267 } |
1290 return false; | 1268 return false; |
1291 } | 1269 } |
1292 | 1270 |
1293 | 1271 |
| 1272 bool Isolate::ShouldReportException(bool* can_be_caught_externally, |
| 1273 bool catchable_by_javascript) { |
| 1274 // Find the top-most try-catch handler. |
| 1275 StackHandler* handler = |
| 1276 StackHandler::FromAddress(Isolate::handler(thread_local_top())); |
| 1277 while (handler != NULL && !handler->is_catch()) { |
| 1278 handler = handler->next(); |
| 1279 } |
| 1280 |
| 1281 // Get the address of the external handler so we can compare the address to |
| 1282 // determine which one is closer to the top of the stack. |
| 1283 Address external_handler_address = |
| 1284 thread_local_top()->try_catch_handler_address(); |
| 1285 |
| 1286 // The exception has been externally caught if and only if there is |
| 1287 // an external handler which is on top of the top-most try-catch |
| 1288 // handler. |
| 1289 *can_be_caught_externally = external_handler_address != NULL && |
| 1290 (handler == NULL || handler->address() > external_handler_address || |
| 1291 !catchable_by_javascript); |
| 1292 |
| 1293 if (*can_be_caught_externally) { |
| 1294 // Only report the exception if the external handler is verbose. |
| 1295 return try_catch_handler()->is_verbose_; |
| 1296 } else { |
| 1297 // Report the exception if it isn't caught by JavaScript code. |
| 1298 return handler == NULL; |
| 1299 } |
| 1300 } |
| 1301 |
| 1302 |
1294 // Traverse prototype chain to find out whether the object is derived from | 1303 // Traverse prototype chain to find out whether the object is derived from |
1295 // the Error object. | 1304 // the Error object. |
1296 bool Isolate::IsErrorObject(Handle<Object> obj) { | 1305 bool Isolate::IsErrorObject(Handle<Object> obj) { |
1297 if (!obj->IsJSObject()) return false; | 1306 if (!obj->IsJSObject()) return false; |
1298 | 1307 |
1299 Handle<String> error_key = | 1308 Handle<String> error_key = |
1300 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("$Error")); | 1309 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("$Error")); |
1301 Handle<Object> error_constructor = Object::GetProperty( | 1310 Handle<Object> error_constructor = Object::GetProperty( |
1302 js_builtins_object(), error_key).ToHandleChecked(); | 1311 js_builtins_object(), error_key).ToHandleChecked(); |
1303 | 1312 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1355 exception = | 1364 exception = |
1356 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("exception")); | 1365 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("exception")); |
1357 } | 1366 } |
1358 } | 1367 } |
1359 return MessageHandler::MakeMessageObject(this, "uncaught_exception", location, | 1368 return MessageHandler::MakeMessageObject(this, "uncaught_exception", location, |
1360 HandleVector<Object>(&exception, 1), | 1369 HandleVector<Object>(&exception, 1), |
1361 stack_trace_object); | 1370 stack_trace_object); |
1362 } | 1371 } |
1363 | 1372 |
1364 | 1373 |
1365 bool Isolate::IsJavaScriptHandlerOnTop(Object* exception) { | 1374 bool Isolate::IsFinallyOnTop() { |
1366 DCHECK_NE(heap()->the_hole_value(), exception); | |
1367 | |
1368 // For uncatchable exceptions, the JavaScript handler cannot be on top. | |
1369 if (!is_catchable_by_javascript(exception)) return false; | |
1370 | |
1371 // Get the top-most JS_ENTRY handler, cannot be on top if it doesn't exist. | |
1372 Address entry_handler = Isolate::handler(thread_local_top()); | |
1373 if (entry_handler == nullptr) return false; | |
1374 | |
1375 // Get the address of the external handler so we can compare the address to | 1375 // Get the address of the external handler so we can compare the address to |
1376 // determine which one is closer to the top of the stack. | 1376 // determine which one is closer to the top of the stack. |
1377 Address external_handler = thread_local_top()->try_catch_handler_address(); | 1377 Address external_handler_address = |
1378 if (external_handler == nullptr) return true; | 1378 thread_local_top()->try_catch_handler_address(); |
| 1379 DCHECK(external_handler_address != NULL); |
1379 | 1380 |
1380 // The exception has been externally caught if and only if there is an | 1381 // The exception has been externally caught if and only if there is |
1381 // external handler which is on top of the top-most JS_ENTRY handler. | 1382 // an external handler which is on top of the top-most try-finally |
| 1383 // handler. |
| 1384 // There should be no try-catch blocks as they would prohibit us from |
| 1385 // finding external catcher in the first place (see catcher_ check above). |
1382 // | 1386 // |
1383 // Note, that finally clauses would re-throw an exception unless it's aborted | 1387 // Note, that finally clause would rethrow an exception unless it's |
1384 // by jumps in control flow (like return, break, etc.) and we'll have another | 1388 // aborted by jumps in control flow like return, break, etc. and we'll |
1385 // chance to set proper v8::TryCatch later. | 1389 // have another chances to set proper v8::TryCatch. |
1386 return (entry_handler < external_handler); | 1390 StackHandler* handler = |
| 1391 StackHandler::FromAddress(Isolate::handler(thread_local_top())); |
| 1392 while (handler != NULL && handler->address() < external_handler_address) { |
| 1393 DCHECK(!handler->is_catch()); |
| 1394 if (handler->is_finally()) return true; |
| 1395 |
| 1396 handler = handler->next(); |
| 1397 } |
| 1398 |
| 1399 return false; |
1387 } | 1400 } |
1388 | 1401 |
1389 | 1402 |
1390 bool Isolate::IsExternalHandlerOnTop(Object* exception) { | |
1391 DCHECK_NE(heap()->the_hole_value(), exception); | |
1392 | |
1393 // Get the address of the external handler so we can compare the address to | |
1394 // determine which one is closer to the top of the stack. | |
1395 Address external_handler = thread_local_top()->try_catch_handler_address(); | |
1396 if (external_handler == nullptr) return false; | |
1397 | |
1398 // For uncatchable exceptions, the external handler is always on top. | |
1399 if (!is_catchable_by_javascript(exception)) return true; | |
1400 | |
1401 // Get the top-most JS_ENTRY handler, cannot be on top if it doesn't exist. | |
1402 Address entry_handler = Isolate::handler(thread_local_top()); | |
1403 if (entry_handler == nullptr) return true; | |
1404 | |
1405 // The exception has been externally caught if and only if there is an | |
1406 // external handler which is on top of the top-most JS_ENTRY handler. | |
1407 // | |
1408 // Note, that finally clauses would re-throw an exception unless it's aborted | |
1409 // by jumps in control flow (like return, break, etc.) and we'll have another | |
1410 // chance to set proper v8::TryCatch later. | |
1411 return (entry_handler > external_handler); | |
1412 } | |
1413 | |
1414 | |
1415 void Isolate::ReportPendingMessages() { | 1403 void Isolate::ReportPendingMessages() { |
1416 Object* exception = pending_exception(); | 1404 Object* exception = pending_exception(); |
1417 | 1405 |
1418 // Try to propagate the exception to an external v8::TryCatch handler. If | 1406 // Try to propagate the exception to an external v8::TryCatch handler. If |
1419 // propagation was unsuccessful, then we will get another chance at reporting | 1407 // propagation was unsuccessful, then we will get another chance at reporting |
1420 // the pending message if the exception is re-thrown. | 1408 // the pending message if the exception is re-thrown. |
1421 bool has_been_propagated = PropagatePendingExceptionToExternalTryCatch(); | 1409 bool has_been_propagated = PropagatePendingExceptionToExternalTryCatch(); |
1422 if (!has_been_propagated) return; | 1410 if (!has_been_propagated) return; |
1423 | 1411 |
1424 // Clear the pending message object early to avoid endless recursion. | 1412 // Clear the pending message object early to avoid endless recursion. |
1425 Object* message_obj = thread_local_top_.pending_message_obj_; | 1413 Object* message_obj = thread_local_top_.pending_message_obj_; |
1426 clear_pending_message(); | 1414 clear_pending_message(); |
1427 | 1415 |
1428 // For uncatchable exceptions we do nothing. If needed, the exception and the | 1416 bool can_be_caught_externally = false; |
1429 // message have already been propagated to v8::TryCatch. | 1417 bool catchable_by_javascript = is_catchable_by_javascript(exception); |
1430 if (!is_catchable_by_javascript(exception)) return; | 1418 bool should_report_exception = |
| 1419 ShouldReportException(&can_be_caught_externally, catchable_by_javascript); |
1431 | 1420 |
1432 // Determine whether the message needs to be reported to all message handlers | 1421 if (!catchable_by_javascript) { |
1433 // depending on whether and external v8::TryCatch or an internal JavaScript | 1422 // Do nothing: if needed, the exception has been already propagated to |
1434 // handler is on top. | 1423 // v8::TryCatch. |
1435 bool should_report_exception; | |
1436 if (IsExternalHandlerOnTop(exception)) { | |
1437 // Only report the exception if the external handler is verbose. | |
1438 should_report_exception = try_catch_handler()->is_verbose_; | |
1439 } else { | 1424 } else { |
1440 // Report the exception if it isn't caught by JavaScript code. | 1425 if (!message_obj->IsTheHole() && should_report_exception) { |
1441 should_report_exception = !IsJavaScriptHandlerOnTop(exception); | 1426 HandleScope scope(this); |
1442 } | 1427 Handle<JSMessageObject> message(JSMessageObject::cast(message_obj)); |
1443 | 1428 Handle<JSValue> script_wrapper(JSValue::cast(message->script())); |
1444 // Actually report the pending message to all message handlers. | 1429 Handle<Script> script(Script::cast(script_wrapper->value())); |
1445 if (!message_obj->IsTheHole() && should_report_exception) { | 1430 int start_pos = message->start_position(); |
1446 HandleScope scope(this); | 1431 int end_pos = message->end_position(); |
1447 Handle<JSMessageObject> message(JSMessageObject::cast(message_obj)); | 1432 MessageLocation location(script, start_pos, end_pos); |
1448 Handle<JSValue> script_wrapper(JSValue::cast(message->script())); | 1433 MessageHandler::ReportMessage(this, &location, message); |
1449 Handle<Script> script(Script::cast(script_wrapper->value())); | 1434 } |
1450 int start_pos = message->start_position(); | |
1451 int end_pos = message->end_position(); | |
1452 MessageLocation location(script, start_pos, end_pos); | |
1453 MessageHandler::ReportMessage(this, &location, message); | |
1454 } | 1435 } |
1455 } | 1436 } |
1456 | 1437 |
1457 | 1438 |
1458 MessageLocation Isolate::GetMessageLocation() { | 1439 MessageLocation Isolate::GetMessageLocation() { |
1459 DCHECK(has_pending_exception()); | 1440 DCHECK(has_pending_exception()); |
1460 | 1441 |
1461 if (thread_local_top_.pending_exception_ != heap()->termination_exception() && | 1442 if (thread_local_top_.pending_exception_ != heap()->termination_exception() && |
1462 !thread_local_top_.pending_message_obj_->IsTheHole()) { | 1443 !thread_local_top_.pending_message_obj_->IsTheHole()) { |
1463 Handle<JSMessageObject> message_obj( | 1444 Handle<JSMessageObject> message_obj( |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1951 | 1932 |
1952 void Isolate::InitializeThreadLocal() { | 1933 void Isolate::InitializeThreadLocal() { |
1953 thread_local_top_.isolate_ = this; | 1934 thread_local_top_.isolate_ = this; |
1954 thread_local_top_.Initialize(); | 1935 thread_local_top_.Initialize(); |
1955 } | 1936 } |
1956 | 1937 |
1957 | 1938 |
1958 bool Isolate::PropagatePendingExceptionToExternalTryCatch() { | 1939 bool Isolate::PropagatePendingExceptionToExternalTryCatch() { |
1959 Object* exception = pending_exception(); | 1940 Object* exception = pending_exception(); |
1960 | 1941 |
1961 if (IsJavaScriptHandlerOnTop(exception)) { | 1942 bool can_be_caught_externally = false; |
| 1943 bool catchable_by_javascript = is_catchable_by_javascript(exception); |
| 1944 ShouldReportException(&can_be_caught_externally, catchable_by_javascript); |
| 1945 if (!can_be_caught_externally) { |
| 1946 thread_local_top_.external_caught_exception_ = false; |
| 1947 return true; |
| 1948 } |
| 1949 |
| 1950 if (catchable_by_javascript && IsFinallyOnTop()) { |
1962 thread_local_top_.external_caught_exception_ = false; | 1951 thread_local_top_.external_caught_exception_ = false; |
1963 return false; | 1952 return false; |
1964 } | 1953 } |
1965 | 1954 |
1966 if (!IsExternalHandlerOnTop(exception)) { | |
1967 thread_local_top_.external_caught_exception_ = false; | |
1968 return true; | |
1969 } | |
1970 | |
1971 thread_local_top_.external_caught_exception_ = true; | 1955 thread_local_top_.external_caught_exception_ = true; |
1972 if (!is_catchable_by_javascript(exception)) { | 1956 if (!catchable_by_javascript) { |
1973 try_catch_handler()->can_continue_ = false; | 1957 try_catch_handler()->can_continue_ = false; |
1974 try_catch_handler()->has_terminated_ = true; | 1958 try_catch_handler()->has_terminated_ = true; |
1975 try_catch_handler()->exception_ = heap()->null_value(); | 1959 try_catch_handler()->exception_ = heap()->null_value(); |
1976 } else { | 1960 } else { |
1977 v8::TryCatch* handler = try_catch_handler(); | 1961 v8::TryCatch* handler = try_catch_handler(); |
1978 DCHECK(thread_local_top_.pending_message_obj_->IsJSMessageObject() || | 1962 DCHECK(thread_local_top_.pending_message_obj_->IsJSMessageObject() || |
1979 thread_local_top_.pending_message_obj_->IsTheHole()); | 1963 thread_local_top_.pending_message_obj_->IsTheHole()); |
1980 handler->can_continue_ = true; | 1964 handler->can_continue_ = true; |
1981 handler->has_terminated_ = false; | 1965 handler->has_terminated_ = false; |
1982 handler->exception_ = pending_exception(); | 1966 handler->exception_ = pending_exception(); |
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2636 if (prev_ && prev_->Intercept(flag)) return true; | 2620 if (prev_ && prev_->Intercept(flag)) return true; |
2637 // Then check whether this scope intercepts. | 2621 // Then check whether this scope intercepts. |
2638 if ((flag & intercept_mask_)) { | 2622 if ((flag & intercept_mask_)) { |
2639 intercepted_flags_ |= flag; | 2623 intercepted_flags_ |= flag; |
2640 return true; | 2624 return true; |
2641 } | 2625 } |
2642 return false; | 2626 return false; |
2643 } | 2627 } |
2644 | 2628 |
2645 } } // namespace v8::internal | 2629 } } // namespace v8::internal |
OLD | NEW |