summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/debug/Frame-onPop-throw-error.js
blob: e0c7b78df0c86dc359d7cb0432c710a87b4b8414 (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
// |jit-test| error: TestComplete
// onPop can change a throw into a termination.

var g = newGlobal();
var dbg = new Debugger(g);

// We use Debugger.Frame.prototype.eval and ignore the outer 'eval' frame so we 
// can catch the termination.

function test(type, provocation) {
    // Help people figure out which 'test' call failed.
    print("type:        " + uneval(type));
    print("provocation: " + uneval(provocation));

    var log;
    dbg.onEnterFrame = function handleFirstFrame(f) {
        log += 'f';
        dbg.onDebuggerStatement = function handleDebugger(f) {
            log += 'd';
        };

        dbg.onEnterFrame = function handleSecondFrame(f) {
            log += 'e';
            assertEq(f.type, 'eval');

            dbg.onEnterFrame = function handleThirdFrame(f) {
                log += '(';
                assertEq(f.type, type);

                dbg.onEnterFrame = function handleExtraFrames(f) {
                    // This should never be called.
                    assertEq(false, true);
                };

                f.onPop = function handlePop(c) {
                    log += ')';
                    assertEq(c.throw, 'mud');
                    return null;
                };
            };
        };

        assertEq(f.eval(provocation), null);
    };

    log = '';
    // This causes handleFirstFrame to be called.
    assertEq(typeof g.eval('eval'), 'function');
    assertEq(log, 'fe(d)');

    print();
}

g.eval('function f() { debugger; throw \'mud\'; }');
test('call', 'f();');
test('call', 'new f;');
test('eval', 'eval(\'debugger; throw \\\'mud\\\';\');');
test('global', 'evaluate(\'debugger; throw \\\'mud\\\';\');');
throw 'TestComplete';