var o; var f1; var counter = 0; function f2(a) { bailout(); return f2.arguments; }; var restartCode = "counter = 0; " + f2.toSource(); // We need to reevaluate this function everytime, otherwise it is flagged as // having an argument object and it would not be re-entered. // This test case is checking that f.arguments reflects the overflow or the // underflow of arguments after a bailout. Due to the way bailouts are // recovered we need to check for the intial frame and for any other JS frame // below. // // To produce a JSFrame, we need to avoid the 'Hot' counters of f1 to be the // same as f2, because IonMonkey will try to inline f2 in f1, and not // compiling/calling f2 separately. This explain why we ignore the 5 first call // of f1 by returning immediately. // // Bailouts are caused by calling an object function, which is expected to be a // function by IonMonkey. So bailout() cause a bailout in the currently // compiled function. // // To avoid any preventive effect to re-enter f2, we re-evaluate it before every // test. // Check bailouts of the initial frame. eval(restartCode); while (counter++ < 50) { o = f2(); assertEq(o.length, 0); } eval(restartCode); while (counter++ < 50) { o = f2(21); assertEq(o.length, 1); assertEq(o[0], 21); } eval(restartCode); while (counter++ < 50) { o = f2(21,42); assertEq(o.length, 2); assertEq(o[0], 21); assertEq(o[1], 42); } // 100 arguments. eval(restartCode); while (counter++ < 50) { o = f2(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); assertEq(o.length, 100); for (var i in o) assertEq(o[i], i % 10); } // 200 arguments. eval(restartCode); while (counter++ < 50) { o = f2(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); assertEq(o.length, 200); for (var i in o) assertEq(o[i], i % 10); } // 300 arguments. eval(restartCode); while (counter++ < 50) { o = f2(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); assertEq(o.length, 300); for (var i in o) assertEq(o[i], i % 10); } // Check bailouts of one frame which is not the initial frame. eval(restartCode); f1 = function() { if (counter < 5) return 0; return f2(); }; while (counter++ < 50) { o = f1(); if (counter < 5) continue; assertEq(o.length, 0); } eval(restartCode); f1 = function() { if (counter < 5) return 0; return f2(21); }; while (counter++ < 50) { o = f1(); if (counter < 5) continue; assertEq(o.length, 1); assertEq(o[0], 21); } eval(restartCode); f1 = function() { if (counter < 5) return 0; return f2(21,42); }; while (counter++ < 50) { o = f1(); if (counter < 5) continue; assertEq(o.length, 2); assertEq(o[0], 21); assertEq(o[1], 42); } // 100 arguments. eval(restartCode); f1 = function() { if (counter < 5) return 0; return f2(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); }; while (counter++ < 50) { o = f1(); if (counter < 5) continue; assertEq(o.length, 100); for (var i in o) assertEq(o[i], i % 10); } // 200 arguments. eval(restartCode); f1 = function() { if (counter < 5) return 0; return f2(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); }; while (counter++ < 50) { o = f1(); if (counter < 5) continue; assertEq(o.length, 200); for (var i in o) assertEq(o[i], i % 10); } // 300 arguments. eval(restartCode); f1 = function() { if (counter < 5) return 0; return f2(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); }; while (counter++ < 500) { o = f1(); if (counter < 5) continue; assertEq(o.length, 300); for (var i in o) assertEq(o[i], i % 10); }