112 lines
4.1 KiB
HTML
112 lines
4.1 KiB
HTML
<p>
|
|
This page verifies that eval has two meanings:
|
|
<ol>
|
|
<li>An operator: executes a script in local scope with the local scope's variable object and "this" object.</li>
|
|
<li>A global function: executes a script in global scope with the global scope's variable object and "this" object.</li>
|
|
</ol>
|
|
Meaning #2 should remain constant even if the global eval function is copied
|
|
into a global variable ("globalEval") or a local variable ("localEval").
|
|
</p>
|
|
<p>If the test passes, you'll see a series of pass messages below.</p>
|
|
<hr>
|
|
<pre id="console"></pre>
|
|
|
|
<script>
|
|
if (window.testRunner)
|
|
testRunner.dumpAsText();
|
|
|
|
var globalEval = 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()
|
|
{
|
|
var x = 1;
|
|
var localEval = window.eval;
|
|
|
|
window.x = 0;
|
|
|
|
shouldBe('eval("x")', eval("x"), 1);
|
|
|
|
shouldBe('window.eval("x")', window.eval("x"), 0);
|
|
shouldBe('globalEval("x")', globalEval("x"), 0);
|
|
shouldBe('localEval("x")', localEval("x"), 0);
|
|
|
|
// Per ES5 15.1.2.11 & 10.2.2.1 any reference that hits an enviromment record (i.e. does not have a base)
|
|
// and has a reference name of "eval" is treated as a direct eval - the assignment to a var makes no difference.
|
|
shouldBe('(function() { var eval = window.eval; return eval("x"); })()', (function() { var eval = window.eval; return eval("x"); })(), 1);
|
|
}
|
|
|
|
function testVarY()
|
|
{
|
|
var localEval = window.eval;
|
|
|
|
shouldBe('eval("var y; \"y\" in window")', eval("var y; \"y\" in window"), false);
|
|
delete window.y;
|
|
|
|
shouldBe('window.eval("var y; \"y\" in window")', window.eval("var y; \"y\" in window"), true);
|
|
delete window.y;
|
|
|
|
shouldBe('globalEval("var y; \"y\" in window")', globalEval("var y; \"y\" in window"), true);
|
|
delete window.y;
|
|
|
|
shouldBe('localEval("var y; \"y\" in window")', localEval("var y; \"y\" in window"), true);
|
|
delete window.y;
|
|
|
|
// Per ES5 15.1.2.11 & 10.2.2.1 any reference that hits an enviromment record (i.e. does not have a base)
|
|
// and has a reference name of "eval" is treated as a direct eval - the assignment to a var makes no difference.
|
|
shouldBe('(function() { var eval = window.eval; return eval("var y; \"y\" in window"); })()', (function() { var eval = window.eval; return eval("var y; \"y\" in window"); })(), false);
|
|
}
|
|
|
|
function testSetZ()
|
|
{
|
|
var z = 0;
|
|
window.z = 0;
|
|
var localEval = window.eval;
|
|
|
|
shouldBe('eval("z = 1; window.z")', eval("z = 1; window.z"), 0);
|
|
|
|
shouldBe('window.eval("z = 2; window.z")', window.eval("z = 2; window.z"), 2);
|
|
|
|
shouldBe('globalEval("z = 3; window.z")', globalEval("z = 3; window.z"), 3);
|
|
|
|
shouldBe('localEval("z = 4; window.z")', localEval("z = 4; window.z"), 4);
|
|
|
|
// Per ES5 15.1.2.11 & 10.2.2.1 any reference that hits an enviromment record (i.e. does not have a base)
|
|
// and has a reference name of "eval" is treated as a direct eval - the assignment to a var makes no difference.
|
|
shouldBe('(function() { var eval = window.eval; return eval("z = 5; window.z"); })()', (function() { var eval = window.eval; return eval("z = 5; window.z"); })(), 4);
|
|
}
|
|
|
|
function testThis()
|
|
{
|
|
var localEval = window.eval;
|
|
|
|
shouldBe('eval("this")', eval("this"), this);
|
|
shouldBe('window.eval("this")', window.eval("this"), window);
|
|
shouldBe('globalEval("this")', globalEval("this"), window);
|
|
shouldBe('localEval("this")', localEval("this"), window);
|
|
shouldBe('(function() { var eval = window.eval; return eval("this"); })()', (function() { var eval = window.eval; return eval("this"); })(), window);
|
|
}
|
|
|
|
log("\n----- Scope Chain for Getters: -----\n");
|
|
testGetX();
|
|
log("\n----- Variable Object: -----\n");
|
|
testVarY();
|
|
log("\n----- Scope Chain for Setters: -----\n");
|
|
testSetZ();
|
|
log("\n----- This Object: -----\n");
|
|
testThis.call({ toString: function() { return "[\"this\" object passed to .call()]"; } });
|
|
</script>
|