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

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
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 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
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
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
OLDNEW
« src/isolate.h ('K') | « src/isolate.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698