| Index: src/ast/scopes.cc
 | 
| diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc
 | 
| index 288196150cea807a7ffdf24e3f7a8d3acfbde174..c088ecc24fb54537a9fa2eb1217c1b7f214c8bf2 100644
 | 
| --- a/src/ast/scopes.cc
 | 
| +++ b/src/ast/scopes.cc
 | 
| @@ -979,18 +979,12 @@ Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) {
 | 
|    return scope_info_;
 | 
|  }
 | 
|  
 | 
| -Handle<StringSet> Scope::CollectNonLocals(Handle<StringSet> non_locals) {
 | 
| -  // Collect non-local variables referenced in the scope.
 | 
| -  // TODO(yangguo): store non-local variables explicitly if we can no longer
 | 
| -  //                rely on unresolved_ to find them.
 | 
| -  for (VariableProxy* proxy = unresolved_; proxy != nullptr;
 | 
| +Handle<StringSet> DeclarationScope::CollectNonLocals(
 | 
| +    ParseInfo* info, Handle<StringSet> non_locals) {
 | 
| +  VariableProxy* free_variables = FetchFreeVariables(this, info);
 | 
| +  for (VariableProxy* proxy = free_variables; proxy != nullptr;
 | 
|         proxy = proxy->next_unresolved()) {
 | 
| -    if (proxy->is_resolved() && proxy->var()->IsStackAllocated()) continue;
 | 
| -    Handle<String> name = proxy->name();
 | 
| -    non_locals = StringSet::Add(non_locals, name);
 | 
| -  }
 | 
| -  for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
 | 
| -    non_locals = scope->CollectNonLocals(non_locals);
 | 
| +    non_locals = StringSet::Add(non_locals, proxy->name());
 | 
|    }
 | 
|    return non_locals;
 | 
|  }
 | 
| @@ -1003,7 +997,12 @@ void DeclarationScope::AnalyzePartially(DeclarationScope* migrate_to,
 | 
|    // Try to resolve unresolved variables for this Scope and migrate those which
 | 
|    // cannot be resolved inside. It doesn't make sense to try to resolve them in
 | 
|    // the outer Scopes here, because they are incomplete.
 | 
| -  MigrateUnresolvableLocals(migrate_to, ast_node_factory, this);
 | 
| +  for (VariableProxy* proxy = FetchFreeVariables(this); proxy != nullptr;
 | 
| +       proxy = proxy->next_unresolved()) {
 | 
| +    DCHECK(!proxy->is_resolved());
 | 
| +    VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
 | 
| +    migrate_to->AddUnresolved(copy);
 | 
| +  }
 | 
|  
 | 
|    // Push scope data up to migrate_to. Note that migrate_to and this Scope
 | 
|    // describe the same Scope, just in different Zones.
 | 
| @@ -1359,6 +1358,11 @@ void Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy,
 | 
|    BindingKind binding_kind;
 | 
|    Variable* var = LookupRecursive(proxy, &binding_kind, factory);
 | 
|  
 | 
| +  ResolveTo(info, binding_kind, proxy, var);
 | 
| +}
 | 
| +
 | 
| +void Scope::ResolveTo(ParseInfo* info, BindingKind binding_kind,
 | 
| +                      VariableProxy* proxy, Variable* var) {
 | 
|  #ifdef DEBUG
 | 
|    if (info->script_is_native()) {
 | 
|      // To avoid polluting the global object in native scripts
 | 
| @@ -1438,30 +1442,38 @@ void Scope::ResolveVariablesRecursively(ParseInfo* info,
 | 
|    }
 | 
|  }
 | 
|  
 | 
| -void Scope::MigrateUnresolvableLocals(DeclarationScope* migrate_to,
 | 
| -                                      AstNodeFactory* ast_node_factory,
 | 
| -                                      DeclarationScope* max_outer_scope) {
 | 
| -  BindingKind binding_kind;
 | 
| +VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope,
 | 
| +                                         ParseInfo* info,
 | 
| +                                         VariableProxy* stack) {
 | 
| +  BindingKind binding_kind = BOUND;
 | 
|    for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr;
 | 
|         proxy = next) {
 | 
|      next = proxy->next_unresolved();
 | 
| +    if (proxy->is_resolved()) continue;
 | 
|      // Note that we pass nullptr as AstNodeFactory: this phase should not create
 | 
|      // any new AstNodes, since none of the Scopes involved are backed up by
 | 
|      // ScopeInfo.
 | 
| -    if (LookupRecursive(proxy, &binding_kind, nullptr, max_outer_scope) ==
 | 
| -        nullptr) {
 | 
| -      // Re-create the VariableProxies in the right Zone and insert them into
 | 
| -      // migrate_to.
 | 
| -      DCHECK(!proxy->is_resolved());
 | 
| -      VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
 | 
| -      migrate_to->AddUnresolved(copy);
 | 
| +    Variable* var =
 | 
| +        LookupRecursive(proxy, &binding_kind, nullptr, max_outer_scope);
 | 
| +    // Anything that was bound
 | 
| +    if (var == nullptr) {
 | 
| +      proxy->set_next_unresolved(stack);
 | 
| +      stack = proxy;
 | 
| +    } else if (info != nullptr) {
 | 
| +      DCHECK_NE(UNBOUND, binding_kind);
 | 
| +      DCHECK_NE(UNBOUND_EVAL_SHADOWED, binding_kind);
 | 
| +      ResolveTo(info, binding_kind, proxy, var);
 | 
|      }
 | 
|    }
 | 
|  
 | 
| +  // Clear unresolved_ as it's in an inconsistent state.
 | 
| +  unresolved_ = nullptr;
 | 
| +
 | 
|    for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
 | 
| -    scope->MigrateUnresolvableLocals(migrate_to, ast_node_factory,
 | 
| -                                     max_outer_scope);
 | 
| +    stack = scope->FetchFreeVariables(max_outer_scope, info, stack);
 | 
|    }
 | 
| +
 | 
| +  return stack;
 | 
|  }
 | 
|  
 | 
|  void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval) {
 | 
| 
 |