Fix step in positions (include various calls and exclude current pc point), add a test
R=yangguo@chromium.org Review URL: https://codereview.chromium.org/22198002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16100 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
5a92a95676
commit
29bb553b1d
@ -409,6 +409,9 @@ bool BreakLocationIterator::IsStepInLocation(Isolate* isolate) {
|
||||
HandleScope scope(debug_info_->GetIsolate());
|
||||
Address target = rinfo()->target_address();
|
||||
Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
|
||||
if (target_code->kind() == Code::STUB) {
|
||||
return target_code->major_key() == CodeStub::CallFunction;
|
||||
}
|
||||
return target_code->is_call_stub() || target_code->is_keyed_call_stub();
|
||||
} else {
|
||||
return false;
|
||||
|
@ -206,10 +206,12 @@ Handle<Object> Execution::TryCall(Handle<JSFunction> func,
|
||||
catcher.SetCaptureMessage(false);
|
||||
*caught_exception = false;
|
||||
|
||||
// Get isolate now, because handle might be persistent
|
||||
// and get destroyed in the next call.
|
||||
Isolate* isolate = func->GetIsolate();
|
||||
Handle<Object> result = Invoke(false, func, receiver, argc, args,
|
||||
caught_exception);
|
||||
|
||||
Isolate* isolate = func->GetIsolate();
|
||||
if (*caught_exception) {
|
||||
ASSERT(catcher.HasCaught());
|
||||
ASSERT(isolate->has_pending_exception());
|
||||
|
@ -12014,8 +12014,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetStepInPositions) {
|
||||
JavaScriptFrameIterator frame_it(isolate, id);
|
||||
JavaScriptFrame* frame = frame_it.frame();
|
||||
|
||||
Handle<JSFunction> fun =
|
||||
Handle<JSFunction>(frame->function());
|
||||
Handle<SharedFunctionInfo> shared =
|
||||
Handle<SharedFunctionInfo>(frame->function()->shared());
|
||||
Handle<SharedFunctionInfo>(fun->shared());
|
||||
|
||||
if (!isolate->debug()->EnsureDebugInfo(shared, fun)) {
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
|
||||
|
||||
int len = 0;
|
||||
@ -12028,12 +12035,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetStepInPositions) {
|
||||
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++;
|
||||
if (break_location_iterator.pc() > frame->pc()) {
|
||||
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();
|
||||
|
142
test/mjsunit/debug-stepin-positions.js
Normal file
142
test/mjsunit/debug-stepin-positions.js
Normal file
@ -0,0 +1,142 @@
|
||||
// Copyright 2008 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Flags: --expose-debug-as debug --nocrankshaft
|
||||
// Get the Debug object exposed from the debug context global object.
|
||||
Debug = debug.Debug
|
||||
|
||||
function DebuggerStatement() {
|
||||
debugger;
|
||||
}
|
||||
|
||||
function TestCase(fun) {
|
||||
var exception = false;
|
||||
var codeSnippet = undefined;
|
||||
var resultPositions = undefined;
|
||||
|
||||
function listener(event, exec_state, event_data, data) {
|
||||
try {
|
||||
if (event == Debug.DebugEvent.Break) {
|
||||
Debug.setListener(null);
|
||||
|
||||
var secondFrame = exec_state.frame(1);
|
||||
codeSnippet = secondFrame.sourceLineText();
|
||||
resultPositions = secondFrame.stepInPositions();
|
||||
}
|
||||
} catch (e) {
|
||||
exception = e
|
||||
}
|
||||
}
|
||||
|
||||
Debug.setListener(listener);
|
||||
|
||||
fun();
|
||||
|
||||
Debug.setListener(null);
|
||||
|
||||
assertTrue(!exception, exception);
|
||||
|
||||
var expectedPositions = {};
|
||||
var markPattern = new RegExp("/\\*#\\*/", "g");
|
||||
|
||||
var matchResult;
|
||||
while ( (matchResult = markPattern.exec(codeSnippet)) ) {
|
||||
expectedPositions[matchResult.index] = true;
|
||||
}
|
||||
|
||||
print(codeSnippet);
|
||||
|
||||
var decoratedResult = codeSnippet;
|
||||
|
||||
function replaceStringRange(s, pos, substitute) {
|
||||
return s.substring(0, pos) + substitute +
|
||||
s.substring(pos + substitute.length);
|
||||
}
|
||||
|
||||
var markLength = 5;
|
||||
var unexpectedPositionFound = false;
|
||||
|
||||
for (var i = 0; i < resultPositions.length; i++) {
|
||||
var col = resultPositions[i].position.column - markLength;
|
||||
if (expectedPositions[col]) {
|
||||
delete expectedPositions[col];
|
||||
decoratedResult = replaceStringRange(decoratedResult, col, "*YES*");
|
||||
} else {
|
||||
decoratedResult = replaceStringRange(decoratedResult, col, "!BAD!");
|
||||
unexpectedPositionFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
print(decoratedResult);
|
||||
|
||||
for (var n in expectedPositions) {
|
||||
assertTrue(false, "Some positions are not reported: " + decoratedResult);
|
||||
break;
|
||||
}
|
||||
assertFalse(unexpectedPositionFound, "Found unexpected position: " +
|
||||
decoratedResult);
|
||||
}
|
||||
|
||||
|
||||
// Test cases.
|
||||
|
||||
// Method calls.
|
||||
var fun = function() {
|
||||
var data = {
|
||||
a: function() {}
|
||||
};
|
||||
var res = [ DebuggerStatement(), data./*#*/a(), data[/*#*/String("a")]/*#*/(), data["a"]/*#*/(), data.a, data["a"] ];
|
||||
};
|
||||
TestCase(fun);
|
||||
|
||||
// Function call on a value.
|
||||
var fun = function() {
|
||||
function g(p) {
|
||||
return g;
|
||||
}
|
||||
var res = [ DebuggerStatement(), /*#*/g(2), /*#*/g(2)/*#*/(3), /*#*/g(0)/*#*/(0)/*#*/(g) ];
|
||||
};
|
||||
TestCase(fun);
|
||||
|
||||
// Local function call, closure function call,
|
||||
// local function construction call.
|
||||
var fun = (function(p) {
|
||||
return function() {
|
||||
function f(a, b) {
|
||||
}
|
||||
var res = /*#*/f(DebuggerStatement(), /*#*/p(/*#*/new f()));
|
||||
};
|
||||
})(Object);
|
||||
TestCase(fun);
|
||||
|
||||
// Global function, global object construction, calls before pause point.
|
||||
var fun = (function(p) {
|
||||
return function() {
|
||||
var res = [ Math.abs(new Object()), DebuggerStatement(), Math./*#*/abs(4), /*#*/new Object()./*#*/toString() ];
|
||||
};
|
||||
})(Object);
|
||||
TestCase(fun);
|
Loading…
Reference in New Issue
Block a user