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