Commit 92841799 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[parser] Declarations store Variables not proxies

Storing a VariableProxy in declarations means that a declaration and
initialisation assignment are tightly coupled to use the same var. In
particular, this means that Var declarations in with scopes have to
clone the VariableProxy to split the declaration and initializer LHS
lookup.

This patch changes declarations to point directly to the Variable, not
the VariableProxy. This will allow future refactoring to decouple
declarations and initialisations.

Change-Id: I0baa77bfd12fe175f9521d292740d7d712cffd37
Reviewed-on: https://chromium-review.googlesource.com/c/1406683Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58843}
parent b12390b2
...@@ -431,14 +431,14 @@ class Declaration : public AstNode { ...@@ -431,14 +431,14 @@ class Declaration : public AstNode {
public: public:
typedef base::ThreadedList<Declaration> List; typedef base::ThreadedList<Declaration> List;
VariableProxy* proxy() const { return proxy_; } Variable* var() const { return var_; }
void set_var(Variable* var) { var_ = var; }
protected: protected:
Declaration(VariableProxy* proxy, int pos, NodeType type) Declaration(int pos, NodeType type) : AstNode(pos, type), next_(nullptr) {}
: AstNode(pos, type), proxy_(proxy), next_(nullptr) {}
private: private:
VariableProxy* proxy_; Variable* var_;
// Declarations list threaded through the declarations. // Declarations list threaded through the declarations.
Declaration** next() { return &next_; } Declaration** next() { return &next_; }
Declaration* next_; Declaration* next_;
...@@ -457,8 +457,8 @@ class VariableDeclaration : public Declaration { ...@@ -457,8 +457,8 @@ class VariableDeclaration : public Declaration {
: public BitField<bool, Declaration::kNextBitFieldIndex, 1> {}; : public BitField<bool, Declaration::kNextBitFieldIndex, 1> {};
protected: protected:
VariableDeclaration(VariableProxy* proxy, int pos, bool is_nested = false) explicit VariableDeclaration(int pos, bool is_nested = false)
: Declaration(proxy, pos, kVariableDeclaration) { : Declaration(pos, kVariableDeclaration) {
bit_field_ = IsNestedField::update(bit_field_, is_nested); bit_field_ = IsNestedField::update(bit_field_, is_nested);
} }
...@@ -475,8 +475,8 @@ class NestedVariableDeclaration final : public VariableDeclaration { ...@@ -475,8 +475,8 @@ class NestedVariableDeclaration final : public VariableDeclaration {
private: private:
friend class AstNodeFactory; friend class AstNodeFactory;
NestedVariableDeclaration(VariableProxy* proxy, Scope* scope, int pos) NestedVariableDeclaration(Scope* scope, int pos)
: VariableDeclaration(proxy, pos, true), scope_(scope) {} : VariableDeclaration(pos, true), scope_(scope) {}
// Nested scope from which the declaration originated. // Nested scope from which the declaration originated.
Scope* scope_; Scope* scope_;
...@@ -501,9 +501,9 @@ class FunctionDeclaration final : public Declaration { ...@@ -501,9 +501,9 @@ class FunctionDeclaration final : public Declaration {
class DeclaresSloppyBlockFunction class DeclaresSloppyBlockFunction
: public BitField<bool, Declaration::kNextBitFieldIndex, 1> {}; : public BitField<bool, Declaration::kNextBitFieldIndex, 1> {};
FunctionDeclaration(VariableProxy* proxy, FunctionLiteral* fun, FunctionDeclaration(FunctionLiteral* fun, bool declares_sloppy_block_function,
bool declares_sloppy_block_function, int pos) int pos)
: Declaration(proxy, pos, kFunctionDeclaration), fun_(fun) { : Declaration(pos, kFunctionDeclaration), fun_(fun) {
bit_field_ = DeclaresSloppyBlockFunction::update( bit_field_ = DeclaresSloppyBlockFunction::update(
bit_field_, declares_sloppy_block_function); bit_field_, declares_sloppy_block_function);
} }
...@@ -2812,22 +2812,19 @@ class AstNodeFactory final { ...@@ -2812,22 +2812,19 @@ class AstNodeFactory final {
AstNodeFactory* ast_node_factory() { return this; } AstNodeFactory* ast_node_factory() { return this; }
AstValueFactory* ast_value_factory() const { return ast_value_factory_; } AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy, int pos) { VariableDeclaration* NewVariableDeclaration(int pos) {
return new (zone_) VariableDeclaration(proxy, pos); return new (zone_) VariableDeclaration(pos);
} }
NestedVariableDeclaration* NewNestedVariableDeclaration(VariableProxy* proxy, NestedVariableDeclaration* NewNestedVariableDeclaration(Scope* scope,
Scope* scope,
int pos) { int pos) {
return new (zone_) NestedVariableDeclaration(proxy, scope, pos); return new (zone_) NestedVariableDeclaration(scope, pos);
} }
FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy, FunctionDeclaration* NewFunctionDeclaration(FunctionLiteral* fun,
FunctionLiteral* fun,
bool is_sloppy_block_function, bool is_sloppy_block_function,
int pos) { int pos) {
return new (zone_) return new (zone_) FunctionDeclaration(fun, is_sloppy_block_function, pos);
FunctionDeclaration(proxy, fun, is_sloppy_block_function, pos);
} }
Block* NewBlock(int capacity, bool ignore_completion_value) { Block* NewBlock(int capacity, bool ignore_completion_value) {
......
...@@ -848,15 +848,15 @@ void AstPrinter::VisitBlock(Block* node) { ...@@ -848,15 +848,15 @@ void AstPrinter::VisitBlock(Block* node) {
// TODO(svenpanne) Start with IndentedScope. // TODO(svenpanne) Start with IndentedScope.
void AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) { void AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
PrintLiteralWithModeIndented("VARIABLE", node->proxy()->var(), PrintLiteralWithModeIndented("VARIABLE", node->var(),
node->proxy()->raw_name()); node->var()->raw_name());
} }
// TODO(svenpanne) Start with IndentedScope. // TODO(svenpanne) Start with IndentedScope.
void AstPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) { void AstPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
PrintIndented("FUNCTION "); PrintIndented("FUNCTION ");
PrintLiteral(node->proxy()->raw_name(), true); PrintLiteral(node->var()->raw_name(), true);
Print(" = function "); Print(" = function ");
PrintLiteral(node->fun()->raw_name(), false); PrintLiteral(node->fun()->raw_name(), false);
Print("\n"); Print("\n");
......
...@@ -560,12 +560,11 @@ void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) { ...@@ -560,12 +560,11 @@ void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
if (factory) { if (factory) {
DCHECK(!is_being_lazily_parsed_); DCHECK(!is_being_lazily_parsed_);
VariableProxy* proxy = factory->NewVariableProxy(name, NORMAL_VARIABLE); VariableProxy* proxy = factory->NewVariableProxy(name, NORMAL_VARIABLE);
auto declaration = auto declaration = factory->NewVariableDeclaration(kNoSourcePosition);
factory->NewVariableDeclaration(proxy, kNoSourcePosition);
// Based on the preceding checks, it doesn't matter what we pass as // Based on the preceding checks, it doesn't matter what we pass as
// sloppy_mode_block_scope_function_redefinition. // sloppy_mode_block_scope_function_redefinition.
bool ok = true; bool ok = true;
DeclareVariable(declaration, VariableMode::kVar, NORMAL_VARIABLE, DeclareVariable(declaration, proxy, VariableMode::kVar, NORMAL_VARIABLE,
Variable::DefaultInitializationFlag(VariableMode::kVar), Variable::DefaultInitializationFlag(VariableMode::kVar),
nullptr, &ok); nullptr, &ok);
DCHECK(ok); DCHECK(ok);
...@@ -977,8 +976,11 @@ Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, ...@@ -977,8 +976,11 @@ Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
return Declare(zone(), name, mode, kind, init_flag); return Declare(zone(), name, mode, kind, init_flag);
} }
void Scope::DeclareVariable(Declaration* declaration, VariableMode mode, // TODO(leszeks): Avoid passing the proxy into here, passing the raw_name alone
VariableKind kind, InitializationFlag init, // instead.
void Scope::DeclareVariable(Declaration* declaration, VariableProxy* proxy,
VariableMode mode, VariableKind kind,
InitializationFlag init,
bool* sloppy_mode_block_scope_function_redefinition, bool* sloppy_mode_block_scope_function_redefinition,
bool* ok) { bool* ok) {
DCHECK(IsDeclaredVariableMode(mode)); DCHECK(IsDeclaredVariableMode(mode));
...@@ -988,7 +990,7 @@ void Scope::DeclareVariable(Declaration* declaration, VariableMode mode, ...@@ -988,7 +990,7 @@ void Scope::DeclareVariable(Declaration* declaration, VariableMode mode,
if (mode == VariableMode::kVar && !is_declaration_scope()) { if (mode == VariableMode::kVar && !is_declaration_scope()) {
return GetDeclarationScope()->DeclareVariable( return GetDeclarationScope()->DeclareVariable(
declaration, mode, kind, init, declaration, proxy, mode, kind, init,
sloppy_mode_block_scope_function_redefinition, ok); sloppy_mode_block_scope_function_redefinition, ok);
} }
DCHECK(!is_catch_scope()); DCHECK(!is_catch_scope());
...@@ -996,7 +998,6 @@ void Scope::DeclareVariable(Declaration* declaration, VariableMode mode, ...@@ -996,7 +998,6 @@ void Scope::DeclareVariable(Declaration* declaration, VariableMode mode,
DCHECK(is_declaration_scope() || DCHECK(is_declaration_scope() ||
(IsLexicalVariableMode(mode) && is_block_scope())); (IsLexicalVariableMode(mode) && is_block_scope()));
VariableProxy* proxy = declaration->proxy();
DCHECK_NOT_NULL(proxy->raw_name()); DCHECK_NOT_NULL(proxy->raw_name());
const AstRawString* name = proxy->raw_name(); const AstRawString* name = proxy->raw_name();
...@@ -1073,6 +1074,7 @@ void Scope::DeclareVariable(Declaration* declaration, VariableMode mode, ...@@ -1073,6 +1074,7 @@ void Scope::DeclareVariable(Declaration* declaration, VariableMode mode,
// semantic issue, but it may be a performance issue since it may // semantic issue, but it may be a performance issue since it may
// lead to repeated DeclareEvalVar or DeclareEvalFunction calls. // lead to repeated DeclareEvalVar or DeclareEvalFunction calls.
decls_.Add(declaration); decls_.Add(declaration);
declaration->set_var(var);
proxy->BindTo(var); proxy->BindTo(var);
} }
...@@ -1160,13 +1162,13 @@ Declaration* Scope::CheckConflictingVarDeclarations() { ...@@ -1160,13 +1162,13 @@ Declaration* Scope::CheckConflictingVarDeclarations() {
// are lexical vs nested var. // are lexical vs nested var.
if (decl->IsVariableDeclaration() && if (decl->IsVariableDeclaration() &&
decl->AsVariableDeclaration()->AsNested() != nullptr) { decl->AsVariableDeclaration()->AsNested() != nullptr) {
DCHECK_EQ(decl->proxy()->var()->mode(), VariableMode::kVar); DCHECK_EQ(decl->var()->mode(), VariableMode::kVar);
Scope* current = decl->AsVariableDeclaration()->AsNested()->scope(); Scope* current = decl->AsVariableDeclaration()->AsNested()->scope();
// Iterate through all scopes until and including the declaration scope. // Iterate through all scopes until and including the declaration scope.
while (true) { while (true) {
// There is a conflict if there exists a non-VAR binding. // There is a conflict if there exists a non-VAR binding.
Variable* other_var = Variable* other_var =
current->variables_.Lookup(decl->proxy()->raw_name()); current->variables_.Lookup(decl->var()->raw_name());
if (other_var != nullptr && IsLexicalVariableMode(other_var->mode())) { if (other_var != nullptr && IsLexicalVariableMode(other_var->mode())) {
return decl; return decl;
} }
......
...@@ -226,8 +226,9 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { ...@@ -226,8 +226,9 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
VariableKind kind = NORMAL_VARIABLE, VariableKind kind = NORMAL_VARIABLE,
InitializationFlag init_flag = kCreatedInitialized); InitializationFlag init_flag = kCreatedInitialized);
void DeclareVariable(Declaration* declaration, VariableMode mode, void DeclareVariable(Declaration* declaration, VariableProxy* proxy,
VariableKind kind, InitializationFlag init, VariableMode mode, VariableKind kind,
InitializationFlag init,
bool* sloppy_mode_block_scope_function_redefinition, bool* sloppy_mode_block_scope_function_redefinition,
bool* ok); bool* ok);
......
...@@ -1220,7 +1220,7 @@ void BytecodeGenerator::VisitBlockDeclarationsAndStatements(Block* stmt) { ...@@ -1220,7 +1220,7 @@ void BytecodeGenerator::VisitBlockDeclarationsAndStatements(Block* stmt) {
} }
void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
Variable* variable = decl->proxy()->var(); Variable* variable = decl->var();
switch (variable->location()) { switch (variable->location()) {
case VariableLocation::UNALLOCATED: { case VariableLocation::UNALLOCATED: {
DCHECK(!variable->binding_needs_init()); DCHECK(!variable->binding_needs_init());
...@@ -1271,7 +1271,7 @@ void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { ...@@ -1271,7 +1271,7 @@ void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
} }
void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
Variable* variable = decl->proxy()->var(); Variable* variable = decl->var();
DCHECK(variable->mode() == VariableMode::kLet || DCHECK(variable->mode() == VariableMode::kLet ||
variable->mode() == VariableMode::kVar); variable->mode() == VariableMode::kVar);
switch (variable->location()) { switch (variable->location()) {
......
...@@ -1361,34 +1361,33 @@ void Parser::DeclareVariable(VariableProxy* proxy, VariableKind kind, ...@@ -1361,34 +1361,33 @@ void Parser::DeclareVariable(VariableProxy* proxy, VariableKind kind,
Declaration* declaration; Declaration* declaration;
if (mode == VariableMode::kVar && !scope->is_declaration_scope()) { if (mode == VariableMode::kVar && !scope->is_declaration_scope()) {
DCHECK(scope->is_block_scope() || scope->is_with_scope()); DCHECK(scope->is_block_scope() || scope->is_with_scope());
declaration = factory()->NewNestedVariableDeclaration(proxy, scope, begin); declaration = factory()->NewNestedVariableDeclaration(scope, begin);
} else { } else {
declaration = factory()->NewVariableDeclaration(proxy, begin); declaration = factory()->NewVariableDeclaration(begin);
} }
Declare(declaration, kind, mode, init, scope, end); Declare(declaration, proxy, kind, mode, init, scope, end);
} }
void Parser::Declare(Declaration* declaration, VariableKind variable_kind, void Parser::Declare(Declaration* declaration, VariableProxy* proxy,
VariableMode mode, InitializationFlag init, Scope* scope, VariableKind variable_kind, VariableMode mode,
int var_end_pos) { InitializationFlag init, Scope* scope, int var_end_pos) {
bool local_ok = true; bool local_ok = true;
bool sloppy_mode_block_scope_function_redefinition = false; bool sloppy_mode_block_scope_function_redefinition = false;
scope->DeclareVariable(declaration, mode, variable_kind, init, scope->DeclareVariable(declaration, proxy, mode, variable_kind, init,
&sloppy_mode_block_scope_function_redefinition, &sloppy_mode_block_scope_function_redefinition,
&local_ok); &local_ok);
if (!local_ok) { if (!local_ok) {
// If we only have the start position of a proxy, we can't highlight the // If we only have the start position of a proxy, we can't highlight the
// whole variable name. Pretend its length is 1 so that we highlight at // whole variable name. Pretend its length is 1 so that we highlight at
// least the first character. // least the first character.
Scanner::Location loc(declaration->proxy()->position(), Scanner::Location loc(proxy->position(), var_end_pos != kNoSourcePosition
var_end_pos != kNoSourcePosition
? var_end_pos ? var_end_pos
: declaration->proxy()->position() + 1); : proxy->position() + 1);
if (variable_kind == PARAMETER_VARIABLE) { if (variable_kind == PARAMETER_VARIABLE) {
ReportMessageAt(loc, MessageTemplate::kParamDupe); ReportMessageAt(loc, MessageTemplate::kParamDupe);
} else { } else {
ReportMessageAt(loc, MessageTemplate::kVarRedeclaration, ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
declaration->proxy()->raw_name()); declaration->var()->raw_name());
} }
} else if (sloppy_mode_block_scope_function_redefinition) { } else if (sloppy_mode_block_scope_function_redefinition) {
++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition]; ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
...@@ -1414,8 +1413,9 @@ Statement* Parser::DeclareFunction(const AstRawString* variable_name, ...@@ -1414,8 +1413,9 @@ Statement* Parser::DeclareFunction(const AstRawString* variable_name,
VariableProxy* proxy = VariableProxy* proxy =
factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE, beg_pos); factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE, beg_pos);
Declaration* declaration = factory()->NewFunctionDeclaration( Declaration* declaration = factory()->NewFunctionDeclaration(
proxy, function, is_sloppy_block_function, beg_pos); function, is_sloppy_block_function, beg_pos);
Declare(declaration, NORMAL_VARIABLE, mode, kCreatedInitialized, scope()); Declare(declaration, proxy, NORMAL_VARIABLE, mode, kCreatedInitialized,
scope());
if (names) names->Add(variable_name, zone()); if (names) names->Add(variable_name, zone());
if (is_sloppy_block_function) { if (is_sloppy_block_function) {
SloppyBlockFunctionStatement* statement = SloppyBlockFunctionStatement* statement =
...@@ -1601,8 +1601,8 @@ Block* Parser::RewriteCatchPattern(CatchInfo* catch_info) { ...@@ -1601,8 +1601,8 @@ Block* Parser::RewriteCatchPattern(CatchInfo* catch_info) {
void Parser::ReportVarRedeclarationIn(const AstRawString* name, Scope* scope) { void Parser::ReportVarRedeclarationIn(const AstRawString* name, Scope* scope) {
for (Declaration* decl : *scope->declarations()) { for (Declaration* decl : *scope->declarations()) {
if (decl->proxy()->raw_name() == name) { if (decl->var()->raw_name() == name) {
int position = decl->proxy()->position(); int position = decl->position();
Scanner::Location location = Scanner::Location location =
position == kNoSourcePosition position == kNoSourcePosition
? Scanner::Location::invalid() ? Scanner::Location::invalid()
...@@ -2968,8 +2968,8 @@ void Parser::CheckConflictingVarDeclarations(Scope* scope) { ...@@ -2968,8 +2968,8 @@ void Parser::CheckConflictingVarDeclarations(Scope* scope) {
Declaration* decl = scope->CheckConflictingVarDeclarations(); Declaration* decl = scope->CheckConflictingVarDeclarations();
if (decl != nullptr) { if (decl != nullptr) {
// In ES6, conflicting variable bindings are early errors. // In ES6, conflicting variable bindings are early errors.
const AstRawString* name = decl->proxy()->raw_name(); const AstRawString* name = decl->var()->raw_name();
int position = decl->proxy()->position(); int position = decl->position();
Scanner::Location location = Scanner::Location location =
position == kNoSourcePosition position == kNoSourcePosition
? Scanner::Location::invalid() ? Scanner::Location::invalid()
...@@ -2997,11 +2997,11 @@ void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) { ...@@ -2997,11 +2997,11 @@ void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
DCHECK(function_scope->is_function_scope()); DCHECK(function_scope->is_function_scope());
BlockState block_state(&scope_, inner_scope); BlockState block_state(&scope_, inner_scope);
for (Declaration* decl : *inner_scope->declarations()) { for (Declaration* decl : *inner_scope->declarations()) {
if (decl->proxy()->var()->mode() != VariableMode::kVar || if (decl->var()->mode() != VariableMode::kVar ||
!decl->IsVariableDeclaration()) { !decl->IsVariableDeclaration()) {
continue; continue;
} }
const AstRawString* name = decl->proxy()->raw_name(); const AstRawString* name = decl->var()->raw_name();
Variable* parameter = function_scope->LookupLocal(name); Variable* parameter = function_scope->LookupLocal(name);
if (parameter == nullptr) continue; if (parameter == nullptr) continue;
VariableProxy* to = NewUnresolved(name); VariableProxy* to = NewUnresolved(name);
......
...@@ -431,9 +431,9 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -431,9 +431,9 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
VariableMode mode, InitializationFlag init, VariableMode mode, InitializationFlag init,
Scope* declaration_scope, int begin, Scope* declaration_scope, int begin,
int end = kNoSourcePosition); int end = kNoSourcePosition);
void Declare(Declaration* declaration, VariableKind kind, VariableMode mode, void Declare(Declaration* declaration, VariableProxy* proxy,
InitializationFlag init, Scope* declaration_scope, VariableKind kind, VariableMode mode, InitializationFlag init,
int var_end_pos = kNoSourcePosition); Scope* declaration_scope, int var_end_pos = kNoSourcePosition);
bool TargetStackContainsLabel(const AstRawString* label); bool TargetStackContainsLabel(const AstRawString* label);
BreakableStatement* LookupBreakTarget(const AstRawString* label); BreakableStatement* LookupBreakTarget(const AstRawString* label);
......
This diff is collapsed.
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