js/src/jit-test/tests/debug/Environment-identity-03.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-identity-03.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,106 @@
     1.4 +// Two Environments nested in the same runtime scope share the correct tail of their parent chains.
     1.5 +
     1.6 +// The compiler must be allowed to elide empty scopes and so forth, so this
     1.7 +// test does not check the number of unshared Environments. Instead, each test
     1.8 +// case identifies the expected innermost shared scope by the name of a
     1.9 +// variable in it.
    1.10 +
    1.11 +var g = newGlobal();
    1.12 +g.eval("function h() { debugger; }");
    1.13 +var dbg = Debugger(g);
    1.14 +var hits, name, shared, unshared;
    1.15 +dbg.onDebuggerStatement = function (hframe) {
    1.16 +    var frame = hframe.older;
    1.17 +
    1.18 +    // Find name in frame.environment.
    1.19 +    var env, child = null;
    1.20 +    for (env = frame.environment; env !== null; env = env.parent) {
    1.21 +        if (env.names().indexOf(name) != -1)
    1.22 +            break;
    1.23 +        child = env;
    1.24 +    }
    1.25 +    assertEq(env !== null, true, "expected '" + name + "' to be in scope");
    1.26 +    assertEq(env, frame.environment.find(name),
    1.27 +             "env.find should find the same frame as the written out search");
    1.28 +
    1.29 +    if (hits === 0) {
    1.30 +        // First hit.
    1.31 +        shared = env;
    1.32 +        unshared = child;
    1.33 +    } else {
    1.34 +        // Subsequent hit.
    1.35 +        assertEq(env, shared, "the environment containing '" + name + "' should be shared");
    1.36 +        assertEq(child === null || unshared === null || unshared !== child, true,
    1.37 +                "environments nested within the one containing '" + name + "' should not be shared");
    1.38 +    }
    1.39 +    hits++;
    1.40 +};
    1.41 +
    1.42 +function test(sharedName, expectedHits, code) {
    1.43 +    hits = 0;
    1.44 +    name = sharedName;
    1.45 +    shared = unshared = undefined;
    1.46 +    g.eval(code);
    1.47 +    assertEq(hits, expectedHits);
    1.48 +}
    1.49 +
    1.50 +// Basic test cases.
    1.51 +//
    1.52 +// (The stray "a = b" assignments in these tests are to inhibit the flat closure
    1.53 +// optimization, which Environments expose. There's nothing really wrong with
    1.54 +// the optimization or with the debugger exposing it, but that's not what we
    1.55 +// want to test here.)
    1.56 +
    1.57 +test("q", 2, "var q = function (a) { h(); }; q(1); q(2);");
    1.58 +test("a", 2, "q = function (a) { (function (b) { h(); a = b; })(2); h(); }; q(1);");
    1.59 +test("a", 2, "q = function (a) { h(); return function (b) { h(); a = b; }; }; q(1)(2);");
    1.60 +test("n", 3, "q = function (n) { for (var i = 0; i < n; i++) { let (j = i) { h(); } } }; q(3);");
    1.61 +
    1.62 +// A function with long dynamic and static chains.
    1.63 +var N = 80;
    1.64 +
    1.65 +var code = "function f" + N + "(a" + N + ") {\neval('a0 + a1'); h();\n}\n";
    1.66 +for (var i = N; --i >= 0;) {
    1.67 +    var call = "f" + (i + 1) + "(a" + i + " - 1);\n";
    1.68 +    code = ("function f" + i + "(a" + i + ") {\n" +
    1.69 +            code +
    1.70 +            call +
    1.71 +            "if (a" + i + " === 0) " + call +
    1.72 +            "}\n");
    1.73 +}
    1.74 +
    1.75 +g.eval(code);
    1.76 +test("a0", 2, "f0(0);");
    1.77 +test("a17", 2, "f0(17);");
    1.78 +test("a" + (N-2), 2, "f0(" + (N-2) + ");");
    1.79 +test("a" + (N-1), 2, "f0(" + (N-1) + ");");
    1.80 +
    1.81 +// A function with a short dynamic chain and a long static chain.
    1.82 +N = 60;
    1.83 +
    1.84 +function DeepStaticShallowDynamic(i, n) {
    1.85 +    var code = "function f" + i + "(a" + i + ") {\n";
    1.86 +    if (i >= n)
    1.87 +        code += "eval('a1 + a2'); h();\n";
    1.88 +    else
    1.89 +        code += "return " + DeepStaticShallowDynamic(i+1, n) + ";\n";
    1.90 +    code += "}";
    1.91 +    return code;
    1.92 +}
    1.93 +g.eval(DeepStaticShallowDynamic(1, N));
    1.94 +
    1.95 +function range(start, stop) {
    1.96 +    for (var i = start; i < stop; i++)
    1.97 +        yield i;
    1.98 +}
    1.99 +
   1.100 +function DSSDsplit(s) {
   1.101 +    return ("var mid = f1" + ["(" + i + ")" for (i in range(0, s))].join("") + ";\n" +
   1.102 +            "mid" +          ["(" + i + ")" for (i in range(s, N))].join("") + ";\n" +
   1.103 +            "mid" +          ["(" + i + ")" for (i in range(s, N))].join("") + ";\n");
   1.104 +}
   1.105 +
   1.106 +test("a1", 2, DSSDsplit(1));
   1.107 +test("a17", 2, DSSDsplit(17));
   1.108 +test("a" + (N-2), 2, DSSDsplit(N-2));
   1.109 +test("a" + (N-1), 2, DSSDsplit(N-1));

mercurial