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 1125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1136 Object* Isolate::ThrowIllegalOperation() { | 1136 Object* Isolate::ThrowIllegalOperation() { |
1137 if (FLAG_stack_trace_on_illegal) PrintStack(stdout); | 1137 if (FLAG_stack_trace_on_illegal) PrintStack(stdout); |
1138 return Throw(heap()->illegal_access_string()); | 1138 return Throw(heap()->illegal_access_string()); |
1139 } | 1139 } |
1140 | 1140 |
1141 | 1141 |
1142 void Isolate::ScheduleThrow(Object* exception) { | 1142 void Isolate::ScheduleThrow(Object* exception) { |
1143 // 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 |
1144 // error reporting if it is uncaught before rescheduling it. | 1144 // error reporting if it is uncaught before rescheduling it. |
1145 Throw(exception); | 1145 Throw(exception); |
1146 ReportPendingMessages(); | 1146 PropagatePendingExceptionToExternalTryCatch(); |
1147 if (has_pending_exception()) { | 1147 if (has_pending_exception()) { |
1148 thread_local_top()->scheduled_exception_ = pending_exception(); | 1148 thread_local_top()->scheduled_exception_ = pending_exception(); |
1149 thread_local_top()->external_caught_exception_ = false; | 1149 thread_local_top()->external_caught_exception_ = false; |
1150 clear_pending_exception(); | 1150 clear_pending_exception(); |
1151 } | 1151 } |
1152 } | 1152 } |
1153 | 1153 |
1154 | 1154 |
1155 void Isolate::RestorePendingMessageFromTryCatch(v8::TryCatch* handler) { | 1155 void Isolate::RestorePendingMessageFromTryCatch(v8::TryCatch* handler) { |
1156 DCHECK(handler == try_catch_handler()); | 1156 DCHECK(handler == try_catch_handler()); |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1403 // Note, that finally clauses would re-throw an exception unless it's aborted | 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 | 1404 // by jumps in control flow (like return, break, etc.) and we'll have another |
1405 // chance to set proper v8::TryCatch later. | 1405 // chance to set proper v8::TryCatch later. |
1406 return (entry_handler > external_handler); | 1406 return (entry_handler > external_handler); |
1407 } | 1407 } |
1408 | 1408 |
1409 | 1409 |
1410 void Isolate::ReportPendingMessages() { | 1410 void Isolate::ReportPendingMessages() { |
1411 Object* exception = pending_exception(); | 1411 Object* exception = pending_exception(); |
1412 | 1412 |
1413 // Propagation is unsuccessful because there still is a JavaScript handler on | 1413 // Try to propagate the exception to an external v8::TryCatch handler. If |
1414 // top that might catch the exception and hence prevent message reporting. | 1414 // propagation was unsuccessful, then we will get another chance at reporting |
1415 if (IsJavaScriptHandlerOnTop(exception)) { | 1415 // the pending message if the exception is re-thrown. |
1416 thread_local_top_.external_caught_exception_ = false; | 1416 bool has_been_propagated = PropagatePendingExceptionToExternalTryCatch(); |
1417 return; | 1417 if (!has_been_propagated) return; |
1418 } | |
1419 | |
1420 // Determine whether the message needs to be reported to all message handlers | |
1421 // depending on whether an external v8::TryCatch handler is on top. | |
1422 bool should_report_exception; | |
1423 Object* message_obj = thread_local_top_.pending_message_obj_; | |
1424 DCHECK(message_obj->IsJSMessageObject() || message_obj->IsTheHole()); | |
1425 if (IsExternalHandlerOnTop(exception)) { | |
1426 // Propagate the exception to an external v8::TryCatch handler. | |
1427 if (!is_catchable_by_javascript(exception)) { | |
1428 try_catch_handler()->can_continue_ = false; | |
1429 try_catch_handler()->has_terminated_ = true; | |
1430 try_catch_handler()->exception_ = heap()->null_value(); | |
1431 } else { | |
1432 try_catch_handler()->can_continue_ = true; | |
1433 try_catch_handler()->has_terminated_ = false; | |
1434 try_catch_handler()->exception_ = exception; | |
1435 // Propagate to the external try-catch only if we got an actual message. | |
1436 if (!message_obj->IsTheHole()) { | |
1437 try_catch_handler()->message_obj_ = message_obj; | |
1438 } | |
1439 } | |
1440 | |
1441 // Only report the exception if the external handler is verbose. | |
1442 thread_local_top_.external_caught_exception_ = true; | |
1443 should_report_exception = try_catch_handler()->is_verbose_; | |
1444 } else { | |
1445 // Report the exception because it cannot be caught by JavaScript code. | |
1446 thread_local_top_.external_caught_exception_ = false; | |
1447 should_report_exception = true; | |
1448 } | |
1449 | 1418 |
1450 // Clear the pending message object early to avoid endless recursion. | 1419 // Clear the pending message object early to avoid endless recursion. |
| 1420 Object* message_obj = thread_local_top_.pending_message_obj_; |
1451 clear_pending_message(); | 1421 clear_pending_message(); |
1452 | 1422 |
1453 // For uncatchable exceptions we do nothing. If needed, the exception and the | 1423 // For uncatchable exceptions we do nothing. If needed, the exception and the |
1454 // message have already been propagated to v8::TryCatch. | 1424 // message have already been propagated to v8::TryCatch. |
1455 if (!is_catchable_by_javascript(exception)) return; | 1425 if (!is_catchable_by_javascript(exception)) return; |
1456 | 1426 |
| 1427 // Determine whether the message needs to be reported to all message handlers |
| 1428 // depending on whether and external v8::TryCatch or an internal JavaScript |
| 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_; |
| 1434 } else { |
| 1435 // Report the exception if it isn't caught by JavaScript code. |
| 1436 should_report_exception = !IsJavaScriptHandlerOnTop(exception); |
| 1437 } |
| 1438 |
1457 // Actually report the pending message to all message handlers. | 1439 // Actually report the pending message to all message handlers. |
1458 if (!message_obj->IsTheHole() && should_report_exception) { | 1440 if (!message_obj->IsTheHole() && should_report_exception) { |
1459 HandleScope scope(this); | 1441 HandleScope scope(this); |
1460 Handle<JSMessageObject> message(JSMessageObject::cast(message_obj)); | 1442 Handle<JSMessageObject> message(JSMessageObject::cast(message_obj)); |
1461 Handle<JSValue> script_wrapper(JSValue::cast(message->script())); | 1443 Handle<JSValue> script_wrapper(JSValue::cast(message->script())); |
1462 Handle<Script> script(Script::cast(script_wrapper->value())); | 1444 Handle<Script> script(Script::cast(script_wrapper->value())); |
1463 int start_pos = message->start_position(); | 1445 int start_pos = message->start_position(); |
1464 int end_pos = message->end_position(); | 1446 int end_pos = message->end_position(); |
1465 MessageLocation location(script, start_pos, end_pos); | 1447 MessageLocation location(script, start_pos, end_pos); |
1466 MessageHandler::ReportMessage(this, &location, message); | 1448 MessageHandler::ReportMessage(this, &location, message); |
(...skipping 14 matching lines...) Expand all Loading... |
1481 int end_pos = message_obj->end_position(); | 1463 int end_pos = message_obj->end_position(); |
1482 return MessageLocation(script, start_pos, end_pos); | 1464 return MessageLocation(script, start_pos, end_pos); |
1483 } | 1465 } |
1484 | 1466 |
1485 return MessageLocation(); | 1467 return MessageLocation(); |
1486 } | 1468 } |
1487 | 1469 |
1488 | 1470 |
1489 bool Isolate::OptionalRescheduleException(bool is_bottom_call) { | 1471 bool Isolate::OptionalRescheduleException(bool is_bottom_call) { |
1490 DCHECK(has_pending_exception()); | 1472 DCHECK(has_pending_exception()); |
1491 ReportPendingMessages(); | 1473 PropagatePendingExceptionToExternalTryCatch(); |
1492 | 1474 |
1493 bool is_termination_exception = | 1475 bool is_termination_exception = |
1494 pending_exception() == heap_.termination_exception(); | 1476 pending_exception() == heap_.termination_exception(); |
1495 | 1477 |
1496 // Do not reschedule the exception if this is the bottom call. | 1478 // Do not reschedule the exception if this is the bottom call. |
1497 bool clear_exception = is_bottom_call; | 1479 bool clear_exception = is_bottom_call; |
1498 | 1480 |
1499 if (is_termination_exception) { | 1481 if (is_termination_exception) { |
1500 if (is_bottom_call) { | 1482 if (is_bottom_call) { |
1501 thread_local_top()->external_caught_exception_ = false; | 1483 thread_local_top()->external_caught_exception_ = false; |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1961 debug_ = NULL; | 1943 debug_ = NULL; |
1962 } | 1944 } |
1963 | 1945 |
1964 | 1946 |
1965 void Isolate::InitializeThreadLocal() { | 1947 void Isolate::InitializeThreadLocal() { |
1966 thread_local_top_.isolate_ = this; | 1948 thread_local_top_.isolate_ = this; |
1967 thread_local_top_.Initialize(); | 1949 thread_local_top_.Initialize(); |
1968 } | 1950 } |
1969 | 1951 |
1970 | 1952 |
| 1953 bool Isolate::PropagatePendingExceptionToExternalTryCatch() { |
| 1954 Object* exception = pending_exception(); |
| 1955 |
| 1956 if (IsJavaScriptHandlerOnTop(exception)) { |
| 1957 thread_local_top_.external_caught_exception_ = false; |
| 1958 return false; |
| 1959 } |
| 1960 |
| 1961 if (!IsExternalHandlerOnTop(exception)) { |
| 1962 thread_local_top_.external_caught_exception_ = false; |
| 1963 return true; |
| 1964 } |
| 1965 |
| 1966 thread_local_top_.external_caught_exception_ = true; |
| 1967 if (!is_catchable_by_javascript(exception)) { |
| 1968 try_catch_handler()->can_continue_ = false; |
| 1969 try_catch_handler()->has_terminated_ = true; |
| 1970 try_catch_handler()->exception_ = heap()->null_value(); |
| 1971 } else { |
| 1972 v8::TryCatch* handler = try_catch_handler(); |
| 1973 DCHECK(thread_local_top_.pending_message_obj_->IsJSMessageObject() || |
| 1974 thread_local_top_.pending_message_obj_->IsTheHole()); |
| 1975 handler->can_continue_ = true; |
| 1976 handler->has_terminated_ = false; |
| 1977 handler->exception_ = pending_exception(); |
| 1978 // Propagate to the external try-catch only if we got an actual message. |
| 1979 if (thread_local_top_.pending_message_obj_->IsTheHole()) return true; |
| 1980 |
| 1981 handler->message_obj_ = thread_local_top_.pending_message_obj_; |
| 1982 } |
| 1983 return true; |
| 1984 } |
| 1985 |
| 1986 |
1971 void Isolate::InitializeLoggingAndCounters() { | 1987 void Isolate::InitializeLoggingAndCounters() { |
1972 if (logger_ == NULL) { | 1988 if (logger_ == NULL) { |
1973 logger_ = new Logger(this); | 1989 logger_ = new Logger(this); |
1974 } | 1990 } |
1975 if (counters_ == NULL) { | 1991 if (counters_ == NULL) { |
1976 counters_ = new Counters(this); | 1992 counters_ = new Counters(this); |
1977 } | 1993 } |
1978 } | 1994 } |
1979 | 1995 |
1980 | 1996 |
(...skipping 634 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 |