| 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 | 
|---|