michael@0: // setVariable works on non-innermost environments. michael@0: michael@0: // (The debuggee code here is a bit convoluted to defeat optimizations that michael@0: // could make obj.b a null closure or obj.i a flat closure--that is, a function michael@0: // that gets a frozen copy of i instead of a reference to the runtime michael@0: // environment that contains it. setVariable does not currently detect this michael@0: // flat closure case.) michael@0: michael@0: var g = newGlobal(); michael@0: g.eval("function d() { debugger; }\n" + michael@0: "var i = 'FAIL';\n" + michael@0: "function a() {\n" + michael@0: " var obj = {b: function (i) { d(obj); return i; },\n" + michael@0: " i: function () { return i; }};\n" + michael@0: " var i = 'FAIL2';\n" + michael@0: " return obj;\n" + michael@0: "}\n"); michael@0: michael@0: var dbg = Debugger(g); michael@0: dbg.onDebuggerStatement = function (frame) { michael@0: var x = 0; michael@0: for (var env = frame.older.environment; env; env = env.parent) { michael@0: if (env.getVariable("i") !== undefined) michael@0: env.setVariable("i", x++); michael@0: } michael@0: }; michael@0: michael@0: var obj = g.a(); michael@0: var r = obj.b('FAIL3'); michael@0: assertEq(r, 0); michael@0: assertEq(obj.i(), 1); michael@0: assertEq(g.i, 2);