| 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 |