| <p> |
| This page verifies that eval, when called as a function, uses the "this" object |
| provided by the call as its variable object, scope chain, and "this" object. |
| However, if the "this" object is not the global object eval was originally |
| associated with, eval throws an exception. |
| </p> |
| <p>If the test passes, you'll see a series of pass messages below.</p> |
| <pre id="console"></pre> |
| |
| <hr> |
| <pre id="console"></pre> |
| <iframe style="width:0; height:0"></iframe> |
| |
| <script> |
| if (window.testRunner) |
| testRunner.dumpAsText(); |
| |
| var topEval = eval; |
| var frameEval = frames[0].eval; |
| |
| function log(s) |
| { |
| document.getElementById("console").appendChild(document.createTextNode(s + "\n")); |
| } |
| |
| function shouldBe(aDescription, a, b) |
| { |
| if (a === b) { |
| log("PASS: " + aDescription + " should be " + b + " and is."); |
| } else { |
| log("FAIL: " + aDescription + " should be " + b + " but instead is " + a + "."); |
| } |
| } |
| |
| function testGetX() |
| { |
| window.x = 0; |
| frames[0].x = 1; |
| var x = 2; |
| |
| shouldBe('window.eval("x")', window.eval("x"), 0); |
| shouldBe('frames[0].eval("x")', frames[0].eval("x"), 1); |
| |
| window.eval = frameEval; |
| shouldBe('window.eval("x")', (function() { try { return window.eval("x") } catch(e) { return e.name; } })(), 1); |
| window.eval = topEval; |
| |
| frames[0].eval = topEval; |
| shouldBe('frames[0].eval("x")', (function() { try { frames[0].eval("x") } catch(e) { return e.name; } })(), undefined); |
| frames[0].eval = frameEval; |
| } |
| |
| function testGetXX() |
| { |
| var xx = 0; |
| |
| shouldBe('window.eval("xx")', (function() { try { return window.eval("xx") } catch(e) { return e.name; } })(), "ReferenceError"); |
| shouldBe('frames[0].eval("xx")', (function() { try { return frames[0].eval("xx") } catch(e) { return e.name; } })(), "ReferenceError"); |
| |
| window.eval = frameEval; |
| shouldBe('window.eval("xx")', (function() { try { return window.eval("xx") } catch(e) { return e.name; } })(), "ReferenceError"); |
| window.eval = topEval; |
| |
| frames[0].eval = topEval; |
| shouldBe('frames[0].eval("xx")', (function() { try { return frames[0].eval("xx") } catch(e) { return e.name; } })(), "ReferenceError"); |
| frames[0].eval = frameEval; |
| } |
| |
| function testVarY() |
| { |
| shouldBe('window.eval("var y; \"y\" in top")', window.eval("var y; \"y\" in top"), true); |
| delete window.y; |
| delete frames[0].y; |
| |
| shouldBe('frames[0].eval("var y; \"y\" in top.frames[0]")', frames[0].eval("var y; \"y\" in top.frames[0]"), true); |
| delete window.y; |
| delete frames[0].y; |
| |
| window.eval = frameEval; |
| shouldBe('window.eval("var y; \"y\" in top.frames[0]")', (function() { try { window.eval("var y; \"y\" in top.frames[0]") } catch(e) { return e.name; } })(), undefined); |
| delete window.y; |
| delete frames[0].y; |
| window.eval = topEval; |
| |
| frames[0].eval = topEval; |
| shouldBe('frames[0].eval("var y; \"y\" in top")', (function() { try { frames[0].eval("var y; \"y\" in top") } catch(e) { return e.name; } })(), undefined); |
| delete window.y; |
| delete frames[0].y; |
| frames[0].eval = frameEval; |
| } |
| |
| function testSetZ() |
| { |
| window.z = 0; |
| frames[0].z = 0; |
| var z = 0; |
| |
| shouldBe('window.eval("z = 1; top.z")', window.eval("z = 1; top.z"), 1); |
| shouldBe('frames[0].eval("z = 2; top.frames[0].z")', frames[0].eval("z = 2; top.frames[0].z"), 2); |
| |
| window.eval = frameEval; |
| shouldBe('window.eval("z = 3; top.frames[0].z")', (function() { try { window.eval("z = 3; top.frames[0].z") } catch(e) { return e.name; } })(), undefined); |
| window.eval = topEval; |
| |
| frames[0].eval = topEval; |
| shouldBe('frames[0].eval("z = 4; top.z")', (function() { try { frames[0].eval("z = 4; top.z") } catch(e) { return e.name; } })(), undefined); |
| frames[0].eval = frameEval; |
| } |
| |
| function testThis() |
| { |
| shouldBe('window.eval("this")', window.eval.call("wrong", "this"), window); |
| shouldBe('frames[0].eval("this")', frames[0].eval.call("wrong", "this"), frames[0]); |
| |
| window.eval = frameEval; |
| shouldBe('window.eval("this")', (function() { try { window.eval.call("wrong", "this"), frames[0] } catch(e) { return e.name; } })(), undefined); |
| window.eval = topEval; |
| |
| frames[0].eval = topEval; |
| shouldBe('frames[0].eval("this")', (function() { try { frames[0].eval.call("wrong", "this"), window } catch(e) { return e.name; } })(), undefined); |
| frames[0].eval = frameEval; |
| } |
| |
| log("\n----- Scope Chain Head for Getters: -----\n"); |
| testGetX(); |
| log("\n----- Scope Chain for Getters: -----\n"); |
| testGetXX(); |
| log("\n----- Variable Object: -----\n"); |
| testVarY(); |
| log("\n----- Scope Chain for Setters: -----\n"); |
| testSetZ(); |
| log("\n----- This Object: -----\n"); |
| testThis.call({}); |
| </script> |