Index: src/scopes.cc |
diff --git a/src/scopes.cc b/src/scopes.cc |
index 8b623f90ce908ac548bfd8ea46bdcf088121bbcf..a011dd1ca82b59680f74c14e008fdb3e322ce4b3 100644 |
--- a/src/scopes.cc |
+++ b/src/scopes.cc |
@@ -150,6 +150,7 @@ void Scope::SetDefaults(ScopeType scope_type, Scope* outer_scope, |
Handle<ScopeInfo> scope_info, |
FunctionKind function_kind) { |
outer_scope_ = outer_scope; |
+ function_body_ = nullptr; |
scope_type_ = scope_type; |
function_kind_ = function_kind; |
block_scope_is_class_scope_ = false; |
@@ -194,6 +195,12 @@ void Scope::SetDefaults(ScopeType scope_type, Scope* outer_scope, |
block_scope_is_class_scope_ = scope_info->block_scope_is_class_scope(); |
function_kind_ = scope_info->function_kind(); |
} |
+ if (scope_type == FUNCTION_BODY_SCOPE) { |
+ DCHECK_NOT_NULL(outer_scope); |
+ DCHECK(outer_scope->is_function_scope()); |
+ DCHECK_NULL(outer_scope->function_body_); |
+ outer_scope->function_body_ = this; |
+ } |
} |
@@ -543,7 +550,12 @@ Variable* Scope::NewTemporary(const AstRawString* name) { |
void Scope::AddDeclaration(Declaration* declaration) { |
- decls_.Add(declaration, zone()); |
+ Scope* target = this; |
+ if (is_function_body_scope() && declaration->mode() == VAR) { |
+ // Add `var` declarations to outer scope, to make allocation simpler |
+ target = outer_scope(); |
+ } |
+ target->decls_.Add(declaration, zone()); |
} |
@@ -819,6 +831,8 @@ static const char* Header(ScopeType scope_type) { |
case BLOCK_SCOPE: return "block"; |
case WITH_SCOPE: return "with"; |
case ARROW_SCOPE: return "arrow"; |
+ case FUNCTION_BODY_SCOPE: |
+ return "function body"; |
} |
UNREACHABLE(); |
return NULL; |
@@ -1356,7 +1370,11 @@ bool Scope::HasArgumentsParameter(Isolate* isolate) { |
void Scope::AllocateStackSlot(Variable* var) { |
- if (is_block_scope()) { |
+ if (is_function_body_scope()) { |
+ // Function body variables need to be allocated in the "real" function |
+ // scope, but can't be resolved from it |
+ outer_scope()->AllocateStackSlot(var); |
+ } else if (is_block_scope()) { |
DeclarationScope()->AllocateStackSlot(var); |
} else { |
var->AllocateTo(Variable::LOCAL, num_stack_slots_++); |