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 23 matching lines...) Expand all Loading... |
34 #include "compiler.h" | 34 #include "compiler.h" |
35 #include "debug.h" | 35 #include "debug.h" |
36 #include "execution.h" | 36 #include "execution.h" |
37 #include "global-handles.h" | 37 #include "global-handles.h" |
38 #include "ic.h" | 38 #include "ic.h" |
39 #include "ic-inl.h" | 39 #include "ic-inl.h" |
40 #include "natives.h" | 40 #include "natives.h" |
41 #include "stub-cache.h" | 41 #include "stub-cache.h" |
42 #include "log.h" | 42 #include "log.h" |
43 | 43 |
| 44 #include "../include/v8-debug.h" |
| 45 |
44 namespace v8 { namespace internal { | 46 namespace v8 { namespace internal { |
45 | 47 |
46 #ifdef ENABLE_DEBUGGER_SUPPORT | 48 #ifdef ENABLE_DEBUGGER_SUPPORT |
47 static void PrintLn(v8::Local<v8::Value> value) { | 49 static void PrintLn(v8::Local<v8::Value> value) { |
48 v8::Local<v8::String> s = value->ToString(); | 50 v8::Local<v8::String> s = value->ToString(); |
49 char* data = NewArray<char>(s->Length() + 1); | 51 char* data = NewArray<char>(s->Length() + 1); |
50 if (data == NULL) { | 52 if (data == NULL) { |
51 V8::FatalProcessOutOfMemory("PrintLn"); | 53 V8::FatalProcessOutOfMemory("PrintLn"); |
52 return; | 54 return; |
53 } | 55 } |
(...skipping 1491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1545 Handle<Object> event_data; | 1547 Handle<Object> event_data; |
1546 if (!caught_exception) { | 1548 if (!caught_exception) { |
1547 event_data = MakeExceptionEvent(exec_state, exception, uncaught, | 1549 event_data = MakeExceptionEvent(exec_state, exception, uncaught, |
1548 &caught_exception); | 1550 &caught_exception); |
1549 } | 1551 } |
1550 // Bail out and don't call debugger if exception. | 1552 // Bail out and don't call debugger if exception. |
1551 if (caught_exception) { | 1553 if (caught_exception) { |
1552 return; | 1554 return; |
1553 } | 1555 } |
1554 | 1556 |
1555 // Process debug event | 1557 // Process debug event. |
1556 ProcessDebugEvent(v8::Exception, event_data, false); | 1558 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); |
1557 // Return to continue execution from where the exception was thrown. | 1559 // Return to continue execution from where the exception was thrown. |
1558 } | 1560 } |
1559 | 1561 |
1560 | 1562 |
1561 void Debugger::OnDebugBreak(Handle<Object> break_points_hit, | 1563 void Debugger::OnDebugBreak(Handle<Object> break_points_hit, |
1562 bool auto_continue) { | 1564 bool auto_continue) { |
1563 HandleScope scope; | 1565 HandleScope scope; |
1564 | 1566 |
1565 // Debugger has already been entered by caller. | 1567 // Debugger has already been entered by caller. |
1566 ASSERT(Top::context() == *Debug::debug_context()); | 1568 ASSERT(Top::context() == *Debug::debug_context()); |
(...skipping 10 matching lines...) Expand all Loading... |
1577 Handle<Object> event_data; | 1579 Handle<Object> event_data; |
1578 if (!caught_exception) { | 1580 if (!caught_exception) { |
1579 event_data = MakeBreakEvent(exec_state, break_points_hit, | 1581 event_data = MakeBreakEvent(exec_state, break_points_hit, |
1580 &caught_exception); | 1582 &caught_exception); |
1581 } | 1583 } |
1582 // Bail out and don't call debugger if exception. | 1584 // Bail out and don't call debugger if exception. |
1583 if (caught_exception) { | 1585 if (caught_exception) { |
1584 return; | 1586 return; |
1585 } | 1587 } |
1586 | 1588 |
1587 // Process debug event | 1589 // Process debug event. |
1588 ProcessDebugEvent(v8::Break, event_data, auto_continue); | 1590 ProcessDebugEvent(v8::Break, |
| 1591 Handle<JSObject>::cast(event_data), |
| 1592 auto_continue); |
1589 } | 1593 } |
1590 | 1594 |
1591 | 1595 |
1592 void Debugger::OnBeforeCompile(Handle<Script> script) { | 1596 void Debugger::OnBeforeCompile(Handle<Script> script) { |
1593 HandleScope scope; | 1597 HandleScope scope; |
1594 | 1598 |
1595 // Bail out based on state or if there is no listener for this event | 1599 // Bail out based on state or if there is no listener for this event |
1596 if (Debug::InDebugger()) return; | 1600 if (Debug::InDebugger()) return; |
1597 if (compiling_natives()) return; | 1601 if (compiling_natives()) return; |
1598 if (!EventActive(v8::BeforeCompile)) return; | 1602 if (!EventActive(v8::BeforeCompile)) return; |
1599 | 1603 |
1600 // Enter the debugger. | 1604 // Enter the debugger. |
1601 EnterDebugger debugger; | 1605 EnterDebugger debugger; |
1602 if (debugger.FailedToEnter()) return; | 1606 if (debugger.FailedToEnter()) return; |
1603 | 1607 |
1604 // Create the event data object. | 1608 // Create the event data object. |
1605 bool caught_exception = false; | 1609 bool caught_exception = false; |
1606 Handle<Object> event_data = MakeCompileEvent(script, true, &caught_exception); | 1610 Handle<Object> event_data = MakeCompileEvent(script, true, &caught_exception); |
1607 // Bail out and don't call debugger if exception. | 1611 // Bail out and don't call debugger if exception. |
1608 if (caught_exception) { | 1612 if (caught_exception) { |
1609 return; | 1613 return; |
1610 } | 1614 } |
1611 | 1615 |
1612 // Process debug event | 1616 // Process debug event. |
1613 ProcessDebugEvent(v8::BeforeCompile, event_data, true); | 1617 ProcessDebugEvent(v8::BeforeCompile, |
| 1618 Handle<JSObject>::cast(event_data), |
| 1619 true); |
1614 } | 1620 } |
1615 | 1621 |
1616 | 1622 |
1617 // Handle debugger actions when a new script is compiled. | 1623 // Handle debugger actions when a new script is compiled. |
1618 void Debugger::OnAfterCompile(Handle<Script> script, Handle<JSFunction> fun) { | 1624 void Debugger::OnAfterCompile(Handle<Script> script, Handle<JSFunction> fun) { |
1619 HandleScope scope; | 1625 HandleScope scope; |
1620 | 1626 |
1621 // No compile events while compiling natives. | 1627 // No compile events while compiling natives. |
1622 if (compiling_natives()) return; | 1628 if (compiling_natives()) return; |
1623 | 1629 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1663 if (!Debugger::EventActive(v8::AfterCompile)) return; | 1669 if (!Debugger::EventActive(v8::AfterCompile)) return; |
1664 | 1670 |
1665 // Create the compile state object. | 1671 // Create the compile state object. |
1666 Handle<Object> event_data = MakeCompileEvent(script, | 1672 Handle<Object> event_data = MakeCompileEvent(script, |
1667 false, | 1673 false, |
1668 &caught_exception); | 1674 &caught_exception); |
1669 // Bail out and don't call debugger if exception. | 1675 // Bail out and don't call debugger if exception. |
1670 if (caught_exception) { | 1676 if (caught_exception) { |
1671 return; | 1677 return; |
1672 } | 1678 } |
1673 // Process debug event | 1679 // Process debug event. |
1674 ProcessDebugEvent(v8::AfterCompile, event_data, true); | 1680 ProcessDebugEvent(v8::AfterCompile, |
| 1681 Handle<JSObject>::cast(event_data), |
| 1682 true); |
1675 } | 1683 } |
1676 | 1684 |
1677 | 1685 |
1678 void Debugger::OnNewFunction(Handle<JSFunction> function) { | 1686 void Debugger::OnNewFunction(Handle<JSFunction> function) { |
1679 return; | 1687 return; |
1680 HandleScope scope; | 1688 HandleScope scope; |
1681 | 1689 |
1682 // Bail out based on state or if there is no listener for this event | 1690 // Bail out based on state or if there is no listener for this event |
1683 if (Debug::InDebugger()) return; | 1691 if (Debug::InDebugger()) return; |
1684 if (compiling_natives()) return; | 1692 if (compiling_natives()) return; |
1685 if (!Debugger::EventActive(v8::NewFunction)) return; | 1693 if (!Debugger::EventActive(v8::NewFunction)) return; |
1686 | 1694 |
1687 // Enter the debugger. | 1695 // Enter the debugger. |
1688 EnterDebugger debugger; | 1696 EnterDebugger debugger; |
1689 if (debugger.FailedToEnter()) return; | 1697 if (debugger.FailedToEnter()) return; |
1690 | 1698 |
1691 // Create the event object. | 1699 // Create the event object. |
1692 bool caught_exception = false; | 1700 bool caught_exception = false; |
1693 Handle<Object> event_data = MakeNewFunctionEvent(function, &caught_exception); | 1701 Handle<Object> event_data = MakeNewFunctionEvent(function, &caught_exception); |
1694 // Bail out and don't call debugger if exception. | 1702 // Bail out and don't call debugger if exception. |
1695 if (caught_exception) { | 1703 if (caught_exception) { |
1696 return; | 1704 return; |
1697 } | 1705 } |
1698 // Process debug event. | 1706 // Process debug event. |
1699 ProcessDebugEvent(v8::NewFunction, event_data, true); | 1707 ProcessDebugEvent(v8::NewFunction, Handle<JSObject>::cast(event_data), true); |
1700 } | 1708 } |
1701 | 1709 |
1702 | 1710 |
1703 void Debugger::ProcessDebugEvent(v8::DebugEvent event, | 1711 void Debugger::ProcessDebugEvent(v8::DebugEvent event, |
1704 Handle<Object> event_data, | 1712 Handle<JSObject> event_data, |
1705 bool auto_continue) { | 1713 bool auto_continue) { |
1706 HandleScope scope; | 1714 HandleScope scope; |
1707 | 1715 |
1708 // Create the execution state. | 1716 // Create the execution state. |
1709 bool caught_exception = false; | 1717 bool caught_exception = false; |
1710 Handle<Object> exec_state = MakeExecutionState(&caught_exception); | 1718 Handle<Object> exec_state = MakeExecutionState(&caught_exception); |
1711 if (caught_exception) { | 1719 if (caught_exception) { |
1712 return; | 1720 return; |
1713 } | 1721 } |
1714 // First notify the message handler if any. | 1722 // First notify the message handler if any. |
1715 if (message_handler_ != NULL) { | 1723 if (message_handler_ != NULL) { |
1716 NotifyMessageHandler(event, exec_state, event_data, auto_continue); | 1724 NotifyMessageHandler(event, |
| 1725 Handle<JSObject>::cast(exec_state), |
| 1726 event_data, |
| 1727 auto_continue); |
1717 } | 1728 } |
1718 // Notify registered debug event listener. This can be either a C or a | 1729 // Notify registered debug event listener. This can be either a C or a |
1719 // JavaScript function. | 1730 // JavaScript function. |
1720 if (!event_listener_.is_null()) { | 1731 if (!event_listener_.is_null()) { |
1721 if (event_listener_->IsProxy()) { | 1732 if (event_listener_->IsProxy()) { |
1722 // C debug event listener. | 1733 // C debug event listener. |
1723 Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_)); | 1734 Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_)); |
1724 v8::Debug::EventCallback callback = | 1735 v8::Debug::EventCallback callback = |
1725 FUNCTION_CAST<v8::Debug::EventCallback>(callback_obj->proxy()); | 1736 FUNCTION_CAST<v8::Debug::EventCallback>(callback_obj->proxy()); |
1726 callback(event, | 1737 callback(event, |
1727 v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)), | 1738 v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)), |
1728 v8::Utils::ToLocal(Handle<JSObject>::cast(event_data)), | 1739 v8::Utils::ToLocal(event_data), |
1729 v8::Utils::ToLocal(Handle<Object>::cast(event_listener_data_))); | 1740 v8::Utils::ToLocal(Handle<Object>::cast(event_listener_data_))); |
1730 } else { | 1741 } else { |
1731 // JavaScript debug event listener. | 1742 // JavaScript debug event listener. |
1732 ASSERT(event_listener_->IsJSFunction()); | 1743 ASSERT(event_listener_->IsJSFunction()); |
1733 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_)); | 1744 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_)); |
1734 | 1745 |
1735 // Invoke the JavaScript debug event listener. | 1746 // Invoke the JavaScript debug event listener. |
1736 const int argc = 4; | 1747 const int argc = 4; |
1737 Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(), | 1748 Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(), |
1738 exec_state.location(), | 1749 exec_state.location(), |
1739 event_data.location(), | 1750 Handle<Object>::cast(event_data).location(), |
1740 event_listener_data_.location() }; | 1751 event_listener_data_.location() }; |
1741 Handle<Object> result = Execution::TryCall(fun, Top::global(), | 1752 Handle<Object> result = Execution::TryCall(fun, Top::global(), |
1742 argc, argv, &caught_exception); | 1753 argc, argv, &caught_exception); |
1743 if (caught_exception) { | 1754 if (caught_exception) { |
1744 // Silently ignore exceptions from debug event listeners. | 1755 // Silently ignore exceptions from debug event listeners. |
1745 } | 1756 } |
1746 } | 1757 } |
1747 } | 1758 } |
1748 | 1759 |
1749 // Clear the mirror cache. | 1760 // Clear the mirror cache. |
1750 Debug::ClearMirrorCache(); | 1761 Debug::ClearMirrorCache(); |
1751 } | 1762 } |
1752 | 1763 |
1753 | 1764 |
1754 void Debugger::UnloadDebugger() { | 1765 void Debugger::UnloadDebugger() { |
1755 // Make sure that there are no breakpoints left. | 1766 // Make sure that there are no breakpoints left. |
1756 Debug::ClearAllBreakPoints(); | 1767 Debug::ClearAllBreakPoints(); |
1757 | 1768 |
1758 // Unload the debugger if feasible. | 1769 // Unload the debugger if feasible. |
1759 if (!never_unload_debugger_) { | 1770 if (!never_unload_debugger_) { |
1760 Debug::Unload(); | 1771 Debug::Unload(); |
1761 } | 1772 } |
1762 | 1773 |
1763 // Clear the flag indicating that the message handler was recently cleared. | 1774 // Clear the flag indicating that the message handler was recently cleared. |
1764 message_handler_cleared_ = false; | 1775 message_handler_cleared_ = false; |
1765 } | 1776 } |
1766 | 1777 |
1767 | 1778 |
1768 void Debugger::NotifyMessageHandler(v8::DebugEvent event, | 1779 void Debugger::NotifyMessageHandler(v8::DebugEvent event, |
1769 Handle<Object> exec_state, | 1780 Handle<JSObject> exec_state, |
1770 Handle<Object> event_data, | 1781 Handle<JSObject> event_data, |
1771 bool auto_continue) { | 1782 bool auto_continue) { |
1772 HandleScope scope; | 1783 HandleScope scope; |
1773 | 1784 |
1774 if (!Debug::Load()) return; | 1785 if (!Debug::Load()) return; |
1775 | 1786 |
1776 // Process the individual events. | 1787 // Process the individual events. |
1777 bool sendEventMessage = false; | 1788 bool sendEventMessage = false; |
1778 switch (event) { | 1789 switch (event) { |
1779 case v8::Break: | 1790 case v8::Break: |
1780 sendEventMessage = !auto_continue; | 1791 sendEventMessage = !auto_continue; |
(...skipping 14 matching lines...) Expand all Loading... |
1795 | 1806 |
1796 // The debug command interrupt flag might have been set when the command was | 1807 // The debug command interrupt flag might have been set when the command was |
1797 // added. It should be enough to clear the flag only once while we are in the | 1808 // added. It should be enough to clear the flag only once while we are in the |
1798 // debugger. | 1809 // debugger. |
1799 ASSERT(Debug::InDebugger()); | 1810 ASSERT(Debug::InDebugger()); |
1800 StackGuard::Continue(DEBUGCOMMAND); | 1811 StackGuard::Continue(DEBUGCOMMAND); |
1801 | 1812 |
1802 // Notify the debugger that a debug event has occurred unless auto continue is | 1813 // Notify the debugger that a debug event has occurred unless auto continue is |
1803 // active in which case no event is send. | 1814 // active in which case no event is send. |
1804 if (sendEventMessage) { | 1815 if (sendEventMessage) { |
1805 InvokeMessageHandlerWithEvent(event_data); | 1816 MessageImpl message = MessageImpl::NewEvent( |
| 1817 event, |
| 1818 auto_continue, |
| 1819 Handle<JSObject>::cast(exec_state), |
| 1820 Handle<JSObject>::cast(event_data)); |
| 1821 InvokeMessageHandler(message); |
1806 } | 1822 } |
1807 if (auto_continue && !HasCommands()) { | 1823 if (auto_continue && !HasCommands()) { |
1808 return; | 1824 return; |
1809 } | 1825 } |
1810 | 1826 |
1811 // Get the DebugCommandProcessor. | 1827 // Get the DebugCommandProcessor. |
1812 v8::Local<v8::Object> api_exec_state = | 1828 v8::Local<v8::Object> api_exec_state = |
1813 v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)); | 1829 v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)); |
1814 v8::Local<v8::String> fun_name = | 1830 v8::Local<v8::String> fun_name = |
1815 v8::String::New("debugCommandProcessor"); | 1831 v8::String::New("debugCommandProcessor"); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1850 // Invoke JavaScript to process the debug request. | 1866 // Invoke JavaScript to process the debug request. |
1851 v8::Local<v8::String> fun_name; | 1867 v8::Local<v8::String> fun_name; |
1852 v8::Local<v8::Function> fun; | 1868 v8::Local<v8::Function> fun; |
1853 v8::Local<v8::Value> request; | 1869 v8::Local<v8::Value> request; |
1854 v8::TryCatch try_catch; | 1870 v8::TryCatch try_catch; |
1855 fun_name = v8::String::New("processDebugRequest"); | 1871 fun_name = v8::String::New("processDebugRequest"); |
1856 fun = v8::Function::Cast(*cmd_processor->Get(fun_name)); | 1872 fun = v8::Function::Cast(*cmd_processor->Get(fun_name)); |
1857 | 1873 |
1858 request = v8::String::New(command.text().start(), | 1874 request = v8::String::New(command.text().start(), |
1859 command.text().length()); | 1875 command.text().length()); |
1860 command.text().Dispose(); | |
1861 static const int kArgc = 1; | 1876 static const int kArgc = 1; |
1862 v8::Handle<Value> argv[kArgc] = { request }; | 1877 v8::Handle<Value> argv[kArgc] = { request }; |
1863 v8::Local<v8::Value> response_val = fun->Call(cmd_processor, kArgc, argv); | 1878 v8::Local<v8::Value> response_val = fun->Call(cmd_processor, kArgc, argv); |
1864 | 1879 |
1865 // Get the response. | 1880 // Get the response. |
1866 v8::Local<v8::String> response; | 1881 v8::Local<v8::String> response; |
1867 bool running = false; | 1882 bool running = false; |
1868 if (!try_catch.HasCaught()) { | 1883 if (!try_catch.HasCaught()) { |
1869 // Get response string. | 1884 // Get response string. |
1870 if (!response_val->IsUndefined()) { | 1885 if (!response_val->IsUndefined()) { |
(...skipping 16 matching lines...) Expand all Loading... |
1887 v8::Local<v8::Value> running_val = fun->Call(cmd_processor, kArgc, argv); | 1902 v8::Local<v8::Value> running_val = fun->Call(cmd_processor, kArgc, argv); |
1888 if (!try_catch.HasCaught()) { | 1903 if (!try_catch.HasCaught()) { |
1889 running = running_val->ToBoolean()->Value(); | 1904 running = running_val->ToBoolean()->Value(); |
1890 } | 1905 } |
1891 } else { | 1906 } else { |
1892 // In case of failure the result text is the exception text. | 1907 // In case of failure the result text is the exception text. |
1893 response = try_catch.Exception()->ToString(); | 1908 response = try_catch.Exception()->ToString(); |
1894 } | 1909 } |
1895 | 1910 |
1896 // Return the result. | 1911 // Return the result. |
1897 InvokeMessageHandler(response, command.client_data()); | 1912 MessageImpl message = MessageImpl::NewResponse( |
| 1913 event, |
| 1914 running, |
| 1915 Handle<JSObject>::cast(exec_state), |
| 1916 Handle<JSObject>::cast(event_data), |
| 1917 Handle<String>(Utils::OpenHandle(*response)), |
| 1918 command.client_data()); |
| 1919 InvokeMessageHandler(message); |
| 1920 command.Dispose(); |
1898 | 1921 |
1899 // Return from debug event processing if either the VM is put into the | 1922 // Return from debug event processing if either the VM is put into the |
1900 // runnning state (through a continue command) or auto continue is active | 1923 // runnning state (through a continue command) or auto continue is active |
1901 // and there are no more commands queued. | 1924 // and there are no more commands queued. |
1902 if (running || (auto_continue && !HasCommands())) { | 1925 if (running || (auto_continue && !HasCommands())) { |
1903 return; | 1926 return; |
1904 } | 1927 } |
1905 } | 1928 } |
1906 } | 1929 } |
1907 | 1930 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1958 | 1981 |
1959 | 1982 |
1960 void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, | 1983 void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, |
1961 int period) { | 1984 int period) { |
1962 host_dispatch_handler_ = handler; | 1985 host_dispatch_handler_ = handler; |
1963 host_dispatch_micros_ = period * 1000; | 1986 host_dispatch_micros_ = period * 1000; |
1964 } | 1987 } |
1965 | 1988 |
1966 | 1989 |
1967 // Calls the registered debug message handler. This callback is part of the | 1990 // Calls the registered debug message handler. This callback is part of the |
1968 // public API. Messages are kept internally as Vector<uint16_t> strings, which | 1991 // public API. |
1969 // are allocated in various places and deallocated by the calling function | 1992 void Debugger::InvokeMessageHandler(MessageImpl message) { |
1970 // sometime after this call. | |
1971 void Debugger::InvokeMessageHandler(v8::Handle<v8::String> output, | |
1972 v8::Debug::ClientData* data) { | |
1973 ScopedLock with(debugger_access_); | 1993 ScopedLock with(debugger_access_); |
1974 | 1994 |
1975 if (message_handler_ != NULL) { | 1995 if (message_handler_ != NULL) { |
1976 Vector<uint16_t> text = Vector<uint16_t>::New(output->Length()); | 1996 message_handler_(message); |
1977 output->Write(text.start(), 0, output->Length()); | |
1978 | |
1979 message_handler_(text.start(), | |
1980 text.length(), | |
1981 data); | |
1982 | |
1983 text.Dispose(); | |
1984 } | 1997 } |
1985 delete data; | |
1986 } | |
1987 | |
1988 | |
1989 bool Debugger::InvokeMessageHandlerWithEvent(Handle<Object> event_data) { | |
1990 v8::HandleScope scope; | |
1991 // Call toJSONProtocol on the debug event object. | |
1992 v8::Local<v8::Object> api_event_data = | |
1993 v8::Utils::ToLocal(Handle<JSObject>::cast(event_data)); | |
1994 v8::Local<v8::String> fun_name = v8::String::New("toJSONProtocol"); | |
1995 v8::Local<v8::Function> fun = | |
1996 v8::Function::Cast(*api_event_data->Get(fun_name)); | |
1997 v8::TryCatch try_catch; | |
1998 v8::Local<v8::Value> json_event = *fun->Call(api_event_data, 0, NULL); | |
1999 v8::Local<v8::String> json_event_string; | |
2000 if (!try_catch.HasCaught()) { | |
2001 if (!json_event->IsUndefined()) { | |
2002 json_event_string = json_event->ToString(); | |
2003 if (FLAG_trace_debug_json) { | |
2004 PrintLn(json_event_string); | |
2005 } | |
2006 InvokeMessageHandler(json_event_string, | |
2007 NULL /* no user data since there was no request */); | |
2008 } else { | |
2009 InvokeMessageHandler(v8::String::Empty(), NULL); | |
2010 } | |
2011 } else { | |
2012 PrintLn(try_catch.Exception()); | |
2013 return false; | |
2014 } | |
2015 return true; | |
2016 } | 1998 } |
2017 | 1999 |
2018 | 2000 |
2019 // Puts a command coming from the public API on the queue. Creates | 2001 // Puts a command coming from the public API on the queue. Creates |
2020 // a copy of the command string managed by the debugger. Up to this | 2002 // a copy of the command string managed by the debugger. Up to this |
2021 // point, the command data was managed by the API client. Called | 2003 // point, the command data was managed by the API client. Called |
2022 // by the API client thread. | 2004 // by the API client thread. |
2023 void Debugger::ProcessCommand(Vector<const uint16_t> command, | 2005 void Debugger::ProcessCommand(Vector<const uint16_t> command, |
2024 v8::Debug::ClientData* client_data) { | 2006 v8::Debug::ClientData* client_data) { |
2025 // Need to cast away const. | 2007 // Need to cast away const. |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2091 void Debugger::StopAgent() { | 2073 void Debugger::StopAgent() { |
2092 if (agent_ != NULL) { | 2074 if (agent_ != NULL) { |
2093 agent_->Shutdown(); | 2075 agent_->Shutdown(); |
2094 agent_->Join(); | 2076 agent_->Join(); |
2095 delete agent_; | 2077 delete agent_; |
2096 agent_ = NULL; | 2078 agent_ = NULL; |
2097 } | 2079 } |
2098 } | 2080 } |
2099 | 2081 |
2100 | 2082 |
| 2083 MessageImpl MessageImpl::NewEvent(DebugEvent event, |
| 2084 bool running, |
| 2085 Handle<JSObject> exec_state, |
| 2086 Handle<JSObject> event_data) { |
| 2087 MessageImpl message(true, event, running, |
| 2088 exec_state, event_data, Handle<String>(), NULL); |
| 2089 return message; |
| 2090 } |
| 2091 |
| 2092 |
| 2093 MessageImpl MessageImpl::NewResponse(DebugEvent event, |
| 2094 bool running, |
| 2095 Handle<JSObject> exec_state, |
| 2096 Handle<JSObject> event_data, |
| 2097 Handle<String> response_json, |
| 2098 v8::Debug::ClientData* client_data) { |
| 2099 MessageImpl message(false, event, running, |
| 2100 exec_state, event_data, response_json, client_data); |
| 2101 return message; |
| 2102 } |
| 2103 |
| 2104 |
| 2105 MessageImpl::MessageImpl(bool is_event, |
| 2106 DebugEvent event, |
| 2107 bool running, |
| 2108 Handle<JSObject> exec_state, |
| 2109 Handle<JSObject> event_data, |
| 2110 Handle<String> response_json, |
| 2111 v8::Debug::ClientData* client_data) |
| 2112 : is_event_(is_event), |
| 2113 event_(event), |
| 2114 running_(running), |
| 2115 exec_state_(exec_state), |
| 2116 event_data_(event_data), |
| 2117 response_json_(response_json), |
| 2118 client_data_(client_data) {} |
| 2119 |
| 2120 |
| 2121 bool MessageImpl::IsEvent() const { |
| 2122 return is_event_; |
| 2123 } |
| 2124 |
| 2125 |
| 2126 bool MessageImpl::IsResponse() const { |
| 2127 return !is_event_; |
| 2128 } |
| 2129 |
| 2130 |
| 2131 DebugEvent MessageImpl::GetEvent() const { |
| 2132 return event_; |
| 2133 } |
| 2134 |
| 2135 |
| 2136 bool MessageImpl::WillStartRunning() const { |
| 2137 return running_; |
| 2138 } |
| 2139 |
| 2140 |
| 2141 v8::Handle<v8::Object> MessageImpl::GetExecutionState() const { |
| 2142 return v8::Utils::ToLocal(exec_state_); |
| 2143 } |
| 2144 |
| 2145 |
| 2146 v8::Handle<v8::Object> MessageImpl::GetEventData() const { |
| 2147 return v8::Utils::ToLocal(event_data_); |
| 2148 } |
| 2149 |
| 2150 |
| 2151 v8::Handle<v8::String> MessageImpl::GetJSON() const { |
| 2152 v8::HandleScope scope; |
| 2153 |
| 2154 if (IsEvent()) { |
| 2155 // Call toJSONProtocol on the debug event object. |
| 2156 Handle<Object> fun = GetProperty(event_data_, "toJSONProtocol"); |
| 2157 if (!fun->IsJSFunction()) { |
| 2158 return v8::Handle<v8::String>(); |
| 2159 } |
| 2160 bool caught_exception; |
| 2161 Handle<Object> json = Execution::TryCall(Handle<JSFunction>::cast(fun), |
| 2162 event_data_, |
| 2163 0, NULL, &caught_exception); |
| 2164 if (caught_exception || !json->IsString()) { |
| 2165 return v8::Handle<v8::String>(); |
| 2166 } |
| 2167 return scope.Close(v8::Utils::ToLocal(Handle<String>::cast(json))); |
| 2168 } else { |
| 2169 return v8::Utils::ToLocal(response_json_); |
| 2170 } |
| 2171 } |
| 2172 |
| 2173 |
| 2174 v8::Handle<v8::Context> MessageImpl::GetEventContext() const { |
| 2175 return v8::Handle<v8::Context>(); |
| 2176 } |
| 2177 |
| 2178 |
| 2179 v8::Debug::ClientData* MessageImpl::GetClientData() const { |
| 2180 return client_data_; |
| 2181 } |
| 2182 |
| 2183 |
2101 CommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()), | 2184 CommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()), |
2102 client_data_(NULL) { | 2185 client_data_(NULL) { |
2103 } | 2186 } |
2104 | 2187 |
2105 | 2188 |
2106 CommandMessage::CommandMessage(const Vector<uint16_t>& text, | 2189 CommandMessage::CommandMessage(const Vector<uint16_t>& text, |
2107 v8::Debug::ClientData* data) | 2190 v8::Debug::ClientData* data) |
2108 : text_(text), | 2191 : text_(text), |
2109 client_data_(data) { | 2192 client_data_(data) { |
2110 } | 2193 } |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2206 | 2289 |
2207 | 2290 |
2208 void LockingCommandMessageQueue::Clear() { | 2291 void LockingCommandMessageQueue::Clear() { |
2209 ScopedLock sl(lock_); | 2292 ScopedLock sl(lock_); |
2210 queue_.Clear(); | 2293 queue_.Clear(); |
2211 } | 2294 } |
2212 | 2295 |
2213 #endif // ENABLE_DEBUGGER_SUPPORT | 2296 #endif // ENABLE_DEBUGGER_SUPPORT |
2214 | 2297 |
2215 } } // namespace v8::internal | 2298 } } // namespace v8::internal |
OLD | NEW |