Chromium Code Reviews| 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 |