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 1864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1875 bool Debugger::debugger_unload_pending_ = false; | 1875 bool Debugger::debugger_unload_pending_ = false; |
1876 v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL; | 1876 v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL; |
1877 Mutex* Debugger::dispatch_handler_access_ = OS::CreateMutex(); | 1877 Mutex* Debugger::dispatch_handler_access_ = OS::CreateMutex(); |
1878 v8::Debug::DebugMessageDispatchHandler | 1878 v8::Debug::DebugMessageDispatchHandler |
1879 Debugger::debug_message_dispatch_handler_ = NULL; | 1879 Debugger::debug_message_dispatch_handler_ = NULL; |
1880 MessageDispatchHelperThread* Debugger::message_dispatch_helper_thread_ = NULL; | 1880 MessageDispatchHelperThread* Debugger::message_dispatch_helper_thread_ = NULL; |
1881 int Debugger::host_dispatch_micros_ = 100 * 1000; | 1881 int Debugger::host_dispatch_micros_ = 100 * 1000; |
1882 DebuggerAgent* Debugger::agent_ = NULL; | 1882 DebuggerAgent* Debugger::agent_ = NULL; |
1883 LockingCommandMessageQueue Debugger::command_queue_(kQueueInitialSize); | 1883 LockingCommandMessageQueue Debugger::command_queue_(kQueueInitialSize); |
1884 Semaphore* Debugger::command_received_ = OS::CreateSemaphore(0); | 1884 Semaphore* Debugger::command_received_ = OS::CreateSemaphore(0); |
| 1885 LockingCommandMessageQueue Debugger::event_command_queue_(kQueueInitialSize); |
1885 | 1886 |
1886 | 1887 |
1887 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, | 1888 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, |
1888 int argc, Object*** argv, | 1889 int argc, Object*** argv, |
1889 bool* caught_exception) { | 1890 bool* caught_exception) { |
1890 ASSERT(Top::context() == *Debug::debug_context()); | 1891 ASSERT(Top::context() == *Debug::debug_context()); |
1891 | 1892 |
1892 // Create the execution state object. | 1893 // Create the execution state object. |
1893 Handle<String> constructor_str = Factory::LookupSymbol(constructor_name); | 1894 Handle<String> constructor_str = Factory::LookupSymbol(constructor_name); |
1894 Handle<Object> constructor(Top::global()->GetProperty(*constructor_str)); | 1895 Handle<Object> constructor(Top::global()->GetProperty(*constructor_str)); |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2200 if (caught_exception) { | 2201 if (caught_exception) { |
2201 return; | 2202 return; |
2202 } | 2203 } |
2203 // First notify the message handler if any. | 2204 // First notify the message handler if any. |
2204 if (message_handler_ != NULL) { | 2205 if (message_handler_ != NULL) { |
2205 NotifyMessageHandler(event, | 2206 NotifyMessageHandler(event, |
2206 Handle<JSObject>::cast(exec_state), | 2207 Handle<JSObject>::cast(exec_state), |
2207 event_data, | 2208 event_data, |
2208 auto_continue); | 2209 auto_continue); |
2209 } | 2210 } |
2210 // Notify registered debug event listener. This can be either a C or a | 2211 // Notify registered debug event listener. This can be either a C or |
2211 // JavaScript function. | 2212 // a JavaScript function. Don't call event listener for v8::Break |
2212 if (!event_listener_.is_null()) { | 2213 // here, if it's only a debug command -- they will be processed later. |
2213 if (event_listener_->IsProxy()) { | 2214 if ((event != v8::Break || !auto_continue) && !event_listener_.is_null()) { |
2214 // C debug event listener. | 2215 CallEventCallback(event, exec_state, event_data, NULL); |
2215 Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_)); | 2216 } |
2216 v8::Debug::EventCallback2 callback = | 2217 // Process pending debug commands. |
2217 FUNCTION_CAST<v8::Debug::EventCallback2>(callback_obj->proxy()); | 2218 if (event == v8::Break) { |
2218 EventDetailsImpl event_details( | 2219 while (!event_command_queue_.IsEmpty()) { |
2219 event, | 2220 CommandMessage command = event_command_queue_.Get(); |
2220 Handle<JSObject>::cast(exec_state), | 2221 if (!event_listener_.is_null()) { |
2221 event_data, | 2222 CallEventCallback(v8::BreakForCommand, |
2222 event_listener_data_); | 2223 exec_state, |
2223 callback(event_details); | 2224 event_data, |
2224 } else { | 2225 command.client_data()); |
2225 // JavaScript debug event listener. | 2226 } |
2226 ASSERT(event_listener_->IsJSFunction()); | 2227 command.Dispose(); |
2227 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_)); | |
2228 | |
2229 // Invoke the JavaScript debug event listener. | |
2230 const int argc = 4; | |
2231 Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(), | |
2232 exec_state.location(), | |
2233 Handle<Object>::cast(event_data).location(), | |
2234 event_listener_data_.location() }; | |
2235 Handle<Object> result = Execution::TryCall(fun, Top::global(), | |
2236 argc, argv, &caught_exception); | |
2237 // Silently ignore exceptions from debug event listeners. | |
2238 } | 2228 } |
2239 } | 2229 } |
2240 } | 2230 } |
2241 | 2231 |
2242 | 2232 |
| 2233 void Debugger::CallEventCallback(v8::DebugEvent event, |
| 2234 Handle<Object> exec_state, |
| 2235 Handle<Object> event_data, |
| 2236 v8::Debug::ClientData* client_data) { |
| 2237 if (event_listener_->IsProxy()) { |
| 2238 CallCEventCallback(event, exec_state, event_data, client_data); |
| 2239 } else { |
| 2240 CallJSEventCallback(event, exec_state, event_data); |
| 2241 } |
| 2242 } |
| 2243 |
| 2244 |
| 2245 void Debugger::CallCEventCallback(v8::DebugEvent event, |
| 2246 Handle<Object> exec_state, |
| 2247 Handle<Object> event_data, |
| 2248 v8::Debug::ClientData* client_data) { |
| 2249 Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_)); |
| 2250 v8::Debug::EventCallback2 callback = |
| 2251 FUNCTION_CAST<v8::Debug::EventCallback2>(callback_obj->proxy()); |
| 2252 EventDetailsImpl event_details( |
| 2253 event, |
| 2254 Handle<JSObject>::cast(exec_state), |
| 2255 Handle<JSObject>::cast(event_data), |
| 2256 event_listener_data_, |
| 2257 client_data); |
| 2258 callback(event_details); |
| 2259 } |
| 2260 |
| 2261 |
| 2262 void Debugger::CallJSEventCallback(v8::DebugEvent event, |
| 2263 Handle<Object> exec_state, |
| 2264 Handle<Object> event_data) { |
| 2265 ASSERT(event_listener_->IsJSFunction()); |
| 2266 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_)); |
| 2267 |
| 2268 // Invoke the JavaScript debug event listener. |
| 2269 const int argc = 4; |
| 2270 Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(), |
| 2271 exec_state.location(), |
| 2272 Handle<Object>::cast(event_data).location(), |
| 2273 event_listener_data_.location() }; |
| 2274 bool caught_exception = false; |
| 2275 Execution::TryCall(fun, Top::global(), argc, argv, &caught_exception); |
| 2276 // Silently ignore exceptions from debug event listeners. |
| 2277 } |
| 2278 |
| 2279 |
2243 Handle<Context> Debugger::GetDebugContext() { | 2280 Handle<Context> Debugger::GetDebugContext() { |
2244 never_unload_debugger_ = true; | 2281 never_unload_debugger_ = true; |
2245 EnterDebugger debugger; | 2282 EnterDebugger debugger; |
2246 return Debug::debug_context(); | 2283 return Debug::debug_context(); |
2247 } | 2284 } |
2248 | 2285 |
2249 | 2286 |
2250 void Debugger::UnloadDebugger() { | 2287 void Debugger::UnloadDebugger() { |
2251 // Make sure that there are no breakpoints left. | 2288 // Make sure that there are no breakpoints left. |
2252 Debug::ClearAllBreakPoints(); | 2289 Debug::ClearAllBreakPoints(); |
(...skipping 13 matching lines...) Expand all Loading... |
2266 Handle<JSObject> event_data, | 2303 Handle<JSObject> event_data, |
2267 bool auto_continue) { | 2304 bool auto_continue) { |
2268 HandleScope scope; | 2305 HandleScope scope; |
2269 | 2306 |
2270 if (!Debug::Load()) return; | 2307 if (!Debug::Load()) return; |
2271 | 2308 |
2272 // Process the individual events. | 2309 // Process the individual events. |
2273 bool sendEventMessage = false; | 2310 bool sendEventMessage = false; |
2274 switch (event) { | 2311 switch (event) { |
2275 case v8::Break: | 2312 case v8::Break: |
| 2313 case v8::BreakForCommand: |
2276 sendEventMessage = !auto_continue; | 2314 sendEventMessage = !auto_continue; |
2277 break; | 2315 break; |
2278 case v8::Exception: | 2316 case v8::Exception: |
2279 sendEventMessage = true; | 2317 sendEventMessage = true; |
2280 break; | 2318 break; |
2281 case v8::BeforeCompile: | 2319 case v8::BeforeCompile: |
2282 break; | 2320 break; |
2283 case v8::AfterCompile: | 2321 case v8::AfterCompile: |
2284 sendEventMessage = true; | 2322 sendEventMessage = true; |
2285 break; | 2323 break; |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2553 dispatch_thread->Schedule(); | 2591 dispatch_thread->Schedule(); |
2554 } | 2592 } |
2555 } | 2593 } |
2556 | 2594 |
2557 | 2595 |
2558 bool Debugger::HasCommands() { | 2596 bool Debugger::HasCommands() { |
2559 return !command_queue_.IsEmpty(); | 2597 return !command_queue_.IsEmpty(); |
2560 } | 2598 } |
2561 | 2599 |
2562 | 2600 |
| 2601 void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) { |
| 2602 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); |
| 2603 event_command_queue_.Put(message); |
| 2604 |
| 2605 // Set the debug command break flag to have the command processed. |
| 2606 if (!Debug::InDebugger()) { |
| 2607 StackGuard::DebugCommand(); |
| 2608 } |
| 2609 } |
| 2610 |
| 2611 |
2563 bool Debugger::IsDebuggerActive() { | 2612 bool Debugger::IsDebuggerActive() { |
2564 ScopedLock with(debugger_access_); | 2613 ScopedLock with(debugger_access_); |
2565 | 2614 |
2566 return message_handler_ != NULL || !event_listener_.is_null(); | 2615 return message_handler_ != NULL || !event_listener_.is_null(); |
2567 } | 2616 } |
2568 | 2617 |
2569 | 2618 |
2570 Handle<Object> Debugger::Call(Handle<JSFunction> fun, | 2619 Handle<Object> Debugger::Call(Handle<JSFunction> fun, |
2571 Handle<Object> data, | 2620 Handle<Object> data, |
2572 bool* pending_exception) { | 2621 bool* pending_exception) { |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2754 | 2803 |
2755 | 2804 |
2756 v8::Debug::ClientData* MessageImpl::GetClientData() const { | 2805 v8::Debug::ClientData* MessageImpl::GetClientData() const { |
2757 return client_data_; | 2806 return client_data_; |
2758 } | 2807 } |
2759 | 2808 |
2760 | 2809 |
2761 EventDetailsImpl::EventDetailsImpl(DebugEvent event, | 2810 EventDetailsImpl::EventDetailsImpl(DebugEvent event, |
2762 Handle<JSObject> exec_state, | 2811 Handle<JSObject> exec_state, |
2763 Handle<JSObject> event_data, | 2812 Handle<JSObject> event_data, |
2764 Handle<Object> callback_data) | 2813 Handle<Object> callback_data, |
| 2814 v8::Debug::ClientData* client_data) |
2765 : event_(event), | 2815 : event_(event), |
2766 exec_state_(exec_state), | 2816 exec_state_(exec_state), |
2767 event_data_(event_data), | 2817 event_data_(event_data), |
2768 callback_data_(callback_data) {} | 2818 callback_data_(callback_data), |
| 2819 client_data_(client_data) {} |
2769 | 2820 |
2770 | 2821 |
2771 DebugEvent EventDetailsImpl::GetEvent() const { | 2822 DebugEvent EventDetailsImpl::GetEvent() const { |
2772 return event_; | 2823 return event_; |
2773 } | 2824 } |
2774 | 2825 |
2775 | 2826 |
2776 v8::Handle<v8::Object> EventDetailsImpl::GetExecutionState() const { | 2827 v8::Handle<v8::Object> EventDetailsImpl::GetExecutionState() const { |
2777 return v8::Utils::ToLocal(exec_state_); | 2828 return v8::Utils::ToLocal(exec_state_); |
2778 } | 2829 } |
2779 | 2830 |
2780 | 2831 |
2781 v8::Handle<v8::Object> EventDetailsImpl::GetEventData() const { | 2832 v8::Handle<v8::Object> EventDetailsImpl::GetEventData() const { |
2782 return v8::Utils::ToLocal(event_data_); | 2833 return v8::Utils::ToLocal(event_data_); |
2783 } | 2834 } |
2784 | 2835 |
2785 | 2836 |
2786 v8::Handle<v8::Context> EventDetailsImpl::GetEventContext() const { | 2837 v8::Handle<v8::Context> EventDetailsImpl::GetEventContext() const { |
2787 return GetDebugEventContext(); | 2838 return GetDebugEventContext(); |
2788 } | 2839 } |
2789 | 2840 |
2790 | 2841 |
2791 v8::Handle<v8::Value> EventDetailsImpl::GetCallbackData() const { | 2842 v8::Handle<v8::Value> EventDetailsImpl::GetCallbackData() const { |
2792 return v8::Utils::ToLocal(callback_data_); | 2843 return v8::Utils::ToLocal(callback_data_); |
2793 } | 2844 } |
2794 | 2845 |
2795 | 2846 |
| 2847 v8::Debug::ClientData* EventDetailsImpl::GetClientData() const { |
| 2848 return client_data_; |
| 2849 } |
| 2850 |
| 2851 |
2796 CommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()), | 2852 CommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()), |
2797 client_data_(NULL) { | 2853 client_data_(NULL) { |
2798 } | 2854 } |
2799 | 2855 |
2800 | 2856 |
2801 CommandMessage::CommandMessage(const Vector<uint16_t>& text, | 2857 CommandMessage::CommandMessage(const Vector<uint16_t>& text, |
2802 v8::Debug::ClientData* data) | 2858 v8::Debug::ClientData* data) |
2803 : text_(text), | 2859 : text_(text), |
2804 client_data_(data) { | 2860 client_data_(data) { |
2805 } | 2861 } |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2940 { | 2996 { |
2941 Locker locker; | 2997 Locker locker; |
2942 Debugger::CallMessageDispatchHandler(); | 2998 Debugger::CallMessageDispatchHandler(); |
2943 } | 2999 } |
2944 } | 3000 } |
2945 } | 3001 } |
2946 | 3002 |
2947 #endif // ENABLE_DEBUGGER_SUPPORT | 3003 #endif // ENABLE_DEBUGGER_SUPPORT |
2948 | 3004 |
2949 } } // namespace v8::internal | 3005 } } // namespace v8::internal |
OLD | NEW |