From 26aaa3b005824396987101fec717f37970cb51ab Mon Sep 17 00:00:00 2001 From: "pfeldman@chromium.org" Date: Thu, 15 Mar 2012 14:17:22 +0000 Subject: [PATCH] Debugger: naive implementation of "step into Function.prototype.bind". Review URL: https://chromiumcodereview.appspot.com/9705018 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11058 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/debug.cc | 25 +++++++++++++++++++++---- src/debug.h | 1 + test/mjsunit/debug-stepin-function-call.js | 17 ++++++++++++++++- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/debug.cc b/src/debug.cc index 2058d48..01f6f39 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -1223,6 +1223,18 @@ void Debug::FloodWithOneShot(Handle shared) { } +void Debug::FloodBoundFunctionWithOneShot(Handle function) { + Handle new_bindings(function->function_bindings()); + Handle bindee(new_bindings->get(JSFunction::kBoundFunctionIndex)); + + if (!bindee.is_null() && bindee->IsJSFunction() && + !JSFunction::cast(*bindee)->IsBuiltin()) { + Handle shared_info(JSFunction::cast(*bindee)->shared()); + Debug::FloodWithOneShot(shared_info); + } +} + + void Debug::FloodHandlerWithOneShot() { // Iterate through the JavaScript stack looking for handlers. StackFrame::Id id = break_frame_id(); @@ -1442,8 +1454,10 @@ void Debug::PrepareStep(StepAction step_action, int step_count) { expressions_count - 2 - call_function_arg_count); if (fun->IsJSFunction()) { Handle js_function(JSFunction::cast(fun)); - // Don't step into builtins. - if (!js_function->IsBuiltin()) { + if (js_function->shared()->bound()) { + Debug::FloodBoundFunctionWithOneShot(js_function); + } else if (!js_function->IsBuiltin()) { + // Don't step into builtins. // It will also compile target function if it's not compiled yet. FloodWithOneShot(Handle(js_function->shared())); } @@ -1639,8 +1653,11 @@ void Debug::HandleStepIn(Handle function, // Flood the function with one-shot break points if it is called from where // step into was requested. if (fp == step_in_fp()) { - // Don't allow step into functions in the native context. - if (!function->IsBuiltin()) { + if (function->shared()->bound()) { + // Handle Function.prototype.bind + Debug::FloodBoundFunctionWithOneShot(function); + } else if (!function->IsBuiltin()) { + // Don't allow step into functions in the native context. if (function->shared()->code() == Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply) || function->shared()->code() == diff --git a/src/debug.h b/src/debug.h index b9384e5..474b90b 100644 --- a/src/debug.h +++ b/src/debug.h @@ -239,6 +239,7 @@ class Debug { void ClearBreakPoint(Handle break_point_object); void ClearAllBreakPoints(); void FloodWithOneShot(Handle shared); + void FloodBoundFunctionWithOneShot(Handle function); void FloodHandlerWithOneShot(); void ChangeBreakOnException(ExceptionBreakType type, bool enable); bool IsBreakOnException(ExceptionBreakType type); diff --git a/test/mjsunit/debug-stepin-function-call.js b/test/mjsunit/debug-stepin-function-call.js index 385fcb2..3b5240c 100644 --- a/test/mjsunit/debug-stepin-function-call.js +++ b/test/mjsunit/debug-stepin-function-call.js @@ -135,8 +135,15 @@ function apply4() { var yetAnotherLocal = 10; } +// Test step into bound function. +function bind1() { + var bound = g.bind(null, 3); + debugger; + bound(); +} + var testFunctions = - [call1, call2, call3, call4, apply1, apply2, apply3, apply4]; + [call1, call2, call3, call4, apply1, apply2, apply3, apply4, bind1]; for (var i = 0; i < testFunctions.length; i++) { state = 0; @@ -145,5 +152,13 @@ for (var i = 0; i < testFunctions.length; i++) { assertEquals(3, state); } +// Test global bound function. +state = 0; +var globalBound = g.bind(null, 3); +debugger; +globalBound(); +assertNull(exception); +assertEquals(3, state); + // Get rid of the debug event listener. Debug.setListener(null); \ No newline at end of file -- 2.7.4