| Index: test/mjsunit/debug-evaluate.js
|
| ===================================================================
|
| --- test/mjsunit/debug-evaluate.js (revision 2164)
|
| +++ test/mjsunit/debug-evaluate.js (working copy)
|
| @@ -30,7 +30,7 @@
|
| Debug = debug.Debug
|
|
|
| listenerComplete = false;
|
| -exception = false;
|
| +exception = null;
|
|
|
| // The base part of all evaluate requests.
|
| var base_request = '"seq":0,"type":"request","command":"evaluate"'
|
| @@ -75,43 +75,196 @@
|
|
|
| // Test some legal evaluate requests.
|
| testRequest(dcp, '{"expression":"1+2"}', true, 3);
|
| - testRequest(dcp, '{"expression":"a+2"}', true, 5);
|
| + testRequest(dcp, '{"expression":"a+2"}', true, 6);
|
| testRequest(dcp, '{"expression":"({\\"a\\":1,\\"b\\":2}).b+2"}', true, 4);
|
|
|
| // Test evaluation of a in the stack frames and the global context.
|
| - testRequest(dcp, '{"expression":"a"}', true, 3);
|
| - testRequest(dcp, '{"expression":"a","frame":0}', true, 3);
|
| - testRequest(dcp, '{"expression":"a","frame":1}', true, 2);
|
| - testRequest(dcp, '{"expression":"a","frame":2}', true, 1);
|
| + testRequest(dcp, '{"expression":"a"}', true, 4);
|
| + testRequest(dcp, '{"expression":"a","frame":0}', true, 4);
|
| + testRequest(dcp, '{"expression":"a","frame":1}', true, 3);
|
| + testRequest(dcp, '{"expression":"a","frame":2}', true, 2);
|
| + testRequest(dcp, '{"expression":"a","frame":3}', true, 1);
|
| testRequest(dcp, '{"expression":"a","global":true}', true, 1);
|
| testRequest(dcp, '{"expression":"this.a","global":true}', true, 1);
|
|
|
| + // Test mutating variables.
|
| + testRequest(dcp, '{"expression":"b=9","frame":0}', true, 9);
|
| + testRequest(dcp, '{"expression":"b","frame":0}', true, 9);
|
| + testRequest(dcp, '{"expression":"a=8","frame":0}', true, 8);
|
| + testRequest(dcp, '{"expression":"a","frame":0}', true, 8);
|
| + testRequest(dcp, '{"expression":"a=7","frame":1}', true, 7);
|
| + testRequest(dcp, '{"expression":"a","frame":1}', true, 7);
|
| + testRequest(dcp, '{"expression":"a=6","frame":2}', true, 6);
|
| + testRequest(dcp, '{"expression":"a","frame":2}', true, 6);
|
| + testRequest(dcp, '{"expression":"a=5","frame":3}', true, 5);
|
| + testRequest(dcp, '{"expression":"a","frame":3}', true, 5);
|
| +
|
| + // Test mutating arguments.
|
| + testRequest(dcp, '{"expression":"x=-8","frame":0}', true, -8);
|
| + testRequest(dcp, '{"expression":"x","frame":0}', true, -8);
|
| + testRequest(dcp, '{"expression":"x=-7","frame":1}', true, -7);
|
| + testRequest(dcp, '{"expression":"x","frame":1}', true, -7);
|
| + testRequest(dcp, '{"expression":"arguments[1]=\'!g\'","frame":1}', true, '!g');
|
| + testRequest(dcp, '{"expression":"arguments[1]","frame":1}', true, '!g');
|
| + testRequest(dcp, '{"expression":"x=-6","frame":2}', true, -6);
|
| + testRequest(dcp, '{"expression":"x","frame":2}', true, -6);
|
| +
|
| // Indicate that all was processed.
|
| listenerComplete = true;
|
| }
|
| } catch (e) {
|
| - exception = e
|
| + print('Exception in listener: ' + e);
|
| + exception = e;
|
| };
|
| };
|
|
|
| -// Add the debug event listener.
|
| +// Set the debug event listener.
|
| Debug.setListener(listener);
|
|
|
| -function f() {
|
| - var a = 3;
|
| +
|
| +// Function h is in frame 0 in the test.
|
| +function h(x) {
|
| + var a = -1 - x + 1; // This expression avoids optimizing a out.
|
| + eval('var b = 5')
|
| + assertEquals(-4, arguments[0]);
|
| + assertEquals(-3, g.arguments[0]);
|
| + assertEquals('g', g.arguments[1]);
|
| + assertEquals(-2, f.arguments[0]);
|
| +
|
| + debugger;
|
| +
|
| + // Check that the mutation of locals and parameters are visible.
|
| + assertEquals(9, b);
|
| + assertEquals(8, a);
|
| + assertEquals(-8, x);
|
| + assertEquals(-8, eval('x'));
|
| + assertEquals(-8, arguments[0]);
|
| + assertEquals(-8, eval('arguments[0]'));
|
| + assertEquals(-7, g.arguments[0]);
|
| + assertEquals('!g', g.arguments[1]);
|
| + assertEquals(-6, f.arguments[0]);
|
| };
|
|
|
| -function g() {
|
| - var a = 2;
|
| - f();
|
| +
|
| +// Function g is in frame 1 in the test. g is called with more arguments that is
|
| +// in its formal parameter list, but does not itself access arguments
|
| +function g(x) {
|
| + var a = -1 - x + 1; // This expression avoids optimizing a out.
|
| + h(-4);
|
| + assertEquals(7, a);
|
| + assertEquals(-7, x);
|
| };
|
|
|
| +
|
| +// Function f is in frame 2 in the test.
|
| +function f(x) {
|
| + var a = -1 - x + 1; // This expression avoids optimizing a out.
|
| + // Invoke g with an additional parameter to ensure an arguments adapter frame.
|
| + g(-3, 'g');
|
| + assertEquals(6, a);
|
| + assertEquals(-6, x);
|
| + assertEquals(-6, arguments[0]);
|
| +};
|
| +
|
| +
|
| +// Invoke f this will break in the debugger statement in h.
|
| a = 1;
|
| +f(-2);
|
| +assertEquals(5, a);
|
|
|
| -// Set a break point at return in f and invoke g to hit the breakpoint.
|
| -Debug.setBreakPoint(f, 2, 0);
|
| -g();
|
| -
|
| // Make sure that the debug event listener vas invoked.
|
| +assertNull(exception, "exception in listener")
|
| assertTrue(listenerComplete, "listener did not run to completion");
|
| -assertFalse(exception, "exception in listener")
|
| +
|
| +
|
| +// Test that exposes a bug caused by the static analysis assumes that the local
|
| +// x contains a string, however it is mutated by the debugger to be a number,
|
| +// which makes the %StringAdd throw a runtime exception. See code generated by
|
| +// CodeGenerator::GenericBinaryOperation.
|
| +
|
| +// Debug event listener which changes x expected to be 'ab' to 0 (Smi).
|
| +function listener_bug1(event, exec_state, event_data, data) {
|
| + try {
|
| + if (event == Debug.DebugEvent.Break) {
|
| + // Get the debug command processor.
|
| + var dcp = exec_state.debugCommandProcessor();
|
| +
|
| + // Test mutating variables.
|
| + testRequest(dcp, '{"expression":"x","frame":0}', true, 'ab');
|
| + testRequest(dcp, '{"expression":"x=0","frame":0}', true, 0);
|
| + testRequest(dcp, '{"expression":"x","frame":0}', true, 0);
|
| +
|
| + // Indicate that all was processed.
|
| + listenerComplete = true;
|
| + }
|
| + } catch (e) {
|
| + print('Exception in listener_bug1: ' + e);
|
| + exception = e;
|
| + };
|
| +};
|
| +
|
| +
|
| +// Set the debug event listener.
|
| +listenerComplete = false;
|
| +exception = null;
|
| +Debug.setListener(listener_bug1);
|
| +
|
| +function c() {
|
| + var x = 'a' + 'b';
|
| + debugger;
|
| + return x + 'b';
|
| +}
|
| +
|
| +try {
|
| + c();
|
| +} catch (e) {
|
| + // This exception is not supposed to happen!
|
| + assertEquals('illegal access', e);
|
| +}
|
| +
|
| +assertNull(exception, "exception in listener_bug1")
|
| +assertTrue(listenerComplete, "listener_bug1 did not run to completion");
|
| +
|
| +
|
| +// Test that exposes a bug caused by the static analysis assumes that the local
|
| +// x is aliased with the parameter p.
|
| +
|
| +// Debug event listener which changes x expected to be 1 to 2.
|
| +function listener_bug2(event, exec_state, event_data, data) {
|
| + try {
|
| + if (event == Debug.DebugEvent.Break) {
|
| + // Get the debug command processor.
|
| + var dcp = exec_state.debugCommandProcessor();
|
| +
|
| + // Test mutating variables.
|
| + testRequest(dcp, '{"expression":"x","frame":0}', true, 1);
|
| + testRequest(dcp, '{"expression":"x=2","frame":0}', true, 2);
|
| + testRequest(dcp, '{"expression":"x","frame":0}', true, 2);
|
| +
|
| + // Indicate that all was processed.
|
| + listenerComplete = true;
|
| + }
|
| + } catch (e) {
|
| + print('Exception in listener_bug2: ' + e);
|
| + exception = e;
|
| + };
|
| +};
|
| +
|
| +
|
| +// Set the debug event listener.
|
| +listenerComplete = false;
|
| +exception = null;
|
| +Debug.setListener(listener_bug2);
|
| +
|
| +function dd() {}
|
| +function d(p) {
|
| + var x = p;
|
| + dd();
|
| + return x;
|
| +}
|
| +
|
| +Debug.setBreakPoint(d, 2); // Break on dd() call.
|
| +// This assertion should expect 2, not 1!
|
| +assertEquals(1, d(1));
|
| +assertNull(exception, "exception in listener_bug2")
|
| +assertTrue(listenerComplete, "listener_bug2 did not run to completion");
|
|
|