Strict mode eval declares its locals in its own environment.
authormmaly@chromium.org <mmaly@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 29 Apr 2011 15:31:39 +0000 (15:31 +0000)
committermmaly@chromium.org <mmaly@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 29 Apr 2011 15:31:39 +0000 (15:31 +0000)
BUG=
TEST=strict-mode.js

Review URL: http://codereview.chromium.org/6883200

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7728 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/parser.cc
src/scopes.h
test/mjsunit/strict-mode.js

index a2c06f8af04a48d3b60f18566f17a0f8ac5f86ca..14eb534b8cf740e1d100e79e01518a4aaafdccbc 100644 (file)
@@ -1303,7 +1303,10 @@ VariableProxy* Parser::Declare(Handle<String> name,
   // to the corresponding activation frame at runtime if necessary.
   // For instance declarations inside an eval scope need to be added
   // to the calling function context.
-  if (top_scope_->is_function_scope()) {
+  // Similarly, strict mode eval scope does not leak variable declarations to
+  // the caller's scope so we declare all locals, too.
+  if (top_scope_->is_function_scope() ||
+      top_scope_->is_strict_mode_eval_scope()) {
     // Declare the variable in the function scope.
     var = top_scope_->LocalLookup(name);
     if (var == NULL) {
index 18db0cdd26ba1a950b282e8f6e4f669c37e393ab..681e62b36981eb0683a5cb1bf4b732ad6ac195c0 100644 (file)
@@ -211,6 +211,9 @@ class Scope: public ZoneObject {
   bool is_function_scope() const { return type_ == FUNCTION_SCOPE; }
   bool is_global_scope() const { return type_ == GLOBAL_SCOPE; }
   bool is_strict_mode() const { return strict_mode_; }
+  bool is_strict_mode_eval_scope() const {
+    return is_eval_scope() && is_strict_mode();
+  }
 
   // Information about which scopes calls eval.
   bool calls_eval() const { return scope_calls_eval_; }
index beca582a02ad3637dc356968ea5915fbf512ab9e..2d676b425946e85974d6692dfcc707c1f5579fa4 100644 (file)
@@ -1179,3 +1179,10 @@ function CheckPillDescriptor(func, name) {
     assertEquals(test(i), true);
   }
 })();
+
+
+(function TestStrictModeEval() {
+  "use strict";
+  eval("var eval_local = 10;");
+  assertThrows(function() { return eval_local; }, ReferenceError);
+})();