Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: src/isolate.cc

Issue 306463002: Don't clear exception pending message if we have externally TryCatch and finally on top of stack. (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/isolate.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « src/isolate.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698