Commit ed665880 authored by nikolaos's avatar nikolaos Committed by Commit bot

This patch implements an alternative approach to the rewriting

of non-pattern expressions, according to the (internally circulated)
design document.  Details to be provided here.

1.  RewritableAssignmentExpression has been renamed to RewritableExpression.
    It is a wrapper for AST nodes that wait for some potential rewriting
    (that may or may not happen).  Also, Is... and As... macros now see
    through RewritableExpressions.

2.  The function state keeps a list of rewritable expressions that must be
    rewritten only if they are used as non-pattern expressions.

3.  Expression classifiers are now templates, parameterized by parser
    traits.  They keep some additional state: a pointer to the list of
    non-pattern rewritable expressions.  It is important that expression
    classifiers be used strictly in a stack fashion, from now on.

4.  The RewriteNonPattern function has been simplified.

BUG=chromium:579913
LOG=N

Committed: https://crrev.com/7f5c864a6faf2b957b7273891e143b9bde35487c
Cr-Commit-Position: refs/heads/master@{#34154}

Review URL: https://codereview.chromium.org/1702063002

Cr-Commit-Position: refs/heads/master@{#34162}
parent 69972208
...@@ -398,10 +398,10 @@ void AstExpressionRewriter::VisitDoExpression(DoExpression* node) { ...@@ -398,10 +398,10 @@ void AstExpressionRewriter::VisitDoExpression(DoExpression* node) {
} }
void AstExpressionRewriter::VisitRewritableAssignmentExpression( void AstExpressionRewriter::VisitRewritableExpression(
RewritableAssignmentExpression* node) { RewritableExpression* node) {
REWRITE_THIS(node); REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, expression); AST_REWRITE(Expression, node->expression(), node->Rewrite(replacement));
} }
......
...@@ -400,8 +400,8 @@ void AstExpressionVisitor::VisitSuperCallReference(SuperCallReference* expr) { ...@@ -400,8 +400,8 @@ void AstExpressionVisitor::VisitSuperCallReference(SuperCallReference* expr) {
} }
void AstExpressionVisitor::VisitRewritableAssignmentExpression( void AstExpressionVisitor::VisitRewritableExpression(
RewritableAssignmentExpression* expr) { RewritableExpression* expr) {
VisitExpression(expr); VisitExpression(expr);
RECURSE(Visit(expr->expression())); RECURSE(Visit(expr->expression()));
} }
......
...@@ -77,8 +77,8 @@ void AstLiteralReindexer::VisitSuperCallReference(SuperCallReference* node) { ...@@ -77,8 +77,8 @@ void AstLiteralReindexer::VisitSuperCallReference(SuperCallReference* node) {
} }
void AstLiteralReindexer::VisitRewritableAssignmentExpression( void AstLiteralReindexer::VisitRewritableExpression(
RewritableAssignmentExpression* node) { RewritableExpression* node) {
Visit(node->expression()); Visit(node->expression());
} }
......
...@@ -554,10 +554,10 @@ void AstNumberingVisitor::VisitFunctionLiteral(FunctionLiteral* node) { ...@@ -554,10 +554,10 @@ void AstNumberingVisitor::VisitFunctionLiteral(FunctionLiteral* node) {
} }
void AstNumberingVisitor::VisitRewritableAssignmentExpression( void AstNumberingVisitor::VisitRewritableExpression(
RewritableAssignmentExpression* node) { RewritableExpression* node) {
IncrementNodeCount(); IncrementNodeCount();
node->set_base_id(ReserveIdRange(RewritableAssignmentExpression::num_ids())); node->set_base_id(ReserveIdRange(RewritableExpression::num_ids()));
Visit(node->expression()); Visit(node->expression());
} }
......
...@@ -91,7 +91,7 @@ namespace internal { ...@@ -91,7 +91,7 @@ namespace internal {
V(CaseClause) \ V(CaseClause) \
V(EmptyParentheses) \ V(EmptyParentheses) \
V(DoExpression) \ V(DoExpression) \
V(RewritableAssignmentExpression) V(RewritableExpression)
#define AST_NODE_LIST(V) \ #define AST_NODE_LIST(V) \
DECLARATION_NODE_LIST(V) \ DECLARATION_NODE_LIST(V) \
...@@ -205,13 +205,9 @@ class AstNode: public ZoneObject { ...@@ -205,13 +205,9 @@ class AstNode: public ZoneObject {
// Type testing & conversion functions overridden by concrete subclasses. // Type testing & conversion functions overridden by concrete subclasses.
#define DECLARE_NODE_FUNCTIONS(type) \ #define DECLARE_NODE_FUNCTIONS(type) \
bool Is##type() const { return node_type() == AstNode::k##type; } \ V8_INLINE bool Is##type() const; \
type* As##type() { \ V8_INLINE type* As##type(); \
return Is##type() ? reinterpret_cast<type*>(this) : NULL; \ V8_INLINE const type* As##type() const;
} \
const type* As##type() const { \
return Is##type() ? reinterpret_cast<const type*>(this) : NULL; \
}
AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
#undef DECLARE_NODE_FUNCTIONS #undef DECLARE_NODE_FUNCTIONS
...@@ -2486,18 +2482,32 @@ class Assignment final : public Expression { ...@@ -2486,18 +2482,32 @@ class Assignment final : public Expression {
}; };
class RewritableAssignmentExpression : public Expression { // 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 : public Expression {
public: public:
DECLARE_NODE_TYPE(RewritableAssignmentExpression) DECLARE_NODE_TYPE(RewritableExpression)
Expression* expression() { return expr_; } Expression* expression() const { return expr_; }
bool is_rewritten() const { return is_rewritten_; } bool is_rewritten() const { return is_rewritten_; }
void set_expression(Expression* e) { expr_ = e; }
void Rewrite(Expression* new_expression) { void Rewrite(Expression* new_expression) {
DCHECK(!is_rewritten()); DCHECK(!is_rewritten());
DCHECK_NOT_NULL(new_expression); DCHECK_NOT_NULL(new_expression);
DCHECK(!new_expression->IsRewritableExpression());
expr_ = new_expression; expr_ = new_expression;
is_rewritten_ = true; is_rewritten_ = true;
} }
...@@ -2505,10 +2515,12 @@ class RewritableAssignmentExpression : public Expression { ...@@ -2505,10 +2515,12 @@ class RewritableAssignmentExpression : public Expression {
static int num_ids() { return parent_num_ids(); } static int num_ids() { return parent_num_ids(); }
protected: protected:
RewritableAssignmentExpression(Zone* zone, Expression* expression) RewritableExpression(Zone* zone, Expression* expression)
: Expression(zone, expression->position()), : Expression(zone, expression->position()),
is_rewritten_(false), is_rewritten_(false),
expr_(expression) {} expr_(expression) {
DCHECK(!expression->IsRewritableExpression());
}
private: private:
int local_id(int n) const { return base_id() + parent_num_ids() + n; } int local_id(int n) const { return base_id() + parent_num_ids() + n; }
...@@ -3365,12 +3377,9 @@ class AstNodeFactory final BASE_EMBEDDED { ...@@ -3365,12 +3377,9 @@ class AstNodeFactory final BASE_EMBEDDED {
local_zone_, condition, then_expression, else_expression, position); local_zone_, condition, then_expression, else_expression, position);
} }
RewritableAssignmentExpression* NewRewritableAssignmentExpression( RewritableExpression* NewRewritableExpression(Expression* expression) {
Expression* expression) {
DCHECK_NOT_NULL(expression); DCHECK_NOT_NULL(expression);
DCHECK(expression->IsAssignment()); return new (local_zone_) RewritableExpression(local_zone_, expression);
return new (local_zone_)
RewritableAssignmentExpression(local_zone_, expression);
} }
Assignment* NewAssignment(Token::Value op, Assignment* NewAssignment(Token::Value op,
...@@ -3508,6 +3517,46 @@ class AstNodeFactory final BASE_EMBEDDED { ...@@ -3508,6 +3517,46 @@ class AstNodeFactory final BASE_EMBEDDED {
}; };
// Type testing & conversion functions overridden by concrete subclasses.
// Inline functions for AstNode.
#define DECLARE_NODE_FUNCTIONS(type) \
bool AstNode::Is##type() const { \
NodeType mine = node_type(); \
if (mine == AstNode::kRewritableExpression && \
AstNode::k##type != AstNode::kRewritableExpression) \
mine = reinterpret_cast<const RewritableExpression*>(this) \
->expression() \
->node_type(); \
return mine == AstNode::k##type; \
} \
type* AstNode::As##type() { \
NodeType mine = node_type(); \
AstNode* result = this; \
if (mine == AstNode::kRewritableExpression && \
AstNode::k##type != AstNode::kRewritableExpression) { \
result = \
reinterpret_cast<const RewritableExpression*>(this)->expression(); \
mine = result->node_type(); \
} \
return mine == AstNode::k##type ? reinterpret_cast<type*>(result) : NULL; \
} \
const type* AstNode::As##type() const { \
NodeType mine = node_type(); \
const AstNode* result = this; \
if (mine == AstNode::kRewritableExpression && \
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) \
: NULL; \
}
AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
#undef DECLARE_NODE_FUNCTIONS
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -412,8 +412,7 @@ void CallPrinter::VisitSuperCallReference(SuperCallReference* node) { ...@@ -412,8 +412,7 @@ void CallPrinter::VisitSuperCallReference(SuperCallReference* node) {
} }
void CallPrinter::VisitRewritableAssignmentExpression( void CallPrinter::VisitRewritableExpression(RewritableExpression* node) {
RewritableAssignmentExpression* node) {
Find(node->expression()); Find(node->expression());
} }
...@@ -929,8 +928,7 @@ void PrettyPrinter::VisitSuperCallReference(SuperCallReference* node) { ...@@ -929,8 +928,7 @@ void PrettyPrinter::VisitSuperCallReference(SuperCallReference* node) {
} }
void PrettyPrinter::VisitRewritableAssignmentExpression( void PrettyPrinter::VisitRewritableExpression(RewritableExpression* node) {
RewritableAssignmentExpression* node) {
Visit(node->expression()); Visit(node->expression());
} }
...@@ -1705,8 +1703,7 @@ void AstPrinter::VisitSuperCallReference(SuperCallReference* node) { ...@@ -1705,8 +1703,7 @@ void AstPrinter::VisitSuperCallReference(SuperCallReference* node) {
} }
void AstPrinter::VisitRewritableAssignmentExpression( void AstPrinter::VisitRewritableExpression(RewritableExpression* node) {
RewritableAssignmentExpression* node) {
Visit(node->expression()); Visit(node->expression());
} }
......
...@@ -3062,8 +3062,7 @@ VectorSlotPair AstGraphBuilder::CreateVectorSlotPair( ...@@ -3062,8 +3062,7 @@ VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(
} }
void AstGraphBuilder::VisitRewritableAssignmentExpression( void AstGraphBuilder::VisitRewritableExpression(RewritableExpression* node) {
RewritableAssignmentExpression* node) {
Visit(node->expression()); Visit(node->expression());
} }
......
...@@ -287,8 +287,7 @@ void ALAA::VisitCountOperation(CountOperation* e) { ...@@ -287,8 +287,7 @@ void ALAA::VisitCountOperation(CountOperation* e) {
} }
void ALAA::VisitRewritableAssignmentExpression( void ALAA::VisitRewritableExpression(RewritableExpression* expr) {
RewritableAssignmentExpression* expr) {
Visit(expr->expression()); Visit(expr->expression());
} }
......
...@@ -12194,8 +12194,8 @@ void HOptimizedGraphBuilder::VisitExportDeclaration( ...@@ -12194,8 +12194,8 @@ void HOptimizedGraphBuilder::VisitExportDeclaration(
} }
void HOptimizedGraphBuilder::VisitRewritableAssignmentExpression( void HOptimizedGraphBuilder::VisitRewritableExpression(
RewritableAssignmentExpression* node) { RewritableExpression* node) {
CHECK_ALIVE(Visit(node->expression())); CHECK_ALIVE(Visit(node->expression()));
} }
......
...@@ -770,8 +770,7 @@ void AstTyper::VisitSuperPropertyReference(SuperPropertyReference* expr) {} ...@@ -770,8 +770,7 @@ void AstTyper::VisitSuperPropertyReference(SuperPropertyReference* expr) {}
void AstTyper::VisitSuperCallReference(SuperCallReference* expr) {} void AstTyper::VisitSuperCallReference(SuperCallReference* expr) {}
void AstTyper::VisitRewritableAssignmentExpression( void AstTyper::VisitRewritableExpression(RewritableExpression* expr) {
RewritableAssignmentExpression* expr) {
Visit(expr->expression()); Visit(expr->expression());
} }
......
...@@ -1507,8 +1507,7 @@ void FullCodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) { ...@@ -1507,8 +1507,7 @@ void FullCodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) {
} }
void FullCodeGenerator::VisitRewritableAssignmentExpression( void FullCodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
RewritableAssignmentExpression* expr) {
Visit(expr->expression()); Visit(expr->expression());
} }
......
...@@ -2860,8 +2860,7 @@ void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) { ...@@ -2860,8 +2860,7 @@ void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) {
} }
void BytecodeGenerator::VisitRewritableAssignmentExpression( void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
RewritableAssignmentExpression* expr) {
Visit(expr->expression()); Visit(expr->expression());
} }
......
...@@ -13,6 +13,7 @@ namespace v8 { ...@@ -13,6 +13,7 @@ namespace v8 {
namespace internal { namespace internal {
template <typename Traits>
class ExpressionClassifier { class ExpressionClassifier {
public: public:
struct Error { struct Error {
...@@ -55,15 +56,25 @@ class ExpressionClassifier { ...@@ -55,15 +56,25 @@ class ExpressionClassifier {
enum FunctionProperties { NonSimpleParameter = 1 << 0 }; enum FunctionProperties { NonSimpleParameter = 1 << 0 };
ExpressionClassifier() explicit ExpressionClassifier(const Traits* t)
: invalid_productions_(0), : zone_(t->zone()),
non_patterns_to_rewrite_(t->GetNonPatternList()),
invalid_productions_(0),
function_properties_(0), function_properties_(0),
duplicate_finder_(nullptr) {} duplicate_finder_(nullptr) {
non_pattern_begin_ = non_patterns_to_rewrite_->length();
}
explicit ExpressionClassifier(DuplicateFinder* duplicate_finder) ExpressionClassifier(const Traits* t, DuplicateFinder* duplicate_finder)
: invalid_productions_(0), : zone_(t->zone()),
non_patterns_to_rewrite_(t->GetNonPatternList()),
invalid_productions_(0),
function_properties_(0), function_properties_(0),
duplicate_finder_(duplicate_finder) {} duplicate_finder_(duplicate_finder) {
non_pattern_begin_ = non_patterns_to_rewrite_->length();
}
~ExpressionClassifier() { Discard(); }
bool is_valid(unsigned productions) const { bool is_valid(unsigned productions) const {
return (invalid_productions_ & productions) == 0; return (invalid_productions_ & productions) == 0;
...@@ -281,12 +292,14 @@ class ExpressionClassifier { ...@@ -281,12 +292,14 @@ class ExpressionClassifier {
assignment_pattern_error_ = Error(); assignment_pattern_error_ = Error();
} }
void Accumulate(const ExpressionClassifier& inner, void Accumulate(ExpressionClassifier* inner,
unsigned productions = StandardProductions) { unsigned productions = StandardProductions,
bool merge_non_patterns = true) {
if (merge_non_patterns) MergeNonPatterns(inner);
// Propagate errors from inner, but don't overwrite already recorded // Propagate errors from inner, but don't overwrite already recorded
// errors. // errors.
unsigned non_arrow_inner_invalid_productions = unsigned non_arrow_inner_invalid_productions =
inner.invalid_productions_ & ~ArrowFormalParametersProduction; inner->invalid_productions_ & ~ArrowFormalParametersProduction;
if (non_arrow_inner_invalid_productions == 0) return; if (non_arrow_inner_invalid_productions == 0) return;
unsigned non_arrow_productions = unsigned non_arrow_productions =
productions & ~ArrowFormalParametersProduction; productions & ~ArrowFormalParametersProduction;
...@@ -296,27 +309,27 @@ class ExpressionClassifier { ...@@ -296,27 +309,27 @@ class ExpressionClassifier {
if (errors != 0) { if (errors != 0) {
invalid_productions_ |= errors; invalid_productions_ |= errors;
if (errors & ExpressionProduction) if (errors & ExpressionProduction)
expression_error_ = inner.expression_error_; expression_error_ = inner->expression_error_;
if (errors & FormalParameterInitializerProduction) if (errors & FormalParameterInitializerProduction)
formal_parameter_initializer_error_ = formal_parameter_initializer_error_ =
inner.formal_parameter_initializer_error_; inner->formal_parameter_initializer_error_;
if (errors & BindingPatternProduction) if (errors & BindingPatternProduction)
binding_pattern_error_ = inner.binding_pattern_error_; binding_pattern_error_ = inner->binding_pattern_error_;
if (errors & AssignmentPatternProduction) if (errors & AssignmentPatternProduction)
assignment_pattern_error_ = inner.assignment_pattern_error_; assignment_pattern_error_ = inner->assignment_pattern_error_;
if (errors & DistinctFormalParametersProduction) if (errors & DistinctFormalParametersProduction)
duplicate_formal_parameter_error_ = duplicate_formal_parameter_error_ =
inner.duplicate_formal_parameter_error_; inner->duplicate_formal_parameter_error_;
if (errors & StrictModeFormalParametersProduction) if (errors & StrictModeFormalParametersProduction)
strict_mode_formal_parameter_error_ = strict_mode_formal_parameter_error_ =
inner.strict_mode_formal_parameter_error_; inner->strict_mode_formal_parameter_error_;
if (errors & StrongModeFormalParametersProduction) if (errors & StrongModeFormalParametersProduction)
strong_mode_formal_parameter_error_ = strong_mode_formal_parameter_error_ =
inner.strong_mode_formal_parameter_error_; inner->strong_mode_formal_parameter_error_;
if (errors & LetPatternProduction) if (errors & LetPatternProduction)
let_pattern_error_ = inner.let_pattern_error_; let_pattern_error_ = inner->let_pattern_error_;
if (errors & CoverInitializedNameProduction) if (errors & CoverInitializedNameProduction)
cover_initialized_name_error_ = inner.cover_initialized_name_error_; cover_initialized_name_error_ = inner->cover_initialized_name_error_;
} }
// As an exception to the above, the result continues to be a valid arrow // As an exception to the above, the result continues to be a valid arrow
...@@ -325,16 +338,31 @@ class ExpressionClassifier { ...@@ -325,16 +338,31 @@ class ExpressionClassifier {
is_valid_arrow_formal_parameters()) { is_valid_arrow_formal_parameters()) {
// Also copy function properties if expecting an arrow function // Also copy function properties if expecting an arrow function
// parameter. // parameter.
function_properties_ |= inner.function_properties_; function_properties_ |= inner->function_properties_;
if (!inner.is_valid_binding_pattern()) { if (!inner->is_valid_binding_pattern()) {
invalid_productions_ |= ArrowFormalParametersProduction; invalid_productions_ |= ArrowFormalParametersProduction;
arrow_formal_parameters_error_ = inner.binding_pattern_error_; arrow_formal_parameters_error_ = inner->binding_pattern_error_;
} }
} }
} }
V8_INLINE int GetNonPatternBegin() const { return non_pattern_begin_; }
V8_INLINE void Discard() {
DCHECK_LE(non_pattern_begin_, non_patterns_to_rewrite_->length());
non_patterns_to_rewrite_->Rewind(non_pattern_begin_);
}
V8_INLINE void MergeNonPatterns(ExpressionClassifier* inner) {
DCHECK_LE(non_pattern_begin_, inner->non_pattern_begin_);
inner->non_pattern_begin_ = inner->non_patterns_to_rewrite_->length();
}
private: private:
Zone* zone_;
ZoneList<typename Traits::Type::Expression>* non_patterns_to_rewrite_;
int non_pattern_begin_;
unsigned invalid_productions_; unsigned invalid_productions_;
unsigned function_properties_; unsigned function_properties_;
Error expression_error_; Error expression_error_;
...@@ -350,6 +378,7 @@ class ExpressionClassifier { ...@@ -350,6 +378,7 @@ class ExpressionClassifier {
DuplicateFinder* duplicate_finder_; DuplicateFinder* duplicate_finder_;
}; };
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
This diff is collapsed.
This diff is collapsed.
...@@ -335,6 +335,9 @@ class ParserTraits { ...@@ -335,6 +335,9 @@ class ParserTraits {
typedef v8::internal::AstProperties AstProperties; typedef v8::internal::AstProperties AstProperties;
typedef v8::internal::ExpressionClassifier<ParserTraits>
ExpressionClassifier;
// Return types for traversing functions. // Return types for traversing functions.
typedef const AstRawString* Identifier; typedef const AstRawString* Identifier;
typedef v8::internal::Expression* Expression; typedef v8::internal::Expression* Expression;
...@@ -549,7 +552,7 @@ class ParserTraits { ...@@ -549,7 +552,7 @@ class ParserTraits {
int initializer_end_position, bool is_rest); int initializer_end_position, bool is_rest);
V8_INLINE void DeclareFormalParameter( V8_INLINE void DeclareFormalParameter(
Scope* scope, const ParserFormalParameters::Parameter& parameter, Scope* scope, const ParserFormalParameters::Parameter& parameter,
ExpressionClassifier* classifier); Type::ExpressionClassifier* classifier);
void ParseArrowFunctionFormalParameters(ParserFormalParameters* parameters, void ParseArrowFunctionFormalParameters(ParserFormalParameters* parameters,
Expression* params, Expression* params,
const Scanner::Location& params_loc, const Scanner::Location& params_loc,
...@@ -643,6 +646,7 @@ class ParserTraits { ...@@ -643,6 +646,7 @@ class ParserTraits {
V8_INLINE void QueueDestructuringAssignmentForRewriting( V8_INLINE void QueueDestructuringAssignmentForRewriting(
Expression* assignment); Expression* assignment);
V8_INLINE void QueueNonPatternForRewriting(Expression* expr);
void SetFunctionNameFromPropertyName(ObjectLiteralProperty* property, void SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
const AstRawString* name); const AstRawString* name);
...@@ -651,12 +655,13 @@ class ParserTraits { ...@@ -651,12 +655,13 @@ class ParserTraits {
Expression* identifier); Expression* identifier);
// Rewrite expressions that are not used as patterns // Rewrite expressions that are not used as patterns
V8_INLINE Expression* RewriteNonPattern( V8_INLINE void RewriteNonPattern(Type::ExpressionClassifier* classifier,
Expression* expr, const ExpressionClassifier* classifier, bool* ok);
V8_INLINE ObjectLiteralProperty* RewriteNonPatternObjectLiteralProperty(
ObjectLiteralProperty* property, const ExpressionClassifier* classifier,
bool* ok); bool* ok);
V8_INLINE Zone* zone() const;
V8_INLINE ZoneList<Expression*>* GetNonPatternList() const;
Expression* RewriteYieldStar( Expression* RewriteYieldStar(
Expression* generator, Expression* expression, int pos); Expression* generator, Expression* expression, int pos);
...@@ -812,8 +817,9 @@ class Parser : public ParserBase<ParserTraits> { ...@@ -812,8 +817,9 @@ class Parser : public ParserBase<ParserTraits> {
const DeclarationParsingResult::Declaration* declaration, const DeclarationParsingResult::Declaration* declaration,
ZoneList<const AstRawString*>* names, bool* ok); ZoneList<const AstRawString*>* names, bool* ok);
static void RewriteDestructuringAssignment( static void RewriteDestructuringAssignment(Parser* parser,
Parser* parser, RewritableAssignmentExpression* expr, Scope* Scope); RewritableExpression* expr,
Scope* Scope);
static Expression* RewriteDestructuringAssignment(Parser* parser, static Expression* RewriteDestructuringAssignment(Parser* parser,
Assignment* assignment, Assignment* assignment,
...@@ -1029,11 +1035,7 @@ class Parser : public ParserBase<ParserTraits> { ...@@ -1029,11 +1035,7 @@ class Parser : public ParserBase<ParserTraits> {
friend class NonPatternRewriter; friend class NonPatternRewriter;
V8_INLINE Expression* RewriteSpreads(ArrayLiteral* lit); V8_INLINE Expression* RewriteSpreads(ArrayLiteral* lit);
V8_INLINE Expression* RewriteNonPattern( V8_INLINE void RewriteNonPattern(ExpressionClassifier* classifier, bool* ok);
Expression* expr, const ExpressionClassifier* classifier, bool* ok);
V8_INLINE ObjectLiteralProperty* RewriteNonPatternObjectLiteralProperty(
ObjectLiteralProperty* property, const ExpressionClassifier* classifier,
bool* ok);
friend class InitializerRewriter; friend class InitializerRewriter;
void RewriteParameterInitializer(Expression* expr, Scope* scope); void RewriteParameterInitializer(Expression* expr, Scope* scope);
...@@ -1184,7 +1186,7 @@ void ParserTraits::AddFormalParameter(ParserFormalParameters* parameters, ...@@ -1184,7 +1186,7 @@ void ParserTraits::AddFormalParameter(ParserFormalParameters* parameters,
void ParserTraits::DeclareFormalParameter( void ParserTraits::DeclareFormalParameter(
Scope* scope, const ParserFormalParameters::Parameter& parameter, Scope* scope, const ParserFormalParameters::Parameter& parameter,
ExpressionClassifier* classifier) { Type::ExpressionClassifier* classifier) {
bool is_duplicate = false; bool is_duplicate = false;
bool is_simple = classifier->is_simple_parameter_list(); bool is_simple = classifier->is_simple_parameter_list();
auto name = is_simple || parameter.is_rest auto name = is_simple || parameter.is_rest
......
...@@ -33,7 +33,7 @@ void Parser::PatternRewriter::DeclareAndInitializeVariables( ...@@ -33,7 +33,7 @@ void Parser::PatternRewriter::DeclareAndInitializeVariables(
void Parser::PatternRewriter::RewriteDestructuringAssignment( void Parser::PatternRewriter::RewriteDestructuringAssignment(
Parser* parser, RewritableAssignmentExpression* to_rewrite, Scope* scope) { Parser* parser, RewritableExpression* to_rewrite, Scope* scope) {
PatternRewriter rewriter; PatternRewriter rewriter;
DCHECK(!to_rewrite->is_rewritten()); DCHECK(!to_rewrite->is_rewritten());
...@@ -58,8 +58,7 @@ Expression* Parser::PatternRewriter::RewriteDestructuringAssignment( ...@@ -58,8 +58,7 @@ Expression* Parser::PatternRewriter::RewriteDestructuringAssignment(
Parser* parser, Assignment* assignment, Scope* scope) { Parser* parser, Assignment* assignment, Scope* scope) {
DCHECK_NOT_NULL(assignment); DCHECK_NOT_NULL(assignment);
DCHECK_EQ(Token::ASSIGN, assignment->op()); DCHECK_EQ(Token::ASSIGN, assignment->op());
auto to_rewrite = auto to_rewrite = parser->factory()->NewRewritableExpression(assignment);
parser->factory()->NewRewritableAssignmentExpression(assignment);
RewriteDestructuringAssignment(parser, to_rewrite, scope); RewriteDestructuringAssignment(parser, to_rewrite, scope);
return to_rewrite->expression(); return to_rewrite->expression();
} }
...@@ -91,8 +90,8 @@ Parser::PatternRewriter::SetInitializerContextIfNeeded(Expression* node) { ...@@ -91,8 +90,8 @@ Parser::PatternRewriter::SetInitializerContextIfNeeded(Expression* node) {
// AssignmentElement nodes // AssignmentElement nodes
PatternContext old_context = context(); PatternContext old_context = context();
bool is_destructuring_assignment = bool is_destructuring_assignment =
node->IsRewritableAssignmentExpression() && node->IsRewritableExpression() &&
!node->AsRewritableAssignmentExpression()->is_rewritten(); !node->AsRewritableExpression()->is_rewritten();
bool is_assignment = bool is_assignment =
node->IsAssignment() && node->AsAssignment()->op() == Token::ASSIGN; node->IsAssignment() && node->AsAssignment()->op() == Token::ASSIGN;
if (is_destructuring_assignment || is_assignment) { if (is_destructuring_assignment || is_assignment) {
...@@ -324,10 +323,11 @@ Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) { ...@@ -324,10 +323,11 @@ Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) {
} }
void Parser::PatternRewriter::VisitRewritableAssignmentExpression( void Parser::PatternRewriter::VisitRewritableExpression(
RewritableAssignmentExpression* node) { RewritableExpression* node) {
if (!IsAssignmentContext()) { // If this is not a destructuring assignment...
// Mark the assignment as rewritten to prevent redundant rewriting, and if (!IsAssignmentContext() || !node->expression()->IsAssignment()) {
// Mark the node as rewritten to prevent redundant rewriting, and
// perform BindingPattern rewriting // perform BindingPattern rewriting
DCHECK(!node->is_rewritten()); DCHECK(!node->is_rewritten());
node->Rewrite(node->expression()); node->Rewrite(node->expression());
......
...@@ -573,7 +573,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations( ...@@ -573,7 +573,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
int decl_pos = peek_position(); int decl_pos = peek_position();
PreParserExpression pattern = PreParserExpression::Default(); PreParserExpression pattern = PreParserExpression::Default();
{ {
ExpressionClassifier pattern_classifier; ExpressionClassifier pattern_classifier(this);
Token::Value next = peek(); Token::Value next = peek();
pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK); pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
...@@ -594,7 +594,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations( ...@@ -594,7 +594,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
Scanner::Location variable_loc = scanner()->location(); Scanner::Location variable_loc = scanner()->location();
nvars++; nvars++;
if (Check(Token::ASSIGN)) { if (Check(Token::ASSIGN)) {
ExpressionClassifier classifier; ExpressionClassifier classifier(this);
ParseAssignmentExpression(var_context != kForStatement, &classifier, ParseAssignmentExpression(var_context != kForStatement, &classifier,
CHECK_OK); CHECK_OK);
ValidateExpression(&classifier, CHECK_OK); ValidateExpression(&classifier, CHECK_OK);
...@@ -648,7 +648,7 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { ...@@ -648,7 +648,7 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
IsClassConstructor(function_state_->kind())) { IsClassConstructor(function_state_->kind())) {
bool is_this = peek() == Token::THIS; bool is_this = peek() == Token::THIS;
Expression expr = Expression::Default(); Expression expr = Expression::Default();
ExpressionClassifier classifier; ExpressionClassifier classifier(this);
if (is_this) { if (is_this) {
expr = ParseStrongInitializationExpression(&classifier, CHECK_OK); expr = ParseStrongInitializationExpression(&classifier, CHECK_OK);
} else { } else {
...@@ -684,7 +684,7 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { ...@@ -684,7 +684,7 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
} }
bool starts_with_identifier = peek_any_identifier(); bool starts_with_identifier = peek_any_identifier();
ExpressionClassifier classifier; ExpressionClassifier classifier(this);
Expression expr = ParseExpression(true, &classifier, CHECK_OK); Expression expr = ParseExpression(true, &classifier, CHECK_OK);
ValidateExpression(&classifier, CHECK_OK); ValidateExpression(&classifier, CHECK_OK);
...@@ -937,10 +937,9 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { ...@@ -937,10 +937,9 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
} }
if (mode == ForEachStatement::ITERATE) { if (mode == ForEachStatement::ITERATE) {
ExpressionClassifier classifier; ExpressionClassifier classifier(this);
Expression enumerable =
ParseAssignmentExpression(true, &classifier, CHECK_OK); ParseAssignmentExpression(true, &classifier, CHECK_OK);
PreParserTraits::RewriteNonPattern(enumerable, &classifier, CHECK_OK); RewriteNonPattern(&classifier, CHECK_OK);
} else { } else {
ParseExpression(true, CHECK_OK); ParseExpression(true, CHECK_OK);
} }
...@@ -951,7 +950,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { ...@@ -951,7 +950,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
} }
} else { } else {
int lhs_beg_pos = peek_position(); int lhs_beg_pos = peek_position();
ExpressionClassifier classifier; ExpressionClassifier classifier(this);
Expression lhs = ParseExpression(false, &classifier, CHECK_OK); Expression lhs = ParseExpression(false, &classifier, CHECK_OK);
int lhs_end_pos = scanner()->location().end_pos; int lhs_end_pos = scanner()->location().end_pos;
is_let_identifier_expression = is_let_identifier_expression =
...@@ -976,10 +975,9 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { ...@@ -976,10 +975,9 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
} }
if (mode == ForEachStatement::ITERATE) { if (mode == ForEachStatement::ITERATE) {
ExpressionClassifier classifier; ExpressionClassifier classifier(this);
Expression enumerable =
ParseAssignmentExpression(true, &classifier, CHECK_OK); ParseAssignmentExpression(true, &classifier, CHECK_OK);
PreParserTraits::RewriteNonPattern(enumerable, &classifier, CHECK_OK); RewriteNonPattern(&classifier, CHECK_OK);
} else { } else {
ParseExpression(true, CHECK_OK); ParseExpression(true, CHECK_OK);
} }
...@@ -1057,7 +1055,7 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) { ...@@ -1057,7 +1055,7 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
if (tok == Token::CATCH) { if (tok == Token::CATCH) {
Consume(Token::CATCH); Consume(Token::CATCH);
Expect(Token::LPAREN, CHECK_OK); Expect(Token::LPAREN, CHECK_OK);
ExpressionClassifier pattern_classifier; ExpressionClassifier pattern_classifier(this);
ParsePrimaryExpression(&pattern_classifier, CHECK_OK); ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
ValidateBindingPattern(&pattern_classifier, CHECK_OK); ValidateBindingPattern(&pattern_classifier, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
...@@ -1114,7 +1112,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral( ...@@ -1114,7 +1112,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
FunctionState function_state(&function_state_, &scope_, function_scope, kind, FunctionState function_state(&function_state_, &scope_, function_scope, kind,
&factory); &factory);
DuplicateFinder duplicate_finder(scanner()->unicode_cache()); DuplicateFinder duplicate_finder(scanner()->unicode_cache());
ExpressionClassifier formals_classifier(&duplicate_finder); ExpressionClassifier formals_classifier(this, &duplicate_finder);
Expect(Token::LPAREN, CHECK_OK); Expect(Token::LPAREN, CHECK_OK);
int start_position = scanner()->location().beg_pos; int start_position = scanner()->location().beg_pos;
...@@ -1220,7 +1218,7 @@ PreParserExpression PreParser::ParseClassLiteral( ...@@ -1220,7 +1218,7 @@ PreParserExpression PreParser::ParseClassLiteral(
bool has_extends = Check(Token::EXTENDS); bool has_extends = Check(Token::EXTENDS);
if (has_extends) { if (has_extends) {
ExpressionClassifier classifier; ExpressionClassifier classifier(this);
ParseLeftHandSideExpression(&classifier, CHECK_OK); ParseLeftHandSideExpression(&classifier, CHECK_OK);
ValidateExpression(&classifier, CHECK_OK); ValidateExpression(&classifier, CHECK_OK);
} }
...@@ -1236,7 +1234,7 @@ PreParserExpression PreParser::ParseClassLiteral( ...@@ -1236,7 +1234,7 @@ PreParserExpression PreParser::ParseClassLiteral(
bool is_computed_name = false; // Classes do not care about computed bool is_computed_name = false; // Classes do not care about computed
// property names here. // property names here.
Identifier name; Identifier name;
ExpressionClassifier classifier; ExpressionClassifier classifier(this);
ParsePropertyDefinition(&checker, in_class, has_extends, is_static, ParsePropertyDefinition(&checker, in_class, has_extends, is_static,
&is_computed_name, &has_seen_constructor, &is_computed_name, &has_seen_constructor,
&classifier, &name, CHECK_OK); &classifier, &name, CHECK_OK);
...@@ -1260,7 +1258,7 @@ PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { ...@@ -1260,7 +1258,7 @@ PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
// Allow "eval" or "arguments" for backward compatibility. // Allow "eval" or "arguments" for backward compatibility.
ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
Scanner::Location spread_pos; Scanner::Location spread_pos;
ExpressionClassifier classifier; ExpressionClassifier classifier(this);
ParseArguments(&spread_pos, &classifier, ok); ParseArguments(&spread_pos, &classifier, ok);
ValidateExpression(&classifier, CHECK_OK); ValidateExpression(&classifier, CHECK_OK);
......
...@@ -197,8 +197,6 @@ class PreParserExpression { ...@@ -197,8 +197,6 @@ class PreParserExpression {
ExpressionTypeField::decode(code_) == kAssignment; ExpressionTypeField::decode(code_) == kAssignment;
} }
bool IsRewritableAssignmentExpression() const { return IsAssignment(); }
bool IsObjectLiteral() const { bool IsObjectLiteral() const {
return TypeField::decode(code_) == kObjectLiteralExpression; return TypeField::decode(code_) == kObjectLiteralExpression;
} }
...@@ -487,8 +485,7 @@ class PreParserFactory { ...@@ -487,8 +485,7 @@ class PreParserFactory {
PreParserExpression right, int pos) { PreParserExpression right, int pos) {
return PreParserExpression::Default(); return PreParserExpression::Default();
} }
PreParserExpression NewRewritableAssignmentExpression( PreParserExpression NewRewritableExpression(PreParserExpression expression) {
PreParserExpression expression) {
return expression; return expression;
} }
PreParserExpression NewAssignment(Token::Value op, PreParserExpression NewAssignment(Token::Value op,
...@@ -589,6 +586,9 @@ class PreParserTraits { ...@@ -589,6 +586,9 @@ class PreParserTraits {
typedef int AstProperties; typedef int AstProperties;
typedef v8::internal::ExpressionClassifier<PreParserTraits>
ExpressionClassifier;
// Return types for traversing functions. // Return types for traversing functions.
typedef PreParserIdentifier Identifier; typedef PreParserIdentifier Identifier;
typedef PreParserExpression Expression; typedef PreParserExpression Expression;
...@@ -885,7 +885,7 @@ class PreParserTraits { ...@@ -885,7 +885,7 @@ class PreParserTraits {
++parameters->arity; ++parameters->arity;
} }
void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter, void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter,
ExpressionClassifier* classifier) { Type::ExpressionClassifier* classifier) {
if (!classifier->is_simple_parameter_list()) { if (!classifier->is_simple_parameter_list()) {
scope->SetHasNonSimpleParameters(); scope->SetHasNonSimpleParameters();
} }
...@@ -923,19 +923,19 @@ class PreParserTraits { ...@@ -923,19 +923,19 @@ class PreParserTraits {
inline void RewriteDestructuringAssignments() {} inline void RewriteDestructuringAssignments() {}
inline void QueueDestructuringAssignmentForRewriting(PreParserExpression) {} inline void QueueDestructuringAssignmentForRewriting(PreParserExpression) {}
inline void QueueNonPatternForRewriting(PreParserExpression) {}
void SetFunctionNameFromPropertyName(PreParserExpression, void SetFunctionNameFromPropertyName(PreParserExpression,
PreParserIdentifier) {} PreParserIdentifier) {}
void SetFunctionNameFromIdentifierRef(PreParserExpression, void SetFunctionNameFromIdentifierRef(PreParserExpression,
PreParserExpression) {} PreParserExpression) {}
inline PreParserExpression RewriteNonPattern( inline void RewriteNonPattern(Type::ExpressionClassifier* classifier,
PreParserExpression expr, const ExpressionClassifier* classifier,
bool* ok);
inline PreParserExpression RewriteNonPatternObjectLiteralProperty(
PreParserExpression property, const ExpressionClassifier* classifier,
bool* ok); bool* ok);
V8_INLINE Zone* zone() const;
V8_INLINE ZoneList<PreParserExpression>* GetNonPatternList() const;
inline PreParserExpression RewriteYieldStar( inline PreParserExpression RewriteYieldStar(
PreParserExpression generator, PreParserExpression expr, int pos); PreParserExpression generator, PreParserExpression expr, int pos);
...@@ -1119,19 +1119,19 @@ PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) { ...@@ -1119,19 +1119,19 @@ PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) {
} }
PreParserExpression PreParserTraits::RewriteNonPattern( void PreParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier,
PreParserExpression expr, const ExpressionClassifier* classifier,
bool* ok) { bool* ok) {
pre_parser_->ValidateExpression(classifier, ok); pre_parser_->ValidateExpression(classifier, ok);
return expr;
} }
PreParserExpression PreParserTraits::RewriteNonPatternObjectLiteralProperty( Zone* PreParserTraits::zone() const {
PreParserExpression property, const ExpressionClassifier* classifier, return pre_parser_->function_state_->scope()->zone();
bool* ok) { }
pre_parser_->ValidateExpression(classifier, ok);
return property;
ZoneList<PreParserExpression>* PreParserTraits::GetNonPatternList() const {
return pre_parser_->function_state_->non_patterns_to_rewrite();
} }
......
...@@ -1551,8 +1551,7 @@ void AsmTyper::VisitWithExpectation(Expression* expr, Type* expected_type, ...@@ -1551,8 +1551,7 @@ void AsmTyper::VisitWithExpectation(Expression* expr, Type* expected_type,
} }
void AsmTyper::VisitRewritableAssignmentExpression( void AsmTyper::VisitRewritableExpression(RewritableExpression* expr) {
RewritableAssignmentExpression* expr) {
RECURSE(Visit(expr->expression())); RECURSE(Visit(expr->expression()));
} }
......
...@@ -1177,10 +1177,7 @@ class AsmWasmBuilderImpl : public AstVisitor { ...@@ -1177,10 +1177,7 @@ class AsmWasmBuilderImpl : public AstVisitor {
void VisitDoExpression(DoExpression* expr) { UNREACHABLE(); } void VisitDoExpression(DoExpression* expr) { UNREACHABLE(); }
void VisitRewritableAssignmentExpression( void VisitRewritableExpression(RewritableExpression* expr) { UNREACHABLE(); }
RewritableAssignmentExpression* expr) {
UNREACHABLE();
}
struct IndexContainer : public ZoneObject { struct IndexContainer : public ZoneObject {
uint16_t index; uint16_t 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