Commit f9529f6b authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[parser] Disambiguate variables through expression-scope

Previously we'd always push variable proxies into the unresolved list of the
current scope, and possibly delete them from the list later in case they end up
being declarations. If variables become assigned, there were two ways to mark
them as such: The preparser would marked the variables tracked on the
PreParserExpression, and the parser would traverse the LHS AST to find and mark
all variables.

After this CL, if the scope already knows it's tracking declarations, the
variables are never added to the unresolved list in the first place. If the
scope is ambigous, it tracks the variable proxies on the side and only adds
them to the unresolved list if they end up being references rather than
declarations. The same list is now used to bulk mark all LHS variables as
assigned; uniformely for both the parser and the preparser.

In a next step we'll also use the scope to create declarations. That way we can
stop tracking variables_ on PreParserExpression altogether.

Change-Id: I6ada37006cc2e066731f29cd4ea314550fc7959f
Reviewed-on: https://chromium-review.googlesource.com/c/1397669
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58629}
parent 3427ec9d
...@@ -577,13 +577,6 @@ void AstTraversalVisitor<Subclass>::VisitSuperCallReference( ...@@ -577,13 +577,6 @@ void AstTraversalVisitor<Subclass>::VisitSuperCallReference(
RECURSE_EXPRESSION(VisitVariableProxy(expr->this_function_var())); RECURSE_EXPRESSION(VisitVariableProxy(expr->this_function_var()));
} }
template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitRewritableExpression(
RewritableExpression* expr) {
PROCESS_EXPRESSION(expr);
RECURSE(Visit(expr->expression()));
}
#undef PROCESS_NODE #undef PROCESS_NODE
#undef PROCESS_EXPRESSION #undef PROCESS_EXPRESSION
#undef RECURSE_EXPRESSION #undef RECURSE_EXPRESSION
......
...@@ -96,7 +96,6 @@ namespace internal { ...@@ -96,7 +96,6 @@ namespace internal {
V(NativeFunctionLiteral) \ V(NativeFunctionLiteral) \
V(Property) \ V(Property) \
V(ResolvedProperty) \ V(ResolvedProperty) \
V(RewritableExpression) \
V(Spread) \ V(Spread) \
V(StoreInArrayLiteral) \ V(StoreInArrayLiteral) \
V(SuperCallReference) \ V(SuperCallReference) \
...@@ -2197,58 +2196,6 @@ class CompoundAssignment final : public Assignment { ...@@ -2197,58 +2196,6 @@ class CompoundAssignment final : public Assignment {
BinaryOperation* binary_operation_; BinaryOperation* binary_operation_;
}; };
// The RewritableExpression class is a wrapper for AST nodes that wait
// for some potential rewriting. However, even if such nodes are indeed
// rewritten, the RewritableExpression wrapper nodes will survive in the
// final AST and should be just ignored, i.e., they should be treated as
// equivalent to the wrapped nodes. For this reason and to simplify later
// phases, RewritableExpressions are considered as exceptions of AST nodes
// in the following sense:
//
// 1. IsRewritableExpression and AsRewritableExpression behave as usual.
// 2. All other Is* and As* methods are practically delegated to the
// wrapped node, i.e. IsArrayLiteral() will return true iff the
// wrapped node is an array literal.
//
// Furthermore, an invariant that should be respected is that the wrapped
// node is not a RewritableExpression.
class RewritableExpression final : public Expression {
public:
Expression* expression() const { return expr_; }
bool is_rewritten() const { return IsRewrittenField::decode(bit_field_); }
void set_rewritten() {
bit_field_ = IsRewrittenField::update(bit_field_, true);
}
void Rewrite(Expression* new_expression) {
DCHECK(!is_rewritten());
DCHECK_NOT_NULL(new_expression);
DCHECK(!new_expression->IsRewritableExpression());
expr_ = new_expression;
set_rewritten();
}
Scope* scope() const { return scope_; }
void set_scope(Scope* scope) { scope_ = scope; }
private:
friend class AstNodeFactory;
RewritableExpression(Expression* expression, Scope* scope)
: Expression(expression->position(), kRewritableExpression),
expr_(expression),
scope_(scope) {
bit_field_ |= IsRewrittenField::encode(false);
DCHECK(!expression->IsRewritableExpression());
}
Expression* expr_;
Scope* scope_;
class IsRewrittenField
: public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
};
// There are several types of Suspend node: // There are several types of Suspend node:
// //
// Yield // Yield
...@@ -2969,6 +2916,7 @@ class AstNodeFactory final { ...@@ -2969,6 +2916,7 @@ class AstNodeFactory final {
empty_statement_(new (zone) class EmptyStatement()), empty_statement_(new (zone) class EmptyStatement()),
failure_expression_(new (zone) class FailureExpression()) {} failure_expression_(new (zone) class FailureExpression()) {}
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(VariableProxy* proxy, int pos) {
...@@ -3326,12 +3274,6 @@ class AstNodeFactory final { ...@@ -3326,12 +3274,6 @@ class AstNodeFactory final {
Conditional(condition, then_expression, else_expression, position); Conditional(condition, then_expression, else_expression, position);
} }
RewritableExpression* NewRewritableExpression(Expression* expression,
Scope* scope) {
DCHECK_NOT_NULL(expression);
return new (zone_) RewritableExpression(expression, scope);
}
Assignment* NewAssignment(Token::Value op, Assignment* NewAssignment(Token::Value op,
Expression* target, Expression* target,
Expression* value, Expression* value,
...@@ -3508,38 +3450,15 @@ class AstNodeFactory final { ...@@ -3508,38 +3450,15 @@ class AstNodeFactory final {
// Inline functions for AstNode. // Inline functions for AstNode.
#define DECLARE_NODE_FUNCTIONS(type) \ #define DECLARE_NODE_FUNCTIONS(type) \
bool AstNode::Is##type() const { \ bool AstNode::Is##type() const { return node_type() == AstNode::k##type; } \
NodeType mine = node_type(); \
if (mine == AstNode::kRewritableExpression && \
AstNode::k##type == AstNode::kAssignment) \
mine = reinterpret_cast<const RewritableExpression*>(this) \
->expression() \
->node_type(); \
return mine == AstNode::k##type; \
} \
type* AstNode::As##type() { \ type* AstNode::As##type() { \
NodeType mine = node_type(); \ return node_type() == AstNode::k##type ? reinterpret_cast<type*>(this) \
AstNode* result = this; \ : nullptr; \
if (mine == AstNode::kRewritableExpression && \
AstNode::k##type == AstNode::kAssignment) { \
result = \
reinterpret_cast<const RewritableExpression*>(this)->expression(); \
mine = result->node_type(); \
} \
return mine == AstNode::k##type ? reinterpret_cast<type*>(result) \
: nullptr; \
} \ } \
const type* AstNode::As##type() const { \ const type* AstNode::As##type() const { \
NodeType mine = node_type(); \ return node_type() == AstNode::k##type \
const AstNode* result = this; \ ? reinterpret_cast<const type*>(this) \
if (mine == AstNode::kRewritableExpression && \ : nullptr; \
AstNode::k##type != AstNode::kRewritableExpression) { \
result = \
reinterpret_cast<const RewritableExpression*>(this)->expression(); \
mine = result->node_type(); \
} \
return mine == AstNode::k##type ? reinterpret_cast<const type*>(result) \
: nullptr; \
} }
AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
FAILURE_NODE_LIST(DECLARE_NODE_FUNCTIONS) FAILURE_NODE_LIST(DECLARE_NODE_FUNCTIONS)
......
...@@ -497,10 +497,6 @@ void CallPrinter::VisitSuperCallReference(SuperCallReference* node) { ...@@ -497,10 +497,6 @@ void CallPrinter::VisitSuperCallReference(SuperCallReference* node) {
} }
void CallPrinter::VisitRewritableExpression(RewritableExpression* node) {
Find(node->expression());
}
void CallPrinter::FindStatements(const ZonePtrList<Statement>* statements) { void CallPrinter::FindStatements(const ZonePtrList<Statement>* statements) {
if (statements == nullptr) return; if (statements == nullptr) return;
for (int i = 0; i < statements->length(); i++) { for (int i = 0; i < statements->length(); i++) {
...@@ -742,8 +738,9 @@ void AstPrinter::PrintLiteralWithModeIndented(const char* info, Variable* var, ...@@ -742,8 +738,9 @@ void AstPrinter::PrintLiteralWithModeIndented(const char* info, Variable* var,
} else { } else {
EmbeddedVector<char, 256> buf; EmbeddedVector<char, 256> buf;
int pos = int pos =
SNPrintF(buf, "%s (%p) (mode = %s", info, reinterpret_cast<void*>(var), SNPrintF(buf, "%s (%p) (mode = %s, assigned = %s", info,
VariableMode2String(var->mode())); reinterpret_cast<void*>(var), VariableMode2String(var->mode()),
var->maybe_assigned() == kMaybeAssigned ? "true" : "false");
SNPrintF(buf + pos, ")"); SNPrintF(buf + pos, ")");
PrintLiteralIndented(buf.start(), value, true); PrintLiteralIndented(buf.start(), value, true);
} }
...@@ -1389,11 +1386,6 @@ void AstPrinter::VisitSuperCallReference(SuperCallReference* node) { ...@@ -1389,11 +1386,6 @@ void AstPrinter::VisitSuperCallReference(SuperCallReference* node) {
} }
void AstPrinter::VisitRewritableExpression(RewritableExpression* node) {
Visit(node->expression());
}
#endif // DEBUG #endif // DEBUG
} // namespace internal } // namespace internal
......
...@@ -770,27 +770,11 @@ Variable* DeclarationScope::DeclareGeneratorObjectVar( ...@@ -770,27 +770,11 @@ Variable* DeclarationScope::DeclareGeneratorObjectVar(
return result; return result;
} }
bool Scope::HasBeenRemoved() const {
if (sibling() == this) {
DCHECK_NULL(inner_scope_);
DCHECK(is_block_scope());
return true;
}
return false;
}
Scope* Scope::GetUnremovedScope() {
Scope* scope = this;
while (scope != nullptr && scope->HasBeenRemoved()) {
scope = scope->outer_scope();
}
DCHECK_NOT_NULL(scope);
return scope;
}
Scope* Scope::FinalizeBlockScope() { Scope* Scope::FinalizeBlockScope() {
DCHECK(is_block_scope()); DCHECK(is_block_scope());
DCHECK(!HasBeenRemoved()); #ifdef DEBUG
DCHECK_NE(sibling_, this);
#endif
if (variables_.occupancy() > 0 || if (variables_.occupancy() > 0 ||
(is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval())) { (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval())) {
...@@ -830,8 +814,9 @@ Scope* Scope::FinalizeBlockScope() { ...@@ -830,8 +814,9 @@ Scope* Scope::FinalizeBlockScope() {
num_heap_slots_ = 0; num_heap_slots_ = 0;
// Mark scope as removed by making it its own sibling. // Mark scope as removed by making it its own sibling.
#ifdef DEBUG
sibling_ = this; sibling_ = this;
DCHECK(HasBeenRemoved()); #endif
return nullptr; return nullptr;
} }
...@@ -986,6 +971,11 @@ Variable* DeclarationScope::DeclareParameter(const AstRawString* name, ...@@ -986,6 +971,11 @@ Variable* DeclarationScope::DeclareParameter(const AstRawString* name,
if (name == ast_value_factory->arguments_string()) { if (name == ast_value_factory->arguments_string()) {
has_arguments_parameter_ = true; has_arguments_parameter_ = true;
} }
// Params are automatically marked as used to make sure that the debugger and
// function.arguments sees them.
// TODO(verwaest): Reevaluate whether we always need to do this, since
// strict-mode function.arguments does not make the arguments available.
var->set_is_used();
return var; return var;
} }
...@@ -1010,6 +1000,11 @@ Variable* DeclarationScope::DeclareParameterName( ...@@ -1010,6 +1000,11 @@ Variable* DeclarationScope::DeclareParameterName(
if (add_parameter) { if (add_parameter) {
params_.Add(var, zone()); params_.Add(var, zone());
} }
// Params are automatically marked as used to make sure that the debugger and
// function.arguments sees them.
// TODO(verwaest): Reevaluate whether we always need to do this, since
// strict-mode function.arguments does not make the arguments available.
var->set_is_used();
return var; return var;
} }
......
...@@ -190,11 +190,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { ...@@ -190,11 +190,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
// tree and its children are reparented. // tree and its children are reparented.
Scope* FinalizeBlockScope(); Scope* FinalizeBlockScope();
bool HasBeenRemoved() const;
// Find the first scope that hasn't been removed.
Scope* GetUnremovedScope();
// Inserts outer_scope into this scope's scope chain (and removes this // Inserts outer_scope into this scope's scope chain (and removes this
// from the current outer_scope_'s inner scope list). // from the current outer_scope_'s inner scope list).
// Assumes outer_scope_ is non-null. // Assumes outer_scope_ is non-null.
......
...@@ -5328,10 +5328,6 @@ void BytecodeGenerator::VisitNaryLogicalAndExpression(NaryOperation* expr) { ...@@ -5328,10 +5328,6 @@ void BytecodeGenerator::VisitNaryLogicalAndExpression(NaryOperation* expr) {
} }
} }
void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
Visit(expr->expression());
}
void BytecodeGenerator::BuildNewLocalActivationContext() { void BytecodeGenerator::BuildNewLocalActivationContext() {
ValueResultScope value_execution_result(this); ValueResultScope value_execution_result(this);
Scope* scope = closure_scope(); Scope* scope = closure_scope();
......
...@@ -27,7 +27,6 @@ class Reparenter final : public AstTraversalVisitor<Reparenter> { ...@@ -27,7 +27,6 @@ class Reparenter final : public AstTraversalVisitor<Reparenter> {
void VisitFunctionLiteral(FunctionLiteral* expr); void VisitFunctionLiteral(FunctionLiteral* expr);
void VisitClassLiteral(ClassLiteral* expr); void VisitClassLiteral(ClassLiteral* expr);
void VisitVariableProxy(VariableProxy* expr); void VisitVariableProxy(VariableProxy* expr);
void VisitRewritableExpression(RewritableExpression* expr);
void VisitBlock(Block* stmt); void VisitBlock(Block* stmt);
void VisitTryCatchStatement(TryCatchStatement* stmt); void VisitTryCatchStatement(TryCatchStatement* stmt);
...@@ -79,11 +78,6 @@ void Reparenter::VisitVariableProxy(VariableProxy* proxy) { ...@@ -79,11 +78,6 @@ void Reparenter::VisitVariableProxy(VariableProxy* proxy) {
} }
} }
void Reparenter::VisitRewritableExpression(RewritableExpression* expr) {
Visit(expr->expression());
expr->set_scope(scope_);
}
void Reparenter::VisitBlock(Block* stmt) { void Reparenter::VisitBlock(Block* stmt) {
if (stmt->scope()) if (stmt->scope())
stmt->scope()->ReplaceOuterScope(scope_); stmt->scope()->ReplaceOuterScope(scope_);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -151,7 +151,6 @@ struct ParserTypes<Parser> { ...@@ -151,7 +151,6 @@ struct ParserTypes<Parser> {
typedef v8::internal::IterationStatement* IterationStatement; typedef v8::internal::IterationStatement* IterationStatement;
typedef ObjectLiteral::Property* ObjectLiteralProperty; typedef ObjectLiteral::Property* ObjectLiteralProperty;
typedef ScopedPtrList<v8::internal::ObjectLiteralProperty> ObjectPropertyList; typedef ScopedPtrList<v8::internal::ObjectLiteralProperty> ObjectPropertyList;
typedef v8::internal::RewritableExpression* RewritableExpression;
typedef v8::internal::Statement* Statement; typedef v8::internal::Statement* Statement;
typedef ScopedPtrList<v8::internal::Statement> StatementList; typedef ScopedPtrList<v8::internal::Statement> StatementList;
typedef v8::internal::Suspend* Suspend; typedef v8::internal::Suspend* Suspend;
...@@ -370,12 +369,10 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -370,12 +369,10 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
// PatternRewriter and associated methods defined in pattern-rewriter.cc. // PatternRewriter and associated methods defined in pattern-rewriter.cc.
friend class PatternRewriter; friend class PatternRewriter;
void DeclareAndInitializeVariables( void InitializeVariables(
Block* block, const DeclarationDescriptor* declaration_descriptor, Block* block, const DeclarationDescriptor* declaration_descriptor,
const DeclarationParsingResult::Declaration* declaration, const DeclarationParsingResult::Declaration* declaration,
ZonePtrList<const AstRawString>* names); ZonePtrList<const AstRawString>* names);
void RewriteDestructuringAssignment(RewritableExpression* expr);
Expression* RewriteDestructuringAssignment(Assignment* assignment);
// [if (IteratorType == kAsync)] // [if (IteratorType == kAsync)]
// !%_IsJSReceiver(result = Await(next.[[Call]](iterator, « »)) && // !%_IsJSReceiver(result = Await(next.[[Call]](iterator, « »)) &&
...@@ -548,14 +545,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -548,14 +545,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
void SetLanguageMode(Scope* scope, LanguageMode mode); void SetLanguageMode(Scope* scope, LanguageMode mode);
void SetAsmModule(); void SetAsmModule();
// Rewrite all DestructuringAssignments in the current FunctionState.
void RewriteDestructuringAssignments();
Expression* RewriteSpreads(ArrayLiteral* lit); Expression* RewriteSpreads(ArrayLiteral* lit);
void QueueDestructuringAssignmentForRewriting(
RewritableExpression* assignment);
friend class InitializerRewriter; friend class InitializerRewriter;
void RewriteParameterInitializer(Expression* expr); void RewriteParameterInitializer(Expression* expr);
...@@ -717,17 +708,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -717,17 +708,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
} }
} }
V8_INLINE static void MarkPatternAsAssigned(Expression* expression) {}
// Determine if the expression is a variable proxy and mark it as being used
// in an assignment or with a increment/decrement operator.
V8_INLINE static void MarkExpressionAsAssigned(Expression* expression) {
DCHECK_NOT_NULL(expression);
if (expression->IsVariableProxy()) {
expression->AsVariableProxy()->set_is_assigned();
}
}
// A shortcut for performing a ToString operation // A shortcut for performing a ToString operation
V8_INLINE Expression* ToString(Expression* expr) { V8_INLINE Expression* ToString(Expression* expr) {
if (expr->IsStringLiteral()) return expr; if (expr->IsStringLiteral()) return expr;
...@@ -877,7 +857,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -877,7 +857,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
if (infer == InferName::kYes) { if (infer == InferName::kYes) {
fni_.PushVariableName(name); fni_.PushVariableName(name);
} }
return NewUnresolved(name, start_position); return expression_scope()->NewVariable(name, start_position);
} }
V8_INLINE Variable* DeclareCatchVariableName(Scope* scope, V8_INLINE Variable* DeclareCatchVariableName(Scope* scope,
......
...@@ -25,15 +25,12 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> { ...@@ -25,15 +25,12 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> {
typedef Parser::DeclarationDescriptor DeclarationDescriptor; typedef Parser::DeclarationDescriptor DeclarationDescriptor;
static void DeclareAndInitializeVariables( static void InitializeVariables(
Parser* parser, Block* block, Parser* parser, Block* block,
const DeclarationDescriptor* declaration_descriptor, const DeclarationDescriptor* declaration_descriptor,
const Parser::DeclarationParsingResult::Declaration* declaration, const Parser::DeclarationParsingResult::Declaration* declaration,
ZonePtrList<const AstRawString>* names); ZonePtrList<const AstRawString>* names);
static Expression* RewriteDestructuringAssignment(Parser* parser,
Assignment* to_rewrite);
private: private:
enum PatternContext : uint8_t { BINDING, ASSIGNMENT }; enum PatternContext : uint8_t { BINDING, ASSIGNMENT };
...@@ -128,51 +125,16 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> { ...@@ -128,51 +125,16 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> {
DEFINE_AST_VISITOR_MEMBERS_WITHOUT_STACKOVERFLOW() DEFINE_AST_VISITOR_MEMBERS_WITHOUT_STACKOVERFLOW()
}; };
void Parser::DeclareAndInitializeVariables( void Parser::InitializeVariables(
Block* block, const DeclarationDescriptor* declaration_descriptor, Block* block, const DeclarationDescriptor* declaration_descriptor,
const DeclarationParsingResult::Declaration* declaration, const DeclarationParsingResult::Declaration* declaration,
ZonePtrList<const AstRawString>* names) { ZonePtrList<const AstRawString>* names) {
if (has_error()) return; if (has_error()) return;
PatternRewriter::DeclareAndInitializeVariables( PatternRewriter::InitializeVariables(this, block, declaration_descriptor,
this, block, declaration_descriptor, declaration, names); declaration, names);
}
namespace {
// Lightweight visitor for the case where bytecode does the desugaring.
void MarkVariablesWritten(Expression* expr) {
if (expr->IsVariableProxy()) {
expr->AsVariableProxy()->set_is_assigned();
} else if (expr->IsObjectLiteral()) {
for (ObjectLiteralProperty* prop : *expr->AsObjectLiteral()->properties()) {
MarkVariablesWritten(prop->value());
}
} else if (expr->IsArrayLiteral()) {
for (Expression* value : *expr->AsArrayLiteral()->values()) {
MarkVariablesWritten(value);
}
} else if (expr->IsSpread()) {
MarkVariablesWritten(expr->AsSpread()->expression());
} else if (expr->IsAssignment()) {
MarkVariablesWritten(expr->AsAssignment()->target());
}
}
} // namespace
void Parser::RewriteDestructuringAssignment(RewritableExpression* to_rewrite) {
DCHECK(!to_rewrite->is_rewritten());
Assignment* assignment = to_rewrite->expression()->AsAssignment();
DCHECK_NOT_NULL(assignment);
MarkVariablesWritten(assignment->target());
} }
Expression* Parser::RewriteDestructuringAssignment(Assignment* assignment) { void PatternRewriter::InitializeVariables(
DCHECK_NOT_NULL(assignment);
DCHECK_EQ(Token::ASSIGN, assignment->op());
MarkVariablesWritten(assignment->target());
return assignment;
}
void PatternRewriter::DeclareAndInitializeVariables(
Parser* parser, Block* block, Parser* parser, Block* block,
const DeclarationDescriptor* declaration_descriptor, const DeclarationDescriptor* declaration_descriptor,
const Parser::DeclarationParsingResult::Declaration* declaration, const Parser::DeclarationParsingResult::Declaration* declaration,
...@@ -191,14 +153,6 @@ void PatternRewriter::DeclareAndInitializeVariables( ...@@ -191,14 +153,6 @@ void PatternRewriter::DeclareAndInitializeVariables(
declaration->initializer); declaration->initializer);
} }
Expression* PatternRewriter::RewriteDestructuringAssignment(
Parser* parser, Assignment* to_rewrite) {
DCHECK(!parser->scope()->HasBeenRemoved());
PatternRewriter rewriter(parser, ASSIGNMENT);
return rewriter.Rewrite(to_rewrite);
}
void PatternRewriter::VisitVariableProxy(VariableProxy* proxy) { void PatternRewriter::VisitVariableProxy(VariableProxy* proxy) {
Expression* value = current_value_; Expression* value = current_value_;
...@@ -219,7 +173,6 @@ void PatternRewriter::VisitVariableProxy(VariableProxy* proxy) { ...@@ -219,7 +173,6 @@ void PatternRewriter::VisitVariableProxy(VariableProxy* proxy) {
if (declares_parameter_containing_sloppy_eval_) { if (declares_parameter_containing_sloppy_eval_) {
target_scope = target_scope->outer_scope(); target_scope = target_scope->outer_scope();
} }
target_scope->DeleteUnresolved(proxy);
// Declare variable. // Declare variable.
// Note that we *always* must treat the initial value via a separate init // Note that we *always* must treat the initial value via a separate init
...@@ -312,16 +265,6 @@ Variable* PatternRewriter::CreateTempVar(Expression* value) { ...@@ -312,16 +265,6 @@ Variable* PatternRewriter::CreateTempVar(Expression* value) {
return temp; return temp;
} }
void PatternRewriter::VisitRewritableExpression(RewritableExpression* node) {
DCHECK(node->expression()->IsAssignment());
// This is not a top-level destructuring assignment. Mark the node as
// rewritten to prevent redundant rewriting and visit the underlying
// expression.
DCHECK(!node->is_rewritten());
node->set_rewritten();
return Visit(node->expression());
}
// When an extra declaration scope needs to be inserted to account for // When an extra declaration scope needs to be inserted to account for
// a sloppy eval in a default parameter or function body, the expressions // a sloppy eval in a default parameter or function body, the expressions
// needs to be in that new inner scope which was added after initial // needs to be in that new inner scope which was added after initial
......
...@@ -142,8 +142,7 @@ PreParser::PreParseResult PreParser::PreParseFunction( ...@@ -142,8 +142,7 @@ PreParser::PreParseResult PreParser::PreParseFunction(
// Parse non-arrow function parameters. For arrow functions, the parameters // Parse non-arrow function parameters. For arrow functions, the parameters
// have already been parsed. // have already been parsed.
DeclarationParsingScope formals_scope( ParameterDeclarationParsingScope formals_scope(this);
this, ExpressionScope::kParameterDeclaration);
// We return kPreParseSuccess in failure cases too - errors are retrieved // We return kPreParseSuccess in failure cases too - errors are retrieved
// separately by Parser::SkipLazyFunctionBody. // separately by Parser::SkipLazyFunctionBody.
ParseFormalParameterList(&formals); ParseFormalParameterList(&formals);
...@@ -302,8 +301,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral( ...@@ -302,8 +301,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
function_scope->set_start_position(start_position); function_scope->set_start_position(start_position);
PreParserFormalParameters formals(function_scope); PreParserFormalParameters formals(function_scope);
{ {
DeclarationParsingScope formals_scope( ParameterDeclarationParsingScope formals_scope(this);
this, ExpressionScope::kParameterDeclaration);
ParseFormalParameterList(&formals); ParseFormalParameterList(&formals);
} }
Expect(Token::RPAREN); Expect(Token::RPAREN);
...@@ -410,22 +408,20 @@ bool PreParser::IdentifierEquals(const PreParserIdentifier& identifier, ...@@ -410,22 +408,20 @@ bool PreParser::IdentifierEquals(const PreParserIdentifier& identifier,
PreParserExpression PreParser::ExpressionFromIdentifier( PreParserExpression PreParser::ExpressionFromIdentifier(
const PreParserIdentifier& name, int start_position, InferName infer) { const PreParserIdentifier& name, int start_position, InferName infer) {
VariableProxy* proxy = nullptr;
DCHECK_IMPLIES(name.string_ == nullptr, has_error()); DCHECK_IMPLIES(name.string_ == nullptr, has_error());
if (name.string_ == nullptr) return PreParserExpression::Default(); if (name.string_ == nullptr) return PreParserExpression::Default();
proxy = scope()->NewUnresolved(factory()->ast_node_factory(), name.string_, VariableProxy* proxy =
start_position, NORMAL_VARIABLE); expression_scope()->NewVariable(name.string_, start_position);
return PreParserExpression::FromIdentifier(name, proxy, zone()); return PreParserExpression::FromIdentifier(name, proxy, zone());
} }
void PreParser::DeclareAndInitializeVariables( void PreParser::InitializeVariables(
PreParserStatement block, PreParserStatement block,
const DeclarationDescriptor* declaration_descriptor, const DeclarationDescriptor* declaration_descriptor,
const DeclarationParsingResult::Declaration* declaration, const DeclarationParsingResult::Declaration* declaration,
ZonePtrList<const AstRawString>* names) { ZonePtrList<const AstRawString>* names) {
if (declaration->pattern.variables_ != nullptr) { if (declaration->pattern.variables_ != nullptr) {
for (auto variable : *(declaration->pattern.variables_)) { for (auto variable : *(declaration->pattern.variables_)) {
scope()->DeleteUnresolved(variable);
Variable* var = scope()->DeclareVariableName( Variable* var = scope()->DeclareVariableName(
variable->raw_name(), declaration_descriptor->mode); variable->raw_name(), declaration_descriptor->mode);
if (var == nullptr) { if (var == nullptr) {
......
...@@ -571,15 +571,7 @@ class PreParserFactory { ...@@ -571,15 +571,7 @@ class PreParserFactory {
PreParserExpression NewStringLiteral(const PreParserIdentifier& identifier, PreParserExpression NewStringLiteral(const PreParserIdentifier& identifier,
int pos) { int pos) {
// This is needed for object literal property names. Property names are return PreParserExpression::Default();
// normalized to string literals during object literal parsing.
PreParserExpression expression = PreParserExpression::Default();
if (identifier.string_ != nullptr) {
VariableProxy* variable = ast_node_factory_.NewVariableProxy(
identifier.string_, NORMAL_VARIABLE);
expression.AddVariable(variable, zone_);
}
return expression;
} }
PreParserExpression NewNumberLiteral(double number, PreParserExpression NewNumberLiteral(double number,
int pos) { int pos) {
...@@ -658,10 +650,6 @@ class PreParserFactory { ...@@ -658,10 +650,6 @@ class PreParserFactory {
int pos) { int pos) {
return PreParserExpression::Default(); return PreParserExpression::Default();
} }
PreParserExpression NewRewritableExpression(
const PreParserExpression& expression, Scope* scope) {
return expression;
}
PreParserExpression NewAssignment(Token::Value op, PreParserExpression NewAssignment(Token::Value op,
const PreParserExpression& left, const PreParserExpression& left,
const PreParserExpression& right, int pos) { const PreParserExpression& right, int pos) {
...@@ -943,7 +931,6 @@ struct ParserTypes<PreParser> { ...@@ -943,7 +931,6 @@ struct ParserTypes<PreParser> {
typedef PreParserExpression Expression; typedef PreParserExpression Expression;
typedef PreParserExpression FunctionLiteral; typedef PreParserExpression FunctionLiteral;
typedef PreParserExpression ObjectLiteralProperty; typedef PreParserExpression ObjectLiteralProperty;
typedef PreParserExpression RewritableExpression;
typedef PreParserExpression Suspend; typedef PreParserExpression Suspend;
typedef PreParserExpressionList ExpressionList; typedef PreParserExpressionList ExpressionList;
typedef PreParserExpressionList ObjectPropertyList; typedef PreParserExpressionList ObjectPropertyList;
...@@ -1116,14 +1103,12 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1116,14 +1103,12 @@ class PreParser : public ParserBase<PreParser> {
SpreadCallNew(const PreParserExpression& function, SpreadCallNew(const PreParserExpression& function,
const PreParserExpressionList& args, int pos); const PreParserExpressionList& args, int pos);
V8_INLINE void RewriteDestructuringAssignments() {}
V8_INLINE void PrepareGeneratorVariables() {} V8_INLINE void PrepareGeneratorVariables() {}
V8_INLINE void RewriteAsyncFunctionBody( V8_INLINE void RewriteAsyncFunctionBody(
const PreParserScopedStatementList* body, PreParserStatement block, const PreParserScopedStatementList* body, PreParserStatement block,
const PreParserExpression& return_value) {} const PreParserExpression& return_value) {}
void DeclareAndInitializeVariables( void InitializeVariables(
PreParserStatement block, PreParserStatement block,
const DeclarationDescriptor* declaration_descriptor, const DeclarationDescriptor* declaration_descriptor,
const DeclarationParsingResult::Declaration* declaration, const DeclarationParsingResult::Declaration* declaration,
...@@ -1401,25 +1386,6 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1401,25 +1386,6 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE static void CheckAssigningFunctionLiteralToProperty( V8_INLINE static void CheckAssigningFunctionLiteralToProperty(
const PreParserExpression& left, const PreParserExpression& right) {} const PreParserExpression& left, const PreParserExpression& right) {}
V8_INLINE void MarkPatternAsAssigned(const PreParserExpression& expression) {
// TODO(marja): To be able to produce the same errors, the preparser needs
// to start tracking which expressions are variables and which are assigned.
if (expression.variables_ != nullptr) {
for (auto variable : *expression.variables_) {
variable->set_is_assigned();
}
}
}
V8_INLINE void MarkExpressionAsAssigned(
const PreParserExpression& expression) {
if (IsIdentifier(expression)) {
DCHECK_NOT_NULL(expression.variables_);
DCHECK_EQ(1, expression.variables_->LengthForTest());
expression.variables_->first()->set_is_assigned();
}
}
V8_INLINE bool ShortcutNumericLiteralBinaryExpression( V8_INLINE bool ShortcutNumericLiteralBinaryExpression(
PreParserExpression* x, const PreParserExpression& y, Token::Value op, PreParserExpression* x, const PreParserExpression& y, Token::Value op,
int pos) { int pos) {
...@@ -1442,9 +1408,8 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1442,9 +1408,8 @@ class PreParser : public ParserBase<PreParser> {
BuildInitializationBlock(DeclarationParsingResult* parsing_result, BuildInitializationBlock(DeclarationParsingResult* parsing_result,
ZonePtrList<const AstRawString>* names) { ZonePtrList<const AstRawString>* names) {
for (auto declaration : parsing_result->declarations) { for (auto declaration : parsing_result->declarations) {
DeclareAndInitializeVariables(PreParserStatement::Default(), InitializeVariables(PreParserStatement::Default(),
&(parsing_result->descriptor), &declaration, &(parsing_result->descriptor), &declaration, names);
names);
} }
return PreParserStatement::Default(); return PreParserStatement::Default();
} }
...@@ -1452,7 +1417,6 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1452,7 +1417,6 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE PreParserStatement InitializeForEachStatement( V8_INLINE PreParserStatement InitializeForEachStatement(
PreParserStatement stmt, const PreParserExpression& each, PreParserStatement stmt, const PreParserExpression& each,
const PreParserExpression& subject, PreParserStatement body) { const PreParserExpression& subject, PreParserStatement body) {
MarkPatternAsAssigned(each);
return stmt; return stmt;
} }
...@@ -1461,7 +1425,6 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1461,7 +1425,6 @@ class PreParser : public ParserBase<PreParser> {
const PreParserExpression& iterable, PreParserStatement body, const PreParserExpression& iterable, PreParserStatement body,
bool finalize, IteratorType type, bool finalize, IteratorType type,
int next_result_pos = kNoSourcePosition) { int next_result_pos = kNoSourcePosition) {
MarkPatternAsAssigned(each);
return stmt; return stmt;
} }
...@@ -1480,10 +1443,10 @@ class PreParser : public ParserBase<PreParser> { ...@@ -1480,10 +1443,10 @@ class PreParser : public ParserBase<PreParser> {
IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) || IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
is_for_var_of; is_for_var_of;
DeclareAndInitializeVariables( InitializeVariables(PreParserStatement::Default(),
PreParserStatement::Default(), &for_info->parsing_result.descriptor, &for_info->parsing_result.descriptor,
&for_info->parsing_result.declarations[0], &for_info->parsing_result.declarations[0],
collect_names ? &for_info->bound_names : nullptr); collect_names ? &for_info->bound_names : nullptr);
} }
V8_INLINE PreParserBlock CreateForEachStatementTDZ(PreParserBlock init_block, V8_INLINE PreParserBlock CreateForEachStatementTDZ(PreParserBlock init_block,
......
...@@ -345,6 +345,7 @@ class ScopedPtrList final { ...@@ -345,6 +345,7 @@ class ScopedPtrList final {
int length() const { return static_cast<int>(end_ - start_); } int length() const { return static_cast<int>(end_ - start_); }
T* at(int i) const { T* at(int i) const {
size_t index = start_ + i; size_t index = start_ + i;
DCHECK_LE(start_, index);
DCHECK_LT(index, buffer_.size()); DCHECK_LT(index, buffer_.size());
return reinterpret_cast<T*>(buffer_[index]); return reinterpret_cast<T*>(buffer_[index]);
} }
......
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