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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage); | 59 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage); |
60 Iterate(v, thread); | 60 Iterate(v, thread); |
61 return thread_storage + sizeof(ThreadLocalTop); | 61 return thread_storage + sizeof(ThreadLocalTop); |
62 } | 62 } |
63 | 63 |
64 | 64 |
65 #define VISIT(field) v->VisitPointer(reinterpret_cast<Object**>(&(field))); | 65 #define VISIT(field) v->VisitPointer(reinterpret_cast<Object**>(&(field))); |
66 | 66 |
67 void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) { | 67 void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) { |
68 v->VisitPointer(&(thread->pending_exception_)); | 68 v->VisitPointer(&(thread->pending_exception_)); |
69 v->VisitPointer(&(thread->pending_message_obj_)); | |
70 v->VisitPointer( | |
71 bit_cast<Object**, Script**>(&(thread->pending_message_script_))); | |
72 v->VisitPointer(bit_cast<Object**, Context**>(&(thread->context_))); | 69 v->VisitPointer(bit_cast<Object**, Context**>(&(thread->context_))); |
73 v->VisitPointer(&(thread->scheduled_exception_)); | 70 v->VisitPointer(&(thread->scheduled_exception_)); |
74 | 71 |
75 for (v8::TryCatch* block = thread->try_catch_handler_; | 72 for (v8::TryCatch* block = thread->try_catch_handler_; |
76 block != NULL; | 73 block != NULL; |
77 block = block->next_) { | 74 block = block->next_) { |
78 v->VisitPointer(bit_cast<Object**, void**>(&(block->exception_))); | 75 v->VisitPointer(bit_cast<Object**, void**>(&(block->exception_))); |
79 v->VisitPointer(bit_cast<Object**, void**>(&(block->message_))); | 76 v->VisitPointer(bit_cast<Object**, void**>(&(block->message_))); |
80 } | 77 } |
81 | 78 |
(...skipping 13 matching lines...) Expand all Loading... |
95 | 92 |
96 void Top::InitializeThreadLocal() { | 93 void Top::InitializeThreadLocal() { |
97 thread_local_.c_entry_fp_ = 0; | 94 thread_local_.c_entry_fp_ = 0; |
98 thread_local_.handler_ = 0; | 95 thread_local_.handler_ = 0; |
99 thread_local_.stack_is_cooked_ = false; | 96 thread_local_.stack_is_cooked_ = false; |
100 thread_local_.try_catch_handler_ = NULL; | 97 thread_local_.try_catch_handler_ = NULL; |
101 thread_local_.context_ = NULL; | 98 thread_local_.context_ = NULL; |
102 thread_local_.external_caught_exception_ = false; | 99 thread_local_.external_caught_exception_ = false; |
103 thread_local_.failed_access_check_callback_ = NULL; | 100 thread_local_.failed_access_check_callback_ = NULL; |
104 clear_pending_exception(); | 101 clear_pending_exception(); |
105 clear_pending_message(); | |
106 clear_scheduled_exception(); | 102 clear_scheduled_exception(); |
107 thread_local_.save_context_ = NULL; | 103 thread_local_.save_context_ = NULL; |
108 thread_local_.catcher_ = NULL; | 104 thread_local_.catcher_ = NULL; |
109 } | 105 } |
110 | 106 |
111 | 107 |
112 // Create a dummy thread that will wait forever on a semaphore. The only | 108 // Create a dummy thread that will wait forever on a semaphore. The only |
113 // purpose for this thread is to have some stack area to save essential data | 109 // purpose for this thread is to have some stack area to save essential data |
114 // into for use by a stacks only core dump (aka minidump). | 110 // into for use by a stacks only core dump (aka minidump). |
115 class PreallocatedMemoryThread: public Thread { | 111 class PreallocatedMemoryThread: public Thread { |
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 void Top::DoThrow(Object* exception, | 784 void Top::DoThrow(Object* exception, |
789 MessageLocation* location, | 785 MessageLocation* location, |
790 const char* message) { | 786 const char* message) { |
791 ASSERT(!has_pending_exception()); | 787 ASSERT(!has_pending_exception()); |
792 | 788 |
793 HandleScope scope; | 789 HandleScope scope; |
794 Handle<Object> exception_handle(exception); | 790 Handle<Object> exception_handle(exception); |
795 | 791 |
796 // Determine reporting and whether the exception is caught externally. | 792 // Determine reporting and whether the exception is caught externally. |
797 bool is_caught_externally = false; | 793 bool is_caught_externally = false; |
798 bool is_out_of_memory = exception == Failure::OutOfMemoryException(); | 794 bool report_exception = (exception != Failure::OutOfMemoryException()) && |
799 bool should_return_exception = ShouldReportException(&is_caught_externally); | 795 ShouldReportException(&is_caught_externally); |
800 bool report_exception = !is_out_of_memory && should_return_exception; | |
801 | |
802 | |
803 // Notify debugger of exception. | |
804 Debugger::OnException(exception_handle, report_exception); | |
805 | 796 |
806 // Generate the message. | 797 // Generate the message. |
807 Handle<Object> message_obj; | 798 Handle<Object> message_obj; |
808 MessageLocation potential_computed_location; | 799 MessageLocation potential_computed_location; |
809 bool try_catch_needs_message = | 800 bool try_catch_needs_message = |
810 is_caught_externally && | 801 is_caught_externally && |
811 thread_local_.try_catch_handler_->capture_message_; | 802 thread_local_.try_catch_handler_->capture_message_; |
812 if (report_exception || try_catch_needs_message) { | 803 if (report_exception || try_catch_needs_message) { |
813 if (location == NULL) { | 804 if (location == NULL) { |
814 // If no location was specified we use a computed one instead | 805 // If no location was specified we use a computed one instead |
815 ComputeLocation(&potential_computed_location); | 806 ComputeLocation(&potential_computed_location); |
816 location = &potential_computed_location; | 807 location = &potential_computed_location; |
817 } | 808 } |
818 Handle<String> stack_trace; | 809 Handle<String> stack_trace; |
819 if (FLAG_trace_exception) stack_trace = StackTrace(); | 810 if (FLAG_trace_exception) stack_trace = StackTrace(); |
820 message_obj = MessageHandler::MakeMessageObject("uncaught_exception", | 811 message_obj = MessageHandler::MakeMessageObject("uncaught_exception", |
821 location, HandleVector<Object>(&exception_handle, 1), stack_trace); | 812 location, HandleVector<Object>(&exception_handle, 1), stack_trace); |
822 } | 813 } |
823 | 814 |
824 // Save the message for reporting if the the exception remains uncaught. | 815 // If the exception is caught externally, we store it in the |
825 thread_local_.pending_message_ = message; | 816 // try/catch handler. The C code can find it later and process it if |
826 if (!message_obj.is_null()) { | 817 // necessary. |
827 thread_local_.pending_message_obj_ = *message_obj; | 818 thread_local_.catcher_ = NULL; |
828 if (location != NULL) { | 819 if (is_caught_externally) { |
829 thread_local_.pending_message_script_ = *location->script(); | 820 thread_local_.catcher_ = thread_local_.try_catch_handler_; |
830 thread_local_.pending_message_start_pos_ = location->start_pos(); | 821 thread_local_.try_catch_handler_->exception_ = |
831 thread_local_.pending_message_end_pos_ = location->end_pos(); | 822 reinterpret_cast<void*>(*exception_handle); |
| 823 if (!message_obj.is_null()) { |
| 824 thread_local_.try_catch_handler_->message_ = |
| 825 reinterpret_cast<void*>(*message_obj); |
832 } | 826 } |
833 } | 827 } |
834 | 828 |
835 if (is_caught_externally) { | 829 // Notify debugger of exception. |
836 thread_local_.catcher_ = thread_local_.try_catch_handler_; | 830 Debugger::OnException(exception_handle, report_exception); |
| 831 |
| 832 if (report_exception) { |
| 833 if (message != NULL) { |
| 834 MessageHandler::ReportMessage(message); |
| 835 } else if (!message_obj.is_null()) { |
| 836 MessageHandler::ReportMessage(location, message_obj); |
| 837 } |
837 } | 838 } |
838 | 839 |
839 // NOTE: Notifying the debugger or generating the message | 840 // NOTE: Notifying the debugger or reporting the exception may have caused |
840 // may have caused new exceptions. For now, we just ignore | 841 // new exceptions. For now, we just ignore that and set the pending exception |
841 // that and set the pending exception to the original one. | 842 // to the original one. |
842 set_pending_exception(*exception_handle); | 843 set_pending_exception(*exception_handle); |
843 } | 844 } |
844 | 845 |
845 | 846 |
846 void Top::ReportPendingMessages() { | |
847 ASSERT(has_pending_exception()); | |
848 setup_external_caught(); | |
849 // If the pending exception is OutOfMemoryException set out_of_memory in | |
850 // the global context. Note: We have to mark the global context here | |
851 // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to | |
852 // set it. | |
853 HandleScope scope; | |
854 if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) { | |
855 context()->mark_out_of_memory(); | |
856 } else { | |
857 Handle<Object> exception(pending_exception()); | |
858 if (thread_local_.external_caught_exception_) { | |
859 thread_local_.try_catch_handler_->exception_ = | |
860 thread_local_.pending_exception_; | |
861 if (!thread_local_.pending_message_obj_->IsTheHole()) { | |
862 try_catch_handler()->message_ = thread_local_.pending_message_obj_; | |
863 } | |
864 } else if (thread_local_.pending_message_ != NULL) { | |
865 MessageHandler::ReportMessage(thread_local_.pending_message_); | |
866 } else if (!thread_local_.pending_message_obj_->IsTheHole()) { | |
867 Handle<Object> message_obj(thread_local_.pending_message_obj_); | |
868 if (thread_local_.pending_message_script_ != NULL) { | |
869 Handle<Script> script(thread_local_.pending_message_script_); | |
870 int start_pos = thread_local_.pending_message_start_pos_; | |
871 int end_pos = thread_local_.pending_message_end_pos_; | |
872 MessageLocation location(script, start_pos, end_pos); | |
873 MessageHandler::ReportMessage(&location, message_obj); | |
874 } else { | |
875 MessageHandler::ReportMessage(NULL, message_obj); | |
876 } | |
877 } | |
878 set_pending_exception(*exception); | |
879 } | |
880 clear_pending_message(); | |
881 } | |
882 | |
883 | |
884 void Top::TraceException(bool flag) { | 847 void Top::TraceException(bool flag) { |
885 FLAG_trace_exception = flag; | 848 FLAG_trace_exception = flag; |
886 } | 849 } |
887 | 850 |
888 | 851 |
889 bool Top::optional_reschedule_exception(bool is_bottom_call) { | 852 bool Top::optional_reschedule_exception(bool is_bottom_call) { |
890 if (!is_out_of_memory() && | 853 if (!is_out_of_memory() && |
891 (thread_local_.external_caught_exception_ || is_bottom_call)) { | 854 (thread_local_.external_caught_exception_ || is_bottom_call)) { |
892 thread_local_.external_caught_exception_ = false; | 855 thread_local_.external_caught_exception_ = false; |
893 clear_pending_exception(); | 856 clear_pending_exception(); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 Top::break_access_->Lock(); | 919 Top::break_access_->Lock(); |
957 } | 920 } |
958 | 921 |
959 | 922 |
960 ExecutionAccess::~ExecutionAccess() { | 923 ExecutionAccess::~ExecutionAccess() { |
961 Top::break_access_->Unlock(); | 924 Top::break_access_->Unlock(); |
962 } | 925 } |
963 | 926 |
964 | 927 |
965 } } // namespace v8::internal | 928 } } // namespace v8::internal |
OLD | NEW |