function loop(f, expected) { // This is the loop that breaks us. // At record time, f's parent is a Call object with no fp. // At second execute time, it is a Call object with fp, // and all the Call object's dslots are still JSVAL_VOID. for (var i = 0; i < 9; i++) assertEq(f(), expected); } function C(bad) { var x = bad; function f() { return x; // We trick TR::callProp() into emitting code that gets // JSVAL_VOID (from the Call object's dslots) // rather than the actual value (true or false). } this.m = f; return f; } var obj = { set m(f) { if (f()) // Call once to resolve x on the Call object, // for shape consistency. Otherwise loop gets // recorded twice. loop(f, true); } }; loop(C.call(obj, false), false); C.call(obj, true);