Commit 18cac20c authored by Adam Klein's avatar Adam Klein Committed by Commit Bot

[parser] Greatly simplify Array spread rewriting code

Since each Array literal containing a spread is individually queued for
rewriting, there's no need for an AstVisitor here: a simple linear
pass through the queue is sufficient.

This patch deletes AstExpressionRewriter and all the machinery supporting
it in the AST. This code was built with the idea of using it as
a general expression rewriting mechanism in the parser, but those use
cases never materialized, and Array spread remains the only thing
that used this code.

Bug: v8:6092
Change-Id: I754c4883099e840881b005f20216f86e57721d5a
Reviewed-on: https://chromium-review.googlesource.com/765051Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Commit-Queue: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49337}
parent 45e52d52
......@@ -1205,8 +1205,6 @@ v8_source_set("v8_base") {
"src/assembler.h",
"src/assert-scope.cc",
"src/assert-scope.h",
"src/ast/ast-expression-rewriter.cc",
"src/ast/ast-expression-rewriter.h",
"src/ast/ast-function-literal-id-reindexer.cc",
"src/ast/ast-function-literal-id-reindexer.h",
"src/ast/ast-numbering.cc",
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/ast/ast-expression-rewriter.h"
#include "src/ast/ast.h"
#include "src/objects-inl.h"
namespace v8 {
namespace internal {
// ----------------------------------------------------------------------------
// Implementation of AstExpressionRewriter
// The AST is traversed but no actual rewriting takes place, unless the
// Visit methods are overriden in subclasses.
#define REWRITE_THIS(node) \
do { \
if (!RewriteExpression(node)) return; \
} while (false)
#define NOTHING() DCHECK_NULL(replacement_)
void AstExpressionRewriter::VisitDeclarations(Declaration::List* declarations) {
for (Declaration::List::Iterator it = declarations->begin();
it != declarations->end(); ++it) {
AST_REWRITE(Declaration, *it, it = replacement);
}
}
void AstExpressionRewriter::VisitStatements(ZoneList<Statement*>* statements) {
for (int i = 0; i < statements->length(); i++) {
AST_REWRITE_LIST_ELEMENT(Statement, statements, i);
if (statements->at(i)->IsJump()) break;
}
}
void AstExpressionRewriter::VisitExpressions(
ZoneList<Expression*>* expressions) {
for (int i = 0; i < expressions->length(); i++) {
// The variable statement visiting code may pass null expressions
// to this code. Maybe this should be handled by introducing an
// undefined expression or literal? Revisit this code if this
// changes.
if (expressions->at(i) != nullptr) {
AST_REWRITE_LIST_ELEMENT(Expression, expressions, i);
}
}
}
void AstExpressionRewriter::VisitVariableDeclaration(
VariableDeclaration* node) {
// Not visiting `proxy_`.
NOTHING();
}
void AstExpressionRewriter::VisitFunctionDeclaration(
FunctionDeclaration* node) {
// Not visiting `proxy_`.
AST_REWRITE_PROPERTY(FunctionLiteral, node, fun);
}
void AstExpressionRewriter::VisitBlock(Block* node) {
VisitStatements(node->statements());
}
void AstExpressionRewriter::VisitExpressionStatement(
ExpressionStatement* node) {
AST_REWRITE_PROPERTY(Expression, node, expression);
}
void AstExpressionRewriter::VisitEmptyStatement(EmptyStatement* node) {
NOTHING();
}
void AstExpressionRewriter::VisitSloppyBlockFunctionStatement(
SloppyBlockFunctionStatement* node) {
AST_REWRITE_PROPERTY(Statement, node, statement);
}
void AstExpressionRewriter::VisitIfStatement(IfStatement* node) {
AST_REWRITE_PROPERTY(Expression, node, condition);
AST_REWRITE_PROPERTY(Statement, node, then_statement);
AST_REWRITE_PROPERTY(Statement, node, else_statement);
}
void AstExpressionRewriter::VisitContinueStatement(ContinueStatement* node) {
NOTHING();
}
void AstExpressionRewriter::VisitBreakStatement(BreakStatement* node) {
NOTHING();
}
void AstExpressionRewriter::VisitReturnStatement(ReturnStatement* node) {
AST_REWRITE_PROPERTY(Expression, node, expression);
}
void AstExpressionRewriter::VisitWithStatement(WithStatement* node) {
AST_REWRITE_PROPERTY(Expression, node, expression);
AST_REWRITE_PROPERTY(Statement, node, statement);
}
void AstExpressionRewriter::VisitSwitchStatement(SwitchStatement* node) {
AST_REWRITE_PROPERTY(Expression, node, tag);
for (CaseClause* clause : *node->cases()) {
if (!clause->is_default()) {
AST_REWRITE_PROPERTY(Expression, clause, label);
}
VisitStatements(clause->statements());
}
}
void AstExpressionRewriter::VisitDoWhileStatement(DoWhileStatement* node) {
AST_REWRITE_PROPERTY(Expression, node, cond);
AST_REWRITE_PROPERTY(Statement, node, body);
}
void AstExpressionRewriter::VisitWhileStatement(WhileStatement* node) {
AST_REWRITE_PROPERTY(Expression, node, cond);
AST_REWRITE_PROPERTY(Statement, node, body);
}
void AstExpressionRewriter::VisitForStatement(ForStatement* node) {
if (node->init() != nullptr) {
AST_REWRITE_PROPERTY(Statement, node, init);
}
if (node->cond() != nullptr) {
AST_REWRITE_PROPERTY(Expression, node, cond);
}
if (node->next() != nullptr) {
AST_REWRITE_PROPERTY(Statement, node, next);
}
AST_REWRITE_PROPERTY(Statement, node, body);
}
void AstExpressionRewriter::VisitForInStatement(ForInStatement* node) {
AST_REWRITE_PROPERTY(Expression, node, each);
AST_REWRITE_PROPERTY(Expression, node, subject);
AST_REWRITE_PROPERTY(Statement, node, body);
}
void AstExpressionRewriter::VisitForOfStatement(ForOfStatement* node) {
AST_REWRITE_PROPERTY(Expression, node, assign_iterator);
AST_REWRITE_PROPERTY(Expression, node, next_result);
AST_REWRITE_PROPERTY(Expression, node, result_done);
AST_REWRITE_PROPERTY(Expression, node, assign_each);
AST_REWRITE_PROPERTY(Statement, node, body);
}
void AstExpressionRewriter::VisitTryCatchStatement(TryCatchStatement* node) {
AST_REWRITE_PROPERTY(Block, node, try_block);
// Not visiting the variable.
AST_REWRITE_PROPERTY(Block, node, catch_block);
}
void AstExpressionRewriter::VisitTryFinallyStatement(
TryFinallyStatement* node) {
AST_REWRITE_PROPERTY(Block, node, try_block);
AST_REWRITE_PROPERTY(Block, node, finally_block);
}
void AstExpressionRewriter::VisitDebuggerStatement(DebuggerStatement* node) {
NOTHING();
}
void AstExpressionRewriter::VisitFunctionLiteral(FunctionLiteral* node) {
REWRITE_THIS(node);
VisitDeclarations(node->scope()->declarations());
ZoneList<Statement*>* body = node->body();
if (body != nullptr) VisitStatements(body);
}
void AstExpressionRewriter::VisitClassLiteral(ClassLiteral* node) {
REWRITE_THIS(node);
// Not visiting `class_variable_proxy_`.
if (node->extends() != nullptr) {
AST_REWRITE_PROPERTY(Expression, node, extends);
}
AST_REWRITE_PROPERTY(FunctionLiteral, node, constructor);
if (node->static_fields_initializer() != nullptr) {
AST_REWRITE_PROPERTY(FunctionLiteral, node, static_fields_initializer);
}
if (node->instance_fields_initializer_function() != nullptr) {
AST_REWRITE_PROPERTY(FunctionLiteral, node,
instance_fields_initializer_function);
}
ZoneList<typename ClassLiteral::Property*>* properties = node->properties();
for (int i = 0; i < properties->length(); i++) {
VisitLiteralProperty(properties->at(i));
}
}
void AstExpressionRewriter::VisitInitializeClassFieldsStatement(
InitializeClassFieldsStatement* node) {
ZoneList<typename ClassLiteral::Property*>* properties = node->fields();
for (int i = 0; i < properties->length(); i++) {
VisitLiteralProperty(properties->at(i));
}
}
void AstExpressionRewriter::VisitNativeFunctionLiteral(
NativeFunctionLiteral* node) {
REWRITE_THIS(node);
NOTHING();
}
void AstExpressionRewriter::VisitConditional(Conditional* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, condition);
AST_REWRITE_PROPERTY(Expression, node, then_expression);
AST_REWRITE_PROPERTY(Expression, node, else_expression);
}
void AstExpressionRewriter::VisitVariableProxy(VariableProxy* node) {
REWRITE_THIS(node);
NOTHING();
}
void AstExpressionRewriter::VisitLiteral(Literal* node) {
REWRITE_THIS(node);
NOTHING();
}
void AstExpressionRewriter::VisitRegExpLiteral(RegExpLiteral* node) {
REWRITE_THIS(node);
NOTHING();
}
void AstExpressionRewriter::VisitObjectLiteral(ObjectLiteral* node) {
REWRITE_THIS(node);
ZoneList<typename ObjectLiteral::Property*>* properties = node->properties();
for (int i = 0; i < properties->length(); i++) {
VisitLiteralProperty(properties->at(i));
}
}
void AstExpressionRewriter::VisitLiteralProperty(LiteralProperty* property) {
if (property == nullptr) return;
AST_REWRITE_PROPERTY(Expression, property, key);
AST_REWRITE_PROPERTY(Expression, property, value);
}
void AstExpressionRewriter::VisitArrayLiteral(ArrayLiteral* node) {
REWRITE_THIS(node);
VisitExpressions(node->values());
}
void AstExpressionRewriter::VisitAssignment(Assignment* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, target);
AST_REWRITE_PROPERTY(Expression, node, value);
}
void AstExpressionRewriter::VisitCompoundAssignment(CompoundAssignment* node) {
VisitAssignment(node);
}
void AstExpressionRewriter::VisitYield(Yield* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, expression);
}
void AstExpressionRewriter::VisitYieldStar(YieldStar* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, expression);
}
void AstExpressionRewriter::VisitAwait(Await* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, expression);
}
void AstExpressionRewriter::VisitThrow(Throw* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, exception);
}
void AstExpressionRewriter::VisitProperty(Property* node) {
REWRITE_THIS(node);
if (node == nullptr) return;
AST_REWRITE_PROPERTY(Expression, node, obj);
AST_REWRITE_PROPERTY(Expression, node, key);
}
void AstExpressionRewriter::VisitCall(Call* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, expression);
VisitExpressions(node->arguments());
}
void AstExpressionRewriter::VisitCallNew(CallNew* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, expression);
VisitExpressions(node->arguments());
}
void AstExpressionRewriter::VisitCallRuntime(CallRuntime* node) {
REWRITE_THIS(node);
VisitExpressions(node->arguments());
}
void AstExpressionRewriter::VisitUnaryOperation(UnaryOperation* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, expression);
}
void AstExpressionRewriter::VisitCountOperation(CountOperation* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, expression);
}
void AstExpressionRewriter::VisitBinaryOperation(BinaryOperation* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, left);
AST_REWRITE_PROPERTY(Expression, node, right);
}
void AstExpressionRewriter::VisitNaryOperation(NaryOperation* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, first);
for (size_t i = 0; i < node->subsequent_length(); ++i) {
AST_REWRITE(Expression, node->subsequent(i),
node->set_subsequent(i, replacement));
}
}
void AstExpressionRewriter::VisitCompareOperation(CompareOperation* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, left);
AST_REWRITE_PROPERTY(Expression, node, right);
}
void AstExpressionRewriter::VisitSpread(Spread* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, expression);
}
void AstExpressionRewriter::VisitThisFunction(ThisFunction* node) {
REWRITE_THIS(node);
NOTHING();
}
void AstExpressionRewriter::VisitSuperPropertyReference(
SuperPropertyReference* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(VariableProxy, node, this_var);
AST_REWRITE_PROPERTY(Expression, node, home_object);
}
void AstExpressionRewriter::VisitSuperCallReference(SuperCallReference* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(VariableProxy, node, this_var);
AST_REWRITE_PROPERTY(VariableProxy, node, new_target_var);
AST_REWRITE_PROPERTY(VariableProxy, node, this_function_var);
}
void AstExpressionRewriter::VisitEmptyParentheses(EmptyParentheses* node) {
NOTHING();
}
void AstExpressionRewriter::VisitGetIterator(GetIterator* node) {
AST_REWRITE_PROPERTY(Expression, node, iterable);
}
void AstExpressionRewriter::VisitGetTemplateObject(GetTemplateObject* node) {
NOTHING();
}
void AstExpressionRewriter::VisitImportCallExpression(
ImportCallExpression* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, argument);
}
void AstExpressionRewriter::VisitDoExpression(DoExpression* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Block, node, block);
AST_REWRITE_PROPERTY(VariableProxy, node, result);
}
void AstExpressionRewriter::VisitRewritableExpression(
RewritableExpression* node) {
REWRITE_THIS(node);
AST_REWRITE(Expression, node->expression(), node->Rewrite(replacement));
}
} // namespace internal
} // namespace v8
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_AST_AST_EXPRESSION_REWRITER_H_
#define V8_AST_AST_EXPRESSION_REWRITER_H_
#include "src/allocation.h"
#include "src/ast/ast.h"
#include "src/ast/scopes.h"
#include "src/zone/zone.h"
namespace v8 {
namespace internal {
// A rewriting Visitor over a CompilationInfo's AST that invokes
// VisitExpression on each expression node.
// This AstVistor is not final, and provides the AstVisitor methods as virtual
// methods so they can be specialized by subclasses.
class AstExpressionRewriter : public AstVisitor<AstExpressionRewriter> {
public:
explicit AstExpressionRewriter(Isolate* isolate) {
InitializeAstRewriter(isolate);
}
explicit AstExpressionRewriter(uintptr_t stack_limit) {
InitializeAstRewriter(stack_limit);
}
virtual ~AstExpressionRewriter() {}
virtual void VisitDeclarations(Declaration::List* declarations);
virtual void VisitStatements(ZoneList<Statement*>* statements);
virtual void VisitExpressions(ZoneList<Expression*>* expressions);
virtual void VisitLiteralProperty(LiteralProperty* property);
protected:
virtual bool RewriteExpression(Expression* expr) = 0;
private:
DEFINE_AST_REWRITER_SUBCLASS_MEMBERS();
#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
AST_NODE_LIST(DECLARE_VISIT)
#undef DECLARE_VISIT
DISALLOW_COPY_AND_ASSIGN(AstExpressionRewriter);
};
} // namespace internal
} // namespace v8
#endif // V8_AST_AST_EXPRESSION_REWRITER_H_
......@@ -337,9 +337,7 @@ inline ZoneList<const AstRawString*>* Block::labels() const {
class DoExpression final : public Expression {
public:
Block* block() { return block_; }
void set_block(Block* b) { block_ = b; }
VariableProxy* result() { return result_; }
void set_result(VariableProxy* v) { result_ = v; }
private:
friend class AstNodeFactory;
......@@ -418,7 +416,6 @@ inline NestedVariableDeclaration* VariableDeclaration::AsNested() {
class FunctionDeclaration final : public Declaration {
public:
FunctionLiteral* fun() const { return fun_; }
void set_fun(FunctionLiteral* f) { fun_ = f; }
private:
friend class AstNodeFactory;
......@@ -475,7 +472,6 @@ class DoWhileStatement final : public IterationStatement {
}
Expression* cond() const { return cond_; }
void set_cond(Expression* e) { cond_ = e; }
private:
friend class AstNodeFactory;
......@@ -495,7 +491,6 @@ class WhileStatement final : public IterationStatement {
}
Expression* cond() const { return cond_; }
void set_cond(Expression* e) { cond_ = e; }
private:
friend class AstNodeFactory;
......@@ -521,10 +516,6 @@ class ForStatement final : public IterationStatement {
Expression* cond() const { return cond_; }
Statement* next() const { return next_; }
void set_init(Statement* s) { init_ = s; }
void set_cond(Expression* e) { cond_ = e; }
void set_next(Statement* s) { next_ = s; }
private:
friend class AstNodeFactory;
......@@ -575,14 +566,8 @@ class ForInStatement final : public ForEachStatement {
Expression* each() const { return each_; }
Expression* subject() const { return subject_; }
void set_each(Expression* e) { each_ = e; }
void set_subject(Expression* e) { subject_ = e; }
enum ForInType { FAST_FOR_IN, SLOW_FOR_IN };
ForInType for_in_type() const { return ForInTypeField::decode(bit_field_); }
void set_for_in_type(ForInType type) {
bit_field_ = ForInTypeField::update(bit_field_, type);
}
private:
friend class AstNodeFactory;
......@@ -639,11 +624,6 @@ class ForOfStatement final : public ForEachStatement {
return assign_each_;
}
void set_assign_iterator(Expression* e) { assign_iterator_ = e; }
void set_next_result(Expression* e) { next_result_ = e; }
void set_result_done(Expression* e) { result_done_ = e; }
void set_assign_each(Expression* e) { assign_each_ = e; }
private:
friend class AstNodeFactory;
......@@ -721,7 +701,6 @@ class ReturnStatement final : public JumpStatement {
enum Type { kNormal, kAsyncReturn };
Expression* expression() const { return expression_; }
void set_expression(Expression* e) { expression_ = e; }
Type type() const { return TypeField::decode(bit_field_); }
bool is_async_return() const { return type() == kAsyncReturn; }
......@@ -749,7 +728,6 @@ class WithStatement final : public Statement {
public:
Scope* scope() { return scope_; }
Expression* expression() const { return expression_; }
void set_expression(Expression* e) { expression_ = e; }
Statement* statement() const { return statement_; }
void set_statement(Statement* s) { statement_ = s; }
......@@ -775,7 +753,6 @@ class CaseClause final : public ZoneObject {
DCHECK(!is_default());
return label_;
}
void set_label(Expression* e) { label_ = e; }
ZoneList<Statement*>* statements() const { return statements_; }
private:
......@@ -827,7 +804,6 @@ class IfStatement final : public Statement {
Statement* then_statement() const { return then_statement_; }
Statement* else_statement() const { return else_statement_; }
void set_condition(Expression* e) { condition_ = e; }
void set_then_statement(Statement* s) { then_statement_ = s; }
void set_else_statement(Statement* s) { else_statement_ = s; }
......@@ -1229,8 +1205,6 @@ class LiteralProperty : public ZoneObject {
public:
Expression* key() const { return key_; }
Expression* value() const { return value_; }
void set_key(Expression* e) { key_ = e; }
void set_value(Expression* e) { value_ = e; }
bool is_computed_name() const { return is_computed_name_; }
bool NeedsSetFunctionName() const;
......@@ -1603,9 +1577,6 @@ class Property final : public Expression {
Expression* obj() const { return obj_; }
Expression* key() const { return key_; }
void set_obj(Expression* e) { obj_ = e; }
void set_key(Expression* e) { key_ = e; }
bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); }
// Returns the properties assign type.
......@@ -1634,8 +1605,6 @@ class Call final : public Expression {
Expression* expression() const { return expression_; }
ZoneList<Expression*>* arguments() const { return arguments_; }
void set_expression(Expression* e) { expression_ = e; }
bool is_possibly_eval() const {
return IsPossiblyEvalField::decode(bit_field_);
}
......@@ -1704,8 +1673,6 @@ class CallNew final : public Expression {
Expression* expression() const { return expression_; }
ZoneList<Expression*>* arguments() const { return arguments_; }
void set_expression(Expression* e) { expression_ = e; }
bool only_last_arg_is_spread() {
return !arguments_->is_empty() && arguments_->last()->IsSpread();
}
......@@ -1737,10 +1704,6 @@ class CallRuntime final : public Expression {
DCHECK(is_jsruntime());
return context_index_;
}
void set_context_index(int index) {
DCHECK(is_jsruntime());
context_index_ = index;
}
const Runtime::Function* function() const {
DCHECK(!is_jsruntime());
return function_;
......@@ -1772,7 +1735,6 @@ class UnaryOperation final : public Expression {
public:
Token::Value op() const { return OperatorField::decode(bit_field_); }
Expression* expression() const { return expression_; }
void set_expression(Expression* e) { expression_ = e; }
private:
friend class AstNodeFactory;
......@@ -1794,9 +1756,7 @@ class BinaryOperation final : public Expression {
public:
Token::Value op() const { return OperatorField::decode(bit_field_); }
Expression* left() const { return left_; }
void set_left(Expression* e) { left_ = e; }
Expression* right() const { return right_; }
void set_right(Expression* e) { right_ = e; }
// Returns true if one side is a Smi literal, returning the other side's
// sub-expression in |subexpr| and the literal Smi in |literal|.
......@@ -1822,13 +1782,9 @@ class NaryOperation final : public Expression {
public:
Token::Value op() const { return OperatorField::decode(bit_field_); }
Expression* first() const { return first_; }
void set_first(Expression* e) { first_ = e; }
Expression* subsequent(size_t index) const {
return subsequent_[index].expression;
}
Expression* set_subsequent(size_t index, Expression* e) {
return subsequent_[index].expression = e;
}
size_t subsequent_length() const { return subsequent_.size(); }
int subsequent_op_position(size_t index) const {
......@@ -1890,7 +1846,6 @@ class CountOperation final : public Expression {
Token::Value op() const { return TokenField::decode(bit_field_); }
Expression* expression() const { return expression_; }
void set_expression(Expression* e) { expression_ = e; }
private:
friend class AstNodeFactory;
......@@ -1914,9 +1869,6 @@ class CompareOperation final : public Expression {
Expression* left() const { return left_; }
Expression* right() const { return right_; }
void set_left(Expression* e) { left_ = e; }
void set_right(Expression* e) { right_ = e; }
// Match special cases.
bool IsLiteralCompareTypeof(Expression** expr, Literal** literal);
bool IsLiteralCompareUndefined(Expression** expr);
......@@ -1943,7 +1895,6 @@ class CompareOperation final : public Expression {
class Spread final : public Expression {
public:
Expression* expression() const { return expression_; }
void set_expression(Expression* e) { expression_ = e; }
int expression_position() const { return expr_pos_; }
......@@ -1966,10 +1917,6 @@ class Conditional final : public Expression {
Expression* then_expression() const { return then_expression_; }
Expression* else_expression() const { return else_expression_; }
void set_condition(Expression* e) { condition_ = e; }
void set_then_expression(Expression* e) { then_expression_ = e; }
void set_else_expression(Expression* e) { else_expression_ = e; }
private:
friend class AstNodeFactory;
......@@ -1991,9 +1938,6 @@ class Assignment : public Expression {
Expression* target() const { return target_; }
Expression* value() const { return value_; }
void set_target(Expression* e) { target_ = e; }
void set_value(Expression* e) { value_ = e; }
// The assignment was generated as part of block-scoped sloppy-mode
// function hoisting, see
// ES#sec-block-level-function-declarations-web-legacy-compatibility-semantics
......@@ -2108,8 +2052,6 @@ class Suspend : public Expression {
}
int suspend_id() const { return suspend_id_; }
void set_expression(Expression* e) { expression_ = e; }
void set_suspend_id(int id) { suspend_id_ = id; }
inline bool IsInitialYield() const { return suspend_id_ == 0 && IsYield(); }
......@@ -2197,7 +2139,6 @@ class Await final : public Suspend {
class Throw final : public Expression {
public:
Expression* exception() const { return exception_; }
void set_exception(Expression* e) { exception_ = e; }
private:
friend class AstNodeFactory;
......@@ -2459,9 +2400,7 @@ class ClassLiteral final : public Expression {
Scope* scope() const { return scope_; }
Variable* class_variable() const { return class_variable_; }
Expression* extends() const { return extends_; }
void set_extends(Expression* e) { extends_ = e; }
FunctionLiteral* constructor() const { return constructor_; }
void set_constructor(FunctionLiteral* f) { constructor_ = f; }
ZoneList<Property*>* properties() const { return properties_; }
int start_position() const { return position(); }
int end_position() const { return end_position_; }
......@@ -2483,26 +2422,14 @@ class ClassLiteral final : public Expression {
return static_fields_initializer_;
}
void set_static_fields_initializer(FunctionLiteral* initializer) {
static_fields_initializer_ = initializer;
}
FunctionLiteral* instance_fields_initializer_function() const {
return instance_fields_initializer_function_;
}
void set_instance_fields_initializer_function(FunctionLiteral* initializer) {
instance_fields_initializer_function_ = initializer;
}
Variable* instance_fields_initializer_var() const {
return instance_fields_initializer_var_;
}
void set_instance_fields_initializer_var(Variable* var) {
instance_fields_initializer_var_ = var;
}
private:
friend class AstNodeFactory;
......@@ -2577,9 +2504,7 @@ class ThisFunction final : public Expression {
class SuperPropertyReference final : public Expression {
public:
VariableProxy* this_var() const { return this_var_; }
void set_this_var(VariableProxy* v) { this_var_ = v; }
Expression* home_object() const { return home_object_; }
void set_home_object(Expression* e) { home_object_ = e; }
private:
friend class AstNodeFactory;
......@@ -2601,11 +2526,8 @@ class SuperPropertyReference final : public Expression {
class SuperCallReference final : public Expression {
public:
VariableProxy* this_var() const { return this_var_; }
void set_this_var(VariableProxy* v) { this_var_ = v; }
VariableProxy* new_target_var() const { return new_target_var_; }
void set_new_target_var(VariableProxy* v) { new_target_var_ = v; }
VariableProxy* this_function_var() const { return this_function_var_; }
void set_this_function_var(VariableProxy* v) { this_function_var_ = v; }
private:
friend class AstNodeFactory;
......@@ -2631,7 +2553,6 @@ class SuperCallReference final : public Expression {
class ImportCallExpression final : public Expression {
public:
Expression* argument() const { return argument_; }
void set_argument(Expression* argument) { argument_ = argument; }
private:
friend class AstNodeFactory;
......@@ -2661,7 +2582,6 @@ class GetIterator final : public Expression {
IteratorType hint() const { return hint_; }
Expression* iterable() const { return iterable_; }
void set_iterable(Expression* iterable) { iterable_ = iterable; }
Expression* iterable_for_call_printer() const {
return destructured_iterable_ != nullptr ? destructured_iterable_
......@@ -2813,69 +2733,6 @@ class AstVisitor BASE_EMBEDDED {
\
private:
#define DEFINE_AST_REWRITER_SUBCLASS_MEMBERS() \
public: \
AstNode* Rewrite(AstNode* node) { \
DCHECK_NULL(replacement_); \
DCHECK_NOT_NULL(node); \
Visit(node); \
if (HasStackOverflow()) return node; \
if (replacement_ == nullptr) return node; \
AstNode* result = replacement_; \
replacement_ = nullptr; \
return result; \
} \
\
private: \
void InitializeAstRewriter(Isolate* isolate) { \
InitializeAstVisitor(isolate); \
replacement_ = nullptr; \
} \
\
void InitializeAstRewriter(uintptr_t stack_limit) { \
InitializeAstVisitor(stack_limit); \
replacement_ = nullptr; \
} \
\
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); \
\
protected: \
AstNode* replacement_
// Generic macro for rewriting things; `GET` is the expression to be
// rewritten; `SET` is a command that should do the rewriting, i.e.
// something sensible with the variable called `replacement`.
#define AST_REWRITE(Type, GET, SET) \
do { \
DCHECK(!HasStackOverflow()); \
DCHECK_NULL(replacement_); \
Visit(GET); \
if (HasStackOverflow()) return; \
if (replacement_ == nullptr) break; \
Type* replacement = reinterpret_cast<Type*>(replacement_); \
do { \
SET; \
} while (false); \
replacement_ = nullptr; \
} while (false)
// Macro for rewriting object properties; it assumes that `object` has
// `property` with a public getter and setter.
#define AST_REWRITE_PROPERTY(Type, object, property) \
do { \
auto _obj = (object); \
AST_REWRITE(Type, _obj->property(), _obj->set_##property(replacement)); \
} while (false)
// Macro for rewriting list elements; it assumes that `list` has methods
// `at` and `Set`.
#define AST_REWRITE_LIST_ELEMENT(Type, list, index) \
do { \
auto _list = (list); \
auto _index = (index); \
AST_REWRITE(Type, _list->at(_index), _list->Set(_index, replacement)); \
} while (false)
// ----------------------------------------------------------------------------
// AstNode factory
......
......@@ -424,7 +424,7 @@ class ExpressionClassifier {
typename Types::Base* base_;
ExpressionClassifier* previous_;
Zone* zone_;
ZoneList<typename Types::Expression>* non_patterns_to_rewrite_;
ZoneList<typename Types::RewritableExpression>* non_patterns_to_rewrite_;
ZoneList<Error>* reported_errors_;
DuplicateFinder* duplicate_finder_;
// The uint16_t for non_pattern_begin_ will not be enough in the case,
......
......@@ -236,6 +236,7 @@ class ParserBase {
typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT;
typedef typename Types::ClassLiteralProperty ClassLiteralPropertyT;
typedef typename Types::Suspend SuspendExpressionT;
typedef typename Types::RewritableExpression RewritableExpressionT;
typedef typename Types::ExpressionList ExpressionListT;
typedef typename Types::FormalParameters FormalParametersT;
typedef typename Types::Statement StatementT;
......@@ -413,7 +414,7 @@ class ParserBase {
return &reported_errors_;
}
ZoneList<ExpressionT>* non_patterns_to_rewrite() {
ZoneList<RewritableExpressionT>* non_patterns_to_rewrite() {
return &non_patterns_to_rewrite_;
}
......@@ -458,11 +459,12 @@ class ParserBase {
destructuring_assignments_to_rewrite_.Add(pair, scope_->zone());
}
void AddNonPatternForRewriting(ExpressionT expr, bool* ok) {
void AddNonPatternForRewriting(RewritableExpressionT expr, bool* ok) {
non_patterns_to_rewrite_.Add(expr, scope_->zone());
if (non_patterns_to_rewrite_.length() >=
std::numeric_limits<uint16_t>::max())
std::numeric_limits<uint16_t>::max()) {
*ok = false;
}
}
// Properties count estimation.
......@@ -473,7 +475,7 @@ class ParserBase {
DeclarationScope* scope_;
ZoneList<DestructuringAssignment> destructuring_assignments_to_rewrite_;
ZoneList<ExpressionT> non_patterns_to_rewrite_;
ZoneList<RewritableExpressionT> non_patterns_to_rewrite_;
ZoneList<typename ExpressionClassifier::Error> reported_errors_;
......@@ -2064,8 +2066,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral(
ExpressionT result =
factory()->NewArrayLiteral(values, first_spread_index, pos);
if (first_spread_index >= 0) {
result = factory()->NewRewritableExpression(result);
impl()->QueueNonPatternForRewriting(result, ok);
auto rewritable = factory()->NewRewritableExpression(result);
impl()->QueueNonPatternForRewriting(rewritable, ok);
if (!*ok) {
// If the non-pattern rewriting mechanism is used in the future for
// rewriting other things than spreads, this error message will have
......@@ -2074,6 +2076,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral(
ReportMessage(MessageTemplate::kTooManySpreads);
return impl()->NullExpression();
}
result = rewritable;
}
return result;
}
......
......@@ -8,7 +8,6 @@
#include <memory>
#include "src/api.h"
#include "src/ast/ast-expression-rewriter.h"
#include "src/ast/ast-function-literal-id-reindexer.h"
#include "src/ast/ast-traversal-visitor.h"
#include "src/ast/ast.h"
......@@ -3826,53 +3825,18 @@ void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block,
body->Add(block, zone());
}
class NonPatternRewriter : public AstExpressionRewriter {
public:
NonPatternRewriter(uintptr_t stack_limit, Parser* parser)
: AstExpressionRewriter(stack_limit), parser_(parser) {}
~NonPatternRewriter() override {}
private:
bool RewriteExpression(Expression* expr) override {
if (expr->IsRewritableExpression()) return true;
// Rewrite only what could have been a pattern but is not.
if (expr->IsArrayLiteral()) {
// Spread rewriting in array literals.
ArrayLiteral* lit = expr->AsArrayLiteral();
VisitExpressions(lit->values());
replacement_ = parser_->RewriteSpreads(lit);
return false;
}
if (expr->IsObjectLiteral()) {
return true;
}
if (expr->IsBinaryOperation() &&
expr->AsBinaryOperation()->op() == Token::COMMA) {
return true;
}
// Everything else does not need rewriting.
return false;
}
void VisitLiteralProperty(LiteralProperty* property) override {
if (property == nullptr) return;
// Do not rewrite (computed) key expressions
AST_REWRITE_PROPERTY(Expression, property, value);
}
Parser* parser_;
};
void Parser::RewriteNonPattern(bool* ok) {
ValidateExpression(CHECK_OK_VOID);
auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite();
int begin = classifier()->GetNonPatternBegin();
int end = non_patterns_to_rewrite->length();
if (begin < end) {
NonPatternRewriter rewriter(stack_limit_, this);
for (int i = begin; i < end; i++) {
DCHECK(non_patterns_to_rewrite->at(i)->IsRewritableExpression());
rewriter.Rewrite(non_patterns_to_rewrite->at(i));
RewritableExpression* expr = non_patterns_to_rewrite->at(i);
// TODO(adamk): Make this more typesafe.
DCHECK(expr->expression()->IsArrayLiteral());
ArrayLiteral* lit = expr->expression()->AsArrayLiteral();
expr->Rewrite(RewriteSpreads(lit));
}
non_patterns_to_rewrite->Rewind(begin);
}
......@@ -4045,8 +4009,7 @@ void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) {
DestructuringAssignment(expr, scope()));
}
void Parser::QueueNonPatternForRewriting(Expression* expr, bool* ok) {
DCHECK(expr->IsRewritableExpression());
void Parser::QueueNonPatternForRewriting(RewritableExpression* expr, bool* ok) {
function_state_->AddNonPatternForRewriting(expr, ok);
}
......
......@@ -167,6 +167,7 @@ struct ParserTypes<Parser> {
typedef ObjectLiteral::Property* ObjectLiteralProperty;
typedef ClassLiteral::Property* ClassLiteralProperty;
typedef v8::internal::Suspend* Suspend;
typedef v8::internal::RewritableExpression* RewritableExpression;
typedef ZoneList<v8::internal::Expression*>* ExpressionList;
typedef ZoneList<ObjectLiteral::Property*>* ObjectPropertyList;
typedef ZoneList<ClassLiteral::Property*>* ClassPropertyList;
......@@ -557,7 +558,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
V8_INLINE Expression* RewriteAssignExponentiation(Expression* left,
Expression* right, int pos);
friend class NonPatternRewriter;
V8_INLINE Expression* RewriteSpreads(ArrayLiteral* lit);
// Rewrite expressions that are not used as patterns
......@@ -565,7 +565,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
V8_INLINE void QueueDestructuringAssignmentForRewriting(
Expression* assignment);
V8_INLINE void QueueNonPatternForRewriting(Expression* expr, bool* ok);
V8_INLINE void QueueNonPatternForRewriting(RewritableExpression* expr,
bool* ok);
friend class InitializerRewriter;
void RewriteParameterInitializer(Expression* expr);
......@@ -996,7 +997,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
return function_state_->GetReportedErrorList();
}
V8_INLINE ZoneList<Expression*>* GetNonPatternList() const {
V8_INLINE ZoneList<RewritableExpression*>* GetNonPatternList() const {
return function_state_->non_patterns_to_rewrite();
}
......
......@@ -831,6 +831,7 @@ struct ParserTypes<PreParser> {
typedef PreParserExpression ObjectLiteralProperty;
typedef PreParserExpression ClassLiteralProperty;
typedef PreParserExpression Suspend;
typedef PreParserExpression RewritableExpression;
typedef PreParserExpressionList ExpressionList;
typedef PreParserExpressionList ObjectPropertyList;
typedef PreParserExpressionList ClassPropertyList;
......
......@@ -581,8 +581,6 @@
'assembler-inl.h',
'assert-scope.h',
'assert-scope.cc',
'ast/ast-expression-rewriter.cc',
'ast/ast-expression-rewriter.h',
'ast/ast-function-literal-id-reindexer.cc',
'ast/ast-function-literal-id-reindexer.h',
'ast/ast-numbering.cc',
......
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