Revert of Non-pattern rewriting revisited (patchset #3 id:40001 of https://codereview.chromium.org/1702063002/ )

Reason for revert:
[Sheriff] This makes jsfunfuzz unhappy:
https://build.chromium.org/p/client.v8/builders/V8%20Fuzzer/builds/7681

Original issue's description:
> 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}

TBR=rossberg@chromium.org,bmeurer@chromium.org,titzer@chromium.org,nikolaos@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=chromium:579913

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

Cr-Commit-Position: refs/heads/master@{#34158}
This commit is contained in:
machenbach 2016-02-19 07:06:17 -08:00 committed by Commit bot
parent 915ae08dd5
commit 5bb6b47bd5
21 changed files with 279 additions and 359 deletions

View File

@ -398,10 +398,10 @@ void AstExpressionRewriter::VisitDoExpression(DoExpression* node) {
}
void AstExpressionRewriter::VisitRewritableExpression(
RewritableExpression* node) {
void AstExpressionRewriter::VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* node) {
REWRITE_THIS(node);
AST_REWRITE(Expression, node->expression(), node->Rewrite(replacement));
AST_REWRITE_PROPERTY(Expression, node, expression);
}

View File

@ -400,8 +400,8 @@ void AstExpressionVisitor::VisitSuperCallReference(SuperCallReference* expr) {
}
void AstExpressionVisitor::VisitRewritableExpression(
RewritableExpression* expr) {
void AstExpressionVisitor::VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* expr) {
VisitExpression(expr);
RECURSE(Visit(expr->expression()));
}

View File

@ -77,8 +77,8 @@ void AstLiteralReindexer::VisitSuperCallReference(SuperCallReference* node) {
}
void AstLiteralReindexer::VisitRewritableExpression(
RewritableExpression* node) {
void AstLiteralReindexer::VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* node) {
Visit(node->expression());
}

View File

@ -554,10 +554,10 @@ void AstNumberingVisitor::VisitFunctionLiteral(FunctionLiteral* node) {
}
void AstNumberingVisitor::VisitRewritableExpression(
RewritableExpression* node) {
void AstNumberingVisitor::VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* node) {
IncrementNodeCount();
node->set_base_id(ReserveIdRange(RewritableExpression::num_ids()));
node->set_base_id(ReserveIdRange(RewritableAssignmentExpression::num_ids()));
Visit(node->expression());
}

View File

@ -91,7 +91,7 @@ namespace internal {
V(CaseClause) \
V(EmptyParentheses) \
V(DoExpression) \
V(RewritableExpression)
V(RewritableAssignmentExpression)
#define AST_NODE_LIST(V) \
DECLARATION_NODE_LIST(V) \
@ -205,9 +205,13 @@ class AstNode: public ZoneObject {
// Type testing & conversion functions overridden by concrete subclasses.
#define DECLARE_NODE_FUNCTIONS(type) \
V8_INLINE bool Is##type() const; \
V8_INLINE type* As##type(); \
V8_INLINE const type* As##type() const;
bool Is##type() const { return node_type() == AstNode::k##type; } \
type* As##type() { \
return Is##type() ? reinterpret_cast<type*>(this) : NULL; \
} \
const type* As##type() const { \
return Is##type() ? reinterpret_cast<const type*>(this) : NULL; \
}
AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
#undef DECLARE_NODE_FUNCTIONS
@ -2482,32 +2486,18 @@ class Assignment final : 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 {
class RewritableAssignmentExpression : public Expression {
public:
DECLARE_NODE_TYPE(RewritableExpression)
DECLARE_NODE_TYPE(RewritableAssignmentExpression)
Expression* expression() const { return expr_; }
Expression* expression() { return expr_; }
bool is_rewritten() const { return is_rewritten_; }
void set_expression(Expression* e) { expr_ = e; }
void Rewrite(Expression* new_expression) {
DCHECK(!is_rewritten());
DCHECK_NOT_NULL(new_expression);
DCHECK(!new_expression->IsRewritableExpression());
expr_ = new_expression;
is_rewritten_ = true;
}
@ -2515,12 +2505,10 @@ class RewritableExpression : public Expression {
static int num_ids() { return parent_num_ids(); }
protected:
RewritableExpression(Zone* zone, Expression* expression)
RewritableAssignmentExpression(Zone* zone, Expression* expression)
: Expression(zone, expression->position()),
is_rewritten_(false),
expr_(expression) {
DCHECK(!expression->IsRewritableExpression());
}
expr_(expression) {}
private:
int local_id(int n) const { return base_id() + parent_num_ids() + n; }
@ -3377,9 +3365,12 @@ class AstNodeFactory final BASE_EMBEDDED {
local_zone_, condition, then_expression, else_expression, position);
}
RewritableExpression* NewRewritableExpression(Expression* expression) {
RewritableAssignmentExpression* NewRewritableAssignmentExpression(
Expression* expression) {
DCHECK_NOT_NULL(expression);
return new (local_zone_) RewritableExpression(local_zone_, expression);
DCHECK(expression->IsAssignment());
return new (local_zone_)
RewritableAssignmentExpression(local_zone_, expression);
}
Assignment* NewAssignment(Token::Value op,
@ -3517,46 +3508,6 @@ 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 v8

View File

@ -412,7 +412,8 @@ void CallPrinter::VisitSuperCallReference(SuperCallReference* node) {
}
void CallPrinter::VisitRewritableExpression(RewritableExpression* node) {
void CallPrinter::VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* node) {
Find(node->expression());
}
@ -928,7 +929,8 @@ void PrettyPrinter::VisitSuperCallReference(SuperCallReference* node) {
}
void PrettyPrinter::VisitRewritableExpression(RewritableExpression* node) {
void PrettyPrinter::VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* node) {
Visit(node->expression());
}
@ -1703,7 +1705,8 @@ void AstPrinter::VisitSuperCallReference(SuperCallReference* node) {
}
void AstPrinter::VisitRewritableExpression(RewritableExpression* node) {
void AstPrinter::VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* node) {
Visit(node->expression());
}

View File

@ -3062,7 +3062,8 @@ VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(
}
void AstGraphBuilder::VisitRewritableExpression(RewritableExpression* node) {
void AstGraphBuilder::VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* node) {
Visit(node->expression());
}

View File

@ -287,7 +287,8 @@ void ALAA::VisitCountOperation(CountOperation* e) {
}
void ALAA::VisitRewritableExpression(RewritableExpression* expr) {
void ALAA::VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* expr) {
Visit(expr->expression());
}

View File

@ -12194,8 +12194,8 @@ void HOptimizedGraphBuilder::VisitExportDeclaration(
}
void HOptimizedGraphBuilder::VisitRewritableExpression(
RewritableExpression* node) {
void HOptimizedGraphBuilder::VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* node) {
CHECK_ALIVE(Visit(node->expression()));
}

View File

@ -770,7 +770,8 @@ void AstTyper::VisitSuperPropertyReference(SuperPropertyReference* expr) {}
void AstTyper::VisitSuperCallReference(SuperCallReference* expr) {}
void AstTyper::VisitRewritableExpression(RewritableExpression* expr) {
void AstTyper::VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* expr) {
Visit(expr->expression());
}

View File

@ -1507,7 +1507,8 @@ void FullCodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) {
}
void FullCodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
void FullCodeGenerator::VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* expr) {
Visit(expr->expression());
}

View File

@ -2860,7 +2860,8 @@ void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) {
}
void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
void BytecodeGenerator::VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* expr) {
Visit(expr->expression());
}

View File

@ -13,7 +13,6 @@ namespace v8 {
namespace internal {
template <typename Traits>
class ExpressionClassifier {
public:
struct Error {
@ -56,25 +55,15 @@ class ExpressionClassifier {
enum FunctionProperties { NonSimpleParameter = 1 << 0 };
explicit ExpressionClassifier(const Traits* t)
: zone_(t->zone()),
non_patterns_to_rewrite_(t->GetNonPatternList()),
invalid_productions_(0),
ExpressionClassifier()
: invalid_productions_(0),
function_properties_(0),
duplicate_finder_(nullptr) {
non_pattern_begin_ = non_patterns_to_rewrite_->length();
}
duplicate_finder_(nullptr) {}
ExpressionClassifier(const Traits* t, DuplicateFinder* duplicate_finder)
: zone_(t->zone()),
non_patterns_to_rewrite_(t->GetNonPatternList()),
invalid_productions_(0),
explicit ExpressionClassifier(DuplicateFinder* duplicate_finder)
: invalid_productions_(0),
function_properties_(0),
duplicate_finder_(duplicate_finder) {
non_pattern_begin_ = non_patterns_to_rewrite_->length();
}
~ExpressionClassifier() { Discard(); }
duplicate_finder_(duplicate_finder) {}
bool is_valid(unsigned productions) const {
return (invalid_productions_ & productions) == 0;
@ -292,14 +281,12 @@ class ExpressionClassifier {
assignment_pattern_error_ = Error();
}
void Accumulate(ExpressionClassifier* inner,
unsigned productions = StandardProductions,
bool merge_non_patterns = true) {
if (merge_non_patterns) MergeNonPatterns(inner);
void Accumulate(const ExpressionClassifier& inner,
unsigned productions = StandardProductions) {
// Propagate errors from inner, but don't overwrite already recorded
// errors.
unsigned non_arrow_inner_invalid_productions =
inner->invalid_productions_ & ~ArrowFormalParametersProduction;
inner.invalid_productions_ & ~ArrowFormalParametersProduction;
if (non_arrow_inner_invalid_productions == 0) return;
unsigned non_arrow_productions =
productions & ~ArrowFormalParametersProduction;
@ -309,27 +296,27 @@ class ExpressionClassifier {
if (errors != 0) {
invalid_productions_ |= errors;
if (errors & ExpressionProduction)
expression_error_ = inner->expression_error_;
expression_error_ = inner.expression_error_;
if (errors & FormalParameterInitializerProduction)
formal_parameter_initializer_error_ =
inner->formal_parameter_initializer_error_;
inner.formal_parameter_initializer_error_;
if (errors & BindingPatternProduction)
binding_pattern_error_ = inner->binding_pattern_error_;
binding_pattern_error_ = inner.binding_pattern_error_;
if (errors & AssignmentPatternProduction)
assignment_pattern_error_ = inner->assignment_pattern_error_;
assignment_pattern_error_ = inner.assignment_pattern_error_;
if (errors & DistinctFormalParametersProduction)
duplicate_formal_parameter_error_ =
inner->duplicate_formal_parameter_error_;
inner.duplicate_formal_parameter_error_;
if (errors & StrictModeFormalParametersProduction)
strict_mode_formal_parameter_error_ =
inner->strict_mode_formal_parameter_error_;
inner.strict_mode_formal_parameter_error_;
if (errors & StrongModeFormalParametersProduction)
strong_mode_formal_parameter_error_ =
inner->strong_mode_formal_parameter_error_;
inner.strong_mode_formal_parameter_error_;
if (errors & LetPatternProduction)
let_pattern_error_ = inner->let_pattern_error_;
let_pattern_error_ = inner.let_pattern_error_;
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
@ -338,31 +325,16 @@ class ExpressionClassifier {
is_valid_arrow_formal_parameters()) {
// Also copy function properties if expecting an arrow function
// 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;
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:
Zone* zone_;
ZoneList<typename Traits::Type::Expression>* non_patterns_to_rewrite_;
int non_pattern_begin_;
unsigned invalid_productions_;
unsigned function_properties_;
Error expression_error_;
@ -378,7 +350,6 @@ class ExpressionClassifier {
DuplicateFinder* duplicate_finder_;
};
} // namespace internal
} // namespace v8

View File

@ -88,7 +88,6 @@ class ParserBase : public Traits {
typedef typename Traits::Type::Literal LiteralT;
typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
typedef typename Traits::Type::StatementList StatementListT;
typedef typename Traits::Type::ExpressionClassifier ExpressionClassifier;
ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
v8::Extension* extension, AstValueFactory* ast_value_factory,
@ -245,6 +244,10 @@ class ParserBase : public Traits {
return destructuring_assignments_to_rewrite_;
}
void AddDestructuringAssignment(DestructuringAssignment pair) {
destructuring_assignments_to_rewrite_.Add(pair);
}
List<ExpressionT>& expressions_in_tail_position() {
return expressions_in_tail_position_;
}
@ -261,21 +264,7 @@ class ParserBase : public Traits {
collect_expressions_in_tail_position_ = collect;
}
ZoneList<ExpressionT>* non_patterns_to_rewrite() {
return &non_patterns_to_rewrite_;
}
private:
void AddDestructuringAssignment(DestructuringAssignment pair) {
destructuring_assignments_to_rewrite_.Add(pair);
}
V8_INLINE Scope* scope() { return *scope_stack_; }
void AddNonPatternForRewriting(ExpressionT expr) {
non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone());
}
// Used to assign an index to each literal that needs materialization in
// the function. Includes regexp literals, and boilerplate for object and
// array literals.
@ -307,12 +296,12 @@ class ParserBase : public Traits {
List<DestructuringAssignment> destructuring_assignments_to_rewrite_;
List<ExpressionT> expressions_in_tail_position_;
bool collect_expressions_in_tail_position_;
ZoneList<ExpressionT> non_patterns_to_rewrite_;
void RewriteDestructuringAssignments();
typename Traits::Type::Factory* factory_;
friend class ParserTraits;
friend class PreParserTraits;
friend class Checkpoint;
};
@ -601,8 +590,8 @@ class ParserBase : public Traits {
Scanner::Location location, Token::Value token,
MessageTemplate::Template message = MessageTemplate::kUnexpectedToken);
void ReportClassifierError(
const typename ExpressionClassifier::Error& error) {
void ReportClassifierError(const ExpressionClassifier::Error& error) {
Traits::ReportMessageAt(error.location, error.message, error.arg,
error.type);
}
@ -680,7 +669,7 @@ class ParserBase : public Traits {
// neither a valid binding pattern nor a valid parenthesized formal
// parameter list, show the "arrow formal parameters" error if the formals
// started with a parenthesis, and the binding pattern error otherwise.
const typename ExpressionClassifier::Error& error =
const ExpressionClassifier::Error& error =
parenthesized_formals ? classifier->arrow_formal_parameters_error()
: classifier->binding_pattern_error();
ReportClassifierError(error);
@ -848,6 +837,11 @@ class ParserBase : public Traits {
return true;
}
bool IsAssignmentExpression(ExpressionT expression) {
return expression->IsAssignment() ||
expression->IsRewritableAssignmentExpression();
}
bool IsValidPattern(ExpressionT expression) {
return expression->IsObjectLiteral() || expression->IsArrayLiteral();
}
@ -974,7 +968,6 @@ ParserBase<Traits>::FunctionState::FunctionState(
scope_stack_(scope_stack),
outer_scope_(*scope_stack),
collect_expressions_in_tail_position_(true),
non_patterns_to_rewrite_(0, scope->zone()),
factory_(factory) {
*scope_stack_ = scope;
*function_state_stack = this;
@ -1061,7 +1054,7 @@ void ParserBase<Traits>::ReportUnexpectedTokenAt(
template <class Traits>
typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
auto result = ParseAndClassifyIdentifier(&classifier, ok);
if (!*ok) return Traits::EmptyIdentifier();
@ -1432,9 +1425,9 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
template <class Traits>
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
bool accept_IN, bool* ok) {
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
Traits::RewriteNonPattern(&classifier, CHECK_OK);
result = Traits::RewriteNonPattern(result, &classifier, CHECK_OK);
return result;
}
@ -1446,10 +1439,10 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
// AssignmentExpression
// Expression ',' AssignmentExpression
ExpressionClassifier binding_classifier(this);
ExpressionClassifier binding_classifier;
ExpressionT result =
this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
classifier->Accumulate(&binding_classifier,
classifier->Accumulate(binding_classifier,
ExpressionClassifier::AllProductions);
bool is_simple_parameter_list = this->IsIdentifier(result);
bool seen_rest = false;
@ -1474,8 +1467,6 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
int pos = position(), expr_pos = peek_position();
ExpressionT right = this->ParseAssignmentExpression(
accept_IN, &binding_classifier, CHECK_OK);
classifier->Accumulate(&binding_classifier,
ExpressionClassifier::AllProductions);
if (is_rest) {
if (!this->IsIdentifier(right) && !IsValidPattern(right)) {
classifier->RecordArrowFormalParametersError(
@ -1486,6 +1477,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
}
is_simple_parameter_list =
is_simple_parameter_list && this->IsIdentifier(right);
classifier->Accumulate(binding_classifier,
ExpressionClassifier::AllProductions);
result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
}
if (!is_simple_parameter_list || seen_rest) {
@ -1529,7 +1522,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
first_spread_index = values->length();
}
if (argument->IsAssignment()) {
if (IsAssignmentExpression(argument)) {
classifier->RecordPatternError(
Scanner::Location(start_pos, scanner()->location().end_pos),
MessageTemplate::kInvalidDestructuringTarget);
@ -1559,14 +1552,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
// Update the scope information before the pre-parsing bailout.
int literal_index = function_state_->NextMaterializedLiteralIndex();
ExpressionT result =
factory()->NewArrayLiteral(values, first_spread_index, literal_index,
is_strong(language_mode()), pos);
if (first_spread_index >= 0) {
result = factory()->NewRewritableExpression(result);
Traits::QueueNonPatternForRewriting(result);
}
return result;
return factory()->NewArrayLiteral(values, first_spread_index, literal_index,
is_strong(language_mode()), pos);
}
@ -1605,11 +1592,12 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
case Token::LBRACK: {
*is_computed_name = true;
Consume(Token::LBRACK);
ExpressionClassifier computed_name_classifier(this);
ExpressionClassifier computed_name_classifier;
ExpressionT expression =
ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK);
Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK);
classifier->Accumulate(&computed_name_classifier,
expression = Traits::RewriteNonPattern(
expression, &computed_name_classifier, CHECK_OK);
classifier->Accumulate(computed_name_classifier,
ExpressionClassifier::ExpressionProductions);
Expect(Token::RBRACK, CHECK_OK);
return expression;
@ -1697,12 +1685,12 @@ ParserBase<Traits>::ParsePropertyDefinition(
if (peek() == Token::ASSIGN) {
Consume(Token::ASSIGN);
ExpressionClassifier rhs_classifier(this);
ExpressionClassifier rhs_classifier;
ExpressionT rhs = this->ParseAssignmentExpression(
true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
Traits::RewriteNonPattern(&rhs_classifier,
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
classifier->Accumulate(&rhs_classifier,
rhs = Traits::RewriteNonPattern(
rhs, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
classifier->Accumulate(rhs_classifier,
ExpressionClassifier::ExpressionProductions);
value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
RelocInfo::kNoPosition);
@ -1764,7 +1752,8 @@ ParserBase<Traits>::ParsePropertyDefinition(
ObjectLiteralPropertyT property = ParsePropertyDefinition(
checker, true, has_extends, true, is_computed_name, nullptr, classifier,
name, ok);
Traits::RewriteNonPattern(classifier, ok);
property = Traits::RewriteNonPatternObjectLiteralProperty(property,
classifier, ok);
return property;
}
@ -1903,7 +1892,8 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
ExpressionT argument = this->ParseAssignmentExpression(
true, classifier, CHECK_OK_CUSTOM(NullExpressionList));
Traits::RewriteNonPattern(classifier, CHECK_OK_CUSTOM(NullExpressionList));
argument = Traits::RewriteNonPattern(argument, classifier,
CHECK_OK_CUSTOM(NullExpressionList));
if (is_spread) {
if (!spread_arg.IsValid()) {
spread_arg.beg_pos = start_pos;
@ -1970,8 +1960,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
FuncNameInferrer::State fni_state(fni_);
ParserBase<Traits>::Checkpoint checkpoint(this);
ExpressionClassifier arrow_formals_classifier(this,
classifier->duplicate_finder());
ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder());
bool parenthesized_formals = peek() == Token::LPAREN;
if (!parenthesized_formals) {
ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
@ -2021,24 +2010,17 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
// "expression" was not itself an arrow function parameter list, but it might
// form part of one. Propagate speculative formal parameter error locations.
// Do not merge pending non-pattern expressions yet!
classifier->Accumulate(
&arrow_formals_classifier,
arrow_formals_classifier,
ExpressionClassifier::StandardProductions |
ExpressionClassifier::FormalParametersProductions |
ExpressionClassifier::CoverInitializedNameProduction,
false);
ExpressionClassifier::FormalParametersProductions |
ExpressionClassifier::CoverInitializedNameProduction);
if (!Token::IsAssignmentOp(peek())) {
// Parsed conditional expression only (no assignment).
// Now pending non-pattern expressions must be merged.
classifier->MergeNonPatterns(&arrow_formals_classifier);
return expression;
}
// Now pending non-pattern expressions must be discarded.
arrow_formals_classifier.Discard();
if (!(allow_harmony_destructuring_bind() ||
allow_harmony_default_parameters())) {
BindingPatternUnexpectedToken(classifier);
@ -2072,14 +2054,14 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
}
int pos = position();
ExpressionClassifier rhs_classifier(this);
ExpressionClassifier rhs_classifier;
ExpressionT right =
this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK);
right = Traits::RewriteNonPattern(right, &rhs_classifier, CHECK_OK);
classifier->Accumulate(
&rhs_classifier, ExpressionClassifier::ExpressionProductions |
ExpressionClassifier::CoverInitializedNameProduction);
rhs_classifier, ExpressionClassifier::ExpressionProductions |
ExpressionClassifier::CoverInitializedNameProduction);
// TODO(1231235): We try to estimate the set of properties set by
// constructors. We define a new property whenever there is an
@ -2111,7 +2093,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
ExpressionT result = factory()->NewAssignment(op, expression, right, pos);
if (is_destructuring_assignment) {
result = factory()->NewRewritableExpression(result);
result = factory()->NewRewritableAssignmentExpression(result);
Traits::QueueDestructuringAssignmentForRewriting(result);
}
@ -2153,7 +2135,8 @@ ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier,
// Delegating yields require an RHS; fall through.
default:
expression = ParseAssignmentExpression(false, classifier, CHECK_OK);
Traits::RewriteNonPattern(classifier, CHECK_OK);
expression =
Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
break;
}
}
@ -2183,7 +2166,7 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
ExpressionT expression =
this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
if (peek() != Token::CONDITIONAL) return expression;
Traits::RewriteNonPattern(classifier, CHECK_OK);
expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
ArrowFormalParametersUnexpectedToken(classifier);
BindingPatternUnexpectedToken(classifier);
Consume(Token::CONDITIONAL);
@ -2191,11 +2174,11 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
// expressions we always accept the 'in' keyword; see ECMA-262,
// section 11.12, page 58.
ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK);
Traits::RewriteNonPattern(classifier, CHECK_OK);
left = Traits::RewriteNonPattern(left, classifier, CHECK_OK);
Expect(Token::COLON, CHECK_OK);
ExpressionT right =
ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
Traits::RewriteNonPattern(classifier, CHECK_OK);
right = Traits::RewriteNonPattern(right, classifier, CHECK_OK);
return factory()->NewConditional(expression, left, right, pos);
}
@ -2211,7 +2194,7 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
// prec1 >= 4
while (Precedence(peek(), accept_IN) == prec1) {
Traits::RewriteNonPattern(classifier, CHECK_OK);
x = Traits::RewriteNonPattern(x, classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
Token::Value op = Next();
@ -2219,7 +2202,7 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
int pos = position();
ExpressionT y =
ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK);
Traits::RewriteNonPattern(classifier, CHECK_OK);
y = Traits::RewriteNonPattern(y, classifier, CHECK_OK);
if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
factory())) {
@ -2282,7 +2265,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
op = Next();
int pos = position();
ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
Traits::RewriteNonPattern(classifier, CHECK_OK);
expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
if (op == Token::DELETE && is_strict(language_mode())) {
if (is_strong(language_mode())) {
@ -2309,7 +2292,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
expression, beg_pos, scanner()->location().end_pos,
MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
this->MarkExpressionAsAssigned(expression);
Traits::RewriteNonPattern(classifier, CHECK_OK);
expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
return factory()->NewCountOperation(op,
true /* prefix */,
@ -2341,7 +2324,7 @@ ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
expression, lhs_beg_pos, scanner()->location().end_pos,
MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
expression = this->MarkExpressionAsAssigned(expression);
Traits::RewriteNonPattern(classifier, CHECK_OK);
expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
Token::Value next = Next();
expression =
@ -2367,20 +2350,20 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
while (true) {
switch (peek()) {
case Token::LBRACK: {
Traits::RewriteNonPattern(classifier, CHECK_OK);
result = Traits::RewriteNonPattern(result, classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
Consume(Token::LBRACK);
int pos = position();
ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
Traits::RewriteNonPattern(classifier, CHECK_OK);
index = Traits::RewriteNonPattern(index, classifier, CHECK_OK);
result = factory()->NewProperty(result, index, pos);
Expect(Token::RBRACK, CHECK_OK);
break;
}
case Token::LPAREN: {
Traits::RewriteNonPattern(classifier, CHECK_OK);
result = Traits::RewriteNonPattern(result, classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
@ -2444,7 +2427,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
}
case Token::PERIOD: {
Traits::RewriteNonPattern(classifier, CHECK_OK);
result = Traits::RewriteNonPattern(result, classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
Consume(Token::PERIOD);
@ -2458,7 +2441,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
case Token::TEMPLATE_SPAN:
case Token::TEMPLATE_TAIL: {
Traits::RewriteNonPattern(classifier, CHECK_OK);
result = Traits::RewriteNonPattern(result, classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK);
@ -2510,7 +2493,7 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
} else {
result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
}
Traits::RewriteNonPattern(classifier, CHECK_OK);
result = Traits::RewriteNonPattern(result, classifier, CHECK_OK);
if (peek() == Token::LPAREN) {
// NewExpression with arguments.
Scanner::Location spread_pos;
@ -2626,7 +2609,7 @@ ParserBase<Traits>::ParseStrongInitializationExpression(
Consume(Token::LBRACK);
int pos = position();
ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
Traits::RewriteNonPattern(classifier, CHECK_OK);
index = Traits::RewriteNonPattern(index, classifier, CHECK_OK);
left = factory()->NewProperty(this_expr, index, pos);
if (fni_ != NULL) {
this->PushPropertyName(fni_, index);
@ -2662,7 +2645,7 @@ ParserBase<Traits>::ParseStrongInitializationExpression(
ExpressionT right =
this->ParseAssignmentExpression(true, classifier, CHECK_OK);
Traits::RewriteNonPattern(classifier, CHECK_OK);
right = Traits::RewriteNonPattern(right, classifier, CHECK_OK);
this->CheckAssigningFunctionLiteralToProperty(left, right);
function_state_->AddProperty();
if (fni_ != NULL) {
@ -2826,14 +2809,15 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
while (true) {
switch (peek()) {
case Token::LBRACK: {
Traits::RewriteNonPattern(classifier, CHECK_OK);
expression =
Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
Consume(Token::LBRACK);
int pos = position();
ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
Traits::RewriteNonPattern(classifier, CHECK_OK);
index = Traits::RewriteNonPattern(index, classifier, CHECK_OK);
expression = factory()->NewProperty(expression, index, pos);
if (fni_ != NULL) {
this->PushPropertyName(fni_, index);
@ -2842,7 +2826,8 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
break;
}
case Token::PERIOD: {
Traits::RewriteNonPattern(classifier, CHECK_OK);
expression =
Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
@ -2858,7 +2843,8 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
}
case Token::TEMPLATE_SPAN:
case Token::TEMPLATE_TAIL: {
Traits::RewriteNonPattern(classifier, CHECK_OK);
expression =
Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
int pos;
@ -2913,14 +2899,13 @@ void ParserBase<Traits>::ParseFormalParameter(
ExpressionT initializer = Traits::EmptyExpression();
if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) {
ExpressionClassifier init_classifier(this);
ExpressionClassifier init_classifier;
initializer = ParseAssignmentExpression(true, &init_classifier, ok);
if (!*ok) return;
Traits::RewriteNonPattern(&init_classifier, ok);
initializer = Traits::RewriteNonPattern(initializer, &init_classifier, ok);
ValidateFormalParameterInitializer(&init_classifier, ok);
if (!*ok) return;
parameters->is_simple = false;
init_classifier.Discard();
classifier->RecordNonSimpleParameter();
if (allow_harmony_function_name()) {
@ -3088,10 +3073,10 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
// Single-expression body
int pos = position();
parenthesized_function_ = false;
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
ExpressionT expression =
ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK);
Traits::RewriteNonPattern(&classifier, CHECK_OK);
expression = Traits::RewriteNonPattern(expression, &classifier, CHECK_OK);
body = this->NewStatementList(1, zone());
this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK);
body->Add(factory()->NewReturnStatement(expression, pos), zone());
@ -3197,7 +3182,7 @@ ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
int expr_pos = peek_position();
ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK);
Traits::RewriteNonPattern(classifier, CHECK_OK);
expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
Traits::AddTemplateExpression(&ts, expression);
if (peek() != Token::RBRACE) {
@ -3251,7 +3236,7 @@ typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::CheckAndRewriteReferenceExpression(
ExpressionT expression, int beg_pos, int end_pos,
MessageTemplate::Template message, ParseErrorType type, bool* ok) {
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
ExpressionT result = ClassifyAndRewriteReferenceExpression(
&classifier, expression, beg_pos, end_pos, message, type);
ValidateExpression(&classifier, ok);
@ -3305,7 +3290,7 @@ template <typename Traits>
void ParserBase<Traits>::CheckDestructuringElement(
ExpressionT expression, ExpressionClassifier* classifier, int begin,
int end) {
if (!IsValidPattern(expression) && !expression->IsAssignment() &&
if (!IsValidPattern(expression) && !IsAssignmentExpression(expression) &&
!IsValidReferenceExpression(expression)) {
classifier->RecordAssignmentPatternError(
Scanner::Location(begin, end),
@ -3371,8 +3356,6 @@ void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
return;
}
}
} // namespace internal
} // namespace v8

View File

@ -1063,7 +1063,7 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
SetLanguageMode(scope, shared_info->language_mode());
scope->set_start_position(shared_info->start_position());
ExpressionClassifier formals_classifier(this);
ExpressionClassifier formals_classifier;
ParserFormalParameters formals(scope);
Checkpoint checkpoint(this);
{
@ -1605,9 +1605,9 @@ Statement* Parser::ParseExportDefault(bool* ok) {
default: {
int pos = peek_position();
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK);
RewriteNonPattern(&classifier, CHECK_OK);
expr = ParserTraits::RewriteNonPattern(expr, &classifier, CHECK_OK);
ExpectSemicolon(CHECK_OK);
result = factory()->NewExpressionStatement(expr, pos);
@ -2377,7 +2377,7 @@ Block* Parser::ParseVariableDeclarations(
Expression* pattern;
int decl_pos = peek_position();
{
ExpressionClassifier pattern_classifier(this);
ExpressionClassifier pattern_classifier;
Token::Value next = peek();
pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
ValidateBindingPattern(&pattern_classifier, CHECK_OK);
@ -2402,10 +2402,10 @@ Block* Parser::ParseVariableDeclarations(
Expression* value = NULL;
int initializer_position = RelocInfo::kNoPosition;
if (Check(Token::ASSIGN)) {
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
value = ParseAssignmentExpression(var_context != kForStatement,
&classifier, CHECK_OK);
RewriteNonPattern(&classifier, ok);
value = ParserTraits::RewriteNonPattern(value, &classifier, CHECK_OK);
variable_loc.end_pos = scanner()->location().end_pos;
if (!parsing_result->first_initializer_loc.IsValid()) {
@ -2521,13 +2521,13 @@ Statement* Parser::ParseExpressionOrLabelledStatement(
IsClassConstructor(function_state_->kind())) {
bool is_this = peek() == Token::THIS;
Expression* expr;
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
if (is_this) {
expr = ParseStrongInitializationExpression(&classifier, CHECK_OK);
} else {
expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK);
}
RewriteNonPattern(&classifier, CHECK_OK);
expr = ParserTraits::RewriteNonPattern(expr, &classifier, CHECK_OK);
switch (peek()) {
case Token::SEMICOLON:
Consume(Token::SEMICOLON);
@ -3060,7 +3060,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
catch_scope = NewScope(scope_, CATCH_SCOPE);
catch_scope->set_start_position(scanner()->location().beg_pos);
ExpressionClassifier pattern_classifier(this);
ExpressionClassifier pattern_classifier;
Expression* pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
ValidateBindingPattern(&pattern_classifier, CHECK_OK);
@ -3690,9 +3690,10 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
Expression* enumerable;
if (mode == ForEachStatement::ITERATE) {
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
enumerable = ParseAssignmentExpression(true, &classifier, CHECK_OK);
RewriteNonPattern(&classifier, CHECK_OK);
enumerable = ParserTraits::RewriteNonPattern(enumerable, &classifier,
CHECK_OK);
} else {
enumerable = ParseExpression(true, CHECK_OK);
}
@ -3782,7 +3783,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
}
} else {
int lhs_beg_pos = peek_position();
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
Expression* expression = ParseExpression(false, &classifier, CHECK_OK);
int lhs_end_pos = scanner()->location().end_pos;
ForEachStatement::VisitMode mode;
@ -3800,7 +3801,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
if (is_destructuring) {
ValidateAssignmentPattern(&classifier, CHECK_OK);
} else {
RewriteNonPattern(&classifier, CHECK_OK);
expression =
ParserTraits::RewriteNonPattern(expression, &classifier, CHECK_OK);
}
if (is_for_each) {
@ -3816,9 +3818,10 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
Expression* enumerable;
if (mode == ForEachStatement::ITERATE) {
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
enumerable = ParseAssignmentExpression(true, &classifier, CHECK_OK);
RewriteNonPattern(&classifier, CHECK_OK);
enumerable = ParserTraits::RewriteNonPattern(enumerable, &classifier,
CHECK_OK);
} else {
enumerable = ParseExpression(true, CHECK_OK);
}
@ -4110,7 +4113,7 @@ void ParserTraits::ParseArrowFunctionFormalParameterList(
ParseArrowFunctionFormalParameters(parameters, expr, params_loc, ok);
if (!*ok) return;
Type::ExpressionClassifier classifier(parser_);
ExpressionClassifier classifier;
if (!parameters->is_simple) {
classifier.RecordNonSimpleParameter();
}
@ -4211,18 +4214,17 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
int materialized_literal_count = -1;
int expected_property_count = -1;
DuplicateFinder duplicate_finder(scanner()->unicode_cache());
ExpressionClassifier formals_classifier(&duplicate_finder);
FunctionLiteral::EagerCompileHint eager_compile_hint =
parenthesized_function_ ? FunctionLiteral::kShouldEagerCompile
: FunctionLiteral::kShouldLazyCompile;
bool should_be_used_once_hint = false;
bool has_duplicate_parameters;
// Parse function.
{
AstNodeFactory function_factory(ast_value_factory());
FunctionState function_state(&function_state_, &scope_, scope, kind,
&function_factory);
scope_->SetScopeName(function_name);
ExpressionClassifier formals_classifier(this, &duplicate_finder);
if (is_generator) {
// For generators, allocating variables in contexts is currently a win
@ -4400,10 +4402,10 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// If body can be inspected, rewrite queued destructuring assignments
ParserTraits::RewriteDestructuringAssignments();
}
has_duplicate_parameters =
!formals_classifier.is_valid_formal_parameter_list_without_duplicates();
}
bool has_duplicate_parameters =
!formals_classifier.is_valid_formal_parameter_list_without_duplicates();
FunctionLiteral::ParameterFlag duplicate_parameters =
has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
: FunctionLiteral::kNoDuplicateParameters;
@ -4537,7 +4539,8 @@ class InitializerRewriter : public AstExpressionVisitor {
private:
void VisitExpression(Expression* expr) {
RewritableExpression* to_rewrite = expr->AsRewritableExpression();
RewritableAssignmentExpression* to_rewrite =
expr->AsRewritableAssignmentExpression();
if (to_rewrite == nullptr || to_rewrite->is_rewritten()) return;
Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite,
@ -4879,9 +4882,9 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
Expression* extends = NULL;
if (Check(Token::EXTENDS)) {
block_scope->set_start_position(scanner()->location().end_pos);
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
extends = ParseLeftHandSideExpression(&classifier, CHECK_OK);
RewriteNonPattern(&classifier, CHECK_OK);
extends = ParserTraits::RewriteNonPattern(extends, &classifier, CHECK_OK);
} else {
block_scope->set_start_position(scanner()->location().end_pos);
}
@ -4902,12 +4905,13 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
const bool is_static = false;
bool is_computed_name = false; // Classes do not care about computed
// property names here.
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
const AstRawString* property_name = nullptr;
ObjectLiteral::Property* property = ParsePropertyDefinition(
&checker, in_class, has_extends, is_static, &is_computed_name,
&has_seen_constructor, &classifier, &property_name, CHECK_OK);
RewriteNonPattern(&classifier, CHECK_OK);
property = ParserTraits::RewriteNonPatternObjectLiteralProperty(
property, &classifier, CHECK_OK);
if (has_seen_constructor && constructor == NULL) {
constructor = GetPropertyValue(property)->AsFunctionLiteral();
@ -4958,7 +4962,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers,
CHECK_OK);
Scanner::Location spread_pos;
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
ZoneList<Expression*>* args =
ParseArguments(&spread_pos, &classifier, CHECK_OK);
@ -5529,19 +5533,17 @@ void ParserTraits::RewriteDestructuringAssignments() {
}
void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier,
bool* ok) {
parser_->RewriteNonPattern(classifier, ok);
Expression* ParserTraits::RewriteNonPattern(
Expression* expr, const ExpressionClassifier* classifier, bool* ok) {
return parser_->RewriteNonPattern(expr, classifier, ok);
}
Zone* ParserTraits::zone() const {
return parser_->function_state_->scope()->zone();
}
ZoneList<Expression*>* ParserTraits::GetNonPatternList() const {
return parser_->function_state_->non_patterns_to_rewrite();
ObjectLiteralProperty* ParserTraits::RewriteNonPatternObjectLiteralProperty(
ObjectLiteralProperty* property, const ExpressionClassifier* classifier,
bool* ok) {
return parser_->RewriteNonPatternObjectLiteralProperty(property, classifier,
ok);
}
@ -5553,7 +5555,6 @@ class NonPatternRewriter : public AstExpressionRewriter {
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.
@ -5583,37 +5584,45 @@ class NonPatternRewriter : public AstExpressionRewriter {
};
void Parser::RewriteNonPattern(ExpressionClassifier* classifier, bool* ok) {
Expression* Parser::RewriteNonPattern(Expression* expr,
const ExpressionClassifier* classifier,
bool* ok) {
ValidateExpression(classifier, ok);
if (!*ok) return;
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));
}
non_patterns_to_rewrite->Rewind(begin);
if (!*ok) return expr;
NonPatternRewriter rewriter(stack_limit_, this);
Expression* result = reinterpret_cast<Expression*>(rewriter.Rewrite(expr));
DCHECK_NOT_NULL(result);
return result;
}
ObjectLiteralProperty* Parser::RewriteNonPatternObjectLiteralProperty(
ObjectLiteralProperty* property, const ExpressionClassifier* classifier,
bool* ok) {
if (property != nullptr) {
// Do not rewrite (computed) key expressions
Expression* value = RewriteNonPattern(property->value(), classifier, ok);
property->set_value(value);
}
return property;
}
void Parser::RewriteDestructuringAssignments() {
FunctionState* func = function_state_;
if (!allow_harmony_destructuring_assignment()) return;
const auto& assignments =
function_state_->destructuring_assignments_to_rewrite();
const List<DestructuringAssignment>& assignments =
func->destructuring_assignments_to_rewrite();
for (int i = assignments.length() - 1; i >= 0; --i) {
// Rewrite list in reverse, so that nested assignment patterns are rewritten
// correctly.
const DestructuringAssignment& pair = assignments.at(i);
RewritableExpression* to_rewrite =
pair.assignment->AsRewritableExpression();
DestructuringAssignment pair = assignments.at(i);
RewritableAssignmentExpression* to_rewrite =
pair.assignment->AsRewritableAssignmentExpression();
Scope* scope = pair.scope;
DCHECK_NOT_NULL(to_rewrite);
if (!to_rewrite->is_rewritten()) {
PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite,
pair.scope);
PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope);
}
}
}
@ -5739,18 +5748,12 @@ Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) {
DCHECK(expr->IsRewritableExpression());
DCHECK(expr->IsRewritableAssignmentExpression());
parser_->function_state_->AddDestructuringAssignment(
Parser::DestructuringAssignment(expr, parser_->scope_));
}
void ParserTraits::QueueNonPatternForRewriting(Expression* expr) {
DCHECK(expr->IsRewritableExpression());
parser_->function_state_->AddNonPatternForRewriting(expr);
}
void ParserTraits::SetFunctionNameFromPropertyName(
ObjectLiteralProperty* property, const AstRawString* name) {
Expression* value = property->value();

View File

@ -335,9 +335,6 @@ class ParserTraits {
typedef v8::internal::AstProperties AstProperties;
typedef v8::internal::ExpressionClassifier<ParserTraits>
ExpressionClassifier;
// Return types for traversing functions.
typedef const AstRawString* Identifier;
typedef v8::internal::Expression* Expression;
@ -552,7 +549,7 @@ class ParserTraits {
int initializer_end_position, bool is_rest);
V8_INLINE void DeclareFormalParameter(
Scope* scope, const ParserFormalParameters::Parameter& parameter,
Type::ExpressionClassifier* classifier);
ExpressionClassifier* classifier);
void ParseArrowFunctionFormalParameters(ParserFormalParameters* parameters,
Expression* params,
const Scanner::Location& params_loc,
@ -646,7 +643,6 @@ class ParserTraits {
V8_INLINE void QueueDestructuringAssignmentForRewriting(
Expression* assignment);
V8_INLINE void QueueNonPatternForRewriting(Expression* expr);
void SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
const AstRawString* name);
@ -655,12 +651,11 @@ class ParserTraits {
Expression* identifier);
// Rewrite expressions that are not used as patterns
V8_INLINE void RewriteNonPattern(Type::ExpressionClassifier* classifier,
bool* ok);
V8_INLINE Zone* zone() const;
V8_INLINE ZoneList<Expression*>* GetNonPatternList() const;
V8_INLINE Expression* RewriteNonPattern(
Expression* expr, const ExpressionClassifier* classifier, bool* ok);
V8_INLINE ObjectLiteralProperty* RewriteNonPatternObjectLiteralProperty(
ObjectLiteralProperty* property, const ExpressionClassifier* classifier,
bool* ok);
Expression* RewriteYieldStar(
Expression* generator, Expression* expression, int pos);
@ -817,9 +812,8 @@ class Parser : public ParserBase<ParserTraits> {
const DeclarationParsingResult::Declaration* declaration,
ZoneList<const AstRawString*>* names, bool* ok);
static void RewriteDestructuringAssignment(Parser* parser,
RewritableExpression* expr,
Scope* Scope);
static void RewriteDestructuringAssignment(
Parser* parser, RewritableAssignmentExpression* expr, Scope* Scope);
static Expression* RewriteDestructuringAssignment(Parser* parser,
Assignment* assignment,
@ -1035,7 +1029,11 @@ class Parser : public ParserBase<ParserTraits> {
friend class NonPatternRewriter;
V8_INLINE Expression* RewriteSpreads(ArrayLiteral* lit);
V8_INLINE void RewriteNonPattern(ExpressionClassifier* classifier, bool* ok);
V8_INLINE Expression* RewriteNonPattern(
Expression* expr, const ExpressionClassifier* classifier, bool* ok);
V8_INLINE ObjectLiteralProperty* RewriteNonPatternObjectLiteralProperty(
ObjectLiteralProperty* property, const ExpressionClassifier* classifier,
bool* ok);
friend class InitializerRewriter;
void RewriteParameterInitializer(Expression* expr, Scope* scope);
@ -1186,7 +1184,7 @@ void ParserTraits::AddFormalParameter(ParserFormalParameters* parameters,
void ParserTraits::DeclareFormalParameter(
Scope* scope, const ParserFormalParameters::Parameter& parameter,
Type::ExpressionClassifier* classifier) {
ExpressionClassifier* classifier) {
bool is_duplicate = false;
bool is_simple = classifier->is_simple_parameter_list();
auto name = is_simple || parameter.is_rest

View File

@ -33,7 +33,7 @@ void Parser::PatternRewriter::DeclareAndInitializeVariables(
void Parser::PatternRewriter::RewriteDestructuringAssignment(
Parser* parser, RewritableExpression* to_rewrite, Scope* scope) {
Parser* parser, RewritableAssignmentExpression* to_rewrite, Scope* scope) {
PatternRewriter rewriter;
DCHECK(!to_rewrite->is_rewritten());
@ -58,7 +58,8 @@ Expression* Parser::PatternRewriter::RewriteDestructuringAssignment(
Parser* parser, Assignment* assignment, Scope* scope) {
DCHECK_NOT_NULL(assignment);
DCHECK_EQ(Token::ASSIGN, assignment->op());
auto to_rewrite = parser->factory()->NewRewritableExpression(assignment);
auto to_rewrite =
parser->factory()->NewRewritableAssignmentExpression(assignment);
RewriteDestructuringAssignment(parser, to_rewrite, scope);
return to_rewrite->expression();
}
@ -90,8 +91,8 @@ Parser::PatternRewriter::SetInitializerContextIfNeeded(Expression* node) {
// AssignmentElement nodes
PatternContext old_context = context();
bool is_destructuring_assignment =
node->IsRewritableExpression() &&
!node->AsRewritableExpression()->is_rewritten();
node->IsRewritableAssignmentExpression() &&
!node->AsRewritableAssignmentExpression()->is_rewritten();
bool is_assignment =
node->IsAssignment() && node->AsAssignment()->op() == Token::ASSIGN;
if (is_destructuring_assignment || is_assignment) {
@ -323,11 +324,10 @@ Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) {
}
void Parser::PatternRewriter::VisitRewritableExpression(
RewritableExpression* node) {
// If this is not a destructuring assignment...
if (!IsAssignmentContext() || !node->expression()->IsAssignment()) {
// Mark the node as rewritten to prevent redundant rewriting, and
void Parser::PatternRewriter::VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* node) {
if (!IsAssignmentContext()) {
// Mark the assignment as rewritten to prevent redundant rewriting, and
// perform BindingPattern rewriting
DCHECK(!node->is_rewritten());
node->Rewrite(node->expression());

View File

@ -573,7 +573,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
int decl_pos = peek_position();
PreParserExpression pattern = PreParserExpression::Default();
{
ExpressionClassifier pattern_classifier(this);
ExpressionClassifier pattern_classifier;
Token::Value next = peek();
pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
@ -594,7 +594,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
Scanner::Location variable_loc = scanner()->location();
nvars++;
if (Check(Token::ASSIGN)) {
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
ParseAssignmentExpression(var_context != kForStatement, &classifier,
CHECK_OK);
ValidateExpression(&classifier, CHECK_OK);
@ -648,7 +648,7 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
IsClassConstructor(function_state_->kind())) {
bool is_this = peek() == Token::THIS;
Expression expr = Expression::Default();
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
if (is_this) {
expr = ParseStrongInitializationExpression(&classifier, CHECK_OK);
} else {
@ -684,7 +684,7 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
}
bool starts_with_identifier = peek_any_identifier();
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
Expression expr = ParseExpression(true, &classifier, CHECK_OK);
ValidateExpression(&classifier, CHECK_OK);
@ -937,9 +937,10 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
}
if (mode == ForEachStatement::ITERATE) {
ExpressionClassifier classifier(this);
ParseAssignmentExpression(true, &classifier, CHECK_OK);
RewriteNonPattern(&classifier, CHECK_OK);
ExpressionClassifier classifier;
Expression enumerable =
ParseAssignmentExpression(true, &classifier, CHECK_OK);
PreParserTraits::RewriteNonPattern(enumerable, &classifier, CHECK_OK);
} else {
ParseExpression(true, CHECK_OK);
}
@ -950,7 +951,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
}
} else {
int lhs_beg_pos = peek_position();
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
Expression lhs = ParseExpression(false, &classifier, CHECK_OK);
int lhs_end_pos = scanner()->location().end_pos;
is_let_identifier_expression =
@ -975,9 +976,10 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
}
if (mode == ForEachStatement::ITERATE) {
ExpressionClassifier classifier(this);
ParseAssignmentExpression(true, &classifier, CHECK_OK);
RewriteNonPattern(&classifier, CHECK_OK);
ExpressionClassifier classifier;
Expression enumerable =
ParseAssignmentExpression(true, &classifier, CHECK_OK);
PreParserTraits::RewriteNonPattern(enumerable, &classifier, CHECK_OK);
} else {
ParseExpression(true, CHECK_OK);
}
@ -1055,7 +1057,7 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
if (tok == Token::CATCH) {
Consume(Token::CATCH);
Expect(Token::LPAREN, CHECK_OK);
ExpressionClassifier pattern_classifier(this);
ExpressionClassifier pattern_classifier;
ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
ValidateBindingPattern(&pattern_classifier, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
@ -1112,7 +1114,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
FunctionState function_state(&function_state_, &scope_, function_scope, kind,
&factory);
DuplicateFinder duplicate_finder(scanner()->unicode_cache());
ExpressionClassifier formals_classifier(this, &duplicate_finder);
ExpressionClassifier formals_classifier(&duplicate_finder);
Expect(Token::LPAREN, CHECK_OK);
int start_position = scanner()->location().beg_pos;
@ -1218,7 +1220,7 @@ PreParserExpression PreParser::ParseClassLiteral(
bool has_extends = Check(Token::EXTENDS);
if (has_extends) {
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
ParseLeftHandSideExpression(&classifier, CHECK_OK);
ValidateExpression(&classifier, CHECK_OK);
}
@ -1234,7 +1236,7 @@ PreParserExpression PreParser::ParseClassLiteral(
bool is_computed_name = false; // Classes do not care about computed
// property names here.
Identifier name;
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
ParsePropertyDefinition(&checker, in_class, has_extends, is_static,
&is_computed_name, &has_seen_constructor,
&classifier, &name, CHECK_OK);
@ -1258,7 +1260,7 @@ PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
// Allow "eval" or "arguments" for backward compatibility.
ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
Scanner::Location spread_pos;
ExpressionClassifier classifier(this);
ExpressionClassifier classifier;
ParseArguments(&spread_pos, &classifier, ok);
ValidateExpression(&classifier, CHECK_OK);

View File

@ -197,6 +197,8 @@ class PreParserExpression {
ExpressionTypeField::decode(code_) == kAssignment;
}
bool IsRewritableAssignmentExpression() const { return IsAssignment(); }
bool IsObjectLiteral() const {
return TypeField::decode(code_) == kObjectLiteralExpression;
}
@ -485,7 +487,8 @@ class PreParserFactory {
PreParserExpression right, int pos) {
return PreParserExpression::Default();
}
PreParserExpression NewRewritableExpression(PreParserExpression expression) {
PreParserExpression NewRewritableAssignmentExpression(
PreParserExpression expression) {
return expression;
}
PreParserExpression NewAssignment(Token::Value op,
@ -586,9 +589,6 @@ class PreParserTraits {
typedef int AstProperties;
typedef v8::internal::ExpressionClassifier<PreParserTraits>
ExpressionClassifier;
// Return types for traversing functions.
typedef PreParserIdentifier Identifier;
typedef PreParserExpression Expression;
@ -885,7 +885,7 @@ class PreParserTraits {
++parameters->arity;
}
void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter,
Type::ExpressionClassifier* classifier) {
ExpressionClassifier* classifier) {
if (!classifier->is_simple_parameter_list()) {
scope->SetHasNonSimpleParameters();
}
@ -923,18 +923,18 @@ class PreParserTraits {
inline void RewriteDestructuringAssignments() {}
inline void QueueDestructuringAssignmentForRewriting(PreParserExpression) {}
inline void QueueNonPatternForRewriting(PreParserExpression) {}
void SetFunctionNameFromPropertyName(PreParserExpression,
PreParserIdentifier) {}
void SetFunctionNameFromIdentifierRef(PreParserExpression,
PreParserExpression) {}
inline void RewriteNonPattern(Type::ExpressionClassifier* classifier,
bool* ok);
V8_INLINE Zone* zone() const;
V8_INLINE ZoneList<PreParserExpression>* GetNonPatternList() const;
inline PreParserExpression RewriteNonPattern(
PreParserExpression expr, const ExpressionClassifier* classifier,
bool* ok);
inline PreParserExpression RewriteNonPatternObjectLiteralProperty(
PreParserExpression property, const ExpressionClassifier* classifier,
bool* ok);
inline PreParserExpression RewriteYieldStar(
PreParserExpression generator, PreParserExpression expr, int pos);
@ -1119,19 +1119,19 @@ PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) {
}
void PreParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier,
bool* ok) {
PreParserExpression PreParserTraits::RewriteNonPattern(
PreParserExpression expr, const ExpressionClassifier* classifier,
bool* ok) {
pre_parser_->ValidateExpression(classifier, ok);
return expr;
}
Zone* PreParserTraits::zone() const {
return pre_parser_->function_state_->scope()->zone();
}
ZoneList<PreParserExpression>* PreParserTraits::GetNonPatternList() const {
return pre_parser_->function_state_->non_patterns_to_rewrite();
PreParserExpression PreParserTraits::RewriteNonPatternObjectLiteralProperty(
PreParserExpression property, const ExpressionClassifier* classifier,
bool* ok) {
pre_parser_->ValidateExpression(classifier, ok);
return property;
}

View File

@ -1551,7 +1551,8 @@ void AsmTyper::VisitWithExpectation(Expression* expr, Type* expected_type,
}
void AsmTyper::VisitRewritableExpression(RewritableExpression* expr) {
void AsmTyper::VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* expr) {
RECURSE(Visit(expr->expression()));
}

View File

@ -1177,7 +1177,10 @@ class AsmWasmBuilderImpl : public AstVisitor {
void VisitDoExpression(DoExpression* expr) { UNREACHABLE(); }
void VisitRewritableExpression(RewritableExpression* expr) { UNREACHABLE(); }
void VisitRewritableAssignmentExpression(
RewritableAssignmentExpression* expr) {
UNREACHABLE();
}
struct IndexContainer : public ZoneObject {
uint16_t index;