| Index: src/runtime/runtime-debug.cc
|
| diff --git a/src/runtime/runtime-debug.cc b/src/runtime/runtime-debug.cc
|
| index 631f5e8153e82538bfc19c170749b78ce836f504..3263a89809c447220fae8b4796f495280967202e 100644
|
| --- a/src/runtime/runtime-debug.cc
|
| +++ b/src/runtime/runtime-debug.cc
|
| @@ -5,11 +5,13 @@
|
| #include "src/runtime/runtime-utils.h"
|
|
|
| #include "src/arguments.h"
|
| -#include "src/debug/debug.h"
|
| #include "src/debug/debug-evaluate.h"
|
| #include "src/debug/debug-frames.h"
|
| #include "src/debug/debug-scopes.h"
|
| +#include "src/debug/debug.h"
|
| #include "src/frames-inl.h"
|
| +#include "src/interpreter/bytecodes.h"
|
| +#include "src/interpreter/interpreter.h"
|
| #include "src/isolate-inl.h"
|
| #include "src/runtime/runtime.h"
|
|
|
| @@ -18,11 +20,39 @@ namespace internal {
|
|
|
| RUNTIME_FUNCTION(Runtime_DebugBreak) {
|
| SealHandleScope shs(isolate);
|
| - DCHECK(args.length() == 0);
|
| + DCHECK(args.length() == 1);
|
| + CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
|
| + isolate->debug()->set_return_value(value);
|
| +
|
| // Get the top-most JavaScript frame.
|
| JavaScriptFrameIterator it(isolate);
|
| - isolate->debug()->Break(args, it.frame());
|
| - return isolate->debug()->SetAfterBreakTarget(it.frame());
|
| + isolate->debug()->Break(it.frame());
|
| +
|
| + isolate->debug()->SetAfterBreakTarget(it.frame());
|
| + return *isolate->debug()->return_value();
|
| +}
|
| +
|
| +RUNTIME_FUNCTION(Runtime_DebugBreakOnBytecode) {
|
| + SealHandleScope shs(isolate);
|
| + DCHECK(args.length() == 1);
|
| + CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
|
| + isolate->debug()->set_return_value(value);
|
| +
|
| + // Get the top-most JavaScript frame.
|
| + JavaScriptFrameIterator it(isolate);
|
| + isolate->debug()->Break(it.frame());
|
| +
|
| + // Return the handler from the original bytecode array.
|
| + DCHECK(it.frame()->is_interpreted());
|
| + InterpretedFrame* interpreted_frame =
|
| + reinterpret_cast<InterpretedFrame*>(it.frame());
|
| + SharedFunctionInfo* shared = interpreted_frame->function()->shared();
|
| + BytecodeArray* bytecode_array = shared->bytecode_array();
|
| + int bytecode_offset = interpreted_frame->GetBytecodeOffset();
|
| + interpreter::Bytecode bytecode =
|
| + interpreter::Bytecodes::FromByte(bytecode_array->get(bytecode_offset));
|
| + return isolate->interpreter()->GetBytecodeHandler(
|
| + bytecode, interpreter::OperandScale::kSingle);
|
| }
|
|
|
|
|
| @@ -591,31 +621,7 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
|
| // to the frame information.
|
| Handle<Object> return_value = isolate->factory()->undefined_value();
|
| if (at_return) {
|
| - StackFrameIterator it2(isolate);
|
| - Address internal_frame_sp = NULL;
|
| - while (!it2.done()) {
|
| - if (it2.frame()->is_internal()) {
|
| - internal_frame_sp = it2.frame()->sp();
|
| - } else {
|
| - if (it2.frame()->is_java_script()) {
|
| - if (it2.frame()->id() == it.frame()->id()) {
|
| - // The internal frame just before the JavaScript frame contains the
|
| - // value to return on top. A debug break at return will create an
|
| - // internal frame to store the return value (eax/rax/r0) before
|
| - // entering the debug break exit frame.
|
| - if (internal_frame_sp != NULL) {
|
| - return_value =
|
| - Handle<Object>(Memory::Object_at(internal_frame_sp), isolate);
|
| - break;
|
| - }
|
| - }
|
| - }
|
| -
|
| - // Indicate that the previous frame was not an internal frame.
|
| - internal_frame_sp = NULL;
|
| - }
|
| - it2.Advance();
|
| - }
|
| + return_value = isolate->debug()->return_value();
|
| }
|
|
|
| // Now advance to the arguments adapter frame (if any). It contains all
|
|
|