Commit cecbe44e authored by prybin@chromium.org's avatar prybin@chromium.org

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
parent 9f05d61a
...@@ -390,6 +390,20 @@ void BreakLocationIterator::ClearDebugBreak() { ...@@ -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<Code> 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) { void BreakLocationIterator::PrepareStepIn(Isolate* isolate) {
HandleScope scope(isolate); HandleScope scope(isolate);
......
...@@ -97,6 +97,7 @@ class BreakLocationIterator { ...@@ -97,6 +97,7 @@ class BreakLocationIterator {
void ClearBreakPoint(Handle<Object> break_point_object); void ClearBreakPoint(Handle<Object> break_point_object);
void SetOneShot(); void SetOneShot();
void ClearOneShot(); void ClearOneShot();
bool IsStepInLocation(Isolate* isolate);
void PrepareStepIn(Isolate* isolate); void PrepareStepIn(Isolate* isolate);
bool IsExit() const; bool IsExit() const;
bool HasBreakPoint(); bool HasBreakPoint();
......
...@@ -1509,6 +1509,11 @@ FrameDetails.prototype.scopeCount = function() { ...@@ -1509,6 +1509,11 @@ FrameDetails.prototype.scopeCount = function() {
}; };
FrameDetails.prototype.stepInPositionsImpl = function() {
return %GetStepInPositions(this.break_id_, this.frameId());
};
/** /**
* Mirror object for stack frames. * Mirror object for stack frames.
* @param {number} break_id The break id in the VM for which this frame is * @param {number} break_id The break id in the VM for which this frame is
...@@ -1669,6 +1674,29 @@ FrameMirror.prototype.scope = function(index) { ...@@ -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, FrameMirror.prototype.evaluate = function(source, disable_break,
opt_context_object) { opt_context_object) {
var result = %DebugEvaluate(this.break_id_, var result = %DebugEvaluate(this.break_id_,
......
...@@ -11778,6 +11778,58 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) { ...@@ -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<SharedFunctionInfo> shared =
Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());
Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
int len = 0;
Handle<JSArray> 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<Object>(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 kScopeDetailsTypeIndex = 0;
static const int kScopeDetailsObjectIndex = 1; static const int kScopeDetailsObjectIndex = 1;
static const int kScopeDetailsSize = 2; static const int kScopeDetailsSize = 2;
......
...@@ -490,6 +490,7 @@ namespace internal { ...@@ -490,6 +490,7 @@ namespace internal {
F(GetFrameCount, 1, 1) \ F(GetFrameCount, 1, 1) \
F(GetFrameDetails, 2, 1) \ F(GetFrameDetails, 2, 1) \
F(GetScopeCount, 2, 1) \ F(GetScopeCount, 2, 1) \
F(GetStepInPositions, 2, 1) \
F(GetScopeDetails, 4, 1) \ F(GetScopeDetails, 4, 1) \
F(GetFunctionScopeCount, 1, 1) \ F(GetFunctionScopeCount, 1, 1) \
F(GetFunctionScopeDetails, 2, 1) \ F(GetFunctionScopeDetails, 2, 1) \
......
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