Skip to content

Commit

Permalink
Handle symbols in FrameMirror#invocationText().
Browse files Browse the repository at this point in the history
Fix a TypeError when putting together the invocationText for a symbol
method's stack frame.

See nodejs/node#7536.

Review-Url: https://codereview.chromium.org/2122793003
Cr-Commit-Position: refs/heads/master@{#37597}
  • Loading branch information
ben authored and Commit bot committed Jul 7, 2016
1 parent 62c950b commit 1f53e42
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 28 deletions.
10 changes: 8 additions & 2 deletions src/debug/mirrors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,12 @@ PropertyMirror.prototype.name = function() {
};


PropertyMirror.prototype.toText = function() {
if (IS_SYMBOL(this.name_)) return %SymbolDescriptiveString(this.name_);
return this.name_;
};


PropertyMirror.prototype.isIndexed = function() {
for (var i = 0; i < this.name_.length; i++) {
if (this.name_[i] < '0' || '9' < this.name_[i]) {
Expand Down Expand Up @@ -2034,10 +2040,10 @@ FrameMirror.prototype.invocationText = function() {
if (display_receiver) {
result += '.';
}
result += property.name();
result += property.toText();
} else {
result += '[';
result += property.name();
result += property.toText();
result += ']';
}
// Also known as - if the name in the function doesn't match the name
Expand Down
80 changes: 54 additions & 26 deletions test/mjsunit/debug-backtrace-text.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ function Point(x, y) {

Point.prototype.distanceTo = function(p) {
debugger;
return Math.sqrt(Math.pow(Math.abs(this.x - p.x), 2) + Math.pow(Math.abs(this.y - p.y), 2))
return Math.sqrt(Math.pow(Math.abs(this.x - p.x), 2) +
Math.pow(Math.abs(this.y - p.y), 2))
}

p1 = new Point(1,1);
Expand All @@ -58,7 +59,7 @@ a=[1,2,distance];
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug

testConstructor = false; // Flag to control which part of the test is run.
what = 'constructor'; // Flag to control which part of the test is run.
listenerCalled = false;
exception = false;

Expand All @@ -72,30 +73,47 @@ function safeEval(code) {

function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Break)
{
if (!testConstructor) {
// The expected backtrace is
// 0: Call distance on Point where distance is a property on the prototype
// 1: Call distance on Point where distance is a direct property
// 2: Call on function an array element 2
// 3: [anonymous]
assertEquals("#<Point>.distanceTo(p=#<Point>)", exec_state.frame(0).invocationText());
assertEquals("#<Point>.distanceTo(p=#<Point>)", exec_state.frame(1).invocationText());
assertEquals("#<Array>[2](aka distance)(p=#<Point>, q=#<Point>)", exec_state.frame(2).invocationText());
assertEquals("[anonymous]()", exec_state.frame(3).invocationText());
listenerCalled = true;
} else {
// The expected backtrace is
// 0: Call Point constructor
// 1: Call on global function createPoint
// 2: [anonymous]
assertEquals("new Point(x=0, y=0)", exec_state.frame(0).invocationText());
assertEquals("createPoint(x=0, y=0)", exec_state.frame(1).invocationText());
assertEquals("[anonymous]()", exec_state.frame(2).invocationText());
listenerCalled = true;
if (event == Debug.DebugEvent.Break) {
if (what == 'constructor') {
// The expected backtrace is
// 0: Call distance on Point where distance is a prototype property
// 1: Call distance on Point where distance is a direct property
// 2: Call on function an array element 2
// 3: [anonymous]
assertEquals("#<Point>.distanceTo(p=#<Point>)",
exec_state.frame(0).invocationText());
assertEquals("#<Point>.distanceTo(p=#<Point>)",
exec_state.frame(1).invocationText());
assertEquals("#<Array>[2](aka distance)(p=#<Point>, q=#<Point>)",
exec_state.frame(2).invocationText());
assertEquals("[anonymous]()", exec_state.frame(3).invocationText());
listenerCalled = true;
} else if (what == 'breakpoint') {
// The expected backtrace is
// 0: Call Point constructor
// 1: Call on global function createPoint
// 2: [anonymous]
assertEquals("new Point(x=0, y=0)",
exec_state.frame(0).invocationText());
assertEquals("createPoint(x=0, y=0)",
exec_state.frame(1).invocationText());
assertEquals("[anonymous]()", exec_state.frame(2).invocationText());
listenerCalled = true;
} else if (what == 'symbol') {
// The expected backtrace is
// 0: Call Point constructor
// 1: Call on symbol method
// 2: [anonymous]
assertEquals("new Point(x=0, y=0)",
exec_state.frame(0).invocationText());
assertEquals("#<Object>[Symbol(Das Symbol)](x=0, y=0)",
exec_state.frame(1).invocationText());
assertEquals("[anonymous]()", exec_state.frame(2).invocationText());
listenerCalled = true;
} else {
assertUnreachable();
}
}
}
} catch (e) {
exception = e
};
Expand All @@ -112,11 +130,21 @@ assertTrue(listenerCalled);
assertFalse(exception, "exception in listener")

// Set a break point and call to invoke the debug event listener.
what = 'breakpoint';
listenerCalled = false;
testConstructor = true;
Debug.setBreakPoint(Point, 0, 0);
createPoint(0, 0);

// Make sure that the debug event listener vas invoked (again).
assertTrue(listenerCalled);
assertFalse(exception, "exception in listener")

what = 'symbol';
listenerCalled = false;
var S = Symbol('Das Symbol');
var o = { [S](x, y) { return new Point(x, y); } };
Debug.setBreakPoint(Point, 0, 0);
o[S](0, 0);

assertTrue(listenerCalled);
assertFalse(exception, "exception in listener")

0 comments on commit 1f53e42

Please sign in to comment.