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