Commit 4484bb41 authored by verwaest's avatar verwaest Committed by Commit bot

Introduce ModuleScope subclass of DeclarationScope

This moves the module_descriptor_ field to that subclass, as well as other module-only methods.

BUG=v8:5209

Review-Url: https://codereview.chromium.org/2252223002
Cr-Commit-Position: refs/heads/master@{#38703}
parent 03d5f875
......@@ -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);
......
......@@ -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 {
......
......@@ -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<const DeclarationScope*>(this);
}
ModuleScope* Scope::AsModuleScope() {
DCHECK(is_module_scope());
return static_cast<ModuleScope*>(this);
}
const ModuleScope* Scope::AsModuleScope() const {
DCHECK(is_module_scope());
return static_cast<const ModuleScope*>(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();
}
......
......@@ -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_;
};
......
......@@ -430,6 +430,7 @@ class ParameterCount;
class Foreign;
class Scope;
class DeclarationScope;
class ModuleScope;
class ScopeInfo;
class Script;
class Smi;
......
......@@ -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(); }
......
......@@ -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
......
......@@ -1036,7 +1036,7 @@ class PreParser : public ParserBase<PreParserTraits> {
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
......
......@@ -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());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment