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 "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/ast.h" | 9 #include "src/ast.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 1148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1159 | 1159 |
1160 // Do not forget to clean catcher_ if currently thrown exception cannot | 1160 // Do not forget to clean catcher_ if currently thrown exception cannot |
1161 // be caught. If necessary, ReThrow will update the catcher. | 1161 // be caught. If necessary, ReThrow will update the catcher. |
1162 thread_local_top()->catcher_ = can_be_caught_externally ? | 1162 thread_local_top()->catcher_ = can_be_caught_externally ? |
1163 try_catch_handler() : NULL; | 1163 try_catch_handler() : NULL; |
1164 | 1164 |
1165 set_pending_exception(*exception_handle); | 1165 set_pending_exception(*exception_handle); |
1166 } | 1166 } |
1167 | 1167 |
1168 | 1168 |
1169 bool Isolate::HasExternalTryCatch() { | 1169 bool Isolate::IsExternallyCaught() { |
1170 ASSERT(has_pending_exception()); | 1170 ASSERT(has_pending_exception()); |
1171 | 1171 |
1172 return (thread_local_top()->catcher_ != NULL) && | 1172 if ((thread_local_top()->catcher_ == NULL) || |
1173 (try_catch_handler() == thread_local_top()->catcher_); | 1173 (try_catch_handler() != thread_local_top()->catcher_)) { |
1174 } | 1174 // When throwing the exception, we found no v8::TryCatch |
| 1175 // which should care about this exception. |
| 1176 return false; |
| 1177 } |
1175 | 1178 |
| 1179 if (!is_catchable_by_javascript(pending_exception())) { |
| 1180 return true; |
| 1181 } |
1176 | 1182 |
1177 bool Isolate::IsFinallyOnTop() { | |
1178 // Get the address of the external handler so we can compare the address to | 1183 // Get the address of the external handler so we can compare the address to |
1179 // determine which one is closer to the top of the stack. | 1184 // determine which one is closer to the top of the stack. |
1180 Address external_handler_address = | 1185 Address external_handler_address = |
1181 thread_local_top()->try_catch_handler_address(); | 1186 thread_local_top()->try_catch_handler_address(); |
1182 ASSERT(external_handler_address != NULL); | 1187 ASSERT(external_handler_address != NULL); |
1183 | 1188 |
1184 // The exception has been externally caught if and only if there is | 1189 // The exception has been externally caught if and only if there is |
1185 // an external handler which is on top of the top-most try-finally | 1190 // an external handler which is on top of the top-most try-finally |
1186 // handler. | 1191 // handler. |
1187 // There should be no try-catch blocks as they would prohibit us from | 1192 // There should be no try-catch blocks as they would prohibit us from |
1188 // finding external catcher in the first place (see catcher_ check above). | 1193 // finding external catcher in the first place (see catcher_ check above). |
1189 // | 1194 // |
1190 // Note, that finally clause would rethrow an exception unless it's | 1195 // Note, that finally clause would rethrow an exception unless it's |
1191 // aborted by jumps in control flow like return, break, etc. and we'll | 1196 // aborted by jumps in control flow like return, break, etc. and we'll |
1192 // have another chances to set proper v8::TryCatch. | 1197 // have another chances to set proper v8::TryCatch. |
1193 StackHandler* handler = | 1198 StackHandler* handler = |
1194 StackHandler::FromAddress(Isolate::handler(thread_local_top())); | 1199 StackHandler::FromAddress(Isolate::handler(thread_local_top())); |
1195 while (handler != NULL && handler->address() < external_handler_address) { | 1200 while (handler != NULL && handler->address() < external_handler_address) { |
1196 ASSERT(!handler->is_catch()); | 1201 ASSERT(!handler->is_catch()); |
1197 if (handler->is_finally()) return true; | 1202 if (handler->is_finally()) return false; |
1198 | 1203 |
1199 handler = handler->next(); | 1204 handler = handler->next(); |
1200 } | 1205 } |
1201 | 1206 |
1202 return false; | 1207 return true; |
1203 } | 1208 } |
1204 | 1209 |
1205 | 1210 |
1206 void Isolate::ReportPendingMessages() { | 1211 void Isolate::ReportPendingMessages() { |
1207 ASSERT(has_pending_exception()); | 1212 ASSERT(has_pending_exception()); |
1208 bool can_clear_message = PropagatePendingExceptionToExternalTryCatch(); | 1213 PropagatePendingExceptionToExternalTryCatch(); |
1209 | 1214 |
1210 HandleScope scope(this); | 1215 HandleScope scope(this); |
1211 if (thread_local_top_.pending_exception_ == | 1216 if (thread_local_top_.pending_exception_ == |
1212 heap()->termination_exception()) { | 1217 heap()->termination_exception()) { |
1213 // Do nothing: if needed, the exception has been already propagated to | 1218 // Do nothing: if needed, the exception has been already propagated to |
1214 // v8::TryCatch. | 1219 // v8::TryCatch. |
1215 } else { | 1220 } else { |
1216 if (thread_local_top_.has_pending_message_) { | 1221 if (thread_local_top_.has_pending_message_) { |
1217 thread_local_top_.has_pending_message_ = false; | 1222 thread_local_top_.has_pending_message_ = false; |
1218 if (!thread_local_top_.pending_message_obj_->IsTheHole()) { | 1223 if (!thread_local_top_.pending_message_obj_->IsTheHole()) { |
1219 HandleScope scope(this); | 1224 HandleScope scope(this); |
1220 Handle<Object> message_obj(thread_local_top_.pending_message_obj_, | 1225 Handle<Object> message_obj(thread_local_top_.pending_message_obj_, |
1221 this); | 1226 this); |
1222 if (!thread_local_top_.pending_message_script_->IsTheHole()) { | 1227 if (!thread_local_top_.pending_message_script_->IsTheHole()) { |
1223 Handle<Script> script( | 1228 Handle<Script> script( |
1224 Script::cast(thread_local_top_.pending_message_script_)); | 1229 Script::cast(thread_local_top_.pending_message_script_)); |
1225 int start_pos = thread_local_top_.pending_message_start_pos_; | 1230 int start_pos = thread_local_top_.pending_message_start_pos_; |
1226 int end_pos = thread_local_top_.pending_message_end_pos_; | 1231 int end_pos = thread_local_top_.pending_message_end_pos_; |
1227 MessageLocation location(script, start_pos, end_pos); | 1232 MessageLocation location(script, start_pos, end_pos); |
1228 MessageHandler::ReportMessage(this, &location, message_obj); | 1233 MessageHandler::ReportMessage(this, &location, message_obj); |
1229 } else { | 1234 } else { |
1230 MessageHandler::ReportMessage(this, NULL, message_obj); | 1235 MessageHandler::ReportMessage(this, NULL, message_obj); |
1231 } | 1236 } |
1232 } | 1237 } |
1233 } | 1238 } |
1234 } | 1239 } |
1235 if (can_clear_message) clear_pending_message(); | 1240 clear_pending_message(); |
1236 } | 1241 } |
1237 | 1242 |
1238 | 1243 |
1239 MessageLocation Isolate::GetMessageLocation() { | 1244 MessageLocation Isolate::GetMessageLocation() { |
1240 ASSERT(has_pending_exception()); | 1245 ASSERT(has_pending_exception()); |
1241 | 1246 |
1242 if (thread_local_top_.pending_exception_ != heap()->termination_exception() && | 1247 if (thread_local_top_.pending_exception_ != heap()->termination_exception() && |
1243 thread_local_top_.has_pending_message_ && | 1248 thread_local_top_.has_pending_message_ && |
1244 !thread_local_top_.pending_message_obj_->IsTheHole() && | 1249 !thread_local_top_.pending_message_obj_->IsTheHole() && |
1245 !thread_local_top_.pending_message_obj_->IsTheHole()) { | 1250 !thread_local_top_.pending_message_obj_->IsTheHole()) { |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1730 debug_ = NULL; | 1735 debug_ = NULL; |
1731 } | 1736 } |
1732 | 1737 |
1733 | 1738 |
1734 void Isolate::InitializeThreadLocal() { | 1739 void Isolate::InitializeThreadLocal() { |
1735 thread_local_top_.isolate_ = this; | 1740 thread_local_top_.isolate_ = this; |
1736 thread_local_top_.Initialize(); | 1741 thread_local_top_.Initialize(); |
1737 } | 1742 } |
1738 | 1743 |
1739 | 1744 |
1740 bool Isolate::PropagatePendingExceptionToExternalTryCatch() { | 1745 void Isolate::PropagatePendingExceptionToExternalTryCatch() { |
1741 ASSERT(has_pending_exception()); | 1746 ASSERT(has_pending_exception()); |
1742 | 1747 |
1743 bool has_external_try_catch = HasExternalTryCatch(); | 1748 bool external_caught = IsExternallyCaught(); |
1744 bool is_catchable_by_js = is_catchable_by_javascript(pending_exception()); | 1749 thread_local_top_.external_caught_exception_ = external_caught; |
1745 bool is_finally_on_top = IsFinallyOnTop(); | |
1746 | 1750 |
1747 bool should_propagate_now = has_external_try_catch && | 1751 if (!external_caught) return; |
1748 (!is_catchable_by_js || !is_finally_on_top); | |
1749 thread_local_top_.external_caught_exception_ = should_propagate_now; | |
1750 | |
1751 if (!should_propagate_now) return !has_external_try_catch; | |
1752 | 1752 |
1753 if (thread_local_top_.pending_exception_ == | 1753 if (thread_local_top_.pending_exception_ == |
1754 heap()->termination_exception()) { | 1754 heap()->termination_exception()) { |
1755 try_catch_handler()->can_continue_ = false; | 1755 try_catch_handler()->can_continue_ = false; |
1756 try_catch_handler()->has_terminated_ = true; | 1756 try_catch_handler()->has_terminated_ = true; |
1757 try_catch_handler()->exception_ = heap()->null_value(); | 1757 try_catch_handler()->exception_ = heap()->null_value(); |
1758 } else { | 1758 } else { |
1759 v8::TryCatch* handler = try_catch_handler(); | 1759 v8::TryCatch* handler = try_catch_handler(); |
1760 ASSERT(thread_local_top_.pending_message_obj_->IsJSMessageObject() || | 1760 ASSERT(thread_local_top_.pending_message_obj_->IsJSMessageObject() || |
1761 thread_local_top_.pending_message_obj_->IsTheHole()); | 1761 thread_local_top_.pending_message_obj_->IsTheHole()); |
1762 ASSERT(thread_local_top_.pending_message_script_->IsScript() || | 1762 ASSERT(thread_local_top_.pending_message_script_->IsScript() || |
1763 thread_local_top_.pending_message_script_->IsTheHole()); | 1763 thread_local_top_.pending_message_script_->IsTheHole()); |
1764 handler->can_continue_ = true; | 1764 handler->can_continue_ = true; |
1765 handler->has_terminated_ = false; | 1765 handler->has_terminated_ = false; |
1766 handler->exception_ = pending_exception(); | 1766 handler->exception_ = pending_exception(); |
1767 // Propagate to the external try-catch only if we got an actual message. | 1767 // Propagate to the external try-catch only if we got an actual message. |
1768 if (thread_local_top_.pending_message_obj_->IsTheHole()) return true; | 1768 if (thread_local_top_.pending_message_obj_->IsTheHole()) return; |
1769 | 1769 |
1770 handler->message_obj_ = thread_local_top_.pending_message_obj_; | 1770 handler->message_obj_ = thread_local_top_.pending_message_obj_; |
1771 handler->message_script_ = thread_local_top_.pending_message_script_; | 1771 handler->message_script_ = thread_local_top_.pending_message_script_; |
1772 handler->message_start_pos_ = thread_local_top_.pending_message_start_pos_; | 1772 handler->message_start_pos_ = thread_local_top_.pending_message_start_pos_; |
1773 handler->message_end_pos_ = thread_local_top_.pending_message_end_pos_; | 1773 handler->message_end_pos_ = thread_local_top_.pending_message_end_pos_; |
1774 } | 1774 } |
1775 return true; | |
1776 } | 1775 } |
1777 | 1776 |
1778 | 1777 |
1779 void Isolate::InitializeLoggingAndCounters() { | 1778 void Isolate::InitializeLoggingAndCounters() { |
1780 if (logger_ == NULL) { | 1779 if (logger_ == NULL) { |
1781 logger_ = new Logger(this); | 1780 logger_ = new Logger(this); |
1782 } | 1781 } |
1783 if (counters_ == NULL) { | 1782 if (counters_ == NULL) { |
1784 counters_ = new Counters(this); | 1783 counters_ = new Counters(this); |
1785 } | 1784 } |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2334 v8::ToCData<v8::MicrotaskCallback>(callback_info->callback()); | 2333 v8::ToCData<v8::MicrotaskCallback>(callback_info->callback()); |
2335 void* data = v8::ToCData<void*>(callback_info->data()); | 2334 void* data = v8::ToCData<void*>(callback_info->data()); |
2336 callback(data); | 2335 callback(data); |
2337 } | 2336 } |
2338 } | 2337 } |
2339 } | 2338 } |
2340 } | 2339 } |
2341 | 2340 |
2342 | 2341 |
2343 } } // namespace v8::internal | 2342 } } // namespace v8::internal |
OLD | NEW |