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