Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index 45202cb3a82b922c7d487061cfff03578cc3a3c9..c5c86eb40cb724d35ec67a2a6c31885f43077b22 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -2011,15 +2011,17 @@ Variable* Parser::Declare(Declaration* declaration, |
// variable and also set its mode. In any case, a Declaration node |
// will be added to the scope so that the declaration can be added |
// 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. |
- // Similarly, strict mode eval scope does not leak variable declarations to |
- // the caller's scope so we declare all locals, too. |
+ // For instance, var declarations inside a sloppy eval scope need |
+ // to be added to the calling function context. Similarly, strict |
+ // mode eval scope and lexical eval bindings do not leak variable |
+ // declarations to the caller's scope so we declare all locals, too. |
if (declaration_scope->is_function_scope() || |
- declaration_scope->is_strict_eval_scope() || |
declaration_scope->is_block_scope() || |
declaration_scope->is_module_scope() || |
- declaration_scope->is_script_scope()) { |
+ declaration_scope->is_script_scope() || |
+ (declaration_scope->is_eval_scope() && |
+ (is_strict(declaration_scope->language_mode()) || |
+ IsLexicalVariableMode(mode)))) { |
// Declare the variable in the declaration scope. |
var = declaration_scope->LookupLocal(name); |
if (var == NULL) { |
@@ -2072,8 +2074,22 @@ Variable* Parser::Declare(Declaration* declaration, |
} else if (mode == VAR) { |
var->set_maybe_assigned(); |
} |
+ } else if (declaration_scope->is_eval_scope() && |
+ is_sloppy(declaration_scope->language_mode()) && |
+ !IsLexicalVariableMode(mode)) { |
+ // In a var binding in a sloppy direct eval, pollute the enclosing scope |
+ // with this new binding by doing the following: |
+ // The proxy is bound to a lookup variable to force a dynamic declaration |
+ // using the DeclareLookupSlot runtime function. |
+ Variable::Kind kind = Variable::NORMAL; |
+ // TODO(sigurds) figure out if kNotAssigned is OK here |
+ var = new (zone()) Variable(declaration_scope, name, mode, kind, |
+ declaration->initialization(), kNotAssigned); |
+ var->AllocateTo(VariableLocation::LOOKUP, -1); |
+ resolve = true; |
} |
+ |
// We add a declaration node for every declaration. The compiler |
// will only generate code if necessary. In particular, declarations |
// for inner local variables that do not represent functions won't |
@@ -2098,17 +2114,6 @@ Variable* Parser::Declare(Declaration* declaration, |
Variable::Kind kind = Variable::NORMAL; |
var = new (zone()) Variable(declaration_scope, name, mode, kind, |
kNeedsInitialization, kNotAssigned); |
- } else if (declaration_scope->is_eval_scope() && |
- is_sloppy(declaration_scope->language_mode())) { |
- // For variable declarations in a sloppy eval scope the proxy is bound |
- // to a lookup variable to force a dynamic declaration using the |
- // DeclareLookupSlot runtime function. |
- Variable::Kind kind = Variable::NORMAL; |
- // TODO(sigurds) figure out if kNotAssigned is OK here |
- var = new (zone()) Variable(declaration_scope, name, mode, kind, |
- declaration->initialization(), kNotAssigned); |
- var->AllocateTo(VariableLocation::LOOKUP, -1); |
- resolve = true; |
} |
// If requested and we have a local variable, bind the proxy to the variable |