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

Side by Side Diff: src/top.cc

Issue 6397011: Make exception thrown via v8 public API propagate to v8::TryCatch as JS thrown exceptions do. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 if (is_object) { 917 if (is_object) {
918 set_pending_exception(*exception_handle); 918 set_pending_exception(*exception_handle);
919 } else { 919 } else {
920 // Failures are not on the heap so they neither need nor work with handles. 920 // Failures are not on the heap so they neither need nor work with handles.
921 ASSERT(exception_handle->IsFailure()); 921 ASSERT(exception_handle->IsFailure());
922 set_pending_exception(exception); 922 set_pending_exception(exception);
923 } 923 }
924 } 924 }
925 925
926 926
927 void Top::PropagatePendingExceptionToExteranlTryCatch() {
928 ASSERT(has_pending_exception());
929
930 if (!thread_local_.external_caught_exception_) return;
931
932 if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) {
933 // Do not propagate OOM exception: we should kill VM asap.
934 } else if (thread_local_.pending_exception_ ==
935 Heap::termination_exception()) {
936 thread_local_.TryCatchHandler()->can_continue_ = false;
Vitaly Repeshko 2011/01/28 14:03:33 try_catch_handler() is a nicer alias for thread_lo
antonm 2011/01/28 14:43:18 Done.
937 thread_local_.TryCatchHandler()->exception_ = Heap::null_value();
938 } else {
939 // At this point all non-object (failure) exceptions have
940 // been dealt with so this shouldn't fail.
941 Object* pending_exception_object = pending_exception()->ToObjectUnchecked();
942 Handle<Object> exception(pending_exception_object);
Vitaly Repeshko 2011/01/28 14:03:33 Unused? If it is intended to be used, shouldn't we
antonm 2011/01/28 14:43:18 Thanks a lot, indeed unused.
943 thread_local_.TryCatchHandler()->can_continue_ = true;
944 thread_local_.TryCatchHandler()->exception_ =
945 thread_local_.pending_exception_;
946 if (!thread_local_.pending_message_obj_->IsTheHole()) {
947 try_catch_handler()->message_ = thread_local_.pending_message_obj_;
948 }
949 }
950 }
951
952
927 void Top::ReportPendingMessages() { 953 void Top::ReportPendingMessages() {
Vitaly Repeshko 2011/01/28 14:03:33 It reports only a single message, doesn't it? Drop
antonm 2011/01/28 14:43:18 I don't know. Let's investigate it later.
928 ASSERT(has_pending_exception()); 954 ASSERT(has_pending_exception());
929 setup_external_caught(); 955 setup_external_caught();
Vitaly Repeshko 2011/01/28 14:03:33 This looks slightly backwards: one function sets a
antonm 2011/01/28 14:43:18 I don't want to rework the things too much. I agr
956 PropagatePendingExceptionToExteranlTryCatch();
957
958 bool external_caught = thread_local_.external_caught_exception_;
930 // If the pending exception is OutOfMemoryException set out_of_memory in 959 // If the pending exception is OutOfMemoryException set out_of_memory in
931 // the global context. Note: We have to mark the global context here 960 // the global context. Note: We have to mark the global context here
932 // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to 961 // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to
933 // set it. 962 // set it.
934 bool external_caught = thread_local_.external_caught_exception_;
935 HandleScope scope;
936 if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) { 963 if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) {
937 context()->mark_out_of_memory(); 964 context()->mark_out_of_memory();
938 } else if (thread_local_.pending_exception_ == 965 } else if (thread_local_.pending_exception_ ==
939 Heap::termination_exception()) { 966 Heap::termination_exception()) {
940 if (external_caught) { 967 // Do nothing: if needed, the exception has been already propagated to
941 thread_local_.TryCatchHandler()->can_continue_ = false; 968 // v8::TryCatch.
942 thread_local_.TryCatchHandler()->exception_ = Heap::null_value();
943 }
944 } else { 969 } else {
945 // At this point all non-object (failure) exceptions have
946 // been dealt with so this shouldn't fail.
947 Object* pending_exception_object = pending_exception()->ToObjectUnchecked();
948 Handle<Object> exception(pending_exception_object);
949 thread_local_.external_caught_exception_ = false;
950 if (external_caught) {
951 thread_local_.TryCatchHandler()->can_continue_ = true;
952 thread_local_.TryCatchHandler()->exception_ =
953 thread_local_.pending_exception_;
954 if (!thread_local_.pending_message_obj_->IsTheHole()) {
955 try_catch_handler()->message_ = thread_local_.pending_message_obj_;
956 }
957 }
958 if (thread_local_.has_pending_message_) { 970 if (thread_local_.has_pending_message_) {
Vitaly Repeshko 2011/01/28 14:03:33 Join with "else" above?
antonm 2011/01/28 14:43:18 I'd like to keep identical structure of failure an
971 HandleScope scope;
972
973 // At this point all non-object (failure) exceptions have
974 // been dealt with so this shouldn't fail.
975 Object* pending_exception_obj = pending_exception()->ToObjectUnchecked();
976 // Message reporting executes arbitrary embedder's code and hence
977 // we need to save this state.
978 // TODO(antonm): consider saving the whole thread_local_.
Vitaly Repeshko 2011/01/28 14:03:33 I don't think we should save the whole thread loca
antonm 2011/01/28 14:43:18 Yep, that's why I left it as todo (there is this f
979 Handle<Object> exception(pending_exception_obj);
980 thread_local_.external_caught_exception_ = false;
981 v8::TryCatch* former_catcher = thread_local_.catcher_;
982
Mads Ager (chromium) 2011/01/28 11:39:18 Clear pending exception here instead of in ReportM
antonm 2011/01/28 13:37:25 See above.
Vitaly Repeshko 2011/01/28 14:03:33 I agree. This logic should be all moved here.
antonm 2011/01/28 14:43:18 See patch 2.
959 thread_local_.has_pending_message_ = false; 983 thread_local_.has_pending_message_ = false;
960 if (thread_local_.pending_message_ != NULL) { 984 if (thread_local_.pending_message_ != NULL) {
961 MessageHandler::ReportMessage(thread_local_.pending_message_); 985 MessageHandler::ReportMessage(thread_local_.pending_message_);
962 } else if (!thread_local_.pending_message_obj_->IsTheHole()) { 986 } else if (!thread_local_.pending_message_obj_->IsTheHole()) {
963 Handle<Object> message_obj(thread_local_.pending_message_obj_); 987 Handle<Object> message_obj(thread_local_.pending_message_obj_);
964 if (thread_local_.pending_message_script_ != NULL) { 988 if (thread_local_.pending_message_script_ != NULL) {
965 Handle<Script> script(thread_local_.pending_message_script_); 989 Handle<Script> script(thread_local_.pending_message_script_);
966 int start_pos = thread_local_.pending_message_start_pos_; 990 int start_pos = thread_local_.pending_message_start_pos_;
967 int end_pos = thread_local_.pending_message_end_pos_; 991 int end_pos = thread_local_.pending_message_end_pos_;
968 MessageLocation location(script, start_pos, end_pos); 992 MessageLocation location(script, start_pos, end_pos);
969 MessageHandler::ReportMessage(&location, message_obj); 993 MessageHandler::ReportMessage(&location, message_obj);
970 } else { 994 } else {
971 MessageHandler::ReportMessage(NULL, message_obj); 995 MessageHandler::ReportMessage(NULL, message_obj);
972 } 996 }
973 } 997 }
998
999 // Restore previously saved state.
1000 thread_local_.catcher_ = former_catcher;
1001 thread_local_.external_caught_exception_ = external_caught;
1002 set_pending_exception(*exception);
974 } 1003 }
975 thread_local_.external_caught_exception_ = external_caught;
976 set_pending_exception(*exception);
977 } 1004 }
978 clear_pending_message(); 1005 clear_pending_message();
979 } 1006 }
980 1007
981 1008
982 void Top::TraceException(bool flag) { 1009 void Top::TraceException(bool flag) {
983 FLAG_trace_exception = flag; 1010 FLAG_trace_exception = flag;
984 } 1011 }
985 1012
986 1013
987 bool Top::OptionalRescheduleException(bool is_bottom_call) { 1014 bool Top::OptionalRescheduleException(bool is_bottom_call) {
1015 setup_external_caught();
1016 PropagatePendingExceptionToExteranlTryCatch();
1017
988 // Allways reschedule out of memory exceptions. 1018 // Allways reschedule out of memory exceptions.
989 if (!is_out_of_memory()) { 1019 if (!is_out_of_memory()) {
990 bool is_termination_exception = 1020 bool is_termination_exception =
991 pending_exception() == Heap::termination_exception(); 1021 pending_exception() == Heap::termination_exception();
992 1022
993 // Do not reschedule the exception if this is the bottom call. 1023 // Do not reschedule the exception if this is the bottom call.
994 bool clear_exception = is_bottom_call; 1024 bool clear_exception = is_bottom_call;
995 1025
996 if (is_termination_exception) { 1026 if (is_termination_exception) {
997 if (is_bottom_call) { 1027 if (is_bottom_call) {
998 thread_local_.external_caught_exception_ = false; 1028 thread_local_.external_caught_exception_ = false;
999 clear_pending_exception(); 1029 clear_pending_exception();
1000 return false; 1030 return false;
1001 } 1031 }
1002 } else if (thread_local_.external_caught_exception_) { 1032 } else if (thread_local_.external_caught_exception_) {
1003 // If the exception is externally caught, clear it if there are no 1033 // If the exception is externally caught, clear it if there are no
1004 // JavaScript frames on the way to the C++ frame that has the 1034 // JavaScript frames on the way to the C++ frame that has the
1005 // external handler. 1035 // external handler.
1006 ASSERT(thread_local_.try_catch_handler_address() != NULL); 1036 ASSERT(thread_local_.try_catch_handler_address() != NULL);
1007 Address external_handler_address = 1037 Address external_handler_address =
1008 thread_local_.try_catch_handler_address(); 1038 thread_local_.try_catch_handler_address();
1009 JavaScriptFrameIterator it; 1039 JavaScriptFrameIterator it;
1010 if (it.done() || (it.frame()->sp() > external_handler_address)) { 1040 if (it.done() || (it.frame()->sp() > external_handler_address)) {
Vitaly Repeshko 2011/01/28 14:03:33 Does this work correctly under ARM simulator?
antonm 2011/01/28 14:43:18 I guess so, there is a special translation for sim
1011 clear_exception = true; 1041 clear_exception = true;
1012 } 1042 }
1013 } 1043 }
1014 1044
1015 // Clear the exception if needed. 1045 // Clear the exception if needed.
1016 if (clear_exception) { 1046 if (clear_exception) {
1017 thread_local_.external_caught_exception_ = false; 1047 thread_local_.external_caught_exception_ = false;
1018 clear_pending_exception(); 1048 clear_pending_exception();
1019 return false; 1049 return false;
1020 } 1050 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1097 #ifdef V8_TARGET_ARCH_ARM 1127 #ifdef V8_TARGET_ARCH_ARM
1098 thread_local_.simulator_ = Simulator::current(); 1128 thread_local_.simulator_ = Simulator::current();
1099 #elif V8_TARGET_ARCH_MIPS 1129 #elif V8_TARGET_ARCH_MIPS
1100 thread_local_.simulator_ = assembler::mips::Simulator::current(); 1130 thread_local_.simulator_ = assembler::mips::Simulator::current();
1101 #endif 1131 #endif
1102 #endif 1132 #endif
1103 return from + sizeof(thread_local_); 1133 return from + sizeof(thread_local_);
1104 } 1134 }
1105 1135
1106 } } // namespace v8::internal 1136 } } // namespace v8::internal
OLDNEW
« src/top.h ('K') | « src/top.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698