js/src/jit-test/tests/debug/Environment-identity-03.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // Two Environments nested in the same runtime scope share the correct tail of their parent chains.
michael@0 2
michael@0 3 // The compiler must be allowed to elide empty scopes and so forth, so this
michael@0 4 // test does not check the number of unshared Environments. Instead, each test
michael@0 5 // case identifies the expected innermost shared scope by the name of a
michael@0 6 // variable in it.
michael@0 7
michael@0 8 var g = newGlobal();
michael@0 9 g.eval("function h() { debugger; }");
michael@0 10 var dbg = Debugger(g);
michael@0 11 var hits, name, shared, unshared;
michael@0 12 dbg.onDebuggerStatement = function (hframe) {
michael@0 13 var frame = hframe.older;
michael@0 14
michael@0 15 // Find name in frame.environment.
michael@0 16 var env, child = null;
michael@0 17 for (env = frame.environment; env !== null; env = env.parent) {
michael@0 18 if (env.names().indexOf(name) != -1)
michael@0 19 break;
michael@0 20 child = env;
michael@0 21 }
michael@0 22 assertEq(env !== null, true, "expected '" + name + "' to be in scope");
michael@0 23 assertEq(env, frame.environment.find(name),
michael@0 24 "env.find should find the same frame as the written out search");
michael@0 25
michael@0 26 if (hits === 0) {
michael@0 27 // First hit.
michael@0 28 shared = env;
michael@0 29 unshared = child;
michael@0 30 } else {
michael@0 31 // Subsequent hit.
michael@0 32 assertEq(env, shared, "the environment containing '" + name + "' should be shared");
michael@0 33 assertEq(child === null || unshared === null || unshared !== child, true,
michael@0 34 "environments nested within the one containing '" + name + "' should not be shared");
michael@0 35 }
michael@0 36 hits++;
michael@0 37 };
michael@0 38
michael@0 39 function test(sharedName, expectedHits, code) {
michael@0 40 hits = 0;
michael@0 41 name = sharedName;
michael@0 42 shared = unshared = undefined;
michael@0 43 g.eval(code);
michael@0 44 assertEq(hits, expectedHits);
michael@0 45 }
michael@0 46
michael@0 47 // Basic test cases.
michael@0 48 //
michael@0 49 // (The stray "a = b" assignments in these tests are to inhibit the flat closure
michael@0 50 // optimization, which Environments expose. There's nothing really wrong with
michael@0 51 // the optimization or with the debugger exposing it, but that's not what we
michael@0 52 // want to test here.)
michael@0 53
michael@0 54 test("q", 2, "var q = function (a) { h(); }; q(1); q(2);");
michael@0 55 test("a", 2, "q = function (a) { (function (b) { h(); a = b; })(2); h(); }; q(1);");
michael@0 56 test("a", 2, "q = function (a) { h(); return function (b) { h(); a = b; }; }; q(1)(2);");
michael@0 57 test("n", 3, "q = function (n) { for (var i = 0; i < n; i++) { let (j = i) { h(); } } }; q(3);");
michael@0 58
michael@0 59 // A function with long dynamic and static chains.
michael@0 60 var N = 80;
michael@0 61
michael@0 62 var code = "function f" + N + "(a" + N + ") {\neval('a0 + a1'); h();\n}\n";
michael@0 63 for (var i = N; --i >= 0;) {
michael@0 64 var call = "f" + (i + 1) + "(a" + i + " - 1);\n";
michael@0 65 code = ("function f" + i + "(a" + i + ") {\n" +
michael@0 66 code +
michael@0 67 call +
michael@0 68 "if (a" + i + " === 0) " + call +
michael@0 69 "}\n");
michael@0 70 }
michael@0 71
michael@0 72 g.eval(code);
michael@0 73 test("a0", 2, "f0(0);");
michael@0 74 test("a17", 2, "f0(17);");
michael@0 75 test("a" + (N-2), 2, "f0(" + (N-2) + ");");
michael@0 76 test("a" + (N-1), 2, "f0(" + (N-1) + ");");
michael@0 77
michael@0 78 // A function with a short dynamic chain and a long static chain.
michael@0 79 N = 60;
michael@0 80
michael@0 81 function DeepStaticShallowDynamic(i, n) {
michael@0 82 var code = "function f" + i + "(a" + i + ") {\n";
michael@0 83 if (i >= n)
michael@0 84 code += "eval('a1 + a2'); h();\n";
michael@0 85 else
michael@0 86 code += "return " + DeepStaticShallowDynamic(i+1, n) + ";\n";
michael@0 87 code += "}";
michael@0 88 return code;
michael@0 89 }
michael@0 90 g.eval(DeepStaticShallowDynamic(1, N));
michael@0 91
michael@0 92 function range(start, stop) {
michael@0 93 for (var i = start; i < stop; i++)
michael@0 94 yield i;
michael@0 95 }
michael@0 96
michael@0 97 function DSSDsplit(s) {
michael@0 98 return ("var mid = f1" + ["(" + i + ")" for (i in range(0, s))].join("") + ";\n" +
michael@0 99 "mid" + ["(" + i + ")" for (i in range(s, N))].join("") + ";\n" +
michael@0 100 "mid" + ["(" + i + ")" for (i in range(s, N))].join("") + ";\n");
michael@0 101 }
michael@0 102
michael@0 103 test("a1", 2, DSSDsplit(1));
michael@0 104 test("a17", 2, DSSDsplit(17));
michael@0 105 test("a" + (N-2), 2, DSSDsplit(N-2));
michael@0 106 test("a" + (N-1), 2, DSSDsplit(N-1));

mercurial