Commit fc168939 authored by aandrey's avatar aandrey Committed by Commit bot

Make debugger step into bound callbacks passed to Array.forEach.

BUG=chromium:450004
R=yangguo@chromium.org, kozyatinskiy@chromium.org
LOG=N

Review URL: https://codereview.chromium.org/1030673002

Cr-Commit-Position: refs/heads/master@{#27419}
parent 82004a5e
...@@ -2738,7 +2738,7 @@ RUNTIME_FUNCTION(Runtime_GetScript) { ...@@ -2738,7 +2738,7 @@ RUNTIME_FUNCTION(Runtime_GetScript) {
} }
// Check whether debugger and is about to step into the callback that is passed // Check whether debugger is about to step into the callback that is passed
// to a built-in function such as Array.forEach. // to a built-in function such as Array.forEach.
RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) { RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) {
DCHECK(args.length() == 1); DCHECK(args.length() == 1);
...@@ -2748,9 +2748,12 @@ RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) { ...@@ -2748,9 +2748,12 @@ RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) {
return isolate->heap()->false_value(); return isolate->heap()->false_value();
} }
CONVERT_ARG_CHECKED(Object, callback, 0); CONVERT_ARG_CHECKED(Object, callback, 0);
// We do not step into the callback if it's a builtin or not even a function. // We do not step into the callback if it's a builtin other than a bound,
return isolate->heap()->ToBoolean(callback->IsJSFunction() && // or not even a function.
!JSFunction::cast(callback)->IsBuiltin()); return isolate->heap()->ToBoolean(
callback->IsJSFunction() &&
(!JSFunction::cast(callback)->IsBuiltin() ||
JSFunction::cast(callback)->shared()->bound()));
} }
...@@ -2775,7 +2778,7 @@ RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) { ...@@ -2775,7 +2778,7 @@ RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
// if we do not leave the builtin. To be able to step into the function // if we do not leave the builtin. To be able to step into the function
// again, we need to clear the step out at this point. // again, we need to clear the step out at this point.
debug->ClearStepOut(); debug->ClearStepOut();
debug->FloodWithOneShot(fun); debug->FloodWithOneShotGeneric(fun);
return isolate->heap()->undefined_value(); return isolate->heap()->undefined_value();
} }
......
...@@ -37,15 +37,17 @@ function listener(event, exec_state, event_data, data) { ...@@ -37,15 +37,17 @@ function listener(event, exec_state, event_data, data) {
}; };
Debug.setListener(listener); Debug.setListener(listener);
var bound_callback = callback.bind(null);
debugger; // Break 0. debugger; // Break 0.
[1,2].forEach(callback); // Break 1. [1,2].forEach(callback); // Break 1.
[3,4].forEach(bound_callback); // Break 6.
function callback(x) { function callback(x) {
return x; // Break 2. // Break 4. return x; // Break 2. // Break 4. // Break 7. // Break 9.
} // Break 3. // Break 5. } // Break 3. // Break 5. // Break 8. // Break 10.
assertNull(exception); // Break 6. assertNull(exception); // Break 11.
assertEquals(expected_breaks, break_count); assertEquals(expected_breaks, break_count);
Debug.setListener(null); Debug.setListener(null);
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-debug-as debug --allow-natives-syntax --noalways-opt
// Tests stepping into through Promises.
Debug = debug.Debug
var exception = null;
var break_count = 0;
var expected_breaks = -1;
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Break) {
assertTrue(exec_state.frameCount() != 0, "FAIL: Empty stack trace");
if (!break_count) {
// Count number of expected breakpoints in this source file.
var source_text = exec_state.frame(0).func().script().source();
expected_breaks = source_text.match(/\/\/\s*Break\s+\d+\./g).length;
print("Expected breaks: " + expected_breaks);
}
var source = exec_state.frame(0).sourceLineText();
print("paused at: " + source);
assertTrue(source.indexOf("// Break " + break_count + ".") > 0,
"Unexpected pause at: " + source + "\n" +
"Expected: // Break " + break_count + ".");
++break_count;
if (break_count !== expected_breaks) {
exec_state.prepareStep(Debug.StepAction.StepIn, 1);
}
}
} catch(e) {
exception = e;
print(e, e.stack);
}
};
Debug.setListener(listener);
Promise.resolve(42)
.then(
function f0() {
debugger; // Break 0.
} // Break 1.
)
.then(callback)
.then(callback.bind(null))
.then(Object)
.then(callback.bind(null).bind(null))
.then(finalize)
.catch(function(err) {
%AbortJS("FAIL: " + err);
});
function callback(x) {
return x; // Break 2. // Break 4. // Break 6.
} // Break 3. // Break 5. // Break 7.
function finalize() {
assertNull(exception); // Break 8.
assertEquals(expected_breaks, break_count);
Debug.setListener(null);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment