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