js/src/jit-test/tests/debug/Environment-variables.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/jit-test/tests/debug/Environment-variables.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,92 @@
     1.4 +// Comprehensive test of get/setVariable on many kinds of environments and
     1.5 +// bindings.
     1.6 +
     1.7 +load(libdir + "asserts.js");
     1.8 +
     1.9 +var cases = [
    1.10 +    // global bindings and bindings on the global prototype chain
    1.11 +    "x = VAL; @@",
    1.12 +    "var x = VAL; @@",
    1.13 +    "Object.prototype.x = VAL; @@",
    1.14 +
    1.15 +    // let, catch, and comprehension bindings
    1.16 +    "let x = VAL; @@",
    1.17 +    "{ let x = VAL; @@ }",
    1.18 +    "let (x = VAL) { @@ }",
    1.19 +    "try { throw VAL; } catch (x) { @@ }",
    1.20 +    "try { throw VAL; } catch (x) { @@ }",
    1.21 +    "for (let x of [VAL]) { @@ }",
    1.22 +    "for each (let x in [VAL]) { @@ }",
    1.23 +    "switch (0) { default: let x = VAL; @@ }",
    1.24 +    "[function () { @@ }() for (x of [VAL])];",
    1.25 +    // "((function () { @@ })() for (x of [VAL])).next();",  // bug 709367
    1.26 +
    1.27 +    // arguments
    1.28 +    "function f(x) { @@ } f(VAL);",
    1.29 +    "function f([w, x]) { @@ } f([0, VAL]);",
    1.30 +    "function f({v: x}) { @@ } f({v: VAL});",
    1.31 +    "function f([w, {v: x}]) { @@ } f([0, {v: VAL}]);",
    1.32 +
    1.33 +    // bindings in functions
    1.34 +    "function f() { var x = VAL; @@ } f();",
    1.35 +    "function f() { let x = VAL; @@ } f();",
    1.36 +    "function f([x]) { let x = VAL; @@ } f(['fail']);",
    1.37 +    "function f(x) { { let x = VAL; @@ } } f('fail');",
    1.38 +    "function f() { function x() {} x = VAL; @@ } f();",
    1.39 +
    1.40 +    // dynamic bindings
    1.41 +    "function f(s) { eval(s); @@ } f('var x = VAL');",
    1.42 +    "function f(s) { let (x = 'fail') { eval(s); } x = VAL; @@ } f('var x;');",
    1.43 +    "var x = VAL; function f(s) { eval('var x = 0;'); eval(s); @@ } f('delete x;');",
    1.44 +    "function f(obj) { with (obj) { @@ } } f({x: VAL});",
    1.45 +    "function f(obj) { with (obj) { @@ } } f(Object.create({x: VAL}));",
    1.46 +    "function f(b) { if (b) { function x(){} } x = VAL; @@ } f(1);",
    1.47 +];
    1.48 +
    1.49 +var nextval = 1000;
    1.50 +
    1.51 +function test(code, debugStmts, followupStmts) {
    1.52 +    var val = nextval++;
    1.53 +    var hits = 0;
    1.54 +
    1.55 +    var g = newGlobal();
    1.56 +    g.eval("function debugMe() { var x = 'wrong-x'; debugger; }");
    1.57 +    g.capture = null;
    1.58 +
    1.59 +    var dbg = Debugger(g);
    1.60 +    dbg.onDebuggerStatement = function (frame) {
    1.61 +        if (frame.callee !== null && frame.callee.name == 'debugMe')
    1.62 +            frame = frame.older;
    1.63 +        var env = frame.environment.find("x");
    1.64 +        assertEq(env.getVariable("x"), val)
    1.65 +        assertEq(env.setVariable("x", 'ok'), undefined);
    1.66 +        assertEq(env.getVariable("x"), 'ok');
    1.67 +
    1.68 +        // setVariable cannot create new variables.
    1.69 +        assertThrowsInstanceOf(function () { env.setVariable("newVar", 0); }, TypeError);
    1.70 +        hits++;
    1.71 +    };
    1.72 +
    1.73 +    code = code.replace("@@", debugStmts);
    1.74 +    if (followupStmts !== undefined)
    1.75 +        code += " " + followupStmts;
    1.76 +    code = code.replace(/VAL/g, uneval(val));
    1.77 +    g.eval(code);
    1.78 +    assertEq(hits, 1);
    1.79 +}
    1.80 +
    1.81 +for (var s of cases) {
    1.82 +    // Test triggering the debugger right in the scope in which x is bound.
    1.83 +    test(s, "debugger; assertEq(x, 'ok');");
    1.84 +
    1.85 +    // Test calling a function that triggers the debugger.
    1.86 +    test(s, "debugMe(); assertEq(x, 'ok');");
    1.87 +
    1.88 +    // Test triggering the debugger from a scope nested in x's scope.
    1.89 +    test(s, "let (y = 'irrelevant') { (function (z) { let (zz = y) { debugger; }})(); } assertEq(x, 'ok');"),
    1.90 +
    1.91 +    // Test closing over the variable and triggering the debugger later, after
    1.92 +    // leaving the variable's scope.
    1.93 +    test(s, "capture = {dbg: function () { debugger; }, get x() { return x; }};",
    1.94 +            "assertEq(capture.x, VAL); capture.dbg(); assertEq(capture.x, 'ok');");
    1.95 +}

mercurial