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