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 +}