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 |