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