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:
parent
915ae08dd5
commit
5bb6b47bd5
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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()));
|
||||
}
|
||||
|
@ -77,8 +77,8 @@ void AstLiteralReindexer::VisitSuperCallReference(SuperCallReference* node) {
|
||||
}
|
||||
|
||||
|
||||
void AstLiteralReindexer::VisitRewritableExpression(
|
||||
RewritableExpression* node) {
|
||||
void AstLiteralReindexer::VisitRewritableAssignmentExpression(
|
||||
RewritableAssignmentExpression* node) {
|
||||
Visit(node->expression());
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -3062,7 +3062,8 @@ VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(
|
||||
}
|
||||
|
||||
|
||||
void AstGraphBuilder::VisitRewritableExpression(RewritableExpression* node) {
|
||||
void AstGraphBuilder::VisitRewritableAssignmentExpression(
|
||||
RewritableAssignmentExpression* node) {
|
||||
Visit(node->expression());
|
||||
}
|
||||
|
||||
|
@ -287,7 +287,8 @@ void ALAA::VisitCountOperation(CountOperation* e) {
|
||||
}
|
||||
|
||||
|
||||
void ALAA::VisitRewritableExpression(RewritableExpression* expr) {
|
||||
void ALAA::VisitRewritableAssignmentExpression(
|
||||
RewritableAssignmentExpression* expr) {
|
||||
Visit(expr->expression());
|
||||
}
|
||||
|
||||
|
@ -12194,8 +12194,8 @@ void HOptimizedGraphBuilder::VisitExportDeclaration(
|
||||
}
|
||||
|
||||
|
||||
void HOptimizedGraphBuilder::VisitRewritableExpression(
|
||||
RewritableExpression* node) {
|
||||
void HOptimizedGraphBuilder::VisitRewritableAssignmentExpression(
|
||||
RewritableAssignmentExpression* node) {
|
||||
CHECK_ALIVE(Visit(node->expression()));
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -1507,7 +1507,8 @@ void FullCodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
|
||||
void FullCodeGenerator::VisitRewritableAssignmentExpression(
|
||||
RewritableAssignmentExpression* expr) {
|
||||
Visit(expr->expression());
|
||||
}
|
||||
|
||||
|
@ -2860,7 +2860,8 @@ void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) {
|
||||
}
|
||||
|
||||
|
||||
void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
|
||||
void BytecodeGenerator::VisitRewritableAssignmentExpression(
|
||||
RewritableAssignmentExpression* expr) {
|
||||
Visit(expr->expression());
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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()));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user