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

Side by Side Diff: src/isolate.cc

Issue 321763002: 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 "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
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
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
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
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