From: prybin@chromium.org Date: Tue, 25 Jun 2013 13:42:44 +0000 (+0000) Subject: Provide list of step-in source positions in JS Debug API X-Git-Tag: upstream/4.7.83~13686 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cecbe44e423d1a115122a3b816d4087343052168;p=platform%2Fupstream%2Fv8.git Provide list of step-in source positions in JS Debug API R=yangguo@chromium.org Review URL: https://codereview.chromium.org/15960016 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15322 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/debug.cc b/src/debug.cc index 0ffdd00..6bafe2a 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -390,6 +390,20 @@ void BreakLocationIterator::ClearDebugBreak() { } +bool BreakLocationIterator::IsStepInLocation(Isolate* isolate) { + if (RelocInfo::IsConstructCall(rmode())) { + return true; + } else if (RelocInfo::IsCodeTarget(rmode())) { + HandleScope scope(debug_info_->GetIsolate()); + Address target = rinfo()->target_address(); + Handle target_code(Code::GetCodeFromTargetAddress(target)); + return target_code->is_call_stub() || target_code->is_keyed_call_stub(); + } else { + return false; + } +} + + void BreakLocationIterator::PrepareStepIn(Isolate* isolate) { HandleScope scope(isolate); diff --git a/src/debug.h b/src/debug.h index 467acb9..209d8db 100644 --- a/src/debug.h +++ b/src/debug.h @@ -97,6 +97,7 @@ class BreakLocationIterator { void ClearBreakPoint(Handle break_point_object); void SetOneShot(); void ClearOneShot(); + bool IsStepInLocation(Isolate* isolate); void PrepareStepIn(Isolate* isolate); bool IsExit() const; bool HasBreakPoint(); diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js index e1fd872..a997fce 100644 --- a/src/mirror-debugger.js +++ b/src/mirror-debugger.js @@ -1509,6 +1509,11 @@ FrameDetails.prototype.scopeCount = function() { }; +FrameDetails.prototype.stepInPositionsImpl = function() { + return %GetStepInPositions(this.break_id_, this.frameId()); +}; + + /** * Mirror object for stack frames. * @param {number} break_id The break id in the VM for which this frame is @@ -1669,6 +1674,29 @@ FrameMirror.prototype.scope = function(index) { }; +FrameMirror.prototype.stepInPositions = function() { + var script = this.func().script(); + var funcOffset = this.func().sourcePosition_(); + + var stepInRaw = this.details_.stepInPositionsImpl(); + var result = []; + if (stepInRaw) { + for (var i = 0; i < stepInRaw.length; i++) { + var posStruct = {}; + var offset = script.locationFromPosition(funcOffset + stepInRaw[i], + true); + serializeLocationFields(offset, posStruct); + var item = { + position: posStruct + }; + result.push(item); + } + } + + return result; +}; + + FrameMirror.prototype.evaluate = function(source, disable_break, opt_context_object) { var result = %DebugEvaluate(this.break_id_, diff --git a/src/runtime.cc b/src/runtime.cc index 02a97e2..e42a9db 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -11778,6 +11778,58 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) { } +// Returns the list of step-in positions (text offset) in a function of the +// stack frame in a range from the current debug break position to the end +// of the corresponding statement. +RUNTIME_FUNCTION(MaybeObject*, Runtime_GetStepInPositions) { + HandleScope scope(isolate); + ASSERT(args.length() == 2); + + // Check arguments. + Object* check; + { MaybeObject* maybe_check = Runtime_CheckExecutionState( + RUNTIME_ARGUMENTS(isolate, args)); + if (!maybe_check->ToObject(&check)) return maybe_check; + } + CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); + + // Get the frame where the debugging is performed. + StackFrame::Id id = UnwrapFrameId(wrapped_id); + JavaScriptFrameIterator frame_it(isolate, id); + JavaScriptFrame* frame = frame_it.frame(); + + Handle shared = + Handle(JSFunction::cast(frame->function())->shared()); + Handle debug_info = Debug::GetDebugInfo(shared); + + int len = 0; + Handle array(isolate->factory()->NewJSArray(10)); + // Find the break point where execution has stopped. + BreakLocationIterator break_location_iterator(debug_info, + ALL_BREAK_LOCATIONS); + + break_location_iterator.FindBreakLocationFromAddress(frame->pc()); + int current_statement_pos = break_location_iterator.statement_position(); + + while (!break_location_iterator.Done()) { + if (break_location_iterator.IsStepInLocation(isolate)) { + Smi* position_value = Smi::FromInt(break_location_iterator.position()); + JSObject::SetElement(array, len, + Handle(position_value, isolate), + NONE, kNonStrictMode); + len++; + } + // Advance iterator. + break_location_iterator.Next(); + if (current_statement_pos != + break_location_iterator.statement_position()) { + break; + } + } + return *array; +} + + static const int kScopeDetailsTypeIndex = 0; static const int kScopeDetailsObjectIndex = 1; static const int kScopeDetailsSize = 2; diff --git a/src/runtime.h b/src/runtime.h index 9502631..4928e78 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -490,6 +490,7 @@ namespace internal { F(GetFrameCount, 1, 1) \ F(GetFrameDetails, 2, 1) \ F(GetScopeCount, 2, 1) \ + F(GetStepInPositions, 2, 1) \ F(GetScopeDetails, 4, 1) \ F(GetFunctionScopeCount, 1, 1) \ F(GetFunctionScopeDetails, 2, 1) \