Isolate* isolate = JSFunction::cast(fun)->GetIsolate();
Code* apply = isolate->builtins()->builtin(Builtins::kFunctionApply);
Code* call = isolate->builtins()->builtin(Builtins::kFunctionCall);
+ // Find target function on the expression stack for expression like
+ // Function.call.call...apply(...)
+ int i = 1;
while (fun->IsJSFunction()) {
Code* code = JSFunction::cast(fun)->shared()->code();
if (code != apply && code != call) break;
- fun = frame->GetExpression(
- expressions_count - 1 - call_function_arg_count);
+ DCHECK(expressions_count - i - call_function_arg_count >= 0);
+ fun = frame->GetExpression(expressions_count - i -
+ call_function_arg_count);
+ i -= 1;
}
}
}
+// Test that step in works with Function.call.apply.
+TEST(DebugStepFunctionCallApply) {
+ DebugLocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ // Create a function for testing stepping.
+ v8::Local<v8::Function> foo =
+ CompileFunction(&env,
+ "function bar() { }"
+ "function foo(){ debugger;"
+ " Function.call.apply(bar);"
+ " Function.call.apply(Function.call, "
+ "[Function.call, bar]);"
+ "}",
+ "foo");
+
+ // Register a debug event listener which steps and counts.
+ v8::Debug::SetDebugEventListener(DebugEventStep);
+ step_action = StepIn;
+
+ break_point_hit_count = 0;
+ foo->Call(env->Global(), 0, NULL);
+ CHECK_EQ(5, break_point_hit_count);
+
+ v8::Debug::SetDebugEventListener(NULL);
+ CheckDebuggerUnloaded();
+
+ // Register a debug event listener which just counts.
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+
+ break_point_hit_count = 0;
+ foo->Call(env->Global(), 0, NULL);
+
+ // Without stepping only the debugger statement is hit.
+ CHECK_EQ(1, break_point_hit_count);
+
+ v8::Debug::SetDebugEventListener(NULL);
+ CheckDebuggerUnloaded();
+}
+
+
// Tests that breakpoint will be hit if it's set in script.
TEST(PauseInScript) {
DebugLocalContext env;