OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |