summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/modules/debugger-frames.js
blob: ba7a1471c4dff89d4c95fe5ebf2ec9b621c32674 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// Test debugger access to frames and environments work as expected inside a module.

load(libdir + "asserts.js");

function assertArrayEq(actual, expected)
{
    var eq = actual.length == expected.length;
    if (eq) {
        for (var i = 0; i < actual.length; i++) {
            if (actual[i] !== expected[i]) {
                eq = false;
                break;
            }
        }
    }
    if (!eq) {
        print("Assertion failed: got " + JSON.stringify(actual) +
              ", expected " + JSON.stringify(expected));
        quit(3);
    }
}

var g2 = newGlobal();

var dbg = Debugger(g2);
dbg.onDebuggerStatement = function (frame) {
    // The current frame is a module frame.
    assertEq(frame.type, 'module');
    assertEq(frame.this, undefined);

    // The frame's environement is a module environment.
    let env = frame.environment;
    assertEq(env.type, 'declarative');
    assertEq(env.callee, null);

    // Top level module definitions and imports are visible.
    assertArrayEq(env.names().sort(), ['a', 'b', 'c', 'x', 'y', 'z']);
    assertArrayEq(['a', 'b', 'c'].map(env.getVariable, env), [1, 2, 3]);
    assertArrayEq(['x', 'y', 'z'].map(env.getVariable, env), [4, 5, 6]);

    // Cannot set imports or const bindings.
    assertThrowsInstanceOf(() => env.setVariable('a', 10), TypeError);
    assertThrowsInstanceOf(() => env.setVariable('b', 11), TypeError);
    assertThrowsInstanceOf(() => env.setVariable('c', 12), TypeError);
    env.setVariable('x', 7);
    env.setVariable('y', 8);
    assertThrowsInstanceOf(() => env.setVariable('z', 9), TypeError);
    assertArrayEq(['a', 'b', 'c'].map(env.getVariable, env), [1, 2, 3]);
    assertArrayEq(['x', 'y', 'z'].map(env.getVariable, env), [7, 8, 6]);

    // The global lexical is the next thing after the module on the scope chain,
    // followed by the global.
    assertEq(env.parent.type, 'declarative');
    assertEq(env.parent.parent.type, 'object');
    assertEq(env.parent.parent.parent, null);
};

f = g2.eval(
`
    let moduleRepo = {};
    setModuleResolveHook(function(module, specifier) {
        if (specifier in moduleRepo)
            return moduleRepo[specifier];
        throw "Module '" + specifier + "' not found";
    });

    // Set up a module to import from.
    a = moduleRepo['a'] = parseModule(
    \`
        export var a = 1;
        export let b = 2;
        export const c = 3;
        export function f(x) { return x + 1; }
    \`);
    a.declarationInstantiation();
    a.evaluation();

    let m = parseModule(
    \`
        import { a, b, c } from 'a';
        var x = 4;
        let y = 5;
        const z = 6;

        debugger;
    \`);
    m.declarationInstantiation();
    m.evaluation();
`);