1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jit-test/tests/debug/Debugger-onEnterFrame-resumption-05.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,98 @@ 1.4 +// Exercise the call to ScriptDebugPrologue in js_InternalInterpret. 1.5 + 1.6 +// This may change, but as of this writing, inline caches (ICs) are 1.7 +// disabled in debug mode, and those are the only users of the out-of-line entry 1.8 +// points for JIT code (arityCheckEntry, argsCheckEntry, fastEntry); debug 1.9 +// mode uses only invokeEntry. This means most of the bytecode tails in 1.10 +// js_InternalInterpret that might call ScriptPrologue or ScriptEpilogue are 1.11 +// unreachable in debug mode: they're only called from the out-of-line entry 1.12 +// points. 1.13 +// 1.14 +// The exception is REJOIN_THIS_PROTOTYPE, which can be reached reliably if you 1.15 +// add a JS_GC call to stubs::GetPropNoCache. JIT code calls that stub to 1.16 +// retrieve the 'prototype' property of a function called as a constructor, if 1.17 +// TI can't establish the exact identity of that prototype's value at compile 1.18 +// time. Thus the preoccupation with constructors here. 1.19 + 1.20 +load(libdir + "asserts.js"); 1.21 + 1.22 +var debuggee = newGlobal(); 1.23 +var dbg = Debugger(debuggee); 1.24 +var hits, savedFrame; 1.25 + 1.26 +// Allow the constructor to return normally. 1.27 +dbg.onEnterFrame = function (frame) { 1.28 + hits++; 1.29 + if (frame.constructing) { 1.30 + savedFrame = frame; 1.31 + assertEq(savedFrame.live, true); 1.32 + return undefined; 1.33 + } 1.34 + return undefined; 1.35 +}; 1.36 +hits = 0; 1.37 +debuggee.hits = 0; 1.38 +savedFrame = undefined; 1.39 +assertEq(typeof debuggee.eval("function f(){ hits++; } f.prototype = {}; new f;"), "object"); 1.40 +assertEq(hits, 2); 1.41 +assertEq(savedFrame.live, false); 1.42 +assertEq(debuggee.hits, 1); 1.43 + 1.44 +// Force an early return from the constructor. 1.45 +dbg.onEnterFrame = function (frame) { 1.46 + hits++; 1.47 + if (frame.constructing) { 1.48 + savedFrame = frame; 1.49 + assertEq(savedFrame.live, true); 1.50 + return { return: "pass" }; 1.51 + } 1.52 + return undefined; 1.53 +}; 1.54 +hits = 0; 1.55 +debuggee.hits = 0; 1.56 +savedFrame = undefined; 1.57 +assertEq(typeof debuggee.eval("function f(){ hits++; } f.prototype = {}; new f;"), "object"); 1.58 +assertEq(hits, 2); 1.59 +assertEq(savedFrame.live, false); 1.60 +assertEq(debuggee.hits, 0); 1.61 + 1.62 +// Force the constructor to throw an exception. 1.63 +dbg.onEnterFrame = function (frame) { 1.64 + hits++; 1.65 + if (frame.constructing) { 1.66 + savedFrame = frame; 1.67 + assertEq(savedFrame.live, true); 1.68 + return { throw: "pass" }; 1.69 + } 1.70 + return undefined; 1.71 +}; 1.72 +hits = 0; 1.73 +debuggee.hits = 0; 1.74 +savedFrame = undefined; 1.75 +assertThrowsValue(function () { 1.76 + debuggee.eval("function f(){ hits++ } f.prototype = {}; new f;"); 1.77 + }, "pass"); 1.78 +assertEq(hits, 2); 1.79 +assertEq(savedFrame.live, false); 1.80 +assertEq(debuggee.hits, 0); 1.81 + 1.82 +// Ensure that forcing an early return only returns from one JS call. 1.83 +debuggee.eval("function g() { var result = new f; g_hits++; return result; }"); 1.84 +dbg.onEnterFrame = function (frame) { 1.85 + hits++; 1.86 + if (frame.constructing) { 1.87 + savedFrame = frame; 1.88 + assertEq(savedFrame.live, true); 1.89 + return { return: "pass" }; 1.90 + } 1.91 + return undefined; 1.92 +}; 1.93 +hits = 0; 1.94 +debuggee.hits = 0; 1.95 +debuggee.g_hits = 0; 1.96 +savedFrame = undefined; 1.97 +assertEq(typeof debuggee.eval("g();"), "object"); 1.98 +assertEq(hits, 3); 1.99 +assertEq(savedFrame.live, false); 1.100 +assertEq(debuggee.hits, 0); 1.101 +assertEq(debuggee.g_hits, 1);