| Index: src/ast/scopes.cc
|
| diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc
|
| index fc020ccefb81466a40ad04295019d6b9a226ae65..16ef6a5409efab551542eec2881a7c7519cfc153 100644
|
| --- a/src/ast/scopes.cc
|
| +++ b/src/ast/scopes.cc
|
| @@ -15,6 +15,10 @@
|
| namespace v8 {
|
| namespace internal {
|
|
|
| +namespace {
|
| +void* kDummyPreParserVariable = reinterpret_cast<void*>(0x1);
|
| +} // namespace
|
| +
|
| // ----------------------------------------------------------------------------
|
| // Implementation of LocalsMap
|
| //
|
| @@ -49,6 +53,17 @@ Variable* VariableMap::Declare(Zone* zone, Scope* scope,
|
| return reinterpret_cast<Variable*>(p->value);
|
| }
|
|
|
| +void VariableMap::DeclareName(Zone* zone, const AstRawString* name) {
|
| + Entry* p =
|
| + ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(),
|
| + ZoneAllocationPolicy(zone));
|
| + if (p->value == nullptr) {
|
| + // The variable has not been declared yet -> insert it.
|
| + DCHECK_EQ(name, p->key);
|
| + p->value = kDummyPreParserVariable;
|
| + }
|
| +}
|
| +
|
| void VariableMap::Remove(Variable* var) {
|
| const AstRawString* name = var->raw_name();
|
| ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->hash());
|
| @@ -263,7 +278,14 @@ void DeclarationScope::SetDefaults() {
|
| arguments_ = nullptr;
|
| this_function_ = nullptr;
|
| should_eager_compile_ = false;
|
| - is_lazily_parsed_ = false;
|
| + was_lazily_parsed_ = false;
|
| +#ifdef DEBUG
|
| + DeclarationScope* outer_declaration_scope =
|
| + outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr;
|
| + is_being_lazily_parsed_ =
|
| + outer_declaration_scope ? outer_declaration_scope->is_being_lazily_parsed_
|
| + : false;
|
| +#endif
|
| }
|
|
|
| void Scope::SetDefaults() {
|
| @@ -305,7 +327,7 @@ bool DeclarationScope::ShouldEagerCompile() const {
|
| }
|
|
|
| void DeclarationScope::set_should_eager_compile() {
|
| - should_eager_compile_ = !is_lazily_parsed_;
|
| + should_eager_compile_ = !was_lazily_parsed_;
|
| }
|
|
|
| void DeclarationScope::set_asm_module() {
|
| @@ -866,6 +888,8 @@ Variable* DeclarationScope::DeclareParameter(
|
| DCHECK(is_function_scope() || is_module_scope());
|
| DCHECK(!has_rest_);
|
| DCHECK(!is_optional || !is_rest);
|
| + DCHECK(!is_being_lazily_parsed_);
|
| + DCHECK(!was_lazily_parsed_);
|
| Variable* var;
|
| if (mode == TEMPORARY) {
|
| var = NewTemporary(name);
|
| @@ -890,6 +914,8 @@ Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
|
| // introduced during variable allocation, and TEMPORARY variables are
|
| // allocated via NewTemporary().
|
| DCHECK(IsDeclaredVariableMode(mode));
|
| + DCHECK(!GetDeclarationScope()->is_being_lazily_parsed());
|
| + DCHECK(!GetDeclarationScope()->was_lazily_parsed());
|
| return Declare(zone(), name, mode, kind, init_flag, maybe_assigned_flag);
|
| }
|
|
|
| @@ -899,6 +925,8 @@ Variable* Scope::DeclareVariable(
|
| bool* sloppy_mode_block_scope_function_redefinition, bool* ok) {
|
| DCHECK(IsDeclaredVariableMode(mode));
|
| DCHECK(!already_resolved_);
|
| + DCHECK(!GetDeclarationScope()->is_being_lazily_parsed());
|
| + DCHECK(!GetDeclarationScope()->was_lazily_parsed());
|
|
|
| if (mode == VAR && !is_declaration_scope()) {
|
| return GetDeclarationScope()->DeclareVariable(
|
| @@ -997,6 +1025,26 @@ Variable* Scope::DeclareVariable(
|
| return var;
|
| }
|
|
|
| +void Scope::DeclareVariableName(const AstRawString* name, VariableMode mode) {
|
| + DCHECK(IsDeclaredVariableMode(mode));
|
| + DCHECK(!already_resolved_);
|
| + DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
|
| +
|
| + if (mode == VAR && !is_declaration_scope()) {
|
| + return GetDeclarationScope()->DeclareVariableName(name, mode);
|
| + }
|
| + DCHECK(!is_catch_scope());
|
| + DCHECK(!is_with_scope());
|
| + DCHECK(!is_eval_scope());
|
| + DCHECK(is_declaration_scope() ||
|
| + (IsLexicalVariableMode(mode) && is_block_scope()));
|
| +
|
| + // Declare the variable in the declaration scope.
|
| + if (LookupLocal(name) == nullptr) {
|
| + variables_.DeclareName(zone(), name);
|
| + }
|
| +}
|
| +
|
| VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory,
|
| const AstRawString* name,
|
| int start_position, VariableKind kind) {
|
| @@ -1271,7 +1319,7 @@ Scope* Scope::GetOuterScopeWithContext() {
|
|
|
| Handle<StringSet> DeclarationScope::CollectNonLocals(
|
| ParseInfo* info, Handle<StringSet> non_locals) {
|
| - VariableProxy* free_variables = FetchFreeVariables(this, true, info);
|
| + VariableProxy* free_variables = FetchFreeVariables(this, info);
|
| for (VariableProxy* proxy = free_variables; proxy != nullptr;
|
| proxy = proxy->next_unresolved()) {
|
| non_locals = StringSet::Add(non_locals, proxy->name());
|
| @@ -1307,9 +1355,10 @@ void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
|
|
|
| #ifdef DEBUG
|
| needs_migration_ = false;
|
| + is_being_lazily_parsed_ = false;
|
| #endif
|
|
|
| - is_lazily_parsed_ = !aborted;
|
| + was_lazily_parsed_ = !aborted;
|
| }
|
|
|
| void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) {
|
| @@ -1320,9 +1369,8 @@ void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) {
|
| // 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.
|
| - for (VariableProxy* proxy =
|
| - FetchFreeVariables(this, !FLAG_lazy_inner_functions);
|
| - proxy != nullptr; proxy = proxy->next_unresolved()) {
|
| + for (VariableProxy* proxy = FetchFreeVariables(this); proxy != nullptr;
|
| + proxy = proxy->next_unresolved()) {
|
| DCHECK(!proxy->is_resolved());
|
| VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
|
| copy->set_next_unresolved(unresolved);
|
| @@ -1490,7 +1538,7 @@ void Scope::Print(int n) {
|
| if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
|
| if (is_declaration_scope()) {
|
| DeclarationScope* scope = AsDeclarationScope();
|
| - if (scope->is_lazily_parsed()) Indent(n1, "// lazily parsed\n");
|
| + if (scope->was_lazily_parsed()) Indent(n1, "// lazily parsed\n");
|
| if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n");
|
| }
|
| if (num_stack_slots_ > 0) {
|
| @@ -1543,7 +1591,7 @@ void Scope::CheckZones() {
|
| DCHECK(!needs_migration_);
|
| for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
|
| if (scope->is_declaration_scope() &&
|
| - scope->AsDeclarationScope()->is_lazily_parsed()) {
|
| + scope->AsDeclarationScope()->was_lazily_parsed()) {
|
| DCHECK_NULL(scope->zone());
|
| DCHECK_NULL(scope->inner_scope_);
|
| continue;
|
| @@ -1599,6 +1647,13 @@ Variable* Scope::LookupRecursive(VariableProxy* proxy, Scope* outer_scope_end) {
|
| // The variable could not be resolved statically.
|
| if (var == nullptr) return var;
|
|
|
| + // TODO(marja): Separate LookupRecursive for preparsed scopes better.
|
| + if (var == kDummyPreParserVariable) {
|
| + DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
|
| + DCHECK(FLAG_lazy_inner_functions);
|
| + return var;
|
| + }
|
| +
|
| if (is_function_scope() && !var->is_dynamic()) {
|
| var->ForceContextAllocation();
|
| }
|
| @@ -1738,7 +1793,7 @@ void Scope::ResolveVariablesRecursively(ParseInfo* info) {
|
| // Lazy parsed declaration scopes are already partially analyzed. If there are
|
| // unresolved references remaining, they just need to be resolved in outer
|
| // scopes.
|
| - if (is_declaration_scope() && AsDeclarationScope()->is_lazily_parsed()) {
|
| + if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) {
|
| DCHECK(variables_.occupancy() == 0);
|
| for (VariableProxy* proxy = unresolved_; proxy != nullptr;
|
| proxy = proxy->next_unresolved()) {
|
| @@ -1765,34 +1820,34 @@ void Scope::ResolveVariablesRecursively(ParseInfo* info) {
|
| }
|
|
|
| VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope,
|
| - bool try_to_resolve, ParseInfo* info,
|
| + ParseInfo* info,
|
| VariableProxy* stack) {
|
| // Lazy parsed declaration scopes are already partially analyzed. If there are
|
| // unresolved references remaining, they just need to be resolved in outer
|
| // scopes.
|
| Scope* lookup =
|
| - is_declaration_scope() && AsDeclarationScope()->is_lazily_parsed()
|
| + is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()
|
| ? outer_scope()
|
| : this;
|
| for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr;
|
| proxy = next) {
|
| next = proxy->next_unresolved();
|
| DCHECK(!proxy->is_resolved());
|
| - Variable* var = nullptr;
|
| - if (try_to_resolve) {
|
| - var = lookup->LookupRecursive(proxy, max_outer_scope->outer_scope());
|
| - }
|
| + Variable* var =
|
| + lookup->LookupRecursive(proxy, max_outer_scope->outer_scope());
|
| if (var == nullptr) {
|
| proxy->set_next_unresolved(stack);
|
| stack = proxy;
|
| - } else if (info != nullptr) {
|
| - // In this case we need to leave scopes in a way that they can be
|
| - // allocated. If we resolved variables from lazy parsed scopes, we need to
|
| - // context allocate the var.
|
| - ResolveTo(info, proxy, var);
|
| - if (!var->is_dynamic() && lookup != this) var->ForceContextAllocation();
|
| - } else {
|
| - var->set_is_used();
|
| + } else if (var != kDummyPreParserVariable) {
|
| + if (info != nullptr) {
|
| + // In this case we need to leave scopes in a way that they can be
|
| + // allocated. If we resolved variables from lazy parsed scopes, we need
|
| + // to context allocate the var.
|
| + ResolveTo(info, proxy, var);
|
| + if (!var->is_dynamic() && lookup != this) var->ForceContextAllocation();
|
| + } else {
|
| + var->set_is_used();
|
| + }
|
| }
|
| }
|
|
|
| @@ -1800,8 +1855,7 @@ VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope,
|
| unresolved_ = nullptr;
|
|
|
| for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
|
| - stack =
|
| - scope->FetchFreeVariables(max_outer_scope, try_to_resolve, info, stack);
|
| + stack = scope->FetchFreeVariables(max_outer_scope, info, stack);
|
| }
|
|
|
| return stack;
|
| @@ -1982,7 +2036,7 @@ void Scope::AllocateVariablesRecursively() {
|
| DCHECK(!already_resolved_);
|
| DCHECK_EQ(0, num_stack_slots_);
|
| // Don't allocate variables of preparsed scopes.
|
| - if (is_declaration_scope() && AsDeclarationScope()->is_lazily_parsed()) {
|
| + if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) {
|
| return;
|
| }
|
|
|
|
|