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::PropagatePendingExceptionToExternalTryCatch() { |
| 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 try_catch_handler()->can_continue_ = false; |
| 937 try_catch_handler()->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 ASSERT(!pending_exception()->IsFailure()); |
| 942 try_catch_handler()->can_continue_ = true; |
| 943 try_catch_handler()->exception_ = pending_exception(); |
| 944 if (!thread_local_.pending_message_obj_->IsTheHole()) { |
| 945 try_catch_handler()->message_ = thread_local_.pending_message_obj_; |
| 946 } |
| 947 } |
| 948 } |
| 949 |
| 950 |
927 void Top::ReportPendingMessages() { | 951 void Top::ReportPendingMessages() { |
928 ASSERT(has_pending_exception()); | 952 ASSERT(has_pending_exception()); |
929 setup_external_caught(); | 953 setup_external_caught(); |
| 954 PropagatePendingExceptionToExternalTryCatch(); |
| 955 |
930 // If the pending exception is OutOfMemoryException set out_of_memory in | 956 // If the pending exception is OutOfMemoryException set out_of_memory in |
931 // the global context. Note: We have to mark the global context here | 957 // the global context. Note: We have to mark the global context here |
932 // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to | 958 // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to |
933 // set it. | 959 // set it. |
934 bool external_caught = thread_local_.external_caught_exception_; | |
935 HandleScope scope; | |
936 if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) { | 960 if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) { |
937 context()->mark_out_of_memory(); | 961 context()->mark_out_of_memory(); |
938 } else if (thread_local_.pending_exception_ == | 962 } else if (thread_local_.pending_exception_ == |
939 Heap::termination_exception()) { | 963 Heap::termination_exception()) { |
940 if (external_caught) { | 964 // Do nothing: if needed, the exception has been already propagated to |
941 thread_local_.TryCatchHandler()->can_continue_ = false; | 965 // v8::TryCatch. |
942 thread_local_.TryCatchHandler()->exception_ = Heap::null_value(); | |
943 } | |
944 } else { | 966 } 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_) { | 967 if (thread_local_.has_pending_message_) { |
959 thread_local_.has_pending_message_ = false; | 968 thread_local_.has_pending_message_ = false; |
960 if (thread_local_.pending_message_ != NULL) { | 969 if (thread_local_.pending_message_ != NULL) { |
961 MessageHandler::ReportMessage(thread_local_.pending_message_); | 970 MessageHandler::ReportMessage(thread_local_.pending_message_); |
962 } else if (!thread_local_.pending_message_obj_->IsTheHole()) { | 971 } else if (!thread_local_.pending_message_obj_->IsTheHole()) { |
| 972 HandleScope scope; |
963 Handle<Object> message_obj(thread_local_.pending_message_obj_); | 973 Handle<Object> message_obj(thread_local_.pending_message_obj_); |
964 if (thread_local_.pending_message_script_ != NULL) { | 974 if (thread_local_.pending_message_script_ != NULL) { |
965 Handle<Script> script(thread_local_.pending_message_script_); | 975 Handle<Script> script(thread_local_.pending_message_script_); |
966 int start_pos = thread_local_.pending_message_start_pos_; | 976 int start_pos = thread_local_.pending_message_start_pos_; |
967 int end_pos = thread_local_.pending_message_end_pos_; | 977 int end_pos = thread_local_.pending_message_end_pos_; |
968 MessageLocation location(script, start_pos, end_pos); | 978 MessageLocation location(script, start_pos, end_pos); |
969 MessageHandler::ReportMessage(&location, message_obj); | 979 MessageHandler::ReportMessage(&location, message_obj); |
970 } else { | 980 } else { |
971 MessageHandler::ReportMessage(NULL, message_obj); | 981 MessageHandler::ReportMessage(NULL, message_obj); |
972 } | 982 } |
973 } | 983 } |
974 } | 984 } |
975 thread_local_.external_caught_exception_ = external_caught; | |
976 set_pending_exception(*exception); | |
977 } | 985 } |
978 clear_pending_message(); | 986 clear_pending_message(); |
979 } | 987 } |
980 | 988 |
981 | 989 |
982 void Top::TraceException(bool flag) { | 990 void Top::TraceException(bool flag) { |
983 FLAG_trace_exception = flag; | 991 FLAG_trace_exception = flag; |
984 } | 992 } |
985 | 993 |
986 | 994 |
987 bool Top::OptionalRescheduleException(bool is_bottom_call) { | 995 bool Top::OptionalRescheduleException(bool is_bottom_call) { |
| 996 ASSERT(has_pending_exception()); |
| 997 setup_external_caught(); |
| 998 PropagatePendingExceptionToExternalTryCatch(); |
| 999 |
988 // Allways reschedule out of memory exceptions. | 1000 // Allways reschedule out of memory exceptions. |
989 if (!is_out_of_memory()) { | 1001 if (!is_out_of_memory()) { |
990 bool is_termination_exception = | 1002 bool is_termination_exception = |
991 pending_exception() == Heap::termination_exception(); | 1003 pending_exception() == Heap::termination_exception(); |
992 | 1004 |
993 // Do not reschedule the exception if this is the bottom call. | 1005 // Do not reschedule the exception if this is the bottom call. |
994 bool clear_exception = is_bottom_call; | 1006 bool clear_exception = is_bottom_call; |
995 | 1007 |
996 if (is_termination_exception) { | 1008 if (is_termination_exception) { |
997 if (is_bottom_call) { | 1009 if (is_bottom_call) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 #ifdef V8_TARGET_ARCH_ARM | 1109 #ifdef V8_TARGET_ARCH_ARM |
1098 thread_local_.simulator_ = Simulator::current(); | 1110 thread_local_.simulator_ = Simulator::current(); |
1099 #elif V8_TARGET_ARCH_MIPS | 1111 #elif V8_TARGET_ARCH_MIPS |
1100 thread_local_.simulator_ = assembler::mips::Simulator::current(); | 1112 thread_local_.simulator_ = assembler::mips::Simulator::current(); |
1101 #endif | 1113 #endif |
1102 #endif | 1114 #endif |
1103 return from + sizeof(thread_local_); | 1115 return from + sizeof(thread_local_); |
1104 } | 1116 } |
1105 | 1117 |
1106 } } // namespace v8::internal | 1118 } } // namespace v8::internal |
OLD | NEW |