OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
6 | 6 |
7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/debug/debug-evaluate.h" | 9 #include "src/debug/debug-evaluate.h" |
10 #include "src/debug/debug-frames.h" | 10 #include "src/debug/debug-frames.h" |
(...skipping 1594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1605 break; | 1605 break; |
1606 } | 1606 } |
1607 } | 1607 } |
1608 } | 1608 } |
1609 | 1609 |
1610 if (found.is_null()) return isolate->heap()->undefined_value(); | 1610 if (found.is_null()) return isolate->heap()->undefined_value(); |
1611 return *Script::GetWrapper(found); | 1611 return *Script::GetWrapper(found); |
1612 } | 1612 } |
1613 | 1613 |
1614 | 1614 |
| 1615 bool DebugStepInIsActive(Debug* debug) { |
| 1616 return debug->is_active() && debug->IsStepping() && |
| 1617 debug->last_step_action() == StepIn; |
| 1618 } |
| 1619 |
| 1620 |
1615 // Check whether debugger is about to step into the callback that is passed | 1621 // Check whether debugger is about to step into the callback that is passed |
1616 // to a built-in function such as Array.forEach. | 1622 // to a built-in function such as Array.forEach. This check is done before |
| 1623 // %DebugPrepareStepInIfStepping and is not strictly necessary. However, if it |
| 1624 // returns false, we can skip %DebugPrepareStepInIfStepping, useful in loops. |
1617 RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) { | 1625 RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) { |
| 1626 SealHandleScope shs(isolate); |
1618 DCHECK(args.length() == 1); | 1627 DCHECK(args.length() == 1); |
1619 Debug* debug = isolate->debug(); | 1628 if (!DebugStepInIsActive(isolate->debug())) { |
1620 if (!debug->is_active() || !debug->IsStepping() || | |
1621 debug->last_step_action() != StepIn) { | |
1622 return isolate->heap()->false_value(); | 1629 return isolate->heap()->false_value(); |
1623 } | 1630 } |
1624 CONVERT_ARG_CHECKED(Object, callback, 0); | 1631 CONVERT_ARG_CHECKED(Object, object, 0); |
| 1632 RUNTIME_ASSERT(object->IsJSFunction() || object->IsJSGeneratorObject()); |
1625 // We do not step into the callback if it's a builtin other than a bound, | 1633 // We do not step into the callback if it's a builtin other than a bound, |
1626 // or not even a function. | 1634 // or not even a function. |
1627 return isolate->heap()->ToBoolean( | 1635 JSFunction* fun; |
1628 callback->IsJSFunction() && | 1636 if (object->IsJSFunction()) { |
1629 (JSFunction::cast(callback)->IsSubjectToDebugging() || | 1637 fun = JSFunction::cast(object); |
1630 JSFunction::cast(callback)->shared()->bound())); | 1638 } else { |
| 1639 fun = JSGeneratorObject::cast(object)->function(); |
| 1640 } |
| 1641 return isolate->heap()->ToBoolean(fun->IsSubjectToDebugging() || |
| 1642 fun->shared()->bound()); |
| 1643 } |
| 1644 |
| 1645 |
| 1646 void FloodDebugSubjectWithOneShot(Debug* debug, Handle<JSFunction> function) { |
| 1647 if (function->IsSubjectToDebugging() || function->shared()->bound()) { |
| 1648 // When leaving the function, step out has been activated, but not performed |
| 1649 // if we do not leave the builtin. To be able to step into the function |
| 1650 // again, we need to clear the step out at this point. |
| 1651 debug->ClearStepOut(); |
| 1652 debug->FloodWithOneShotGeneric(function); |
| 1653 } |
1631 } | 1654 } |
1632 | 1655 |
1633 | 1656 |
1634 // Set one shot breakpoints for the callback function that is passed to a | 1657 // Set one shot breakpoints for the callback function that is passed to a |
1635 // built-in function such as Array.forEach to enable stepping into the callback. | 1658 // built-in function such as Array.forEach to enable stepping into the callback, |
| 1659 // if we are indeed stepping and the callback is subject to debugging. |
1636 RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) { | 1660 RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) { |
1637 DCHECK(args.length() == 1); | 1661 DCHECK(args.length() == 1); |
1638 RUNTIME_ASSERT(isolate->debug()->is_active()); | |
1639 | |
1640 Debug* debug = isolate->debug(); | 1662 Debug* debug = isolate->debug(); |
1641 if (!debug->IsStepping()) return isolate->heap()->undefined_value(); | 1663 if (!DebugStepInIsActive(debug)) return isolate->heap()->undefined_value(); |
1642 | 1664 |
1643 HandleScope scope(isolate); | 1665 HandleScope scope(isolate); |
1644 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); | 1666 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); |
1645 RUNTIME_ASSERT(object->IsJSFunction() || object->IsJSGeneratorObject()); | 1667 RUNTIME_ASSERT(object->IsJSFunction() || object->IsJSGeneratorObject()); |
1646 Handle<JSFunction> fun; | 1668 Handle<JSFunction> fun; |
1647 if (object->IsJSFunction()) { | 1669 if (object->IsJSFunction()) { |
1648 fun = Handle<JSFunction>::cast(object); | 1670 fun = Handle<JSFunction>::cast(object); |
1649 } else { | 1671 } else { |
1650 fun = Handle<JSFunction>( | 1672 fun = Handle<JSFunction>( |
1651 Handle<JSGeneratorObject>::cast(object)->function(), isolate); | 1673 Handle<JSGeneratorObject>::cast(object)->function(), isolate); |
1652 } | 1674 } |
1653 // When leaving the function, step out has been activated, but not performed | 1675 |
1654 // if we do not leave the builtin. To be able to step into the function | 1676 FloodDebugSubjectWithOneShot(debug, fun); |
1655 // again, we need to clear the step out at this point. | |
1656 debug->ClearStepOut(); | |
1657 debug->FloodWithOneShotGeneric(fun); | |
1658 return isolate->heap()->undefined_value(); | 1677 return isolate->heap()->undefined_value(); |
1659 } | 1678 } |
1660 | 1679 |
1661 | 1680 |
1662 RUNTIME_FUNCTION(Runtime_DebugPushPromise) { | 1681 RUNTIME_FUNCTION(Runtime_DebugPushPromise) { |
1663 DCHECK(args.length() == 2); | 1682 DCHECK(args.length() == 3); |
1664 HandleScope scope(isolate); | 1683 HandleScope scope(isolate); |
1665 CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); | 1684 CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); |
1666 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 1); | 1685 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 1); |
| 1686 CONVERT_ARG_HANDLE_CHECKED(Object, handler, 2); |
1667 isolate->PushPromise(promise, function); | 1687 isolate->PushPromise(promise, function); |
| 1688 Debug* debug = isolate->debug(); |
| 1689 if (handler->IsJSFunction() && DebugStepInIsActive(debug)) { |
| 1690 FloodDebugSubjectWithOneShot(debug, Handle<JSFunction>::cast(handler)); |
| 1691 } |
1668 return isolate->heap()->undefined_value(); | 1692 return isolate->heap()->undefined_value(); |
1669 } | 1693 } |
1670 | 1694 |
1671 | 1695 |
1672 RUNTIME_FUNCTION(Runtime_DebugPopPromise) { | 1696 RUNTIME_FUNCTION(Runtime_DebugPopPromise) { |
1673 DCHECK(args.length() == 0); | 1697 DCHECK(args.length() == 0); |
1674 SealHandleScope shs(isolate); | 1698 SealHandleScope shs(isolate); |
1675 isolate->PopPromise(); | 1699 isolate->PopPromise(); |
1676 return isolate->heap()->undefined_value(); | 1700 return isolate->heap()->undefined_value(); |
1677 } | 1701 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1711 return *isolate->factory()->undefined_value(); | 1735 return *isolate->factory()->undefined_value(); |
1712 } | 1736 } |
1713 | 1737 |
1714 | 1738 |
1715 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { | 1739 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { |
1716 UNIMPLEMENTED(); | 1740 UNIMPLEMENTED(); |
1717 return NULL; | 1741 return NULL; |
1718 } | 1742 } |
1719 } // namespace internal | 1743 } // namespace internal |
1720 } // namespace v8 | 1744 } // namespace v8 |
OLD | NEW |