diff --git a/src/ast/modules.cc b/src/ast/modules.cc index a5ef69e1bb..cd47c00b92 100644 --- a/src/ast/modules.cc +++ b/src/ast/modules.cc @@ -97,10 +97,9 @@ void ModuleDescriptor::MakeIndirectExportsExplicit() { } } -bool ModuleDescriptor::Validate(DeclarationScope* module_scope, +bool ModuleDescriptor::Validate(ModuleScope* module_scope, PendingCompilationErrorHandler* error_handler, Zone* zone) { - DCHECK(module_scope->is_module_scope()); DCHECK_EQ(this, module_scope->module()); DCHECK_NOT_NULL(error_handler); diff --git a/src/ast/modules.h b/src/ast/modules.h index 5f63fce269..c8f7aa3793 100644 --- a/src/ast/modules.h +++ b/src/ast/modules.h @@ -64,7 +64,7 @@ class ModuleDescriptor : public ZoneObject { // Check if module is well-formed and report error if not. // Also canonicalize indirect exports. - bool Validate(DeclarationScope* module_scope, + bool Validate(ModuleScope* module_scope, PendingCompilationErrorHandler* error_handler, Zone* zone); struct ModuleEntry : public ZoneObject { diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc index c6f7e0c15e..7df1a00b29 100644 --- a/src/ast/scopes.cc +++ b/src/ast/scopes.cc @@ -111,10 +111,14 @@ DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope, params_(4, zone), sloppy_block_function_map_(zone) { SetDefaults(); - if (scope_type == MODULE_SCOPE) { - module_descriptor_ = new (zone) ModuleDescriptor(zone); - language_mode_ = STRICT; - } +} + +ModuleScope::ModuleScope(Zone* zone, DeclarationScope* script_scope, + AstValueFactory* ast_value_factory) + : DeclarationScope(zone, script_scope, MODULE_SCOPE) { + module_descriptor_ = new (zone) ModuleDescriptor(zone); + set_language_mode(STRICT); + DeclareThis(ast_value_factory); } Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, @@ -181,7 +185,6 @@ void DeclarationScope::SetDefaults() { arity_ = 0; rest_parameter_ = nullptr; rest_index_ = -1; - module_descriptor_ = nullptr; } void Scope::SetDefaults() { @@ -366,6 +369,16 @@ const DeclarationScope* Scope::AsDeclarationScope() const { return static_cast(this); } +ModuleScope* Scope::AsModuleScope() { + DCHECK(is_module_scope()); + return static_cast(this); +} + +const ModuleScope* Scope::AsModuleScope() const { + DCHECK(is_module_scope()); + return static_cast(this); +} + int Scope::num_parameters() const { return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0; } @@ -1690,7 +1703,7 @@ void DeclarationScope::AllocateLocals() { } } -void DeclarationScope::AllocateModuleVariables() { +void ModuleScope::AllocateModuleVariables() { for (auto it = module()->regular_imports().begin(); it != module()->regular_imports().end(); ++it) { Variable* var = LookupLocal(it->second->local_name); @@ -1721,7 +1734,7 @@ void Scope::AllocateVariablesRecursively() { // Parameters must be allocated first, if any. if (is_declaration_scope()) { if (is_module_scope()) { - AsDeclarationScope()->AllocateModuleVariables(); + AsModuleScope()->AllocateModuleVariables(); } else if (is_function_scope()) { AsDeclarationScope()->AllocateParameterLocals(); } diff --git a/src/ast/scopes.h b/src/ast/scopes.h index 8cfac5262a..05df42c198 100644 --- a/src/ast/scopes.h +++ b/src/ast/scopes.h @@ -69,13 +69,10 @@ class SloppyBlockFunctionMap : public ZoneHashMap { // a location. Note that many VariableProxy nodes may refer to the same Java- // Script variable. -class DeclarationScope; - -// JS environments are represented in the parser using two scope classes, Scope -// and its subclass DeclarationScope. DeclarationScope is used for any scope -// that hosts 'var' declarations. This includes script, module, eval, varblock, -// and function scope. All fields required by such scopes are only available on -// DeclarationScope. +// JS environments are represented in the parser using Scope, DeclarationScope +// and ModuleScope. DeclarationScope is used for any scope that hosts 'var' +// declarations. This includes script, module, eval, varblock, and function +// scope. ModuleScope further specializes DeclarationScope. class Scope: public ZoneObject { public: // --------------------------------------------------------------------------- @@ -95,6 +92,8 @@ class Scope: public ZoneObject { DeclarationScope* AsDeclarationScope(); const DeclarationScope* AsDeclarationScope() const; + ModuleScope* AsModuleScope(); + const ModuleScope* AsModuleScope() const; class Snapshot final BASE_EMBEDDED { public: @@ -444,6 +443,11 @@ class Scope: public ZoneObject { bool HasSimpleParameters(); void set_is_debug_evaluate_scope() { is_debug_evaluate_scope_ = true; } + protected: + void set_language_mode(LanguageMode language_mode) { + language_mode_ = language_mode; + } + private: Zone* zone_; @@ -673,14 +677,6 @@ class DeclarationScope : public Scope { IsClassConstructor(function_kind()))); } - // The ModuleDescriptor for this scope; only for module scopes. - // TODO(verwaest): Move to ModuleScope? - ModuleDescriptor* module() const { - DCHECK(is_module_scope()); - DCHECK_NOT_NULL(module_descriptor_); - return module_descriptor_; - } - void DeclareThis(AstValueFactory* ast_value_factory); void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory); @@ -847,9 +843,6 @@ class DeclarationScope : public Scope { void AllocateLocals(); void AllocateParameterLocals(); void AllocateReceiver(); - // Set MODULE as VariableLocation for all variables that will live in some - // module's export table. - void AllocateModuleVariables(); private: void AllocateParameter(Variable* var, int index); @@ -881,7 +874,23 @@ class DeclarationScope : public Scope { Variable* arguments_; // Convenience variable; Subclass constructor only Variable* this_function_; - // Module descriptor; module scopes only. +}; + +class ModuleScope final : public DeclarationScope { + public: + ModuleScope(Zone* zone, DeclarationScope* script_scope, + AstValueFactory* ast_value_factory); + + ModuleDescriptor* module() const { + DCHECK_NOT_NULL(module_descriptor_); + return module_descriptor_; + } + + // Set MODULE as VariableLocation for all variables that will live in some + // module's export table. + void AllocateModuleVariables(); + + private: ModuleDescriptor* module_descriptor_; }; diff --git a/src/globals.h b/src/globals.h index 6fc93d92db..eec83edaae 100644 --- a/src/globals.h +++ b/src/globals.h @@ -430,6 +430,7 @@ class ParameterCount; class Foreign; class Scope; class DeclarationScope; +class ModuleScope; class ScopeInfo; class Script; class Smi; diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h index 192235dd77..b3b516ead1 100644 --- a/src/parsing/parser-base.h +++ b/src/parsing/parser-base.h @@ -618,12 +618,8 @@ class ParserBase : public Traits { return new (zone()) DeclarationScope(zone(), scope(), BLOCK_SCOPE); } - DeclarationScope* NewModuleScope(Scope* parent) { - DeclarationScope* result = - new (zone()) DeclarationScope(zone(), parent, MODULE_SCOPE); - // TODO(verwaest): Move into the DeclarationScope constructor. - result->DeclareThis(ast_value_factory()); - return result; + ModuleScope* NewModuleScope(DeclarationScope* parent) { + return new (zone()) ModuleScope(zone(), parent, ast_value_factory()); } DeclarationScope* NewEvalScope(Scope* parent) { @@ -1234,7 +1230,7 @@ class ParserBase : public Traits { }; ModuleDescriptor* module() const { - return scope()->AsDeclarationScope()->module(); + return scope()->AsModuleScope()->module(); } Scope* scope() const { return scope_state_->scope(); } diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc index f60c05896f..da300a8139 100644 --- a/src/parsing/parser.cc +++ b/src/parsing/parser.cc @@ -1004,7 +1004,8 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) { } outer = NewEvalScope(outer); } else if (info->is_module()) { - outer = NewModuleScope(outer); + DCHECK_EQ(outer, info->script_scope()); + outer = NewModuleScope(info->script_scope()); } DeclarationScope* scope = outer->AsDeclarationScope(); @@ -1023,7 +1024,7 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) { if (parsing_module_) { ParseModuleItemList(body, &ok); ok = ok && - module()->Validate(this->scope()->AsDeclarationScope(), + module()->Validate(this->scope()->AsModuleScope(), &pending_error_handler_, zone()); } else { // Don't count the mode in the use counters--give the program a chance diff --git a/src/parsing/preparser.h b/src/parsing/preparser.h index 2499769e97..484da2e2a5 100644 --- a/src/parsing/preparser.h +++ b/src/parsing/preparser.h @@ -1036,7 +1036,7 @@ class PreParser : public ParserBase { PreParseResult PreParseProgram(int* materialized_literals = 0, bool is_module = false) { DCHECK_NULL(scope_state_); - Scope* scope = NewScriptScope(); + DeclarationScope* scope = NewScriptScope(); // ModuleDeclarationInstantiation for Source Text Module Records creates a // new Module Environment Record whose outer lexical environment record is diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc index 5f944a88b5..12c6a4012d 100644 --- a/test/cctest/test-parsing.cc +++ b/test/cctest/test-parsing.cc @@ -5982,7 +5982,7 @@ TEST(ModuleParsingInternals) { CHECK(parser.Parse(&info)); CHECK(i::Compiler::Analyze(&info)); i::FunctionLiteral* func = info.literal(); - i::DeclarationScope* module_scope = func->scope(); + i::ModuleScope* module_scope = func->scope()->AsModuleScope(); i::Scope* outer_scope = module_scope->outer_scope(); CHECK(outer_scope->is_script_scope()); CHECK_NULL(outer_scope->outer_scope());