testGuardCalleeSneakAttack2.js (1011B)
1 function loop(f, expected) { 2 // This is the loop that breaks us. 3 // At record time, f's parent is a Call object with no fp. 4 // At second execute time, it is a Call object with fp, 5 // and all the Call object's dslots are still JSVAL_VOID. 6 for (var i = 0; i < 9; i++) 7 assertEq(f(), expected); 8 } 9 10 function C(bad) { 11 var x = bad; 12 function f() { 13 return x; // We trick TR::callProp() into emitting code that gets 14 // JSVAL_VOID (from the Call object's dslots) 15 // rather than the actual value (true or false). 16 } 17 if (bad) 18 void (f + "a!"); 19 return f; 20 } 21 22 var obj = { 23 }; 24 25 // Warm up and trace with C's Call object entrained but its stack frame gone. 26 loop(C.call(obj, false), false); 27 28 // Sneaky access to f via a prototype method called implicitly by operator +. 29 Function.prototype.toString = function () { loop(this, true); return "hah"; }; 30 31 // Fail hard if we don't handle the implicit call out of C to F.p.toString. 32 C.call(obj, true);