|
1 // We detect and stop the runaway recursion caused by making onEnterFrame a |
|
2 // wrapper of a debuggee function. |
|
3 |
|
4 // This is all a bit silly. In any reasonable design, both debugger re-entry |
|
5 // (the second onEnterFrame invocation) and debuggee re-entry (the call to g.f |
|
6 // from within the debugger, not via a Debugger invocation function) would raise |
|
7 // errors immediately. We have plans to do so, but in the mean time, we settle |
|
8 // for at least detecting the recursion. |
|
9 |
|
10 load(libdir + 'asserts.js'); |
|
11 |
|
12 var g = newGlobal(); |
|
13 g.eval("function f(frame) { n++; return 42; }"); |
|
14 g.n = 0; |
|
15 |
|
16 var dbg = Debugger(); |
|
17 var gw = dbg.addDebuggee(g); |
|
18 |
|
19 // Register the debuggee function as the onEnterFrame handler. When we first |
|
20 // call or eval in the debuggee: |
|
21 // |
|
22 // - The onEnterFrame call reporting that frame's creation is itself an event |
|
23 // that must be reported, so we call onEnterFrame again. |
|
24 // |
|
25 // - SpiderMonkey detects the out-of-control recursion, and generates a "too |
|
26 // much recursion" InternalError in the youngest onEnterFrame call. |
|
27 // |
|
28 // - We don't catch it, so the onEnterFrame handler call itself throws. |
|
29 // |
|
30 // - Since the Debugger doesn't have an uncaughtExceptionHook (it can't; such a |
|
31 // hook would itself raise a "too much recursion" exception), Spidermonkey |
|
32 // reports the exception immediately and terminates the debuggee --- which is |
|
33 // the next-older onEnterFrame call. |
|
34 // |
|
35 // - This termination propagates all the way out to the initial attempt to |
|
36 // create a frame in the debuggee. |
|
37 dbg.onEnterFrame = g.f; |
|
38 |
|
39 // Get a Debugger.Object instance referring to f. |
|
40 var debuggeeF = gw.makeDebuggeeValue(g.f); |
|
41 |
|
42 // Using f.call allows us to catch the termination. |
|
43 assertEq(debuggeeF.call(), null); |
|
44 |
|
45 // We should never actually begin execution of the function. |
|
46 assertEq(g.n, 0); |
|
47 |
|
48 // When an error is reported, the shell usually exits with a nonzero exit code. |
|
49 // If we get here, the test passed, so override that behavior. |
|
50 quit(0); |