}
+// Handle stepping into a function.
+void Debug::HandleStepIn(Handle<JSFunction> function,
+ Address fp,
+ bool is_constructor) {
+ // If the frame pointer is not supplied by the caller find it.
+ if (fp == 0) {
+ StackFrameIterator it;
+ it.Advance();
+ // For constructor functions skip another frame.
+ if (is_constructor) {
+ ASSERT(it.frame()->is_construct());
+ it.Advance();
+ }
+ fp = it.frame()->fp();
+ }
+
+ // Flood the function with one-shot break points if it is called from where
+ // step into was requested.
+ if (fp == Debug::step_in_fp()) {
+ // Don't allow step into functions in the native context.
+ if (function->context()->global() != Top::context()->builtins()) {
+ Debug::FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
+ }
+ }
+}
+
+
void Debug::ClearStepping() {
// Clear the various stepping setup.
ClearOneShot();
inline static bool has_break_points() { return has_break_points_; }
static bool StepInActive() { return thread_local_.step_into_fp_ != 0; }
+ static void HandleStepIn(Handle<JSFunction> function,
+ Address fp,
+ bool is_constructor);
static Address step_in_fp() { return thread_local_.step_into_fp_; }
static Address* step_in_fp_addr() { return &thread_local_.step_into_fp_; }
if (opt->IsJSFunction()) return opt;
}
- // If performing debug step into then flood this function with one-shot
- // break points if it is called from where step into was requested.
- if (Debug::StepInActive() && fp() == Debug::step_in_fp()) {
+ // Handle stepping into a function if step into is active.
+ if (Debug::StepInActive()) {
// Protect the result in a handle as the debugger can allocate and might
// cause GC.
HandleScope scope;
- Handle<Object> result_handle(result);
- // Don't allow step into functions in the native context.
- if (JSFunction::cast(result)->context()->global() !=
- Top::context()->builtins()) {
- Handle<SharedFunctionInfo> shared(JSFunction::cast(result)->shared());
- Debug::FloodWithOneShot(shared);
- }
- return *result_handle;
+ Handle<JSFunction> function(JSFunction::cast(result));
+ Debug::HandleStepIn(function, fp(), false);
+ return *function;
}
return result;
if (constructor->IsJSFunction()) {
JSFunction* function = JSFunction::cast(constructor);
- // Handle steping into constructors.
+ // Handle steping into constructors if step into is active.
if (Debug::StepInActive()) {
- StackFrameIterator it;
- it.Advance();
- ASSERT(it.frame()->is_construct());
- it.Advance();
- if (it.frame()->fp() == Debug::step_in_fp()) {
- HandleScope scope;
- Debug::FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
- }
+ HandleScope scope;
+ Debug::HandleStepIn(Handle<JSFunction>(function), 0, true);
}
if (function->has_initial_map() &&
break_break_point_hit_count = 0;
g();
-assertEquals(5, break_break_point_hit_count);
+assertEquals(4, break_break_point_hit_count);
// Get rid of the debug event listener.
Debug.removeListener(listener);