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 "v8.h" | 7 #include "v8.h" |
8 | 8 |
9 #include "ast.h" | 9 #include "ast.h" |
10 #include "bootstrapper.h" | 10 #include "bootstrapper.h" |
(...skipping 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1137 | 1137 |
1138 // Do not forget to clean catcher_ if currently thrown exception cannot | 1138 // Do not forget to clean catcher_ if currently thrown exception cannot |
1139 // be caught. If necessary, ReThrow will update the catcher. | 1139 // be caught. If necessary, ReThrow will update the catcher. |
1140 thread_local_top()->catcher_ = can_be_caught_externally ? | 1140 thread_local_top()->catcher_ = can_be_caught_externally ? |
1141 try_catch_handler() : NULL; | 1141 try_catch_handler() : NULL; |
1142 | 1142 |
1143 set_pending_exception(*exception_handle); | 1143 set_pending_exception(*exception_handle); |
1144 } | 1144 } |
1145 | 1145 |
1146 | 1146 |
1147 bool Isolate::IsExternallyCaught() { | 1147 bool Isolate::HasExternalTryCatch() { |
1148 ASSERT(has_pending_exception()); | 1148 ASSERT(has_pending_exception()); |
1149 | 1149 |
1150 if ((thread_local_top()->catcher_ == NULL) || | 1150 return (thread_local_top()->catcher_ != NULL) && |
1151 (try_catch_handler() != thread_local_top()->catcher_)) { | 1151 (try_catch_handler() == thread_local_top()->catcher_); |
1152 // When throwing the exception, we found no v8::TryCatch | 1152 } |
1153 // which should care about this exception. | |
1154 return false; | |
1155 } | |
1156 | 1153 |
1157 if (!is_catchable_by_javascript(pending_exception())) { | |
1158 return true; | |
1159 } | |
1160 | 1154 |
| 1155 bool Isolate::IsFinallyOnTop() { |
1161 // Get the address of the external handler so we can compare the address to | 1156 // Get the address of the external handler so we can compare the address to |
1162 // determine which one is closer to the top of the stack. | 1157 // determine which one is closer to the top of the stack. |
1163 Address external_handler_address = | 1158 Address external_handler_address = |
1164 thread_local_top()->try_catch_handler_address(); | 1159 thread_local_top()->try_catch_handler_address(); |
1165 ASSERT(external_handler_address != NULL); | 1160 ASSERT(external_handler_address != NULL); |
1166 | 1161 |
1167 // The exception has been externally caught if and only if there is | 1162 // The exception has been externally caught if and only if there is |
1168 // an external handler which is on top of the top-most try-finally | 1163 // an external handler which is on top of the top-most try-finally |
1169 // handler. | 1164 // handler. |
1170 // There should be no try-catch blocks as they would prohibit us from | 1165 // There should be no try-catch blocks as they would prohibit us from |
1171 // finding external catcher in the first place (see catcher_ check above). | 1166 // finding external catcher in the first place (see catcher_ check above). |
1172 // | 1167 // |
1173 // Note, that finally clause would rethrow an exception unless it's | 1168 // Note, that finally clause would rethrow an exception unless it's |
1174 // aborted by jumps in control flow like return, break, etc. and we'll | 1169 // aborted by jumps in control flow like return, break, etc. and we'll |
1175 // have another chances to set proper v8::TryCatch. | 1170 // have another chances to set proper v8::TryCatch. |
1176 StackHandler* handler = | 1171 StackHandler* handler = |
1177 StackHandler::FromAddress(Isolate::handler(thread_local_top())); | 1172 StackHandler::FromAddress(Isolate::handler(thread_local_top())); |
1178 while (handler != NULL && handler->address() < external_handler_address) { | 1173 while (handler != NULL && handler->address() < external_handler_address) { |
1179 ASSERT(!handler->is_catch()); | 1174 ASSERT(!handler->is_catch()); |
1180 if (handler->is_finally()) return false; | 1175 if (handler->is_finally()) return true; |
1181 | 1176 |
1182 handler = handler->next(); | 1177 handler = handler->next(); |
1183 } | 1178 } |
1184 | 1179 |
1185 return true; | 1180 return false; |
1186 } | 1181 } |
1187 | 1182 |
1188 | 1183 |
1189 void Isolate::ReportPendingMessages() { | 1184 void Isolate::ReportPendingMessages() { |
1190 ASSERT(has_pending_exception()); | 1185 ASSERT(has_pending_exception()); |
1191 PropagatePendingExceptionToExternalTryCatch(); | 1186 bool can_clear_message = PropagatePendingExceptionToExternalTryCatch(); |
1192 | 1187 |
1193 HandleScope scope(this); | 1188 HandleScope scope(this); |
1194 if (thread_local_top_.pending_exception_ == | 1189 if (thread_local_top_.pending_exception_ == |
1195 heap()->termination_exception()) { | 1190 heap()->termination_exception()) { |
1196 // Do nothing: if needed, the exception has been already propagated to | 1191 // Do nothing: if needed, the exception has been already propagated to |
1197 // v8::TryCatch. | 1192 // v8::TryCatch. |
1198 } else { | 1193 } else { |
1199 if (thread_local_top_.has_pending_message_) { | 1194 if (thread_local_top_.has_pending_message_) { |
1200 thread_local_top_.has_pending_message_ = false; | 1195 thread_local_top_.has_pending_message_ = false; |
1201 if (!thread_local_top_.pending_message_obj_->IsTheHole()) { | 1196 if (!thread_local_top_.pending_message_obj_->IsTheHole()) { |
1202 HandleScope scope(this); | 1197 HandleScope scope(this); |
1203 Handle<Object> message_obj(thread_local_top_.pending_message_obj_, | 1198 Handle<Object> message_obj(thread_local_top_.pending_message_obj_, |
1204 this); | 1199 this); |
1205 if (!thread_local_top_.pending_message_script_->IsTheHole()) { | 1200 if (!thread_local_top_.pending_message_script_->IsTheHole()) { |
1206 Handle<Script> script( | 1201 Handle<Script> script( |
1207 Script::cast(thread_local_top_.pending_message_script_)); | 1202 Script::cast(thread_local_top_.pending_message_script_)); |
1208 int start_pos = thread_local_top_.pending_message_start_pos_; | 1203 int start_pos = thread_local_top_.pending_message_start_pos_; |
1209 int end_pos = thread_local_top_.pending_message_end_pos_; | 1204 int end_pos = thread_local_top_.pending_message_end_pos_; |
1210 MessageLocation location(script, start_pos, end_pos); | 1205 MessageLocation location(script, start_pos, end_pos); |
1211 MessageHandler::ReportMessage(this, &location, message_obj); | 1206 MessageHandler::ReportMessage(this, &location, message_obj); |
1212 } else { | 1207 } else { |
1213 MessageHandler::ReportMessage(this, NULL, message_obj); | 1208 MessageHandler::ReportMessage(this, NULL, message_obj); |
1214 } | 1209 } |
1215 } | 1210 } |
1216 } | 1211 } |
1217 } | 1212 } |
1218 clear_pending_message(); | 1213 if (can_clear_message) clear_pending_message(); |
1219 } | 1214 } |
1220 | 1215 |
1221 | 1216 |
1222 MessageLocation Isolate::GetMessageLocation() { | 1217 MessageLocation Isolate::GetMessageLocation() { |
1223 ASSERT(has_pending_exception()); | 1218 ASSERT(has_pending_exception()); |
1224 | 1219 |
1225 if (thread_local_top_.pending_exception_ != heap()->termination_exception() && | 1220 if (thread_local_top_.pending_exception_ != heap()->termination_exception() && |
1226 thread_local_top_.has_pending_message_ && | 1221 thread_local_top_.has_pending_message_ && |
1227 !thread_local_top_.pending_message_obj_->IsTheHole() && | 1222 !thread_local_top_.pending_message_obj_->IsTheHole() && |
1228 !thread_local_top_.pending_message_obj_->IsTheHole()) { | 1223 !thread_local_top_.pending_message_obj_->IsTheHole()) { |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1715 debug_ = NULL; | 1710 debug_ = NULL; |
1716 } | 1711 } |
1717 | 1712 |
1718 | 1713 |
1719 void Isolate::InitializeThreadLocal() { | 1714 void Isolate::InitializeThreadLocal() { |
1720 thread_local_top_.isolate_ = this; | 1715 thread_local_top_.isolate_ = this; |
1721 thread_local_top_.Initialize(); | 1716 thread_local_top_.Initialize(); |
1722 } | 1717 } |
1723 | 1718 |
1724 | 1719 |
1725 void Isolate::PropagatePendingExceptionToExternalTryCatch() { | 1720 bool Isolate::PropagatePendingExceptionToExternalTryCatch() { |
1726 ASSERT(has_pending_exception()); | 1721 ASSERT(has_pending_exception()); |
1727 | 1722 |
1728 bool external_caught = IsExternallyCaught(); | 1723 bool has_external_try_catch = HasExternalTryCatch(); |
1729 thread_local_top_.external_caught_exception_ = external_caught; | 1724 if (!has_external_try_catch) { |
| 1725 thread_local_top_.external_caught_exception_ = false; |
| 1726 return true; |
| 1727 } |
1730 | 1728 |
1731 if (!external_caught) return; | 1729 bool is_catchable_by_js = is_catchable_by_javascript(pending_exception()); |
| 1730 if (is_catchable_by_js) { |
| 1731 bool is_finally_on_top = IsFinallyOnTop(); |
| 1732 if (is_finally_on_top) { |
| 1733 thread_local_top_.external_caught_exception_ = false; |
| 1734 return false; |
| 1735 } |
| 1736 } |
1732 | 1737 |
| 1738 thread_local_top_.external_caught_exception_ = true; |
1733 if (thread_local_top_.pending_exception_ == | 1739 if (thread_local_top_.pending_exception_ == |
1734 heap()->termination_exception()) { | 1740 heap()->termination_exception()) { |
1735 try_catch_handler()->can_continue_ = false; | 1741 try_catch_handler()->can_continue_ = false; |
1736 try_catch_handler()->has_terminated_ = true; | 1742 try_catch_handler()->has_terminated_ = true; |
1737 try_catch_handler()->exception_ = heap()->null_value(); | 1743 try_catch_handler()->exception_ = heap()->null_value(); |
1738 } else { | 1744 } else { |
1739 v8::TryCatch* handler = try_catch_handler(); | 1745 v8::TryCatch* handler = try_catch_handler(); |
1740 ASSERT(thread_local_top_.pending_message_obj_->IsJSMessageObject() || | 1746 ASSERT(thread_local_top_.pending_message_obj_->IsJSMessageObject() || |
1741 thread_local_top_.pending_message_obj_->IsTheHole()); | 1747 thread_local_top_.pending_message_obj_->IsTheHole()); |
1742 ASSERT(thread_local_top_.pending_message_script_->IsScript() || | 1748 ASSERT(thread_local_top_.pending_message_script_->IsScript() || |
1743 thread_local_top_.pending_message_script_->IsTheHole()); | 1749 thread_local_top_.pending_message_script_->IsTheHole()); |
1744 handler->can_continue_ = true; | 1750 handler->can_continue_ = true; |
1745 handler->has_terminated_ = false; | 1751 handler->has_terminated_ = false; |
1746 handler->exception_ = pending_exception(); | 1752 handler->exception_ = pending_exception(); |
1747 // Propagate to the external try-catch only if we got an actual message. | 1753 // Propagate to the external try-catch only if we got an actual message. |
1748 if (thread_local_top_.pending_message_obj_->IsTheHole()) return; | 1754 if (thread_local_top_.pending_message_obj_->IsTheHole()) return true; |
1749 | 1755 |
1750 handler->message_obj_ = thread_local_top_.pending_message_obj_; | 1756 handler->message_obj_ = thread_local_top_.pending_message_obj_; |
1751 handler->message_script_ = thread_local_top_.pending_message_script_; | 1757 handler->message_script_ = thread_local_top_.pending_message_script_; |
1752 handler->message_start_pos_ = thread_local_top_.pending_message_start_pos_; | 1758 handler->message_start_pos_ = thread_local_top_.pending_message_start_pos_; |
1753 handler->message_end_pos_ = thread_local_top_.pending_message_end_pos_; | 1759 handler->message_end_pos_ = thread_local_top_.pending_message_end_pos_; |
1754 } | 1760 } |
| 1761 return true; |
1755 } | 1762 } |
1756 | 1763 |
1757 | 1764 |
1758 void Isolate::InitializeLoggingAndCounters() { | 1765 void Isolate::InitializeLoggingAndCounters() { |
1759 if (logger_ == NULL) { | 1766 if (logger_ == NULL) { |
1760 logger_ = new Logger(this); | 1767 logger_ = new Logger(this); |
1761 } | 1768 } |
1762 if (counters_ == NULL) { | 1769 if (counters_ == NULL) { |
1763 counters_ = new Counters(this); | 1770 counters_ = new Counters(this); |
1764 } | 1771 } |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2247 handle_scope_implementer()->IncrementCallDepth(); | 2254 handle_scope_implementer()->IncrementCallDepth(); |
2248 if (run_microtasks) Execution::RunMicrotasks(this); | 2255 if (run_microtasks) Execution::RunMicrotasks(this); |
2249 for (int i = 0; i < call_completed_callbacks_.length(); i++) { | 2256 for (int i = 0; i < call_completed_callbacks_.length(); i++) { |
2250 call_completed_callbacks_.at(i)(); | 2257 call_completed_callbacks_.at(i)(); |
2251 } | 2258 } |
2252 handle_scope_implementer()->DecrementCallDepth(); | 2259 handle_scope_implementer()->DecrementCallDepth(); |
2253 } | 2260 } |
2254 | 2261 |
2255 | 2262 |
2256 } } // namespace v8::internal | 2263 } } // namespace v8::internal |
OLD | NEW |