Reviewers: rossberg,
Message:
PTAL.
Description:
Fix load of potentially eval-shadowed let bindings.
BUG=
TEST=test/mjsunit/harmony/block-let-semantics.js
Please review this at http://codereview.chromium.org/8118032/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/ia32/full-codegen-ia32.cc
M test/mjsunit/harmony/block-let-semantics.js
Index: src/ia32/full-codegen-ia32.cc
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index
d45a9cdaeea3ab3725152056bb3a87ecde43e77d..b66711fb7693fa82cd8dd33c01e67380092dee90
100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -1207,10 +1207,16 @@ void
FullCodeGenerator::EmitDynamicLookupFastCase(Variable* var,
} else if (var->mode() == Variable::DYNAMIC_LOCAL) {
Variable* local = var->local_if_not_shadowed();
__ mov(eax, ContextSlotOperandCheckExtensions(local, slow));
- if (local->mode() == Variable::CONST) {
+ if (local->mode() == Variable::CONST ||
+ local->mode() == Variable::LET) {
__ cmp(eax, isolate()->factory()->the_hole_value());
__ j(not_equal, done);
- __ mov(eax, isolate()->factory()->undefined_value());
+ if (local->mode() == Variable::CONST) {
+ __ mov(eax, isolate()->factory()->undefined_value());
+ } else { // Variable::LET
+ __ push(Immediate(var->name()));
+ __ CallRuntime(Runtime::kThrowReferenceError, 1);
+ }
}
__ jmp(done);
}
Index: test/mjsunit/harmony/block-let-semantics.js
diff --git a/test/mjsunit/harmony/block-let-semantics.js
b/test/mjsunit/harmony/block-let-semantics.js
index
198c3b4fb96803b415fdc65e0c69d3573eb23465..f50c3ed03f140eb47831a2b3992e9bdfb8067d6a
100644
--- a/test/mjsunit/harmony/block-let-semantics.js
+++ b/test/mjsunit/harmony/block-let-semantics.js
@@ -81,13 +81,20 @@ TestAll('f()(); let x; function f() { return function()
{ x += 1; } }');
TestAll('f()(); let x; function f() { return function() { ++x; } }');
TestAll('f()(); let x; function f() { return function() { x++; } }');
-// Use in before initialization with a dynamic lookup.
+// Use before initialization with a dynamic lookup.
TestAll('eval("x + 1;"); let x;');
TestAll('eval("x = 1;"); let x;');
TestAll('eval("x += 1;"); let x;');
TestAll('eval("++x;"); let x;');
TestAll('eval("x++;"); let x;');
+// Use before initialization with check for eval-shadowed bindings.
+TestAll('function f() { eval("var y = 2;"); x + 1; }; f(); let x;');
+TestAll('function f() { eval("var y = 2;"); x = 1; }; f(); let x;');
+TestAll('function f() { eval("var y = 2;"); x += 1; }; f(); let x;');
+TestAll('function f() { eval("var y = 2;"); ++x; }; f(); let x;');
+TestAll('function f() { eval("var y = 2;"); x++; }; f(); let x;');
+
// Test that variables introduced by function declarations are created and
// initialized upon entering a function / block scope.
function f() {
@@ -136,3 +143,19 @@ function f2() {
}
assertEquals(5, n());
}
+
+// Test that resolution of let bound variables works with scopes that call
eval.
+function outer() {
+ function middle() {
+ function inner() {
+ return x;
+ }
+ eval("1 + 1");
+ return x + inner();
+ }
+
+ let x = 1;
+ middle();
+}
+
+assertEquals(2, outer());
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev