if (!bindee.is_null() && bindee->IsJSFunction() &&
!JSFunction::cast(*bindee)->IsFromNativeScript()) {
Handle<JSFunction> bindee_function(JSFunction::cast(*bindee));
- FloodWithOneShot(bindee_function);
+ FloodWithOneShotGeneric(bindee_function);
+ }
+}
+
+
+void Debug::FloodDefaultConstructorWithOneShot(Handle<JSFunction> function) {
+ DCHECK(function->shared()->is_default_constructor());
+ // Instead of stepping into the function we directly step into the super class
+ // constructor.
+ Isolate* isolate = function->GetIsolate();
+ PrototypeIterator iter(isolate, function);
+ Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
+ if (!proto->IsJSFunction()) return; // Object.prototype
+ Handle<JSFunction> function_proto = Handle<JSFunction>::cast(proto);
+ FloodWithOneShotGeneric(function_proto);
+}
+
+
+void Debug::FloodWithOneShotGeneric(Handle<JSFunction> function,
+ Handle<Object> holder) {
+ if (function->shared()->bound()) {
+ FloodBoundFunctionWithOneShot(function);
+ } else if (function->shared()->is_default_constructor()) {
+ FloodDefaultConstructorWithOneShot(function);
+ } else if (!function->IsFromNativeScript()) {
+ Isolate* isolate = function->GetIsolate();
+ // Don't allow step into functions in the native context.
+ if (function->shared()->code() ==
+ isolate->builtins()->builtin(Builtins::kFunctionApply) ||
+ function->shared()->code() ==
+ isolate->builtins()->builtin(Builtins::kFunctionCall)) {
+ // Handle function.apply and function.call separately to flood the
+ // function to be called and not the code for Builtins::FunctionApply or
+ // Builtins::FunctionCall. The receiver of call/apply is the target
+ // function.
+ if (!holder.is_null() && holder->IsJSFunction()) {
+ Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder);
+ FloodWithOneShotGeneric(js_function);
+ }
+ } else {
+ FloodWithOneShot(function);
+ }
}
}
if (fun->IsJSFunction()) {
Handle<JSFunction> js_function(JSFunction::cast(fun));
- if (js_function->shared()->bound()) {
- FloodBoundFunctionWithOneShot(js_function);
- } else if (!js_function->IsFromNativeScript()) {
- // Don't step into builtins.
- // It will also compile target function if it's not compiled yet.
- FloodWithOneShot(js_function);
- }
+ FloodWithOneShotGeneric(js_function);
}
}
// Flood the function with one-shot break points if it is called from where
// step into was requested, or when stepping into a new frame.
if (fp == thread_local_.step_into_fp_ || step_frame) {
- if (function->shared()->bound()) {
- // Handle Function.prototype.bind
- FloodBoundFunctionWithOneShot(function);
- } else if (!function->IsFromNativeScript()) {
- // Don't allow step into functions in the native context.
- if (function->shared()->code() ==
- isolate->builtins()->builtin(Builtins::kFunctionApply) ||
- function->shared()->code() ==
- isolate->builtins()->builtin(Builtins::kFunctionCall)) {
- // Handle function.apply and function.call separately to flood the
- // function to be called and not the code for Builtins::FunctionApply or
- // Builtins::FunctionCall. The receiver of call/apply is the target
- // function.
- if (!holder.is_null() && holder->IsJSFunction()) {
- Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder);
- if (!js_function->IsFromNativeScript()) {
- FloodWithOneShot(js_function);
- } else if (js_function->shared()->bound()) {
- // Handle Function.prototype.bind
- FloodBoundFunctionWithOneShot(js_function);
- }
- }
- } else {
- FloodWithOneShot(function);
- }
- }
+ FloodWithOneShotGeneric(function, holder);
}
}
--- /dev/null
+// Copyright 2014 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 --harmony-classes
+
+'use strict';
+
+var Debug = debug.Debug
+
+var done = false;
+var stepCount = 0;
+
+function listener(event, execState, eventData, data) {
+ if (event == Debug.DebugEvent.Break) {
+ if (!done) {
+ execState.prepareStep(Debug.StepAction.StepInto);
+ var s = execState.frame().sourceLineText();
+ assertTrue(s.indexOf('// ' + stepCount + '.') !== -1);
+ stepCount++;
+ }
+ }
+};
+
+Debug.setListener(listener);
+
+function GetBase() {
+ var x = 1; // 1.
+ var y = 2; // 2.
+ done = true; // 3.
+ return null;
+}
+
+function f() {
+ class Derived extends GetBase() {} // 0.
+}
+
+var bp = Debug.setBreakPoint(f, 0);
+f();
+assertEquals(4, stepCount);
+
+Debug.setListener(null);
--- /dev/null
+// Copyright 2014 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 --harmony-classes
+
+'use strict';
+
+var Debug = debug.Debug
+var done, stepCount;
+
+function listener(event, execState, eventData, data) {
+ if (event == Debug.DebugEvent.Break) {
+ if (!done) {
+ execState.prepareStep(Debug.StepAction.StepInto);
+ var s = execState.frame().sourceLineText();
+ assertTrue(s.indexOf('// ' + stepCount + '.') !== -1);
+ stepCount++;
+ }
+ }
+};
+
+Debug.setListener(listener);
+
+
+class Base {
+ constructor() {
+ var x = 1; // 1.
+ var y = 2; // 2.
+ done = true; // 3.
+ }
+}
+
+class Derived extends Base {}
+
+
+(function TestBreakPointInConstructor() {
+ done = false;
+ stepCount = 1;
+ var bp = Debug.setBreakPoint(Base, 0);
+
+ new Base();
+ assertEquals(4, stepCount);
+
+ Debug.clearBreakPoint(bp);
+})();
+
+
+(function TestDefaultConstructor() {
+ done = false;
+ stepCount = 1;
+
+ var bp = Debug.setBreakPoint(Base, 0);
+ new Derived();
+ assertEquals(4, stepCount);
+
+ Debug.clearBreakPoint(bp);
+})();
+
+
+(function TestStepInto() {
+ done = false;
+ stepCount = 0;
+
+ function f() {
+ new Derived(); // 0.
+ }
+
+ var bp = Debug.setBreakPoint(f, 0);
+ f();
+ assertEquals(4, stepCount);
+
+ Debug.clearBreakPoint(bp);
+})();
+
+
+(function TestExtraIndirection() {
+ done = false;
+ stepCount = 0;
+
+ class Derived2 extends Derived {}
+
+ function f() {
+ new Derived2(); // 0.
+ }
+
+ var bp = Debug.setBreakPoint(f, 0);
+ f();
+ assertEquals(4, stepCount);
+
+ Debug.clearBreakPoint(bp);
+})();
+
+
+(function TestBoundClass() {
+ done = false;
+ stepCount = 0;
+
+ var bound = Derived.bind(null);
+
+ function f() {
+ new bound(); // 0.
+ }
+
+ var bp = Debug.setBreakPoint(f, 0);
+ f();
+ assertEquals(4, stepCount);
+
+ Debug.clearBreakPoint(bp);
+})();
+
+
+Debug.setListener(null);