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