| 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" | |
| 9 #include "src/debug/debug-evaluate.h" | 8 #include "src/debug/debug-evaluate.h" |
| 10 #include "src/debug/debug-frames.h" | 9 #include "src/debug/debug-frames.h" |
| 11 #include "src/debug/debug-scopes.h" | 10 #include "src/debug/debug-scopes.h" |
| 11 #include "src/debug/debug.h" |
| 12 #include "src/frames-inl.h" | 12 #include "src/frames-inl.h" |
| 13 #include "src/interpreter/bytecodes.h" |
| 14 #include "src/interpreter/interpreter.h" |
| 13 #include "src/isolate-inl.h" | 15 #include "src/isolate-inl.h" |
| 14 #include "src/runtime/runtime.h" | 16 #include "src/runtime/runtime.h" |
| 15 | 17 |
| 16 namespace v8 { | 18 namespace v8 { |
| 17 namespace internal { | 19 namespace internal { |
| 18 | 20 |
| 19 RUNTIME_FUNCTION(Runtime_DebugBreak) { | 21 RUNTIME_FUNCTION(Runtime_DebugBreak) { |
| 20 SealHandleScope shs(isolate); | 22 SealHandleScope shs(isolate); |
| 21 DCHECK(args.length() == 0); | 23 DCHECK(args.length() == 1); |
| 24 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); |
| 25 isolate->debug()->set_return_value(value); |
| 26 |
| 22 // Get the top-most JavaScript frame. | 27 // Get the top-most JavaScript frame. |
| 23 JavaScriptFrameIterator it(isolate); | 28 JavaScriptFrameIterator it(isolate); |
| 24 isolate->debug()->Break(args, it.frame()); | 29 isolate->debug()->Break(it.frame()); |
| 25 return isolate->debug()->SetAfterBreakTarget(it.frame()); | 30 |
| 31 isolate->debug()->SetAfterBreakTarget(it.frame()); |
| 32 return *isolate->debug()->return_value(); |
| 33 } |
| 34 |
| 35 RUNTIME_FUNCTION(Runtime_DebugBreakOnBytecode) { |
| 36 SealHandleScope shs(isolate); |
| 37 DCHECK(args.length() == 1); |
| 38 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); |
| 39 isolate->debug()->set_return_value(value); |
| 40 |
| 41 // Get the top-most JavaScript frame. |
| 42 JavaScriptFrameIterator it(isolate); |
| 43 isolate->debug()->Break(it.frame()); |
| 44 |
| 45 // Return the handler from the original bytecode array. |
| 46 DCHECK(it.frame()->is_interpreted()); |
| 47 InterpretedFrame* interpreted_frame = |
| 48 reinterpret_cast<InterpretedFrame*>(it.frame()); |
| 49 SharedFunctionInfo* shared = interpreted_frame->function()->shared(); |
| 50 BytecodeArray* bytecode_array = shared->bytecode_array(); |
| 51 int bytecode_offset = interpreted_frame->GetBytecodeOffset(); |
| 52 interpreter::Bytecode bytecode = |
| 53 interpreter::Bytecodes::FromByte(bytecode_array->get(bytecode_offset)); |
| 54 return isolate->interpreter()->GetBytecodeHandler( |
| 55 bytecode, interpreter::OperandScale::kSingle); |
| 26 } | 56 } |
| 27 | 57 |
| 28 | 58 |
| 29 RUNTIME_FUNCTION(Runtime_HandleDebuggerStatement) { | 59 RUNTIME_FUNCTION(Runtime_HandleDebuggerStatement) { |
| 30 SealHandleScope shs(isolate); | 60 SealHandleScope shs(isolate); |
| 31 DCHECK(args.length() == 0); | 61 DCHECK(args.length() == 0); |
| 32 if (isolate->debug()->break_points_active()) { | 62 if (isolate->debug()->break_points_active()) { |
| 33 isolate->debug()->HandleDebugBreak(); | 63 isolate->debug()->HandleDebugBreak(); |
| 34 } | 64 } |
| 35 return isolate->heap()->undefined_value(); | 65 return isolate->heap()->undefined_value(); |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 // frame or if the frame is optimized it cannot be at a return. | 614 // frame or if the frame is optimized it cannot be at a return. |
| 585 bool at_return = false; | 615 bool at_return = false; |
| 586 if (!is_optimized && index == 0) { | 616 if (!is_optimized && index == 0) { |
| 587 at_return = isolate->debug()->IsBreakAtReturn(it.frame()); | 617 at_return = isolate->debug()->IsBreakAtReturn(it.frame()); |
| 588 } | 618 } |
| 589 | 619 |
| 590 // If positioned just before return find the value to be returned and add it | 620 // If positioned just before return find the value to be returned and add it |
| 591 // to the frame information. | 621 // to the frame information. |
| 592 Handle<Object> return_value = isolate->factory()->undefined_value(); | 622 Handle<Object> return_value = isolate->factory()->undefined_value(); |
| 593 if (at_return) { | 623 if (at_return) { |
| 594 StackFrameIterator it2(isolate); | 624 return_value = isolate->debug()->return_value(); |
| 595 Address internal_frame_sp = NULL; | |
| 596 while (!it2.done()) { | |
| 597 if (it2.frame()->is_internal()) { | |
| 598 internal_frame_sp = it2.frame()->sp(); | |
| 599 } else { | |
| 600 if (it2.frame()->is_java_script()) { | |
| 601 if (it2.frame()->id() == it.frame()->id()) { | |
| 602 // The internal frame just before the JavaScript frame contains the | |
| 603 // value to return on top. A debug break at return will create an | |
| 604 // internal frame to store the return value (eax/rax/r0) before | |
| 605 // entering the debug break exit frame. | |
| 606 if (internal_frame_sp != NULL) { | |
| 607 return_value = | |
| 608 Handle<Object>(Memory::Object_at(internal_frame_sp), isolate); | |
| 609 break; | |
| 610 } | |
| 611 } | |
| 612 } | |
| 613 | |
| 614 // Indicate that the previous frame was not an internal frame. | |
| 615 internal_frame_sp = NULL; | |
| 616 } | |
| 617 it2.Advance(); | |
| 618 } | |
| 619 } | 625 } |
| 620 | 626 |
| 621 // Now advance to the arguments adapter frame (if any). It contains all | 627 // Now advance to the arguments adapter frame (if any). It contains all |
| 622 // the provided parameters whereas the function frame always have the number | 628 // the provided parameters whereas the function frame always have the number |
| 623 // of arguments matching the functions parameters. The rest of the | 629 // of arguments matching the functions parameters. The rest of the |
| 624 // information (except for what is collected above) is the same. | 630 // information (except for what is collected above) is the same. |
| 625 if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) { | 631 if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) { |
| 626 it.AdvanceToArgumentsFrame(); | 632 it.AdvanceToArgumentsFrame(); |
| 627 frame_inspector.SetArgumentsFrame(it.frame()); | 633 frame_inspector.SetArgumentsFrame(it.frame()); |
| 628 } | 634 } |
| (...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1652 return Smi::FromInt(isolate->debug()->is_active()); | 1658 return Smi::FromInt(isolate->debug()->is_active()); |
| 1653 } | 1659 } |
| 1654 | 1660 |
| 1655 | 1661 |
| 1656 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { | 1662 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { |
| 1657 UNIMPLEMENTED(); | 1663 UNIMPLEMENTED(); |
| 1658 return NULL; | 1664 return NULL; |
| 1659 } | 1665 } |
| 1660 } // namespace internal | 1666 } // namespace internal |
| 1661 } // namespace v8 | 1667 } // namespace v8 |
| OLD | NEW |