1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_PARSING_PARSER_BASE_H
6 #define V8_PARSING_PARSER_BASE_H
7
8 #include "src/ast/ast.h"
9 #include "src/ast/scopes.h"
10 #include "src/bailout-reason.h"
11 #include "src/base/hashmap.h"
12 #include "src/globals.h"
13 #include "src/messages.h"
14 #include "src/parsing/expression-classifier.h"
15 #include "src/parsing/func-name-inferrer.h"
16 #include "src/parsing/scanner.h"
17 #include "src/parsing/token.h"
18
19 namespace v8 {
20 namespace internal {
21
22
23 enum FunctionNameValidity {
24 kFunctionNameIsStrictReserved,
25 kSkipFunctionNameCheck,
26 kFunctionNameValidityUnknown
27 };
28
29 enum AllowLabelledFunctionStatement {
30 kAllowLabelledFunctionStatement,
31 kDisallowLabelledFunctionStatement,
32 };
33
34 enum class ParseFunctionFlags {
35 kIsNormal = 0,
36 kIsGenerator = 1,
37 kIsAsync = 2,
38 kIsDefault = 4
39 };
40
41 static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs,
42 ParseFunctionFlags rhs) {
43 typedef unsigned char T;
44 return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) |
45 static_cast<T>(rhs));
46 }
47
48 static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs,
49 const ParseFunctionFlags& rhs) {
50 lhs = lhs | rhs;
51 return lhs;
52 }
53
54 static inline bool operator&(ParseFunctionFlags bitfield,
55 ParseFunctionFlags mask) {
56 typedef unsigned char T;
57 return static_cast<T>(bitfield) & static_cast<T>(mask);
58 }
59
60 struct FormalParametersBase {
FormalParametersBaseFormalParametersBase61 explicit FormalParametersBase(DeclarationScope* scope) : scope(scope) {}
62
num_parametersFormalParametersBase63 int num_parameters() const {
64 // Don't include the rest parameter into the function's formal parameter
65 // count (esp. the SharedFunctionInfo::internal_formal_parameter_count,
66 // which says whether we need to create an arguments adaptor frame).
67 return arity - has_rest;
68 }
69
UpdateArityAndFunctionLengthFormalParametersBase70 void UpdateArityAndFunctionLength(bool is_optional, bool is_rest) {
71 if (!is_optional && !is_rest && function_length == arity) {
72 ++function_length;
73 }
74 ++arity;
75 }
76
77 DeclarationScope* scope;
78 bool has_rest = false;
79 bool is_simple = true;
80 int materialized_literals_count = 0;
81 int function_length = 0;
82 int arity = 0;
83 };
84
85
86 // ----------------------------------------------------------------------------
87 // The CHECK_OK macro is a convenient macro to enforce error
88 // handling for functions that may fail (by returning !*ok).
89 //
90 // CAUTION: This macro appends extra statements after a call,
91 // thus it must never be used where only a single statement
92 // is correct (e.g. an if statement branch w/o braces)!
93
94 #define CHECK_OK_CUSTOM(x, ...) ok); \
95 if (!*ok) return impl()->x(__VA_ARGS__); \
96 ((void)0
97 #define DUMMY ) // to make indentation work
98 #undef DUMMY
99
100 // Used in functions where the return type is ExpressionT.
101 #define CHECK_OK CHECK_OK_CUSTOM(EmptyExpression)
102
103 // Common base class template shared between parser and pre-parser.
104 // The Impl parameter is the actual class of the parser/pre-parser,
105 // following the Curiously Recurring Template Pattern (CRTP).
106 // The structure of the parser objects is roughly the following:
107 //
108 // // A structure template containing type definitions, needed to
109 // // avoid a cyclic dependency.
110 // template <typename Impl>
111 // struct ParserTypes;
112 //
113 // // The parser base object, which should just implement pure
114 // // parser behavior. The Impl parameter is the actual derived
115 // // class (according to CRTP), which implements impure parser
116 // // behavior.
117 // template <typename Impl>
118 // class ParserBase { ... };
119 //
120 // // And then, for each parser variant (e.g., parser, preparser, etc):
121 // class Parser;
122 //
123 // template <>
124 // class ParserTypes<Parser> { ... };
125 //
126 // class Parser : public ParserBase<Parser> { ... };
127 //
128 // The parser base object implements pure parsing, according to the
129 // language grammar. Different parser implementations may exhibit
130 // different parser-driven behavior that is not considered as pure
131 // parsing, e.g., early error detection and reporting, AST generation, etc.
132
133 // The ParserTypes structure encapsulates the differences in the
134 // types used in parsing methods. E.g., Parser methods use Expression*
135 // and PreParser methods use PreParserExpression. For any given parser
136 // implementation class Impl, it is expected to contain the following typedefs:
137 //
138 // template <>
139 // struct ParserTypes<Impl> {
140 // // Synonyms for ParserBase<Impl> and Impl, respectively.
141 // typedef Base;
142 // typedef Impl;
143 // // TODO(nikolaos): this one will probably go away, as it is
144 // // not related to pure parsing.
145 // typedef Variable;
146 // // Return types for traversing functions.
147 // typedef Identifier;
148 // typedef Expression;
149 // typedef FunctionLiteral;
150 // typedef ObjectLiteralProperty;
151 // typedef ClassLiteralProperty;
152 // typedef ExpressionList;
153 // typedef ObjectPropertyList;
154 // typedef ClassPropertyList;
155 // typedef FormalParameters;
156 // typedef Statement;
157 // typedef StatementList;
158 // typedef Block;
159 // typedef BreakableStatement;
160 // typedef IterationStatement;
161 // // For constructing objects returned by the traversing functions.
162 // typedef Factory;
163 // // For other implementation-specific tasks.
164 // typedef Target;
165 // typedef TargetScope;
166 // };
167
168 template <typename Impl>
169 struct ParserTypes;
170
171 template <typename Impl>
172 class ParserBase {
173 public:
174 // Shorten type names defined by ParserTypes<Impl>.
175 typedef ParserTypes<Impl> Types;
176 typedef typename Types::Identifier IdentifierT;
177 typedef typename Types::Expression ExpressionT;
178 typedef typename Types::FunctionLiteral FunctionLiteralT;
179 typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT;
180 typedef typename Types::ClassLiteralProperty ClassLiteralPropertyT;
181 typedef typename Types::ExpressionList ExpressionListT;
182 typedef typename Types::FormalParameters FormalParametersT;
183 typedef typename Types::Statement StatementT;
184 typedef typename Types::StatementList StatementListT;
185 typedef typename Types::Block BlockT;
186 typedef typename v8::internal::ExpressionClassifier<Types>
187 ExpressionClassifier;
188
189 // All implementation-specific methods must be called through this.
impl()190 Impl* impl() { return static_cast<Impl*>(this); }
impl()191 const Impl* impl() const { return static_cast<const Impl*>(this); }
192
ParserBase(Zone * zone,Scanner * scanner,uintptr_t stack_limit,v8::Extension * extension,AstValueFactory * ast_value_factory,RuntimeCallStats * runtime_call_stats)193 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
194 v8::Extension* extension, AstValueFactory* ast_value_factory,
195 RuntimeCallStats* runtime_call_stats)
196 : scope_state_(nullptr),
197 function_state_(nullptr),
198 extension_(extension),
199 fni_(nullptr),
200 ast_value_factory_(ast_value_factory),
201 ast_node_factory_(ast_value_factory),
202 runtime_call_stats_(runtime_call_stats),
203 parsing_module_(false),
204 stack_limit_(stack_limit),
205 zone_(zone),
206 classifier_(nullptr),
207 scanner_(scanner),
208 stack_overflow_(false),
209 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile),
210 allow_lazy_(false),
211 allow_natives_(false),
212 allow_tailcalls_(false),
213 allow_harmony_do_expressions_(false),
214 allow_harmony_function_sent_(false),
215 allow_harmony_async_await_(false),
216 allow_harmony_restrictive_generators_(false),
217 allow_harmony_trailing_commas_(false),
218 allow_harmony_class_fields_(false) {}
219
220 #define ALLOW_ACCESSORS(name) \
221 bool allow_##name() const { return allow_##name##_; } \
222 void set_allow_##name(bool allow) { allow_##name##_ = allow; }
223
224 ALLOW_ACCESSORS(lazy);
225 ALLOW_ACCESSORS(natives);
226 ALLOW_ACCESSORS(tailcalls);
227 ALLOW_ACCESSORS(harmony_do_expressions);
228 ALLOW_ACCESSORS(harmony_function_sent);
229 ALLOW_ACCESSORS(harmony_async_await);
230 ALLOW_ACCESSORS(harmony_restrictive_generators);
231 ALLOW_ACCESSORS(harmony_trailing_commas);
232 ALLOW_ACCESSORS(harmony_class_fields);
233
234 #undef ALLOW_ACCESSORS
235
stack_limit()236 uintptr_t stack_limit() const { return stack_limit_; }
237
set_stack_limit(uintptr_t stack_limit)238 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }
239
set_default_eager_compile_hint(FunctionLiteral::EagerCompileHint eager_compile_hint)240 void set_default_eager_compile_hint(
241 FunctionLiteral::EagerCompileHint eager_compile_hint) {
242 default_eager_compile_hint_ = eager_compile_hint;
243 }
244
default_eager_compile_hint()245 FunctionLiteral::EagerCompileHint default_eager_compile_hint() const {
246 return default_eager_compile_hint_;
247 }
248
zone()249 Zone* zone() const { return zone_; }
250
251 protected:
252 friend class v8::internal::ExpressionClassifier<ParserTypes<Impl>>;
253
254 enum AllowRestrictedIdentifiers {
255 kAllowRestrictedIdentifiers,
256 kDontAllowRestrictedIdentifiers
257 };
258
259 enum LazyParsingResult { kLazyParsingComplete, kLazyParsingAborted };
260
261 enum VariableDeclarationContext {
262 kStatementListItem,
263 kStatement,
264 kForStatement
265 };
266
267 enum class FunctionBodyType { kNormal, kSingleExpression };
268
269 class Checkpoint;
270 class ClassLiteralChecker;
271 class ObjectLiteralChecker;
272
273 // ---------------------------------------------------------------------------
274 // ScopeState and its subclasses implement the parser's scope stack.
275 // ScopeState keeps track of the current scope, and the outer ScopeState. The
276 // parser's scope_state_ points to the top ScopeState. ScopeState's
277 // constructor push on the scope stack and the destructors pop. BlockState and
278 // FunctionState are used to hold additional per-block and per-function state.
279 class ScopeState BASE_EMBEDDED {
280 public:
scope()281 V8_INLINE Scope* scope() const { return scope_; }
zone()282 Zone* zone() const { return scope_->zone(); }
283
284 protected:
ScopeState(ScopeState ** scope_stack,Scope * scope)285 ScopeState(ScopeState** scope_stack, Scope* scope)
286 : scope_stack_(scope_stack), outer_scope_(*scope_stack), scope_(scope) {
287 *scope_stack = this;
288 }
~ScopeState()289 ~ScopeState() { *scope_stack_ = outer_scope_; }
290
291 private:
292 ScopeState** const scope_stack_;
293 ScopeState* const outer_scope_;
294 Scope* const scope_;
295 };
296
297 class BlockState final : public ScopeState {
298 public:
BlockState(ScopeState ** scope_stack,Scope * scope)299 BlockState(ScopeState** scope_stack, Scope* scope)
300 : ScopeState(scope_stack, scope) {}
301
302 // BlockState(ScopeState**) automatically manages Scope(BLOCK_SCOPE)
303 // allocation.
304 // TODO(verwaest): Move to LazyBlockState class that only allocates the
305 // scope when needed.
BlockState(Zone * zone,ScopeState ** scope_stack)306 explicit BlockState(Zone* zone, ScopeState** scope_stack)
307 : ScopeState(scope_stack, NewScope(zone, *scope_stack)) {}
308
SetNonlinear()309 void SetNonlinear() { this->scope()->SetNonlinear(); }
set_start_position(int pos)310 void set_start_position(int pos) { this->scope()->set_start_position(pos); }
set_end_position(int pos)311 void set_end_position(int pos) { this->scope()->set_end_position(pos); }
set_is_hidden()312 void set_is_hidden() { this->scope()->set_is_hidden(); }
FinalizedBlockScope()313 Scope* FinalizedBlockScope() const {
314 return this->scope()->FinalizeBlockScope();
315 }
language_mode()316 LanguageMode language_mode() const {
317 return this->scope()->language_mode();
318 }
319
320 private:
NewScope(Zone * zone,ScopeState * outer_state)321 Scope* NewScope(Zone* zone, ScopeState* outer_state) {
322 Scope* parent = outer_state->scope();
323 return new (zone) Scope(zone, parent, BLOCK_SCOPE);
324 }
325 };
326
327 struct DestructuringAssignment {
328 public:
DestructuringAssignmentDestructuringAssignment329 DestructuringAssignment(ExpressionT expression, Scope* scope)
330 : assignment(expression), scope(scope) {}
331
332 ExpressionT assignment;
333 Scope* scope;
334 };
335
336 class TailCallExpressionList {
337 public:
TailCallExpressionList(Zone * zone)338 explicit TailCallExpressionList(Zone* zone)
339 : zone_(zone), expressions_(0, zone), has_explicit_tail_calls_(false) {}
340
expressions()341 const ZoneList<ExpressionT>& expressions() const { return expressions_; }
location()342 const Scanner::Location& location() const { return loc_; }
343
has_explicit_tail_calls()344 bool has_explicit_tail_calls() const { return has_explicit_tail_calls_; }
345
Swap(TailCallExpressionList & other)346 void Swap(TailCallExpressionList& other) {
347 expressions_.Swap(&other.expressions_);
348 std::swap(loc_, other.loc_);
349 std::swap(has_explicit_tail_calls_, other.has_explicit_tail_calls_);
350 }
351
AddImplicitTailCall(ExpressionT expr)352 void AddImplicitTailCall(ExpressionT expr) {
353 expressions_.Add(expr, zone_);
354 }
355
Append(const TailCallExpressionList & other)356 void Append(const TailCallExpressionList& other) {
357 if (!has_explicit_tail_calls()) {
358 loc_ = other.loc_;
359 has_explicit_tail_calls_ = other.has_explicit_tail_calls_;
360 }
361 expressions_.AddAll(other.expressions_, zone_);
362 }
363
364 private:
365 Zone* zone_;
366 ZoneList<ExpressionT> expressions_;
367 Scanner::Location loc_;
368 bool has_explicit_tail_calls_;
369 };
370
371 // Defines whether tail call expressions are allowed or not.
372 enum class ReturnExprContext {
373 // We are inside return statement which is allowed to contain tail call
374 // expressions. Tail call expressions are allowed.
375 kInsideValidReturnStatement,
376
377 // We are inside a block in which tail call expressions are allowed but
378 // not yet inside a return statement.
379 kInsideValidBlock,
380
381 // Tail call expressions are not allowed in the following blocks.
382 kInsideTryBlock,
383 kInsideForInOfBody,
384 };
385
386 class FunctionState final : public ScopeState {
387 public:
388 FunctionState(FunctionState** function_state_stack,
389 ScopeState** scope_stack, DeclarationScope* scope);
390 ~FunctionState();
391
scope()392 DeclarationScope* scope() const {
393 return ScopeState::scope()->AsDeclarationScope();
394 }
395
NextMaterializedLiteralIndex()396 int NextMaterializedLiteralIndex() {
397 return next_materialized_literal_index_++;
398 }
materialized_literal_count()399 int materialized_literal_count() {
400 return next_materialized_literal_index_;
401 }
402
SkipMaterializedLiterals(int count)403 void SkipMaterializedLiterals(int count) {
404 next_materialized_literal_index_ += count;
405 }
406
AddProperty()407 void AddProperty() { expected_property_count_++; }
expected_property_count()408 int expected_property_count() { return expected_property_count_; }
409
kind()410 FunctionKind kind() const { return scope()->function_kind(); }
outer()411 FunctionState* outer() const { return outer_function_state_; }
412
set_generator_object_variable(typename Types::Variable * variable)413 void set_generator_object_variable(typename Types::Variable* variable) {
414 DCHECK(variable != NULL);
415 DCHECK(IsResumableFunction(kind()));
416 generator_object_variable_ = variable;
417 }
generator_object_variable()418 typename Types::Variable* generator_object_variable() const {
419 return generator_object_variable_;
420 }
421
set_promise_variable(typename Types::Variable * variable)422 void set_promise_variable(typename Types::Variable* variable) {
423 DCHECK(variable != NULL);
424 DCHECK(IsAsyncFunction(kind()));
425 promise_variable_ = variable;
426 }
promise_variable()427 typename Types::Variable* promise_variable() const {
428 return promise_variable_;
429 }
430
431 const ZoneList<DestructuringAssignment>&
destructuring_assignments_to_rewrite()432 destructuring_assignments_to_rewrite() const {
433 return destructuring_assignments_to_rewrite_;
434 }
435
tail_call_expressions()436 TailCallExpressionList& tail_call_expressions() {
437 return tail_call_expressions_;
438 }
AddImplicitTailCallExpression(ExpressionT expression)439 void AddImplicitTailCallExpression(ExpressionT expression) {
440 if (return_expr_context() ==
441 ReturnExprContext::kInsideValidReturnStatement) {
442 tail_call_expressions_.AddImplicitTailCall(expression);
443 }
444 }
445
GetReportedErrorList()446 ZoneList<typename ExpressionClassifier::Error>* GetReportedErrorList() {
447 return &reported_errors_;
448 }
449
return_expr_context()450 ReturnExprContext return_expr_context() const {
451 return return_expr_context_;
452 }
set_return_expr_context(ReturnExprContext context)453 void set_return_expr_context(ReturnExprContext context) {
454 return_expr_context_ = context;
455 }
456
non_patterns_to_rewrite()457 ZoneList<ExpressionT>* non_patterns_to_rewrite() {
458 return &non_patterns_to_rewrite_;
459 }
460
next_function_is_parenthesized()461 bool next_function_is_parenthesized() const {
462 return next_function_is_parenthesized_;
463 }
464
set_next_function_is_parenthesized(bool parenthesized)465 void set_next_function_is_parenthesized(bool parenthesized) {
466 next_function_is_parenthesized_ = parenthesized;
467 }
468
this_function_is_parenthesized()469 bool this_function_is_parenthesized() const {
470 return this_function_is_parenthesized_;
471 }
472
473 private:
AddDestructuringAssignment(DestructuringAssignment pair)474 void AddDestructuringAssignment(DestructuringAssignment pair) {
475 destructuring_assignments_to_rewrite_.Add(pair, this->zone());
476 }
477
AddNonPatternForRewriting(ExpressionT expr,bool * ok)478 void AddNonPatternForRewriting(ExpressionT expr, bool* ok) {
479 non_patterns_to_rewrite_.Add(expr, this->zone());
480 if (non_patterns_to_rewrite_.length() >=
481 std::numeric_limits<uint16_t>::max())
482 *ok = false;
483 }
484
485 // Used to assign an index to each literal that needs materialization in
486 // the function. Includes regexp literals, and boilerplate for object and
487 // array literals.
488 int next_materialized_literal_index_;
489
490 // Properties count estimation.
491 int expected_property_count_;
492
493 // For generators, this variable may hold the generator object. It variable
494 // is used by yield expressions and return statements. It is not necessary
495 // for generator functions to have this variable set.
496 Variable* generator_object_variable_;
497 // For async functions, this variable holds a temporary for the Promise
498 // being created as output of the async function.
499 Variable* promise_variable_;
500
501 FunctionState** function_state_stack_;
502 FunctionState* outer_function_state_;
503
504 ZoneList<DestructuringAssignment> destructuring_assignments_to_rewrite_;
505 TailCallExpressionList tail_call_expressions_;
506 ReturnExprContext return_expr_context_;
507 ZoneList<ExpressionT> non_patterns_to_rewrite_;
508
509 ZoneList<typename ExpressionClassifier::Error> reported_errors_;
510
511 // If true, the next (and immediately following) function literal is
512 // preceded by a parenthesis.
513 bool next_function_is_parenthesized_;
514
515 // The value of the parents' next_function_is_parenthesized_, as it applies
516 // to this function. Filled in by constructor.
517 bool this_function_is_parenthesized_;
518
519 friend Impl;
520 friend class Checkpoint;
521 };
522
523 // This scope sets current ReturnExprContext to given value.
524 class ReturnExprScope {
525 public:
ReturnExprScope(FunctionState * function_state,ReturnExprContext return_expr_context)526 explicit ReturnExprScope(FunctionState* function_state,
527 ReturnExprContext return_expr_context)
528 : function_state_(function_state),
529 sav_return_expr_context_(function_state->return_expr_context()) {
530 // Don't update context if we are requested to enable tail call
531 // expressions but current block does not allow them.
532 if (return_expr_context !=
533 ReturnExprContext::kInsideValidReturnStatement ||
534 sav_return_expr_context_ == ReturnExprContext::kInsideValidBlock) {
535 function_state->set_return_expr_context(return_expr_context);
536 }
537 }
~ReturnExprScope()538 ~ReturnExprScope() {
539 function_state_->set_return_expr_context(sav_return_expr_context_);
540 }
541
542 private:
543 FunctionState* function_state_;
544 ReturnExprContext sav_return_expr_context_;
545 };
546
547 // Collects all return expressions at tail call position in this scope
548 // to a separate list.
549 class CollectExpressionsInTailPositionToListScope {
550 public:
CollectExpressionsInTailPositionToListScope(FunctionState * function_state,TailCallExpressionList * list)551 CollectExpressionsInTailPositionToListScope(FunctionState* function_state,
552 TailCallExpressionList* list)
553 : function_state_(function_state), list_(list) {
554 function_state->tail_call_expressions().Swap(*list_);
555 }
~CollectExpressionsInTailPositionToListScope()556 ~CollectExpressionsInTailPositionToListScope() {
557 function_state_->tail_call_expressions().Swap(*list_);
558 }
559
560 private:
561 FunctionState* function_state_;
562 TailCallExpressionList* list_;
563 };
564
565 // Annoyingly, arrow functions first parse as comma expressions, then when we
566 // see the => we have to go back and reinterpret the arguments as being formal
567 // parameters. To do so we need to reset some of the parser state back to
568 // what it was before the arguments were first seen.
569 class Checkpoint BASE_EMBEDDED {
570 public:
Checkpoint(ParserBase * parser)571 explicit Checkpoint(ParserBase* parser) {
572 function_state_ = parser->function_state_;
573 next_materialized_literal_index_ =
574 function_state_->next_materialized_literal_index_;
575 expected_property_count_ = function_state_->expected_property_count_;
576 }
577
Restore(int * materialized_literal_index_delta)578 void Restore(int* materialized_literal_index_delta) {
579 *materialized_literal_index_delta =
580 function_state_->next_materialized_literal_index_ -
581 next_materialized_literal_index_;
582 function_state_->next_materialized_literal_index_ =
583 next_materialized_literal_index_;
584 function_state_->expected_property_count_ = expected_property_count_;
585 }
586
587 private:
588 FunctionState* function_state_;
589 int next_materialized_literal_index_;
590 int expected_property_count_;
591 };
592
593 struct DeclarationDescriptor {
594 enum Kind { NORMAL, PARAMETER };
595 Scope* scope;
596 Scope* hoist_scope;
597 VariableMode mode;
598 int declaration_pos;
599 int initialization_pos;
600 Kind declaration_kind;
601 };
602
603 struct DeclarationParsingResult {
604 struct Declaration {
DeclarationDeclarationParsingResult::Declaration605 Declaration(ExpressionT pattern, int initializer_position,
606 ExpressionT initializer)
607 : pattern(pattern),
608 initializer_position(initializer_position),
609 initializer(initializer) {}
610
611 ExpressionT pattern;
612 int initializer_position;
613 ExpressionT initializer;
614 };
615
DeclarationParsingResultDeclarationParsingResult616 DeclarationParsingResult()
617 : declarations(4),
618 first_initializer_loc(Scanner::Location::invalid()),
619 bindings_loc(Scanner::Location::invalid()) {}
620
621 DeclarationDescriptor descriptor;
622 List<Declaration> declarations;
623 Scanner::Location first_initializer_loc;
624 Scanner::Location bindings_loc;
625 };
626
627 struct CatchInfo {
628 public:
CatchInfoCatchInfo629 explicit CatchInfo(ParserBase* parser)
630 : name(parser->impl()->EmptyIdentifier()),
631 variable(nullptr),
632 pattern(parser->impl()->EmptyExpression()),
633 scope(nullptr),
634 init_block(parser->impl()->NullBlock()),
635 inner_block(parser->impl()->NullBlock()),
636 for_promise_reject(false),
637 bound_names(1, parser->zone()),
638 tail_call_expressions(parser->zone()) {}
639 IdentifierT name;
640 Variable* variable;
641 ExpressionT pattern;
642 Scope* scope;
643 BlockT init_block;
644 BlockT inner_block;
645 bool for_promise_reject;
646 ZoneList<const AstRawString*> bound_names;
647 TailCallExpressionList tail_call_expressions;
648 };
649
650 struct ForInfo {
651 public:
ForInfoForInfo652 explicit ForInfo(ParserBase* parser)
653 : bound_names(1, parser->zone()),
654 mode(ForEachStatement::ENUMERATE),
655 position(kNoSourcePosition),
656 parsing_result() {}
657 ZoneList<const AstRawString*> bound_names;
658 ForEachStatement::VisitMode mode;
659 int position;
660 DeclarationParsingResult parsing_result;
661 };
662
663 struct ClassInfo {
664 public:
ClassInfoClassInfo665 explicit ClassInfo(ParserBase* parser)
666 : proxy(nullptr),
667 extends(parser->impl()->EmptyExpression()),
668 properties(parser->impl()->NewClassPropertyList(4)),
669 instance_field_initializers(parser->impl()->NewExpressionList(0)),
670 constructor(parser->impl()->EmptyFunctionLiteral()),
671 has_seen_constructor(false),
672 static_initializer_var(nullptr) {}
673 VariableProxy* proxy;
674 ExpressionT extends;
675 typename Types::ClassPropertyList properties;
676 ExpressionListT instance_field_initializers;
677 FunctionLiteralT constructor;
678 bool has_seen_constructor;
679 Variable* static_initializer_var;
680 };
681
NewScriptScope()682 DeclarationScope* NewScriptScope() const {
683 return new (zone()) DeclarationScope(zone(), ast_value_factory());
684 }
685
NewVarblockScope()686 DeclarationScope* NewVarblockScope() const {
687 return new (zone()) DeclarationScope(zone(), scope(), BLOCK_SCOPE);
688 }
689
NewModuleScope(DeclarationScope * parent)690 ModuleScope* NewModuleScope(DeclarationScope* parent) const {
691 return new (zone()) ModuleScope(parent, ast_value_factory());
692 }
693
NewEvalScope(Scope * parent)694 DeclarationScope* NewEvalScope(Scope* parent) const {
695 return new (zone()) DeclarationScope(zone(), parent, EVAL_SCOPE);
696 }
697
NewScope(ScopeType scope_type)698 Scope* NewScope(ScopeType scope_type) const {
699 return NewScopeWithParent(scope(), scope_type);
700 }
701
702 // This constructor should only be used when absolutely necessary. Most scopes
703 // should automatically use scope() as parent, and be fine with
704 // NewScope(ScopeType) above.
NewScopeWithParent(Scope * parent,ScopeType scope_type)705 Scope* NewScopeWithParent(Scope* parent, ScopeType scope_type) const {
706 // Must always use the specific constructors for the blacklisted scope
707 // types.
708 DCHECK_NE(FUNCTION_SCOPE, scope_type);
709 DCHECK_NE(SCRIPT_SCOPE, scope_type);
710 DCHECK_NE(MODULE_SCOPE, scope_type);
711 DCHECK_NOT_NULL(parent);
712 return new (zone()) Scope(zone(), parent, scope_type);
713 }
714
NewFunctionScope(FunctionKind kind)715 DeclarationScope* NewFunctionScope(FunctionKind kind) const {
716 DCHECK(ast_value_factory());
717 DeclarationScope* result =
718 new (zone()) DeclarationScope(zone(), scope(), FUNCTION_SCOPE, kind);
719 // TODO(verwaest): Move into the DeclarationScope constructor.
720 if (!IsArrowFunction(kind)) {
721 result->DeclareDefaultFunctionVariables(ast_value_factory());
722 }
723 return result;
724 }
725
GetDeclarationScope()726 V8_INLINE DeclarationScope* GetDeclarationScope() const {
727 return scope()->GetDeclarationScope();
728 }
GetClosureScope()729 V8_INLINE DeclarationScope* GetClosureScope() const {
730 return scope()->GetClosureScope();
731 }
732
scanner()733 Scanner* scanner() const { return scanner_; }
ast_value_factory()734 AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
position()735 int position() const { return scanner_->location().beg_pos; }
peek_position()736 int peek_position() const { return scanner_->peek_location().beg_pos; }
stack_overflow()737 bool stack_overflow() const { return stack_overflow_; }
set_stack_overflow()738 void set_stack_overflow() { stack_overflow_ = true; }
739
INLINE(Token::Value peek ())740 INLINE(Token::Value peek()) {
741 if (stack_overflow_) return Token::ILLEGAL;
742 return scanner()->peek();
743 }
744
INLINE(Token::Value PeekAhead ())745 INLINE(Token::Value PeekAhead()) {
746 if (stack_overflow_) return Token::ILLEGAL;
747 return scanner()->PeekAhead();
748 }
749
INLINE(Token::Value Next ())750 INLINE(Token::Value Next()) {
751 if (stack_overflow_) return Token::ILLEGAL;
752 {
753 if (GetCurrentStackPosition() < stack_limit_) {
754 // Any further calls to Next or peek will return the illegal token.
755 // The current call must return the next token, which might already
756 // have been peek'ed.
757 stack_overflow_ = true;
758 }
759 }
760 return scanner()->Next();
761 }
762
Consume(Token::Value token)763 void Consume(Token::Value token) {
764 Token::Value next = Next();
765 USE(next);
766 USE(token);
767 DCHECK(next == token);
768 }
769
Check(Token::Value token)770 bool Check(Token::Value token) {
771 Token::Value next = peek();
772 if (next == token) {
773 Consume(next);
774 return true;
775 }
776 return false;
777 }
778
Expect(Token::Value token,bool * ok)779 void Expect(Token::Value token, bool* ok) {
780 Token::Value next = Next();
781 if (next != token) {
782 ReportUnexpectedToken(next);
783 *ok = false;
784 }
785 }
786
ExpectSemicolon(bool * ok)787 void ExpectSemicolon(bool* ok) {
788 // Check for automatic semicolon insertion according to
789 // the rules given in ECMA-262, section 7.9, page 21.
790 Token::Value tok = peek();
791 if (tok == Token::SEMICOLON) {
792 Next();
793 return;
794 }
795 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
796 tok == Token::RBRACE ||
797 tok == Token::EOS) {
798 return;
799 }
800 Expect(Token::SEMICOLON, ok);
801 }
802
803 // Dummy functions, just useful as arguments to CHECK_OK_CUSTOM.
Void()804 static void Void() {}
805 template <typename T>
Return(T result)806 static T Return(T result) {
807 return result;
808 }
809
is_any_identifier(Token::Value token)810 bool is_any_identifier(Token::Value token) {
811 return token == Token::IDENTIFIER || token == Token::ENUM ||
812 token == Token::AWAIT || token == Token::ASYNC ||
813 token == Token::FUTURE_STRICT_RESERVED_WORD || token == Token::LET ||
814 token == Token::STATIC || token == Token::YIELD;
815 }
peek_any_identifier()816 bool peek_any_identifier() { return is_any_identifier(peek()); }
817
CheckContextualKeyword(Vector<const char> keyword)818 bool CheckContextualKeyword(Vector<const char> keyword) {
819 if (PeekContextualKeyword(keyword)) {
820 Consume(Token::IDENTIFIER);
821 return true;
822 }
823 return false;
824 }
825
PeekContextualKeyword(Vector<const char> keyword)826 bool PeekContextualKeyword(Vector<const char> keyword) {
827 return peek() == Token::IDENTIFIER &&
828 scanner()->is_next_contextual_keyword(keyword);
829 }
830
831 void ExpectMetaProperty(Vector<const char> property_name,
832 const char* full_name, int pos, bool* ok);
833
ExpectContextualKeyword(Vector<const char> keyword,bool * ok)834 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
835 Expect(Token::IDENTIFIER, CHECK_OK_CUSTOM(Void));
836 if (!scanner()->is_literal_contextual_keyword(keyword)) {
837 ReportUnexpectedToken(scanner()->current_token());
838 *ok = false;
839 }
840 }
841
CheckInOrOf(ForEachStatement::VisitMode * visit_mode)842 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode) {
843 if (Check(Token::IN)) {
844 *visit_mode = ForEachStatement::ENUMERATE;
845 return true;
846 } else if (CheckContextualKeyword(CStrVector("of"))) {
847 *visit_mode = ForEachStatement::ITERATE;
848 return true;
849 }
850 return false;
851 }
852
PeekInOrOf()853 bool PeekInOrOf() {
854 return peek() == Token::IN || PeekContextualKeyword(CStrVector("of"));
855 }
856
857 // Checks whether an octal literal was last seen between beg_pos and end_pos.
858 // If so, reports an error. Only called for strict mode and template strings.
CheckOctalLiteral(int beg_pos,int end_pos,MessageTemplate::Template message,bool * ok)859 void CheckOctalLiteral(int beg_pos, int end_pos,
860 MessageTemplate::Template message, bool* ok) {
861 Scanner::Location octal = scanner()->octal_position();
862 if (octal.IsValid() && beg_pos <= octal.beg_pos &&
863 octal.end_pos <= end_pos) {
864 impl()->ReportMessageAt(octal, message);
865 scanner()->clear_octal_position();
866 *ok = false;
867 }
868 }
869 // for now, this check just collects statistics.
CheckDecimalLiteralWithLeadingZero(int beg_pos,int end_pos)870 void CheckDecimalLiteralWithLeadingZero(int beg_pos, int end_pos) {
871 Scanner::Location token_location =
872 scanner()->decimal_with_leading_zero_position();
873 if (token_location.IsValid() && beg_pos <= token_location.beg_pos &&
874 token_location.end_pos <= end_pos) {
875 scanner()->clear_decimal_with_leading_zero_position();
876 impl()->CountUsage(v8::Isolate::kDecimalWithLeadingZeroInStrictMode);
877 }
878 }
879
CheckStrictOctalLiteral(int beg_pos,int end_pos,bool * ok)880 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
881 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral,
882 ok);
883 }
884
CheckTemplateOctalLiteral(int beg_pos,int end_pos,bool * ok)885 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
886 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral,
887 ok);
888 }
889
890 void CheckDestructuringElement(ExpressionT element, int beg_pos, int end_pos);
891
892 // Checking the name of a function literal. This has to be done after parsing
893 // the function, since the function can declare itself strict.
CheckFunctionName(LanguageMode language_mode,IdentifierT function_name,FunctionNameValidity function_name_validity,const Scanner::Location & function_name_loc,bool * ok)894 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
895 FunctionNameValidity function_name_validity,
896 const Scanner::Location& function_name_loc, bool* ok) {
897 if (function_name_validity == kSkipFunctionNameCheck) return;
898 // The function name needs to be checked in strict mode.
899 if (is_sloppy(language_mode)) return;
900
901 if (impl()->IsEvalOrArguments(function_name)) {
902 impl()->ReportMessageAt(function_name_loc,
903 MessageTemplate::kStrictEvalArguments);
904 *ok = false;
905 return;
906 }
907 if (function_name_validity == kFunctionNameIsStrictReserved) {
908 impl()->ReportMessageAt(function_name_loc,
909 MessageTemplate::kUnexpectedStrictReserved);
910 *ok = false;
911 return;
912 }
913 }
914
915 // Determine precedence of given token.
Precedence(Token::Value token,bool accept_IN)916 static int Precedence(Token::Value token, bool accept_IN) {
917 if (token == Token::IN && !accept_IN)
918 return 0; // 0 precedence will terminate binary expression parsing
919 return Token::Precedence(token);
920 }
921
factory()922 typename Types::Factory* factory() { return &ast_node_factory_; }
923
GetReceiverScope()924 DeclarationScope* GetReceiverScope() const {
925 return scope()->GetReceiverScope();
926 }
language_mode()927 LanguageMode language_mode() { return scope()->language_mode(); }
RaiseLanguageMode(LanguageMode mode)928 void RaiseLanguageMode(LanguageMode mode) {
929 LanguageMode old = scope()->language_mode();
930 impl()->SetLanguageMode(scope(), old > mode ? old : mode);
931 }
is_generator()932 bool is_generator() const {
933 return IsGeneratorFunction(function_state_->kind());
934 }
is_async_function()935 bool is_async_function() const {
936 return IsAsyncFunction(function_state_->kind());
937 }
is_resumable()938 bool is_resumable() const {
939 return IsResumableFunction(function_state_->kind());
940 }
941
942 // Report syntax errors.
ReportMessage(MessageTemplate::Template message)943 void ReportMessage(MessageTemplate::Template message) {
944 Scanner::Location source_location = scanner()->location();
945 impl()->ReportMessageAt(source_location, message,
946 static_cast<const char*>(nullptr), kSyntaxError);
947 }
948
949 template <typename T>
950 void ReportMessage(MessageTemplate::Template message, T arg,
951 ParseErrorType error_type = kSyntaxError) {
952 Scanner::Location source_location = scanner()->location();
953 impl()->ReportMessageAt(source_location, message, arg, error_type);
954 }
955
ReportMessageAt(Scanner::Location location,MessageTemplate::Template message,ParseErrorType error_type)956 void ReportMessageAt(Scanner::Location location,
957 MessageTemplate::Template message,
958 ParseErrorType error_type) {
959 impl()->ReportMessageAt(location, message,
960 static_cast<const char*>(nullptr), error_type);
961 }
962
963 void GetUnexpectedTokenMessage(
964 Token::Value token, MessageTemplate::Template* message,
965 Scanner::Location* location, const char** arg,
966 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken);
967
968 void ReportUnexpectedToken(Token::Value token);
969 void ReportUnexpectedTokenAt(
970 Scanner::Location location, Token::Value token,
971 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken);
972
ReportClassifierError(const typename ExpressionClassifier::Error & error)973 void ReportClassifierError(
974 const typename ExpressionClassifier::Error& error) {
975 impl()->ReportMessageAt(error.location, error.message, error.arg,
976 error.type);
977 }
978
ValidateExpression(bool * ok)979 void ValidateExpression(bool* ok) {
980 if (!classifier()->is_valid_expression()) {
981 ReportClassifierError(classifier()->expression_error());
982 *ok = false;
983 }
984 }
985
ValidateFormalParameterInitializer(bool * ok)986 void ValidateFormalParameterInitializer(bool* ok) {
987 if (!classifier()->is_valid_formal_parameter_initializer()) {
988 ReportClassifierError(classifier()->formal_parameter_initializer_error());
989 *ok = false;
990 }
991 }
992
ValidateBindingPattern(bool * ok)993 void ValidateBindingPattern(bool* ok) {
994 if (!classifier()->is_valid_binding_pattern()) {
995 ReportClassifierError(classifier()->binding_pattern_error());
996 *ok = false;
997 }
998 }
999
ValidateAssignmentPattern(bool * ok)1000 void ValidateAssignmentPattern(bool* ok) {
1001 if (!classifier()->is_valid_assignment_pattern()) {
1002 ReportClassifierError(classifier()->assignment_pattern_error());
1003 *ok = false;
1004 }
1005 }
1006
ValidateFormalParameters(LanguageMode language_mode,bool allow_duplicates,bool * ok)1007 void ValidateFormalParameters(LanguageMode language_mode,
1008 bool allow_duplicates, bool* ok) {
1009 if (!allow_duplicates &&
1010 !classifier()->is_valid_formal_parameter_list_without_duplicates()) {
1011 ReportClassifierError(classifier()->duplicate_formal_parameter_error());
1012 *ok = false;
1013 } else if (is_strict(language_mode) &&
1014 !classifier()->is_valid_strict_mode_formal_parameters()) {
1015 ReportClassifierError(classifier()->strict_mode_formal_parameter_error());
1016 *ok = false;
1017 }
1018 }
1019
IsValidArrowFormalParametersStart(Token::Value token)1020 bool IsValidArrowFormalParametersStart(Token::Value token) {
1021 return is_any_identifier(token) || token == Token::LPAREN;
1022 }
1023
ValidateArrowFormalParameters(ExpressionT expr,bool parenthesized_formals,bool is_async,bool * ok)1024 void ValidateArrowFormalParameters(ExpressionT expr,
1025 bool parenthesized_formals, bool is_async,
1026 bool* ok) {
1027 if (classifier()->is_valid_binding_pattern()) {
1028 // A simple arrow formal parameter: IDENTIFIER => BODY.
1029 if (!impl()->IsIdentifier(expr)) {
1030 impl()->ReportMessageAt(scanner()->location(),
1031 MessageTemplate::kUnexpectedToken,
1032 Token::String(scanner()->current_token()));
1033 *ok = false;
1034 }
1035 } else if (!classifier()->is_valid_arrow_formal_parameters()) {
1036 // If after parsing the expr, we see an error but the expression is
1037 // neither a valid binding pattern nor a valid parenthesized formal
1038 // parameter list, show the "arrow formal parameters" error if the formals
1039 // started with a parenthesis, and the binding pattern error otherwise.
1040 const typename ExpressionClassifier::Error& error =
1041 parenthesized_formals ? classifier()->arrow_formal_parameters_error()
1042 : classifier()->binding_pattern_error();
1043 ReportClassifierError(error);
1044 *ok = false;
1045 }
1046 if (is_async && !classifier()->is_valid_async_arrow_formal_parameters()) {
1047 const typename ExpressionClassifier::Error& error =
1048 classifier()->async_arrow_formal_parameters_error();
1049 ReportClassifierError(error);
1050 *ok = false;
1051 }
1052 }
1053
ValidateLetPattern(bool * ok)1054 void ValidateLetPattern(bool* ok) {
1055 if (!classifier()->is_valid_let_pattern()) {
1056 ReportClassifierError(classifier()->let_pattern_error());
1057 *ok = false;
1058 }
1059 }
1060
ExpressionUnexpectedToken()1061 void ExpressionUnexpectedToken() {
1062 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
1063 const char* arg;
1064 Scanner::Location location = scanner()->peek_location();
1065 GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
1066 classifier()->RecordExpressionError(location, message, arg);
1067 }
1068
BindingPatternUnexpectedToken()1069 void BindingPatternUnexpectedToken() {
1070 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
1071 const char* arg;
1072 Scanner::Location location = scanner()->peek_location();
1073 GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
1074 classifier()->RecordBindingPatternError(location, message, arg);
1075 }
1076
ArrowFormalParametersUnexpectedToken()1077 void ArrowFormalParametersUnexpectedToken() {
1078 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
1079 const char* arg;
1080 Scanner::Location location = scanner()->peek_location();
1081 GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
1082 classifier()->RecordArrowFormalParametersError(location, message, arg);
1083 }
1084
1085 // Recursive descent functions.
1086 // All ParseXXX functions take as the last argument an *ok parameter
1087 // which is set to false if parsing failed; it is unchanged otherwise.
1088 // By making the 'exception handling' explicit, we are forced to check
1089 // for failure at the call sites. The family of CHECK_OK* macros can
1090 // be useful for this.
1091
1092 // Parses an identifier that is valid for the current scope, in particular it
1093 // fails on strict mode future reserved keywords in a strict scope. If
1094 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
1095 // "arguments" as identifier even in strict mode (this is needed in cases like
1096 // "var foo = eval;").
1097 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok);
1098 IdentifierT ParseAndClassifyIdentifier(bool* ok);
1099 // Parses an identifier or a strict mode future reserved word, and indicate
1100 // whether it is strict mode future reserved. Allows passing in function_kind
1101 // for the case of parsing the identifier in a function expression, where the
1102 // relevant "function_kind" bit is of the function being parsed, not the
1103 // containing function.
1104 IdentifierT ParseIdentifierOrStrictReservedWord(FunctionKind function_kind,
1105 bool* is_strict_reserved,
1106 bool* ok);
ParseIdentifierOrStrictReservedWord(bool * is_strict_reserved,bool * ok)1107 IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
1108 bool* ok) {
1109 return ParseIdentifierOrStrictReservedWord(function_state_->kind(),
1110 is_strict_reserved, ok);
1111 }
1112
1113 IdentifierT ParseIdentifierName(bool* ok);
1114
1115 ExpressionT ParseRegExpLiteral(bool* ok);
1116
1117 ExpressionT ParsePrimaryExpression(bool* is_async, bool* ok);
ParsePrimaryExpression(bool * ok)1118 ExpressionT ParsePrimaryExpression(bool* ok) {
1119 bool is_async;
1120 return ParsePrimaryExpression(&is_async, ok);
1121 }
1122
1123 // This method wraps the parsing of the expression inside a new expression
1124 // classifier and calls RewriteNonPattern if parsing is successful.
1125 // It should be used whenever we're parsing an expression that will be
1126 // used as a non-pattern (i.e., in most cases).
1127 V8_INLINE ExpressionT ParseExpression(bool accept_IN, bool* ok);
1128
1129 // This method does not wrap the parsing of the expression inside a
1130 // new expression classifier; it uses the top-level classifier instead.
1131 // It should be used whenever we're parsing something with the "cover"
1132 // grammar that recognizes both patterns and non-patterns (which roughly
1133 // corresponds to what's inside the parentheses generated by the symbol
1134 // "CoverParenthesizedExpressionAndArrowParameterList" in the ES 2017
1135 // specification).
1136 ExpressionT ParseExpressionCoverGrammar(bool accept_IN, bool* ok);
1137
1138 ExpressionT ParseArrayLiteral(bool* ok);
1139
1140 enum class PropertyKind {
1141 kAccessorProperty,
1142 kValueProperty,
1143 kShorthandProperty,
1144 kMethodProperty,
1145 kClassField,
1146 kNotSet
1147 };
1148
1149 bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind);
1150 ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind,
1151 bool* is_generator, bool* is_get, bool* is_set,
1152 bool* is_async, bool* is_computed_name,
1153 bool* ok);
1154 ExpressionT ParseObjectLiteral(bool* ok);
1155 ClassLiteralPropertyT ParseClassPropertyDefinition(
1156 ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name,
1157 bool* has_seen_constructor, bool* ok);
1158 FunctionLiteralT ParseClassFieldForInitializer(bool has_initializer,
1159 bool* ok);
1160 ObjectLiteralPropertyT ParseObjectPropertyDefinition(
1161 ObjectLiteralChecker* checker, bool* is_computed_name, bool* ok);
1162 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos,
1163 bool maybe_arrow, bool* ok);
ParseArguments(Scanner::Location * first_spread_pos,bool * ok)1164 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos,
1165 bool* ok) {
1166 return ParseArguments(first_spread_pos, false, ok);
1167 }
1168
1169 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
1170 ExpressionT ParseYieldExpression(bool accept_IN, bool* ok);
1171 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
1172 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
1173 ExpressionT ParseUnaryExpression(bool* ok);
1174 ExpressionT ParsePostfixExpression(bool* ok);
1175 ExpressionT ParseLeftHandSideExpression(bool* ok);
1176 ExpressionT ParseMemberWithNewPrefixesExpression(bool* is_async, bool* ok);
1177 ExpressionT ParseMemberExpression(bool* is_async, bool* ok);
1178 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
1179 bool* is_async, bool* ok);
1180 ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
1181 const FormalParametersT& parameters,
1182 bool* ok);
1183 void ParseAsyncFunctionBody(Scope* scope, StatementListT body,
1184 FunctionKind kind, FunctionBodyType type,
1185 bool accept_IN, int pos, bool* ok);
1186 ExpressionT ParseAsyncFunctionLiteral(bool* ok);
1187 ExpressionT ParseClassLiteral(IdentifierT name,
1188 Scanner::Location class_name_location,
1189 bool name_is_strict_reserved,
1190 int class_token_pos, bool* ok);
1191 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
1192 ExpressionT ParseSuperExpression(bool is_new, bool* ok);
1193 ExpressionT ParseNewTargetExpression(bool* ok);
1194
1195 void ParseFormalParameter(FormalParametersT* parameters, bool* ok);
1196 void ParseFormalParameterList(FormalParametersT* parameters, bool* ok);
1197 void CheckArityRestrictions(int param_count, FunctionKind function_type,
1198 bool has_rest, int formals_start_pos,
1199 int formals_end_pos, bool* ok);
1200
1201 BlockT ParseVariableDeclarations(VariableDeclarationContext var_context,
1202 DeclarationParsingResult* parsing_result,
1203 ZoneList<const AstRawString*>* names,
1204 bool* ok);
1205 StatementT ParseAsyncFunctionDeclaration(ZoneList<const AstRawString*>* names,
1206 bool default_export, bool* ok);
1207 StatementT ParseFunctionDeclaration(bool* ok);
1208 StatementT ParseHoistableDeclaration(ZoneList<const AstRawString*>* names,
1209 bool default_export, bool* ok);
1210 StatementT ParseHoistableDeclaration(int pos, ParseFunctionFlags flags,
1211 ZoneList<const AstRawString*>* names,
1212 bool default_export, bool* ok);
1213 StatementT ParseClassDeclaration(ZoneList<const AstRawString*>* names,
1214 bool default_export, bool* ok);
1215 StatementT ParseNativeDeclaration(bool* ok);
1216
1217 // Under some circumstances, we allow preparsing to abort if the preparsed
1218 // function is "long and trivial", and fully parse instead. Our current
1219 // definition of "long and trivial" is:
1220 // - over kLazyParseTrialLimit statements
1221 // - all starting with an identifier (i.e., no if, for, while, etc.)
1222 static const int kLazyParseTrialLimit = 200;
1223
1224 // TODO(nikolaos, marja): The first argument should not really be passed
1225 // by value. The method is expected to add the parsed statements to the
1226 // list. This works because in the case of the parser, StatementListT is
1227 // a pointer whereas the preparser does not really modify the body.
ParseStatementList(StatementListT body,int end_token,bool * ok)1228 V8_INLINE void ParseStatementList(StatementListT body, int end_token,
1229 bool* ok) {
1230 LazyParsingResult result = ParseStatementList(body, end_token, false, ok);
1231 USE(result);
1232 DCHECK_EQ(result, kLazyParsingComplete);
1233 }
1234 LazyParsingResult ParseStatementList(StatementListT body, int end_token,
1235 bool may_abort, bool* ok);
1236 StatementT ParseStatementListItem(bool* ok);
1237 StatementT ParseStatement(ZoneList<const AstRawString*>* labels,
1238 AllowLabelledFunctionStatement allow_function,
1239 bool* ok);
1240 StatementT ParseStatementAsUnlabelled(ZoneList<const AstRawString*>* labels,
1241 bool* ok);
1242 BlockT ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok);
1243
1244 // Parse a SubStatement in strict mode, or with an extra block scope in
1245 // sloppy mode to handle
1246 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
1247 // The legacy parameter indicates whether function declarations are
1248 // banned by the ES2015 specification in this location, and they are being
1249 // permitted here to match previous V8 behavior.
1250 StatementT ParseScopedStatement(ZoneList<const AstRawString*>* labels,
1251 bool legacy, bool* ok);
1252
1253 StatementT ParseVariableStatement(VariableDeclarationContext var_context,
1254 ZoneList<const AstRawString*>* names,
1255 bool* ok);
1256
1257 // Magical syntax support.
1258 ExpressionT ParseV8Intrinsic(bool* ok);
1259
1260 ExpressionT ParseDoExpression(bool* ok);
1261
1262 StatementT ParseDebuggerStatement(bool* ok);
1263
1264 StatementT ParseExpressionOrLabelledStatement(
1265 ZoneList<const AstRawString*>* labels,
1266 AllowLabelledFunctionStatement allow_function, bool* ok);
1267 StatementT ParseIfStatement(ZoneList<const AstRawString*>* labels, bool* ok);
1268 StatementT ParseContinueStatement(bool* ok);
1269 StatementT ParseBreakStatement(ZoneList<const AstRawString*>* labels,
1270 bool* ok);
1271 StatementT ParseReturnStatement(bool* ok);
1272 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels,
1273 bool* ok);
1274 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
1275 bool* ok);
1276 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels,
1277 bool* ok);
1278 StatementT ParseThrowStatement(bool* ok);
1279 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
1280 bool* ok);
1281 StatementT ParseTryStatement(bool* ok);
1282 StatementT ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
1283
1284 bool IsNextLetKeyword();
1285 bool IsTrivialExpression();
1286
1287 // Checks if the expression is a valid reference expression (e.g., on the
1288 // left-hand side of assignments). Although ruled out by ECMA as early errors,
1289 // we allow calls for web compatibility and rewrite them to a runtime throw.
1290 ExpressionT CheckAndRewriteReferenceExpression(
1291 ExpressionT expression, int beg_pos, int end_pos,
1292 MessageTemplate::Template message, bool* ok);
1293 ExpressionT CheckAndRewriteReferenceExpression(
1294 ExpressionT expression, int beg_pos, int end_pos,
1295 MessageTemplate::Template message, ParseErrorType type, bool* ok);
1296
1297 bool IsValidReferenceExpression(ExpressionT expression);
1298
IsAssignableIdentifier(ExpressionT expression)1299 bool IsAssignableIdentifier(ExpressionT expression) {
1300 if (!impl()->IsIdentifier(expression)) return false;
1301 if (is_strict(language_mode()) &&
1302 impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) {
1303 return false;
1304 }
1305 return true;
1306 }
1307
IsValidPattern(ExpressionT expression)1308 bool IsValidPattern(ExpressionT expression) {
1309 return expression->IsObjectLiteral() || expression->IsArrayLiteral();
1310 }
1311
1312 // Keep track of eval() calls since they disable all local variable
1313 // optimizations. This checks if expression is an eval call, and if yes,
1314 // forwards the information to scope.
CheckPossibleEvalCall(ExpressionT expression,Scope * scope)1315 Call::PossiblyEval CheckPossibleEvalCall(ExpressionT expression,
1316 Scope* scope) {
1317 if (impl()->IsIdentifier(expression) &&
1318 impl()->IsEval(impl()->AsIdentifier(expression))) {
1319 scope->RecordEvalCall();
1320 if (is_sloppy(scope->language_mode())) {
1321 // For sloppy scopes we also have to record the call at function level,
1322 // in case it includes declarations that will be hoisted.
1323 scope->GetDeclarationScope()->RecordEvalCall();
1324 }
1325 return Call::IS_POSSIBLY_EVAL;
1326 }
1327 return Call::NOT_EVAL;
1328 }
1329
1330 // Validation per ES6 object literals.
1331 class ObjectLiteralChecker {
1332 public:
ObjectLiteralChecker(ParserBase * parser)1333 explicit ObjectLiteralChecker(ParserBase* parser)
1334 : parser_(parser), has_seen_proto_(false) {}
1335
1336 void CheckDuplicateProto(Token::Value property);
1337
1338 private:
IsProto()1339 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
1340
parser()1341 ParserBase* parser() const { return parser_; }
scanner()1342 Scanner* scanner() const { return parser_->scanner(); }
1343
1344 ParserBase* parser_;
1345 bool has_seen_proto_;
1346 };
1347
1348 // Validation per ES6 class literals.
1349 class ClassLiteralChecker {
1350 public:
ClassLiteralChecker(ParserBase * parser)1351 explicit ClassLiteralChecker(ParserBase* parser)
1352 : parser_(parser), has_seen_constructor_(false) {}
1353
1354 void CheckClassMethodName(Token::Value property, PropertyKind type,
1355 bool is_generator, bool is_async, bool is_static,
1356 bool* ok);
1357
1358 private:
IsConstructor()1359 bool IsConstructor() {
1360 return this->scanner()->LiteralMatches("constructor", 11);
1361 }
IsPrototype()1362 bool IsPrototype() {
1363 return this->scanner()->LiteralMatches("prototype", 9);
1364 }
1365
parser()1366 ParserBase* parser() const { return parser_; }
scanner()1367 Scanner* scanner() const { return parser_->scanner(); }
1368
1369 ParserBase* parser_;
1370 bool has_seen_constructor_;
1371 };
1372
module()1373 ModuleDescriptor* module() const {
1374 return scope()->AsModuleScope()->module();
1375 }
scope()1376 Scope* scope() const { return scope_state_->scope(); }
1377
1378 // Stack of expression classifiers.
1379 // The top of the stack is always pointed to by classifier().
classifier()1380 V8_INLINE ExpressionClassifier* classifier() const {
1381 DCHECK_NOT_NULL(classifier_);
1382 return classifier_;
1383 }
1384
1385 // Accumulates the classifier that is on top of the stack (inner) to
1386 // the one that is right below (outer) and pops the inner.
1387 V8_INLINE void Accumulate(unsigned productions,
1388 bool merge_non_patterns = true) {
1389 DCHECK_NOT_NULL(classifier_);
1390 ExpressionClassifier* previous = classifier_->previous();
1391 DCHECK_NOT_NULL(previous);
1392 previous->Accumulate(classifier_, productions, merge_non_patterns);
1393 classifier_ = previous;
1394 }
1395
1396 // Pops and discards the classifier that is on top of the stack
1397 // without accumulating.
Discard()1398 V8_INLINE void Discard() {
1399 DCHECK_NOT_NULL(classifier_);
1400 classifier_->Discard();
1401 classifier_ = classifier_->previous();
1402 }
1403
1404 // Accumulate errors that can be arbitrarily deep in an expression.
1405 // These correspond to the ECMAScript spec's 'Contains' operation
1406 // on productions. This includes:
1407 //
1408 // - YieldExpression is disallowed in arrow parameters in a generator.
1409 // - AwaitExpression is disallowed in arrow parameters in an async function.
1410 // - AwaitExpression is disallowed in async arrow parameters.
1411 //
AccumulateFormalParameterContainmentErrors()1412 V8_INLINE void AccumulateFormalParameterContainmentErrors() {
1413 Accumulate(ExpressionClassifier::FormalParameterInitializerProduction |
1414 ExpressionClassifier::AsyncArrowFormalParametersProduction);
1415 }
1416
1417 // Parser base's protected field members.
1418
1419 ScopeState* scope_state_; // Scope stack.
1420 FunctionState* function_state_; // Function state stack.
1421 v8::Extension* extension_;
1422 FuncNameInferrer* fni_;
1423 AstValueFactory* ast_value_factory_; // Not owned.
1424 typename Types::Factory ast_node_factory_;
1425 RuntimeCallStats* runtime_call_stats_;
1426 bool parsing_module_;
1427 uintptr_t stack_limit_;
1428
1429 // Parser base's private field members.
1430
1431 private:
1432 Zone* zone_;
1433 ExpressionClassifier* classifier_;
1434
1435 Scanner* scanner_;
1436 bool stack_overflow_;
1437
1438 FunctionLiteral::EagerCompileHint default_eager_compile_hint_;
1439
1440 bool allow_lazy_;
1441 bool allow_natives_;
1442 bool allow_tailcalls_;
1443 bool allow_harmony_do_expressions_;
1444 bool allow_harmony_function_sent_;
1445 bool allow_harmony_async_await_;
1446 bool allow_harmony_restrictive_generators_;
1447 bool allow_harmony_trailing_commas_;
1448 bool allow_harmony_class_fields_;
1449
1450 friend class DiscardableZoneScope;
1451 };
1452
1453 template <typename Impl>
FunctionState(FunctionState ** function_state_stack,ScopeState ** scope_stack,DeclarationScope * scope)1454 ParserBase<Impl>::FunctionState::FunctionState(
1455 FunctionState** function_state_stack, ScopeState** scope_stack,
1456 DeclarationScope* scope)
1457 : ScopeState(scope_stack, scope),
1458 next_materialized_literal_index_(0),
1459 expected_property_count_(0),
1460 generator_object_variable_(nullptr),
1461 promise_variable_(nullptr),
1462 function_state_stack_(function_state_stack),
1463 outer_function_state_(*function_state_stack),
1464 destructuring_assignments_to_rewrite_(16, scope->zone()),
1465 tail_call_expressions_(scope->zone()),
1466 return_expr_context_(ReturnExprContext::kInsideValidBlock),
1467 non_patterns_to_rewrite_(0, scope->zone()),
1468 reported_errors_(16, scope->zone()),
1469 next_function_is_parenthesized_(false),
1470 this_function_is_parenthesized_(false) {
1471 *function_state_stack = this;
1472 if (outer_function_state_) {
1473 this_function_is_parenthesized_ =
1474 outer_function_state_->next_function_is_parenthesized_;
1475 outer_function_state_->next_function_is_parenthesized_ = false;
1476 }
1477 }
1478
1479 template <typename Impl>
~FunctionState()1480 ParserBase<Impl>::FunctionState::~FunctionState() {
1481 *function_state_stack_ = outer_function_state_;
1482 }
1483
1484 template <typename Impl>
GetUnexpectedTokenMessage(Token::Value token,MessageTemplate::Template * message,Scanner::Location * location,const char ** arg,MessageTemplate::Template default_)1485 void ParserBase<Impl>::GetUnexpectedTokenMessage(
1486 Token::Value token, MessageTemplate::Template* message,
1487 Scanner::Location* location, const char** arg,
1488 MessageTemplate::Template default_) {
1489 *arg = nullptr;
1490 switch (token) {
1491 case Token::EOS:
1492 *message = MessageTemplate::kUnexpectedEOS;
1493 break;
1494 case Token::SMI:
1495 case Token::NUMBER:
1496 *message = MessageTemplate::kUnexpectedTokenNumber;
1497 break;
1498 case Token::STRING:
1499 *message = MessageTemplate::kUnexpectedTokenString;
1500 break;
1501 case Token::IDENTIFIER:
1502 *message = MessageTemplate::kUnexpectedTokenIdentifier;
1503 break;
1504 case Token::AWAIT:
1505 case Token::ENUM:
1506 *message = MessageTemplate::kUnexpectedReserved;
1507 break;
1508 case Token::LET:
1509 case Token::STATIC:
1510 case Token::YIELD:
1511 case Token::FUTURE_STRICT_RESERVED_WORD:
1512 *message = is_strict(language_mode())
1513 ? MessageTemplate::kUnexpectedStrictReserved
1514 : MessageTemplate::kUnexpectedTokenIdentifier;
1515 break;
1516 case Token::TEMPLATE_SPAN:
1517 case Token::TEMPLATE_TAIL:
1518 *message = MessageTemplate::kUnexpectedTemplateString;
1519 break;
1520 case Token::ESCAPED_STRICT_RESERVED_WORD:
1521 case Token::ESCAPED_KEYWORD:
1522 *message = MessageTemplate::kInvalidEscapedReservedWord;
1523 break;
1524 case Token::ILLEGAL:
1525 if (scanner()->has_error()) {
1526 *message = scanner()->error();
1527 *location = scanner()->error_location();
1528 } else {
1529 *message = MessageTemplate::kInvalidOrUnexpectedToken;
1530 }
1531 break;
1532 case Token::REGEXP_LITERAL:
1533 *message = MessageTemplate::kUnexpectedTokenRegExp;
1534 break;
1535 default:
1536 const char* name = Token::String(token);
1537 DCHECK(name != NULL);
1538 *arg = name;
1539 break;
1540 }
1541 }
1542
1543 template <typename Impl>
ReportUnexpectedToken(Token::Value token)1544 void ParserBase<Impl>::ReportUnexpectedToken(Token::Value token) {
1545 return ReportUnexpectedTokenAt(scanner_->location(), token);
1546 }
1547
1548 template <typename Impl>
ReportUnexpectedTokenAt(Scanner::Location source_location,Token::Value token,MessageTemplate::Template message)1549 void ParserBase<Impl>::ReportUnexpectedTokenAt(
1550 Scanner::Location source_location, Token::Value token,
1551 MessageTemplate::Template message) {
1552 const char* arg;
1553 GetUnexpectedTokenMessage(token, &message, &source_location, &arg);
1554 impl()->ReportMessageAt(source_location, message, arg);
1555 }
1556
1557 template <typename Impl>
ParseIdentifier(AllowRestrictedIdentifiers allow_restricted_identifiers,bool * ok)1558 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier(
1559 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
1560 ExpressionClassifier classifier(this);
1561 auto result = ParseAndClassifyIdentifier(CHECK_OK_CUSTOM(EmptyIdentifier));
1562
1563 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
1564 ValidateAssignmentPattern(CHECK_OK_CUSTOM(EmptyIdentifier));
1565 ValidateBindingPattern(CHECK_OK_CUSTOM(EmptyIdentifier));
1566 }
1567
1568 return result;
1569 }
1570
1571 template <typename Impl>
1572 typename ParserBase<Impl>::IdentifierT
ParseAndClassifyIdentifier(bool * ok)1573 ParserBase<Impl>::ParseAndClassifyIdentifier(bool* ok) {
1574 Token::Value next = Next();
1575 if (next == Token::IDENTIFIER || next == Token::ASYNC ||
1576 (next == Token::AWAIT && !parsing_module_ && !is_async_function())) {
1577 IdentifierT name = impl()->GetSymbol();
1578 // When this function is used to read a formal parameter, we don't always
1579 // know whether the function is going to be strict or sloppy. Indeed for
1580 // arrow functions we don't always know that the identifier we are reading
1581 // is actually a formal parameter. Therefore besides the errors that we
1582 // must detect because we know we're in strict mode, we also record any
1583 // error that we might make in the future once we know the language mode.
1584 if (impl()->IsEvalOrArguments(name)) {
1585 classifier()->RecordStrictModeFormalParameterError(
1586 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1587 if (is_strict(language_mode())) {
1588 classifier()->RecordBindingPatternError(
1589 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1590 }
1591 } else if (next == Token::AWAIT) {
1592 classifier()->RecordAsyncArrowFormalParametersError(
1593 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
1594 }
1595
1596 if (classifier()->duplicate_finder() != nullptr &&
1597 scanner()->FindSymbol(classifier()->duplicate_finder(), 1) != 0) {
1598 classifier()->RecordDuplicateFormalParameterError(scanner()->location());
1599 }
1600 return name;
1601 } else if (is_sloppy(language_mode()) &&
1602 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1603 next == Token::ESCAPED_STRICT_RESERVED_WORD ||
1604 next == Token::LET || next == Token::STATIC ||
1605 (next == Token::YIELD && !is_generator()))) {
1606 classifier()->RecordStrictModeFormalParameterError(
1607 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
1608 if (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
1609 is_strict(language_mode())) {
1610 ReportUnexpectedToken(next);
1611 *ok = false;
1612 return impl()->EmptyIdentifier();
1613 }
1614 if (next == Token::LET ||
1615 (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
1616 scanner()->is_literal_contextual_keyword(CStrVector("let")))) {
1617 classifier()->RecordLetPatternError(
1618 scanner()->location(), MessageTemplate::kLetInLexicalBinding);
1619 }
1620 return impl()->GetSymbol();
1621 } else {
1622 ReportUnexpectedToken(next);
1623 *ok = false;
1624 return impl()->EmptyIdentifier();
1625 }
1626 }
1627
1628 template <class Impl>
1629 typename ParserBase<Impl>::IdentifierT
ParseIdentifierOrStrictReservedWord(FunctionKind function_kind,bool * is_strict_reserved,bool * ok)1630 ParserBase<Impl>::ParseIdentifierOrStrictReservedWord(
1631 FunctionKind function_kind, bool* is_strict_reserved, bool* ok) {
1632 Token::Value next = Next();
1633 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_ &&
1634 !IsAsyncFunction(function_kind)) ||
1635 next == Token::ASYNC) {
1636 *is_strict_reserved = false;
1637 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
1638 next == Token::STATIC ||
1639 (next == Token::YIELD && !IsGeneratorFunction(function_kind))) {
1640 *is_strict_reserved = true;
1641 } else {
1642 ReportUnexpectedToken(next);
1643 *ok = false;
1644 return impl()->EmptyIdentifier();
1645 }
1646
1647 return impl()->GetSymbol();
1648 }
1649
1650 template <typename Impl>
ParseIdentifierName(bool * ok)1651 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifierName(
1652 bool* ok) {
1653 Token::Value next = Next();
1654 if (next != Token::IDENTIFIER && next != Token::ASYNC &&
1655 next != Token::ENUM && next != Token::AWAIT && next != Token::LET &&
1656 next != Token::STATIC && next != Token::YIELD &&
1657 next != Token::FUTURE_STRICT_RESERVED_WORD &&
1658 next != Token::ESCAPED_KEYWORD &&
1659 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1660 ReportUnexpectedToken(next);
1661 *ok = false;
1662 return impl()->EmptyIdentifier();
1663 }
1664
1665 return impl()->GetSymbol();
1666 }
1667
1668 template <typename Impl>
ParseRegExpLiteral(bool * ok)1669 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral(
1670 bool* ok) {
1671 int pos = peek_position();
1672 if (!scanner()->ScanRegExpPattern()) {
1673 Next();
1674 ReportMessage(MessageTemplate::kUnterminatedRegExp);
1675 *ok = false;
1676 return impl()->EmptyExpression();
1677 }
1678
1679 int literal_index = function_state_->NextMaterializedLiteralIndex();
1680
1681 IdentifierT js_pattern = impl()->GetNextSymbol();
1682 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags();
1683 if (flags.IsNothing()) {
1684 Next();
1685 ReportMessage(MessageTemplate::kMalformedRegExpFlags);
1686 *ok = false;
1687 return impl()->EmptyExpression();
1688 }
1689 int js_flags = flags.FromJust();
1690 Next();
1691 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
1692 }
1693
1694 template <typename Impl>
ParsePrimaryExpression(bool * is_async,bool * ok)1695 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
1696 bool* is_async, bool* ok) {
1697 // PrimaryExpression ::
1698 // 'this'
1699 // 'null'
1700 // 'true'
1701 // 'false'
1702 // Identifier
1703 // Number
1704 // String
1705 // ArrayLiteral
1706 // ObjectLiteral
1707 // RegExpLiteral
1708 // ClassLiteral
1709 // '(' Expression ')'
1710 // TemplateLiteral
1711 // do Block
1712 // AsyncFunctionLiteral
1713
1714 int beg_pos = peek_position();
1715 switch (peek()) {
1716 case Token::THIS: {
1717 BindingPatternUnexpectedToken();
1718 Consume(Token::THIS);
1719 return impl()->ThisExpression(beg_pos);
1720 }
1721
1722 case Token::NULL_LITERAL:
1723 case Token::TRUE_LITERAL:
1724 case Token::FALSE_LITERAL:
1725 case Token::SMI:
1726 case Token::NUMBER:
1727 BindingPatternUnexpectedToken();
1728 return impl()->ExpressionFromLiteral(Next(), beg_pos);
1729
1730 case Token::ASYNC:
1731 if (allow_harmony_async_await() &&
1732 !scanner()->HasAnyLineTerminatorAfterNext() &&
1733 PeekAhead() == Token::FUNCTION) {
1734 Consume(Token::ASYNC);
1735 return ParseAsyncFunctionLiteral(CHECK_OK);
1736 }
1737 // CoverCallExpressionAndAsyncArrowHead
1738 *is_async = true;
1739 /* falls through */
1740 case Token::IDENTIFIER:
1741 case Token::LET:
1742 case Token::STATIC:
1743 case Token::YIELD:
1744 case Token::AWAIT:
1745 case Token::ESCAPED_STRICT_RESERVED_WORD:
1746 case Token::FUTURE_STRICT_RESERVED_WORD: {
1747 // Using eval or arguments in this context is OK even in strict mode.
1748 IdentifierT name = ParseAndClassifyIdentifier(CHECK_OK);
1749 return impl()->ExpressionFromIdentifier(name, beg_pos);
1750 }
1751
1752 case Token::STRING: {
1753 BindingPatternUnexpectedToken();
1754 Consume(Token::STRING);
1755 return impl()->ExpressionFromString(beg_pos);
1756 }
1757
1758 case Token::ASSIGN_DIV:
1759 case Token::DIV:
1760 classifier()->RecordBindingPatternError(
1761 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
1762 return ParseRegExpLiteral(ok);
1763
1764 case Token::LBRACK:
1765 return ParseArrayLiteral(ok);
1766
1767 case Token::LBRACE:
1768 return ParseObjectLiteral(ok);
1769
1770 case Token::LPAREN: {
1771 // Arrow function formal parameters are either a single identifier or a
1772 // list of BindingPattern productions enclosed in parentheses.
1773 // Parentheses are not valid on the LHS of a BindingPattern, so we use the
1774 // is_valid_binding_pattern() check to detect multiple levels of
1775 // parenthesization.
1776 bool pattern_error = !classifier()->is_valid_binding_pattern();
1777 classifier()->RecordPatternError(scanner()->peek_location(),
1778 MessageTemplate::kUnexpectedToken,
1779 Token::String(Token::LPAREN));
1780 if (pattern_error) ArrowFormalParametersUnexpectedToken();
1781 Consume(Token::LPAREN);
1782 if (Check(Token::RPAREN)) {
1783 // ()=>x. The continuation that looks for the => is in
1784 // ParseAssignmentExpression.
1785 classifier()->RecordExpressionError(scanner()->location(),
1786 MessageTemplate::kUnexpectedToken,
1787 Token::String(Token::RPAREN));
1788 return factory()->NewEmptyParentheses(beg_pos);
1789 }
1790 // Heuristically try to detect immediately called functions before
1791 // seeing the call parentheses.
1792 function_state_->set_next_function_is_parenthesized(peek() ==
1793 Token::FUNCTION);
1794 ExpressionT expr = ParseExpressionCoverGrammar(true, CHECK_OK);
1795 Expect(Token::RPAREN, CHECK_OK);
1796 return expr;
1797 }
1798
1799 case Token::CLASS: {
1800 BindingPatternUnexpectedToken();
1801 Consume(Token::CLASS);
1802 int class_token_pos = position();
1803 IdentifierT name = impl()->EmptyIdentifier();
1804 bool is_strict_reserved_name = false;
1805 Scanner::Location class_name_location = Scanner::Location::invalid();
1806 if (peek_any_identifier()) {
1807 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1808 CHECK_OK);
1809 class_name_location = scanner()->location();
1810 }
1811 return ParseClassLiteral(name, class_name_location,
1812 is_strict_reserved_name, class_token_pos, ok);
1813 }
1814
1815 case Token::TEMPLATE_SPAN:
1816 case Token::TEMPLATE_TAIL:
1817 BindingPatternUnexpectedToken();
1818 return ParseTemplateLiteral(impl()->NoTemplateTag(), beg_pos, ok);
1819
1820 case Token::MOD:
1821 if (allow_natives() || extension_ != NULL) {
1822 BindingPatternUnexpectedToken();
1823 return ParseV8Intrinsic(ok);
1824 }
1825 break;
1826
1827 case Token::DO:
1828 if (allow_harmony_do_expressions()) {
1829 BindingPatternUnexpectedToken();
1830 return ParseDoExpression(ok);
1831 }
1832 break;
1833
1834 default:
1835 break;
1836 }
1837
1838 ReportUnexpectedToken(Next());
1839 *ok = false;
1840 return impl()->EmptyExpression();
1841 }
1842
1843 template <typename Impl>
ParseExpression(bool accept_IN,bool * ok)1844 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression(
1845 bool accept_IN, bool* ok) {
1846 ExpressionClassifier classifier(this);
1847 ExpressionT result = ParseExpressionCoverGrammar(accept_IN, CHECK_OK);
1848 impl()->RewriteNonPattern(CHECK_OK);
1849 return result;
1850 }
1851
1852 template <typename Impl>
1853 typename ParserBase<Impl>::ExpressionT
ParseExpressionCoverGrammar(bool accept_IN,bool * ok)1854 ParserBase<Impl>::ParseExpressionCoverGrammar(bool accept_IN, bool* ok) {
1855 // Expression ::
1856 // AssignmentExpression
1857 // Expression ',' AssignmentExpression
1858
1859 ExpressionT result = impl()->EmptyExpression();
1860 while (true) {
1861 int comma_pos = position();
1862 ExpressionClassifier binding_classifier(this);
1863 ExpressionT right;
1864 if (Check(Token::ELLIPSIS)) {
1865 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
1866 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
1867 // valid expression.
1868 classifier()->RecordExpressionError(scanner()->location(),
1869 MessageTemplate::kUnexpectedToken,
1870 Token::String(Token::ELLIPSIS));
1871 int ellipsis_pos = position();
1872 int pattern_pos = peek_position();
1873 ExpressionT pattern = ParsePrimaryExpression(CHECK_OK);
1874 ValidateBindingPattern(CHECK_OK);
1875 right = factory()->NewSpread(pattern, ellipsis_pos, pattern_pos);
1876 } else {
1877 right = ParseAssignmentExpression(accept_IN, CHECK_OK);
1878 }
1879 // No need to accumulate binding pattern-related errors, since
1880 // an Expression can't be a binding pattern anyway.
1881 impl()->Accumulate(ExpressionClassifier::AllProductions &
1882 ~(ExpressionClassifier::BindingPatternProduction |
1883 ExpressionClassifier::LetPatternProduction));
1884 if (!impl()->IsIdentifier(right)) classifier()->RecordNonSimpleParameter();
1885 if (impl()->IsEmptyExpression(result)) {
1886 // First time through the loop.
1887 result = right;
1888 } else {
1889 result =
1890 factory()->NewBinaryOperation(Token::COMMA, result, right, comma_pos);
1891 }
1892
1893 if (!Check(Token::COMMA)) break;
1894
1895 if (right->IsSpread()) {
1896 classifier()->RecordArrowFormalParametersError(
1897 scanner()->location(), MessageTemplate::kParamAfterRest);
1898 }
1899
1900 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN &&
1901 PeekAhead() == Token::ARROW) {
1902 // a trailing comma is allowed at the end of an arrow parameter list
1903 break;
1904 }
1905 }
1906
1907 return result;
1908 }
1909
1910 template <typename Impl>
ParseArrayLiteral(bool * ok)1911 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral(
1912 bool* ok) {
1913 // ArrayLiteral ::
1914 // '[' Expression? (',' Expression?)* ']'
1915
1916 int pos = peek_position();
1917 ExpressionListT values = impl()->NewExpressionList(4);
1918 int first_spread_index = -1;
1919 Expect(Token::LBRACK, CHECK_OK);
1920 while (peek() != Token::RBRACK) {
1921 ExpressionT elem;
1922 if (peek() == Token::COMMA) {
1923 elem = impl()->GetLiteralTheHole(peek_position());
1924 } else if (peek() == Token::ELLIPSIS) {
1925 int start_pos = peek_position();
1926 Consume(Token::ELLIPSIS);
1927 int expr_pos = peek_position();
1928 ExpressionT argument = ParseAssignmentExpression(true, CHECK_OK);
1929 elem = factory()->NewSpread(argument, start_pos, expr_pos);
1930
1931 if (first_spread_index < 0) {
1932 first_spread_index = values->length();
1933 }
1934
1935 if (argument->IsAssignment()) {
1936 classifier()->RecordPatternError(
1937 Scanner::Location(start_pos, scanner()->location().end_pos),
1938 MessageTemplate::kInvalidDestructuringTarget);
1939 } else {
1940 CheckDestructuringElement(argument, start_pos,
1941 scanner()->location().end_pos);
1942 }
1943
1944 if (peek() == Token::COMMA) {
1945 classifier()->RecordPatternError(
1946 Scanner::Location(start_pos, scanner()->location().end_pos),
1947 MessageTemplate::kElementAfterRest);
1948 }
1949 } else {
1950 int beg_pos = peek_position();
1951 elem = ParseAssignmentExpression(true, CHECK_OK);
1952 CheckDestructuringElement(elem, beg_pos, scanner()->location().end_pos);
1953 }
1954 values->Add(elem, zone_);
1955 if (peek() != Token::RBRACK) {
1956 Expect(Token::COMMA, CHECK_OK);
1957 }
1958 }
1959 Expect(Token::RBRACK, CHECK_OK);
1960
1961 // Update the scope information before the pre-parsing bailout.
1962 int literal_index = function_state_->NextMaterializedLiteralIndex();
1963
1964 ExpressionT result = factory()->NewArrayLiteral(values, first_spread_index,
1965 literal_index, pos);
1966 if (first_spread_index >= 0) {
1967 result = factory()->NewRewritableExpression(result);
1968 impl()->QueueNonPatternForRewriting(result, ok);
1969 if (!*ok) {
1970 // If the non-pattern rewriting mechanism is used in the future for
1971 // rewriting other things than spreads, this error message will have
1972 // to change. Also, this error message will never appear while pre-
1973 // parsing (this is OK, as it is an implementation limitation).
1974 ReportMessage(MessageTemplate::kTooManySpreads);
1975 return impl()->EmptyExpression();
1976 }
1977 }
1978 return result;
1979 }
1980
1981 template <class Impl>
SetPropertyKindFromToken(Token::Value token,PropertyKind * kind)1982 bool ParserBase<Impl>::SetPropertyKindFromToken(Token::Value token,
1983 PropertyKind* kind) {
1984 // This returns true, setting the property kind, iff the given token is one
1985 // which must occur after a property name, indicating that the previous token
1986 // was in fact a name and not a modifier (like the "get" in "get x").
1987 switch (token) {
1988 case Token::COLON:
1989 *kind = PropertyKind::kValueProperty;
1990 return true;
1991 case Token::COMMA:
1992 case Token::RBRACE:
1993 case Token::ASSIGN:
1994 *kind = PropertyKind::kShorthandProperty;
1995 return true;
1996 case Token::LPAREN:
1997 *kind = PropertyKind::kMethodProperty;
1998 return true;
1999 case Token::MUL:
2000 case Token::SEMICOLON:
2001 *kind = PropertyKind::kClassField;
2002 return true;
2003 default:
2004 break;
2005 }
2006 return false;
2007 }
2008
2009 template <class Impl>
ParsePropertyName(IdentifierT * name,PropertyKind * kind,bool * is_generator,bool * is_get,bool * is_set,bool * is_async,bool * is_computed_name,bool * ok)2010 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
2011 IdentifierT* name, PropertyKind* kind, bool* is_generator, bool* is_get,
2012 bool* is_set, bool* is_async, bool* is_computed_name, bool* ok) {
2013 DCHECK(*kind == PropertyKind::kNotSet);
2014 DCHECK(!*is_generator);
2015 DCHECK(!*is_get);
2016 DCHECK(!*is_set);
2017 DCHECK(!*is_async);
2018 DCHECK(!*is_computed_name);
2019
2020 *is_generator = Check(Token::MUL);
2021 if (*is_generator) {
2022 *kind = PropertyKind::kMethodProperty;
2023 }
2024
2025 Token::Value token = peek();
2026 int pos = peek_position();
2027
2028 if (allow_harmony_async_await() && !*is_generator && token == Token::ASYNC &&
2029 !scanner()->HasAnyLineTerminatorAfterNext()) {
2030 Consume(Token::ASYNC);
2031 token = peek();
2032 if (SetPropertyKindFromToken(token, kind)) {
2033 *name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'async'
2034 impl()->PushLiteralName(*name);
2035 return factory()->NewStringLiteral(*name, pos);
2036 }
2037 *kind = PropertyKind::kMethodProperty;
2038 *is_async = true;
2039 pos = peek_position();
2040 }
2041
2042 if (token == Token::IDENTIFIER && !*is_generator && !*is_async) {
2043 // This is checking for 'get' and 'set' in particular.
2044 Consume(Token::IDENTIFIER);
2045 token = peek();
2046 if (SetPropertyKindFromToken(token, kind) ||
2047 !scanner()->IsGetOrSet(is_get, is_set)) {
2048 *name = impl()->GetSymbol();
2049 impl()->PushLiteralName(*name);
2050 return factory()->NewStringLiteral(*name, pos);
2051 }
2052 *kind = PropertyKind::kAccessorProperty;
2053 pos = peek_position();
2054 }
2055
2056 // For non computed property names we normalize the name a bit:
2057 //
2058 // "12" -> 12
2059 // 12.3 -> "12.3"
2060 // 12.30 -> "12.3"
2061 // identifier -> "identifier"
2062 //
2063 // This is important because we use the property name as a key in a hash
2064 // table when we compute constant properties.
2065 ExpressionT expression = impl()->EmptyExpression();
2066 switch (token) {
2067 case Token::STRING:
2068 Consume(Token::STRING);
2069 *name = impl()->GetSymbol();
2070 break;
2071
2072 case Token::SMI:
2073 Consume(Token::SMI);
2074 *name = impl()->GetNumberAsSymbol();
2075 break;
2076
2077 case Token::NUMBER:
2078 Consume(Token::NUMBER);
2079 *name = impl()->GetNumberAsSymbol();
2080 break;
2081
2082 case Token::LBRACK: {
2083 *name = impl()->EmptyIdentifier();
2084 *is_computed_name = true;
2085 Consume(Token::LBRACK);
2086 ExpressionClassifier computed_name_classifier(this);
2087 expression = ParseAssignmentExpression(true, CHECK_OK);
2088 impl()->RewriteNonPattern(CHECK_OK);
2089 impl()->AccumulateFormalParameterContainmentErrors();
2090 Expect(Token::RBRACK, CHECK_OK);
2091 break;
2092 }
2093
2094 default:
2095 *name = ParseIdentifierName(CHECK_OK);
2096 break;
2097 }
2098
2099 if (*kind == PropertyKind::kNotSet) {
2100 SetPropertyKindFromToken(peek(), kind);
2101 }
2102
2103 if (*is_computed_name) {
2104 return expression;
2105 }
2106
2107 impl()->PushLiteralName(*name);
2108
2109 uint32_t index;
2110 return impl()->IsArrayIndex(*name, &index)
2111 ? factory()->NewNumberLiteral(index, pos)
2112 : factory()->NewStringLiteral(*name, pos);
2113 }
2114
2115 template <typename Impl>
2116 typename ParserBase<Impl>::ClassLiteralPropertyT
ParseClassPropertyDefinition(ClassLiteralChecker * checker,bool has_extends,bool * is_computed_name,bool * has_seen_constructor,bool * ok)2117 ParserBase<Impl>::ParseClassPropertyDefinition(ClassLiteralChecker* checker,
2118 bool has_extends,
2119 bool* is_computed_name,
2120 bool* has_seen_constructor,
2121 bool* ok) {
2122 DCHECK(has_seen_constructor != nullptr);
2123 bool is_get = false;
2124 bool is_set = false;
2125 bool is_generator = false;
2126 bool is_async = false;
2127 bool is_static = false;
2128 PropertyKind kind = PropertyKind::kNotSet;
2129
2130 Token::Value name_token = peek();
2131
2132 IdentifierT name = impl()->EmptyIdentifier();
2133 ExpressionT name_expression;
2134 if (name_token == Token::STATIC) {
2135 Consume(Token::STATIC);
2136 if (peek() == Token::LPAREN) {
2137 kind = PropertyKind::kMethodProperty;
2138 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static'
2139 name_expression = factory()->NewStringLiteral(name, position());
2140 } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON ||
2141 peek() == Token::RBRACE) {
2142 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static'
2143 name_expression = factory()->NewStringLiteral(name, position());
2144 } else {
2145 is_static = true;
2146 name_expression = ParsePropertyName(
2147 &name, &kind, &is_generator, &is_get, &is_set, &is_async,
2148 is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2149 }
2150 } else {
2151 name_expression = ParsePropertyName(
2152 &name, &kind, &is_generator, &is_get, &is_set, &is_async,
2153 is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2154 }
2155
2156 switch (kind) {
2157 case PropertyKind::kClassField:
2158 case PropertyKind::kNotSet: // This case is a name followed by a name or
2159 // other property. Here we have to assume
2160 // that's an uninitialized field followed by a
2161 // linebreak followed by a property, with ASI
2162 // adding the semicolon. If not, there will be
2163 // a syntax error after parsing the first name
2164 // as an uninitialized field.
2165 case PropertyKind::kShorthandProperty:
2166 case PropertyKind::kValueProperty:
2167 if (allow_harmony_class_fields()) {
2168 bool has_initializer = Check(Token::ASSIGN);
2169 ExpressionT function_literal = ParseClassFieldForInitializer(
2170 has_initializer, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2171 ExpectSemicolon(CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2172 return factory()->NewClassLiteralProperty(
2173 name_expression, function_literal, ClassLiteralProperty::FIELD,
2174 is_static, *is_computed_name);
2175 } else {
2176 ReportUnexpectedToken(Next());
2177 *ok = false;
2178 return impl()->EmptyClassLiteralProperty();
2179 }
2180
2181 case PropertyKind::kMethodProperty: {
2182 DCHECK(!is_get && !is_set);
2183
2184 // MethodDefinition
2185 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2186 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2187
2188 if (!*is_computed_name) {
2189 checker->CheckClassMethodName(
2190 name_token, PropertyKind::kMethodProperty, is_generator, is_async,
2191 is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2192 }
2193
2194 FunctionKind kind = is_generator
2195 ? FunctionKind::kConciseGeneratorMethod
2196 : is_async ? FunctionKind::kAsyncConciseMethod
2197 : FunctionKind::kConciseMethod;
2198
2199 if (!is_static && impl()->IsConstructor(name)) {
2200 *has_seen_constructor = true;
2201 kind = has_extends ? FunctionKind::kSubclassConstructor
2202 : FunctionKind::kBaseConstructor;
2203 }
2204
2205 ExpressionT value = impl()->ParseFunctionLiteral(
2206 name, scanner()->location(), kSkipFunctionNameCheck, kind,
2207 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod,
2208 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2209
2210 return factory()->NewClassLiteralProperty(name_expression, value,
2211 ClassLiteralProperty::METHOD,
2212 is_static, *is_computed_name);
2213 }
2214
2215 case PropertyKind::kAccessorProperty: {
2216 DCHECK((is_get || is_set) && !is_generator && !is_async);
2217
2218 if (!*is_computed_name) {
2219 checker->CheckClassMethodName(
2220 name_token, PropertyKind::kAccessorProperty, false, false,
2221 is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2222 // Make sure the name expression is a string since we need a Name for
2223 // Runtime_DefineAccessorPropertyUnchecked and since we can determine
2224 // this statically we can skip the extra runtime check.
2225 name_expression =
2226 factory()->NewStringLiteral(name, name_expression->position());
2227 }
2228
2229 FunctionKind kind = is_get ? FunctionKind::kGetterFunction
2230 : FunctionKind::kSetterFunction;
2231
2232 FunctionLiteralT value = impl()->ParseFunctionLiteral(
2233 name, scanner()->location(), kSkipFunctionNameCheck, kind,
2234 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod,
2235 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
2236
2237 if (!*is_computed_name) {
2238 impl()->AddAccessorPrefixToFunctionName(is_get, value, name);
2239 }
2240
2241 return factory()->NewClassLiteralProperty(
2242 name_expression, value,
2243 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER,
2244 is_static, *is_computed_name);
2245 }
2246 }
2247 UNREACHABLE();
2248 return impl()->EmptyClassLiteralProperty();
2249 }
2250
2251 template <typename Impl>
2252 typename ParserBase<Impl>::FunctionLiteralT
ParseClassFieldForInitializer(bool has_initializer,bool * ok)2253 ParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer,
2254 bool* ok) {
2255 // Makes a concise method which evaluates and returns the initialized value
2256 // (or undefined if absent).
2257 FunctionKind kind = FunctionKind::kConciseMethod;
2258 DeclarationScope* initializer_scope = NewFunctionScope(kind);
2259 initializer_scope->set_start_position(scanner()->location().end_pos);
2260 FunctionState initializer_state(&function_state_, &scope_state_,
2261 initializer_scope);
2262 DCHECK(scope() == initializer_scope);
2263 scope()->SetLanguageMode(STRICT);
2264 ExpressionClassifier expression_classifier(this);
2265 ExpressionT value;
2266 if (has_initializer) {
2267 value = this->ParseAssignmentExpression(
2268 true, CHECK_OK_CUSTOM(EmptyFunctionLiteral));
2269 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(EmptyFunctionLiteral));
2270 } else {
2271 value = factory()->NewUndefinedLiteral(kNoSourcePosition);
2272 }
2273 initializer_scope->set_end_position(scanner()->location().end_pos);
2274 typename Types::StatementList body = impl()->NewStatementList(1);
2275 body->Add(factory()->NewReturnStatement(value, kNoSourcePosition), zone());
2276 FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
2277 impl()->EmptyIdentifierString(), initializer_scope, body,
2278 initializer_state.materialized_literal_count(),
2279 initializer_state.expected_property_count(), 0, 0,
2280 FunctionLiteral::kNoDuplicateParameters,
2281 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_,
2282 initializer_scope->start_position(), true);
2283 function_literal->set_is_class_field_initializer(true);
2284 return function_literal;
2285 }
2286
2287 template <typename Impl>
2288 typename ParserBase<Impl>::ObjectLiteralPropertyT
ParseObjectPropertyDefinition(ObjectLiteralChecker * checker,bool * is_computed_name,bool * ok)2289 ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
2290 bool* is_computed_name,
2291 bool* ok) {
2292 bool is_get = false;
2293 bool is_set = false;
2294 bool is_generator = false;
2295 bool is_async = false;
2296 PropertyKind kind = PropertyKind::kNotSet;
2297
2298 IdentifierT name = impl()->EmptyIdentifier();
2299 Token::Value name_token = peek();
2300 int next_beg_pos = scanner()->peek_location().beg_pos;
2301 int next_end_pos = scanner()->peek_location().end_pos;
2302
2303 ExpressionT name_expression = ParsePropertyName(
2304 &name, &kind, &is_generator, &is_get, &is_set, &is_async,
2305 is_computed_name, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2306
2307 switch (kind) {
2308 case PropertyKind::kValueProperty: {
2309 DCHECK(!is_get && !is_set && !is_generator && !is_async);
2310
2311 if (!*is_computed_name) {
2312 checker->CheckDuplicateProto(name_token);
2313 }
2314 Consume(Token::COLON);
2315 int beg_pos = peek_position();
2316 ExpressionT value = ParseAssignmentExpression(
2317 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2318 CheckDestructuringElement(value, beg_pos, scanner()->location().end_pos);
2319
2320 ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2321 name_expression, value, *is_computed_name);
2322
2323 if (!*is_computed_name) {
2324 impl()->SetFunctionNameFromPropertyName(result, name);
2325 }
2326
2327 return result;
2328 }
2329
2330 case PropertyKind::kShorthandProperty: {
2331 // PropertyDefinition
2332 // IdentifierReference
2333 // CoverInitializedName
2334 //
2335 // CoverInitializedName
2336 // IdentifierReference Initializer?
2337 DCHECK(!is_get && !is_set && !is_generator && !is_async);
2338
2339 if (!Token::IsIdentifier(name_token, language_mode(),
2340 this->is_generator(),
2341 parsing_module_ || is_async_function())) {
2342 ReportUnexpectedToken(Next());
2343 *ok = false;
2344 return impl()->EmptyObjectLiteralProperty();
2345 }
2346
2347 DCHECK(!*is_computed_name);
2348
2349 if (classifier()->duplicate_finder() != nullptr &&
2350 scanner()->FindSymbol(classifier()->duplicate_finder(), 1) != 0) {
2351 classifier()->RecordDuplicateFormalParameterError(
2352 scanner()->location());
2353 }
2354
2355 if (impl()->IsEvalOrArguments(name) && is_strict(language_mode())) {
2356 classifier()->RecordBindingPatternError(
2357 scanner()->location(), MessageTemplate::kStrictEvalArguments);
2358 }
2359
2360 if (name_token == Token::LET) {
2361 classifier()->RecordLetPatternError(
2362 scanner()->location(), MessageTemplate::kLetInLexicalBinding);
2363 }
2364 if (name_token == Token::AWAIT) {
2365 DCHECK(!is_async_function());
2366 classifier()->RecordAsyncArrowFormalParametersError(
2367 Scanner::Location(next_beg_pos, next_end_pos),
2368 MessageTemplate::kAwaitBindingIdentifier);
2369 }
2370 ExpressionT lhs = impl()->ExpressionFromIdentifier(name, next_beg_pos);
2371 CheckDestructuringElement(lhs, next_beg_pos, next_end_pos);
2372
2373 ExpressionT value;
2374 if (peek() == Token::ASSIGN) {
2375 Consume(Token::ASSIGN);
2376 ExpressionClassifier rhs_classifier(this);
2377 ExpressionT rhs = ParseAssignmentExpression(
2378 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2379 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2380 impl()->AccumulateFormalParameterContainmentErrors();
2381 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
2382 kNoSourcePosition);
2383 classifier()->RecordExpressionError(
2384 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
2385 MessageTemplate::kInvalidCoverInitializedName);
2386
2387 impl()->SetFunctionNameFromIdentifierRef(rhs, lhs);
2388 } else {
2389 value = lhs;
2390 }
2391
2392 return factory()->NewObjectLiteralProperty(
2393 name_expression, value, ObjectLiteralProperty::COMPUTED, false);
2394 }
2395
2396 case PropertyKind::kMethodProperty: {
2397 DCHECK(!is_get && !is_set);
2398
2399 // MethodDefinition
2400 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2401 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2402
2403 classifier()->RecordPatternError(
2404 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
2405 MessageTemplate::kInvalidDestructuringTarget);
2406
2407 FunctionKind kind = is_generator
2408 ? FunctionKind::kConciseGeneratorMethod
2409 : is_async ? FunctionKind::kAsyncConciseMethod
2410 : FunctionKind::kConciseMethod;
2411
2412 ExpressionT value = impl()->ParseFunctionLiteral(
2413 name, scanner()->location(), kSkipFunctionNameCheck, kind,
2414 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod,
2415 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2416
2417 return factory()->NewObjectLiteralProperty(
2418 name_expression, value, ObjectLiteralProperty::COMPUTED,
2419 *is_computed_name);
2420 }
2421
2422 case PropertyKind::kAccessorProperty: {
2423 DCHECK((is_get || is_set) && !(is_set && is_get) && !is_generator &&
2424 !is_async);
2425
2426 classifier()->RecordPatternError(
2427 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
2428 MessageTemplate::kInvalidDestructuringTarget);
2429
2430 if (!*is_computed_name) {
2431 // Make sure the name expression is a string since we need a Name for
2432 // Runtime_DefineAccessorPropertyUnchecked and since we can determine
2433 // this statically we can skip the extra runtime check.
2434 name_expression =
2435 factory()->NewStringLiteral(name, name_expression->position());
2436 }
2437
2438 FunctionKind kind = is_get ? FunctionKind::kGetterFunction
2439 : FunctionKind::kSetterFunction;
2440
2441 FunctionLiteralT value = impl()->ParseFunctionLiteral(
2442 name, scanner()->location(), kSkipFunctionNameCheck, kind,
2443 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod,
2444 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2445
2446 if (!*is_computed_name) {
2447 impl()->AddAccessorPrefixToFunctionName(is_get, value, name);
2448 }
2449
2450 return factory()->NewObjectLiteralProperty(
2451 name_expression, value, is_get ? ObjectLiteralProperty::GETTER
2452 : ObjectLiteralProperty::SETTER,
2453 *is_computed_name);
2454 }
2455
2456 case PropertyKind::kClassField:
2457 case PropertyKind::kNotSet:
2458 ReportUnexpectedToken(Next());
2459 *ok = false;
2460 return impl()->EmptyObjectLiteralProperty();
2461 }
2462 UNREACHABLE();
2463 return impl()->EmptyObjectLiteralProperty();
2464 }
2465
2466 template <typename Impl>
ParseObjectLiteral(bool * ok)2467 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral(
2468 bool* ok) {
2469 // ObjectLiteral ::
2470 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2471
2472 int pos = peek_position();
2473 typename Types::ObjectPropertyList properties =
2474 impl()->NewObjectPropertyList(4);
2475 int number_of_boilerplate_properties = 0;
2476 bool has_computed_names = false;
2477 ObjectLiteralChecker checker(this);
2478
2479 Expect(Token::LBRACE, CHECK_OK);
2480
2481 while (peek() != Token::RBRACE) {
2482 FuncNameInferrer::State fni_state(fni_);
2483
2484 bool is_computed_name = false;
2485 ObjectLiteralPropertyT property =
2486 ParseObjectPropertyDefinition(&checker, &is_computed_name, CHECK_OK);
2487
2488 if (is_computed_name) {
2489 has_computed_names = true;
2490 }
2491
2492 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2493 if (!has_computed_names && impl()->IsBoilerplateProperty(property)) {
2494 number_of_boilerplate_properties++;
2495 }
2496 properties->Add(property, zone());
2497
2498 if (peek() != Token::RBRACE) {
2499 // Need {} because of the CHECK_OK macro.
2500 Expect(Token::COMMA, CHECK_OK);
2501 }
2502
2503 if (fni_ != nullptr) fni_->Infer();
2504 }
2505 Expect(Token::RBRACE, CHECK_OK);
2506
2507 // Computation of literal_index must happen before pre parse bailout.
2508 int literal_index = function_state_->NextMaterializedLiteralIndex();
2509
2510 return factory()->NewObjectLiteral(properties,
2511 literal_index,
2512 number_of_boilerplate_properties,
2513 pos);
2514 }
2515
2516 template <typename Impl>
ParseArguments(Scanner::Location * first_spread_arg_loc,bool maybe_arrow,bool * ok)2517 typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments(
2518 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, bool* ok) {
2519 // Arguments ::
2520 // '(' (AssignmentExpression)*[','] ')'
2521
2522 Scanner::Location spread_arg = Scanner::Location::invalid();
2523 ExpressionListT result = impl()->NewExpressionList(4);
2524 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
2525 bool done = (peek() == Token::RPAREN);
2526 bool was_unspread = false;
2527 int unspread_sequences_count = 0;
2528 while (!done) {
2529 int start_pos = peek_position();
2530 bool is_spread = Check(Token::ELLIPSIS);
2531 int expr_pos = peek_position();
2532
2533 ExpressionT argument =
2534 ParseAssignmentExpression(true, CHECK_OK_CUSTOM(NullExpressionList));
2535 if (!maybe_arrow) {
2536 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList));
2537 }
2538 if (is_spread) {
2539 if (!spread_arg.IsValid()) {
2540 spread_arg.beg_pos = start_pos;
2541 spread_arg.end_pos = peek_position();
2542 }
2543 argument = factory()->NewSpread(argument, start_pos, expr_pos);
2544 }
2545 result->Add(argument, zone_);
2546
2547 // unspread_sequences_count is the number of sequences of parameters which
2548 // are not prefixed with a spread '...' operator.
2549 if (is_spread) {
2550 was_unspread = false;
2551 } else if (!was_unspread) {
2552 was_unspread = true;
2553 unspread_sequences_count++;
2554 }
2555
2556 if (result->length() > Code::kMaxArguments) {
2557 ReportMessage(MessageTemplate::kTooManyArguments);
2558 *ok = false;
2559 return impl()->NullExpressionList();
2560 }
2561 done = (peek() != Token::COMMA);
2562 if (!done) {
2563 Next();
2564 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) {
2565 // allow trailing comma
2566 done = true;
2567 }
2568 }
2569 }
2570 Scanner::Location location = scanner_->location();
2571 if (Token::RPAREN != Next()) {
2572 impl()->ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
2573 *ok = false;
2574 return impl()->NullExpressionList();
2575 }
2576 *first_spread_arg_loc = spread_arg;
2577
2578 if (!maybe_arrow || peek() != Token::ARROW) {
2579 if (maybe_arrow) {
2580 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList));
2581 }
2582 if (spread_arg.IsValid()) {
2583 // Unspread parameter sequences are translated into array literals in the
2584 // parser. Ensure that the number of materialized literals matches between
2585 // the parser and preparser
2586 impl()->MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
2587 }
2588 }
2589
2590 return result;
2591 }
2592
2593 // Precedence = 2
2594 template <typename Impl>
2595 typename ParserBase<Impl>::ExpressionT
ParseAssignmentExpression(bool accept_IN,bool * ok)2596 ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
2597 // AssignmentExpression ::
2598 // ConditionalExpression
2599 // ArrowFunction
2600 // YieldExpression
2601 // LeftHandSideExpression AssignmentOperator AssignmentExpression
2602 int lhs_beg_pos = peek_position();
2603
2604 if (peek() == Token::YIELD && is_generator()) {
2605 return ParseYieldExpression(accept_IN, ok);
2606 }
2607
2608 FuncNameInferrer::State fni_state(fni_);
2609 Checkpoint checkpoint(this);
2610 ExpressionClassifier arrow_formals_classifier(
2611 this, classifier()->duplicate_finder());
2612
2613 Scope::Snapshot scope_snapshot(scope());
2614
2615 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC &&
2616 !scanner()->HasAnyLineTerminatorAfterNext() &&
2617 IsValidArrowFormalParametersStart(PeekAhead());
2618
2619 bool parenthesized_formals = peek() == Token::LPAREN;
2620 if (!is_async && !parenthesized_formals) {
2621 ArrowFormalParametersUnexpectedToken();
2622 }
2623
2624 // Parse a simple, faster sub-grammar (primary expression) if it's evident
2625 // that we have only a trivial expression to parse.
2626 ExpressionT expression;
2627 if (IsTrivialExpression()) {
2628 expression = ParsePrimaryExpression(&is_async, CHECK_OK);
2629 } else {
2630 expression = ParseConditionalExpression(accept_IN, CHECK_OK);
2631 }
2632
2633 if (is_async && impl()->IsIdentifier(expression) && peek_any_identifier() &&
2634 PeekAhead() == Token::ARROW) {
2635 // async Identifier => AsyncConciseBody
2636 IdentifierT name = ParseAndClassifyIdentifier(CHECK_OK);
2637 expression =
2638 impl()->ExpressionFromIdentifier(name, position(), InferName::kNo);
2639 if (fni_) {
2640 // Remove `async` keyword from inferred name stack.
2641 fni_->RemoveAsyncKeywordFromEnd();
2642 }
2643 }
2644
2645 if (peek() == Token::ARROW) {
2646 Scanner::Location arrow_loc = scanner()->peek_location();
2647 ValidateArrowFormalParameters(expression, parenthesized_formals, is_async,
2648 CHECK_OK);
2649 // This reads strangely, but is correct: it checks whether any
2650 // sub-expression of the parameter list failed to be a valid formal
2651 // parameter initializer. Since YieldExpressions are banned anywhere
2652 // in an arrow parameter list, this is correct.
2653 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to
2654 // "YieldExpression", which is its only use.
2655 ValidateFormalParameterInitializer(ok);
2656
2657 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
2658 DeclarationScope* scope =
2659 NewFunctionScope(is_async ? FunctionKind::kAsyncArrowFunction
2660 : FunctionKind::kArrowFunction);
2661 // Because the arrow's parameters were parsed in the outer scope, any
2662 // usage flags that might have been triggered there need to be copied
2663 // to the arrow scope.
2664 this->scope()->PropagateUsageFlagsToScope(scope);
2665
2666 scope_snapshot.Reparent(scope);
2667
2668 FormalParametersT parameters(scope);
2669 if (!classifier()->is_simple_parameter_list()) {
2670 scope->SetHasNonSimpleParameters();
2671 parameters.is_simple = false;
2672 }
2673
2674 checkpoint.Restore(¶meters.materialized_literals_count);
2675
2676 scope->set_start_position(lhs_beg_pos);
2677 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2678 impl()->DeclareArrowFunctionFormalParameters(¶meters, expression, loc,
2679 &duplicate_loc, CHECK_OK);
2680 if (duplicate_loc.IsValid()) {
2681 classifier()->RecordDuplicateFormalParameterError(duplicate_loc);
2682 }
2683 expression = ParseArrowFunctionLiteral(accept_IN, parameters, CHECK_OK);
2684 impl()->Discard();
2685 classifier()->RecordPatternError(arrow_loc,
2686 MessageTemplate::kUnexpectedToken,
2687 Token::String(Token::ARROW));
2688
2689 if (fni_ != nullptr) fni_->Infer();
2690
2691 return expression;
2692 }
2693
2694 // "expression" was not itself an arrow function parameter list, but it might
2695 // form part of one. Propagate speculative formal parameter error locations
2696 // (including those for binding patterns, since formal parameters can
2697 // themselves contain binding patterns).
2698 unsigned productions = ExpressionClassifier::AllProductions &
2699 ~ExpressionClassifier::ArrowFormalParametersProduction;
2700
2701 // Parenthesized identifiers and property references are allowed as part
2702 // of a larger assignment pattern, even though parenthesized patterns
2703 // themselves are not allowed, e.g., "[(x)] = []". Only accumulate
2704 // assignment pattern errors if the parsed expression is more complex.
2705 if (IsValidReferenceExpression(expression)) {
2706 productions &= ~ExpressionClassifier::AssignmentPatternProduction;
2707 }
2708
2709 const bool is_destructuring_assignment =
2710 IsValidPattern(expression) && peek() == Token::ASSIGN;
2711 if (is_destructuring_assignment) {
2712 // This is definitely not an expression so don't accumulate
2713 // expression-related errors.
2714 productions &= ~ExpressionClassifier::ExpressionProduction;
2715 }
2716
2717 if (!Token::IsAssignmentOp(peek())) {
2718 // Parsed conditional expression only (no assignment).
2719 // Pending non-pattern expressions must be merged.
2720 impl()->Accumulate(productions);
2721 return expression;
2722 } else {
2723 // Pending non-pattern expressions must be discarded.
2724 impl()->Accumulate(productions, false);
2725 }
2726
2727 if (is_destructuring_assignment) {
2728 ValidateAssignmentPattern(CHECK_OK);
2729 } else {
2730 expression = CheckAndRewriteReferenceExpression(
2731 expression, lhs_beg_pos, scanner()->location().end_pos,
2732 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK);
2733 }
2734
2735 expression = impl()->MarkExpressionAsAssigned(expression);
2736
2737 Token::Value op = Next(); // Get assignment operator.
2738 if (op != Token::ASSIGN) {
2739 classifier()->RecordPatternError(scanner()->location(),
2740 MessageTemplate::kUnexpectedToken,
2741 Token::String(op));
2742 }
2743 int pos = position();
2744
2745 ExpressionClassifier rhs_classifier(this);
2746
2747 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2748 impl()->RewriteNonPattern(CHECK_OK);
2749 impl()->AccumulateFormalParameterContainmentErrors();
2750
2751 // TODO(1231235): We try to estimate the set of properties set by
2752 // constructors. We define a new property whenever there is an
2753 // assignment to a property of 'this'. We should probably only add
2754 // properties if we haven't seen them before. Otherwise we'll
2755 // probably overestimate the number of properties.
2756 if (op == Token::ASSIGN && impl()->IsThisProperty(expression)) {
2757 function_state_->AddProperty();
2758 }
2759
2760 impl()->CheckAssigningFunctionLiteralToProperty(expression, right);
2761
2762 if (fni_ != NULL) {
2763 // Check if the right hand side is a call to avoid inferring a
2764 // name if we're dealing with "a = function(){...}();"-like
2765 // expression.
2766 if ((op == Token::INIT || op == Token::ASSIGN) &&
2767 (!right->IsCall() && !right->IsCallNew())) {
2768 fni_->Infer();
2769 } else {
2770 fni_->RemoveLastFunction();
2771 }
2772 }
2773
2774 if (op == Token::ASSIGN) {
2775 impl()->SetFunctionNameFromIdentifierRef(right, expression);
2776 }
2777
2778 if (op == Token::ASSIGN_EXP) {
2779 DCHECK(!is_destructuring_assignment);
2780 return impl()->RewriteAssignExponentiation(expression, right, pos);
2781 }
2782
2783 ExpressionT result = factory()->NewAssignment(op, expression, right, pos);
2784
2785 if (is_destructuring_assignment) {
2786 result = factory()->NewRewritableExpression(result);
2787 impl()->QueueDestructuringAssignmentForRewriting(result);
2788 }
2789
2790 return result;
2791 }
2792
2793 template <typename Impl>
ParseYieldExpression(bool accept_IN,bool * ok)2794 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression(
2795 bool accept_IN, bool* ok) {
2796 // YieldExpression ::
2797 // 'yield' ([no line terminator] '*'? AssignmentExpression)?
2798 int pos = peek_position();
2799 classifier()->RecordPatternError(
2800 scanner()->peek_location(), MessageTemplate::kInvalidDestructuringTarget);
2801 classifier()->RecordFormalParameterInitializerError(
2802 scanner()->peek_location(), MessageTemplate::kYieldInParameter);
2803 Expect(Token::YIELD, CHECK_OK);
2804 ExpressionT generator_object =
2805 factory()->NewVariableProxy(function_state_->generator_object_variable());
2806 // The following initialization is necessary.
2807 ExpressionT expression = impl()->EmptyExpression();
2808 bool delegating = false; // yield*
2809 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
2810 if (Check(Token::MUL)) delegating = true;
2811 switch (peek()) {
2812 case Token::EOS:
2813 case Token::SEMICOLON:
2814 case Token::RBRACE:
2815 case Token::RBRACK:
2816 case Token::RPAREN:
2817 case Token::COLON:
2818 case Token::COMMA:
2819 // The above set of tokens is the complete set of tokens that can appear
2820 // after an AssignmentExpression, and none of them can start an
2821 // AssignmentExpression. This allows us to avoid looking for an RHS for
2822 // a regular yield, given only one look-ahead token.
2823 if (!delegating) break;
2824 // Delegating yields require an RHS; fall through.
2825 default:
2826 expression = ParseAssignmentExpression(accept_IN, CHECK_OK);
2827 impl()->RewriteNonPattern(CHECK_OK);
2828 break;
2829 }
2830 }
2831
2832 if (delegating) {
2833 return impl()->RewriteYieldStar(generator_object, expression, pos);
2834 }
2835
2836 expression = impl()->BuildIteratorResult(expression, false);
2837 // Hackily disambiguate o from o.next and o [Symbol.iterator]().
2838 // TODO(verwaest): Come up with a better solution.
2839 ExpressionT yield = factory()->NewYield(generator_object, expression, pos,
2840 Yield::kOnExceptionThrow);
2841 return yield;
2842 }
2843
2844 // Precedence = 3
2845 template <typename Impl>
2846 typename ParserBase<Impl>::ExpressionT
ParseConditionalExpression(bool accept_IN,bool * ok)2847 ParserBase<Impl>::ParseConditionalExpression(bool accept_IN,
2848 bool* ok) {
2849 // ConditionalExpression ::
2850 // LogicalOrExpression
2851 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2852
2853 int pos = peek_position();
2854 // We start using the binary expression parser for prec >= 4 only!
2855 ExpressionT expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
2856 if (peek() != Token::CONDITIONAL) return expression;
2857 impl()->RewriteNonPattern(CHECK_OK);
2858 BindingPatternUnexpectedToken();
2859 ArrowFormalParametersUnexpectedToken();
2860 Consume(Token::CONDITIONAL);
2861 // In parsing the first assignment expression in conditional
2862 // expressions we always accept the 'in' keyword; see ECMA-262,
2863 // section 11.12, page 58.
2864 ExpressionT left = ParseAssignmentExpression(true, CHECK_OK);
2865 impl()->RewriteNonPattern(CHECK_OK);
2866 Expect(Token::COLON, CHECK_OK);
2867 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2868 impl()->RewriteNonPattern(CHECK_OK);
2869 return factory()->NewConditional(expression, left, right, pos);
2870 }
2871
2872
2873 // Precedence >= 4
2874 template <typename Impl>
ParseBinaryExpression(int prec,bool accept_IN,bool * ok)2875 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
2876 int prec, bool accept_IN, bool* ok) {
2877 DCHECK(prec >= 4);
2878 ExpressionT x = ParseUnaryExpression(CHECK_OK);
2879 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2880 // prec1 >= 4
2881 while (Precedence(peek(), accept_IN) == prec1) {
2882 impl()->RewriteNonPattern(CHECK_OK);
2883 BindingPatternUnexpectedToken();
2884 ArrowFormalParametersUnexpectedToken();
2885 Token::Value op = Next();
2886 int pos = position();
2887
2888 const bool is_right_associative = op == Token::EXP;
2889 const int next_prec = is_right_associative ? prec1 : prec1 + 1;
2890 ExpressionT y = ParseBinaryExpression(next_prec, accept_IN, CHECK_OK);
2891 impl()->RewriteNonPattern(CHECK_OK);
2892
2893 if (impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos)) {
2894 continue;
2895 }
2896
2897 // For now we distinguish between comparisons and other binary
2898 // operations. (We could combine the two and get rid of this
2899 // code and AST node eventually.)
2900 if (Token::IsCompareOp(op)) {
2901 // We have a comparison.
2902 Token::Value cmp = op;
2903 switch (op) {
2904 case Token::NE: cmp = Token::EQ; break;
2905 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2906 default: break;
2907 }
2908 x = factory()->NewCompareOperation(cmp, x, y, pos);
2909 if (cmp != op) {
2910 // The comparison was negated - add a NOT.
2911 x = factory()->NewUnaryOperation(Token::NOT, x, pos);
2912 }
2913 } else if (op == Token::EXP) {
2914 x = impl()->RewriteExponentiation(x, y, pos);
2915 } else {
2916 // We have a "normal" binary operation.
2917 x = factory()->NewBinaryOperation(op, x, y, pos);
2918 }
2919 }
2920 }
2921 return x;
2922 }
2923
2924 template <typename Impl>
ParseUnaryExpression(bool * ok)2925 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression(
2926 bool* ok) {
2927 // UnaryExpression ::
2928 // PostfixExpression
2929 // 'delete' UnaryExpression
2930 // 'void' UnaryExpression
2931 // 'typeof' UnaryExpression
2932 // '++' UnaryExpression
2933 // '--' UnaryExpression
2934 // '+' UnaryExpression
2935 // '-' UnaryExpression
2936 // '~' UnaryExpression
2937 // '!' UnaryExpression
2938 // [+Await] AwaitExpression[?Yield]
2939
2940 Token::Value op = peek();
2941 if (Token::IsUnaryOp(op)) {
2942 BindingPatternUnexpectedToken();
2943 ArrowFormalParametersUnexpectedToken();
2944
2945 op = Next();
2946 int pos = position();
2947 ExpressionT expression = ParseUnaryExpression(CHECK_OK);
2948 impl()->RewriteNonPattern(CHECK_OK);
2949
2950 if (op == Token::DELETE && is_strict(language_mode())) {
2951 if (impl()->IsIdentifier(expression)) {
2952 // "delete identifier" is a syntax error in strict mode.
2953 ReportMessage(MessageTemplate::kStrictDelete);
2954 *ok = false;
2955 return impl()->EmptyExpression();
2956 }
2957 }
2958
2959 if (peek() == Token::EXP) {
2960 ReportUnexpectedToken(Next());
2961 *ok = false;
2962 return impl()->EmptyExpression();
2963 }
2964
2965 // Allow the parser's implementation to rewrite the expression.
2966 return impl()->BuildUnaryExpression(expression, op, pos);
2967 } else if (Token::IsCountOp(op)) {
2968 BindingPatternUnexpectedToken();
2969 ArrowFormalParametersUnexpectedToken();
2970 op = Next();
2971 int beg_pos = peek_position();
2972 ExpressionT expression = ParseUnaryExpression(CHECK_OK);
2973 expression = CheckAndRewriteReferenceExpression(
2974 expression, beg_pos, scanner()->location().end_pos,
2975 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
2976 expression = impl()->MarkExpressionAsAssigned(expression);
2977 impl()->RewriteNonPattern(CHECK_OK);
2978
2979 return factory()->NewCountOperation(op,
2980 true /* prefix */,
2981 expression,
2982 position());
2983
2984 } else if (is_async_function() && peek() == Token::AWAIT) {
2985 classifier()->RecordFormalParameterInitializerError(
2986 scanner()->peek_location(),
2987 MessageTemplate::kAwaitExpressionFormalParameter);
2988
2989 int await_pos = peek_position();
2990 Consume(Token::AWAIT);
2991
2992 ExpressionT value = ParseUnaryExpression(CHECK_OK);
2993
2994 return impl()->RewriteAwaitExpression(value, await_pos);
2995 } else {
2996 return ParsePostfixExpression(ok);
2997 }
2998 }
2999
3000 template <typename Impl>
ParsePostfixExpression(bool * ok)3001 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression(
3002 bool* ok) {
3003 // PostfixExpression ::
3004 // LeftHandSideExpression ('++' | '--')?
3005
3006 int lhs_beg_pos = peek_position();
3007 ExpressionT expression = ParseLeftHandSideExpression(CHECK_OK);
3008 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
3009 Token::IsCountOp(peek())) {
3010 BindingPatternUnexpectedToken();
3011 ArrowFormalParametersUnexpectedToken();
3012
3013 expression = CheckAndRewriteReferenceExpression(
3014 expression, lhs_beg_pos, scanner()->location().end_pos,
3015 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
3016 expression = impl()->MarkExpressionAsAssigned(expression);
3017 impl()->RewriteNonPattern(CHECK_OK);
3018
3019 Token::Value next = Next();
3020 expression =
3021 factory()->NewCountOperation(next,
3022 false /* postfix */,
3023 expression,
3024 position());
3025 }
3026 return expression;
3027 }
3028
3029 template <typename Impl>
3030 typename ParserBase<Impl>::ExpressionT
ParseLeftHandSideExpression(bool * ok)3031 ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
3032 // LeftHandSideExpression ::
3033 // (NewExpression | MemberExpression) ...
3034
3035 bool is_async = false;
3036 ExpressionT result =
3037 ParseMemberWithNewPrefixesExpression(&is_async, CHECK_OK);
3038
3039 while (true) {
3040 switch (peek()) {
3041 case Token::LBRACK: {
3042 impl()->RewriteNonPattern(CHECK_OK);
3043 BindingPatternUnexpectedToken();
3044 ArrowFormalParametersUnexpectedToken();
3045 Consume(Token::LBRACK);
3046 int pos = position();
3047 ExpressionT index = ParseExpressionCoverGrammar(true, CHECK_OK);
3048 impl()->RewriteNonPattern(CHECK_OK);
3049 result = factory()->NewProperty(result, index, pos);
3050 Expect(Token::RBRACK, CHECK_OK);
3051 break;
3052 }
3053
3054 case Token::LPAREN: {
3055 int pos;
3056 impl()->RewriteNonPattern(CHECK_OK);
3057 BindingPatternUnexpectedToken();
3058 if (scanner()->current_token() == Token::IDENTIFIER ||
3059 scanner()->current_token() == Token::SUPER ||
3060 scanner()->current_token() == Token::ASYNC) {
3061 // For call of an identifier we want to report position of
3062 // the identifier as position of the call in the stack trace.
3063 pos = position();
3064 } else {
3065 // For other kinds of calls we record position of the parenthesis as
3066 // position of the call. Note that this is extremely important for
3067 // expressions of the form function(){...}() for which call position
3068 // should not point to the closing brace otherwise it will intersect
3069 // with positions recorded for function literal and confuse debugger.
3070 pos = peek_position();
3071 // Also the trailing parenthesis are a hint that the function will
3072 // be called immediately. If we happen to have parsed a preceding
3073 // function literal eagerly, we can also compile it eagerly.
3074 if (result->IsFunctionLiteral()) {
3075 result->AsFunctionLiteral()->SetShouldEagerCompile();
3076 }
3077 }
3078 Scanner::Location spread_pos;
3079 ExpressionListT args;
3080 if (V8_UNLIKELY(is_async && impl()->IsIdentifier(result))) {
3081 ExpressionClassifier async_classifier(this);
3082 args = ParseArguments(&spread_pos, true, CHECK_OK);
3083 if (peek() == Token::ARROW) {
3084 if (fni_) {
3085 fni_->RemoveAsyncKeywordFromEnd();
3086 }
3087 ValidateBindingPattern(CHECK_OK);
3088 ValidateFormalParameterInitializer(CHECK_OK);
3089 if (!classifier()->is_valid_async_arrow_formal_parameters()) {
3090 ReportClassifierError(
3091 classifier()->async_arrow_formal_parameters_error());
3092 *ok = false;
3093 return impl()->EmptyExpression();
3094 }
3095 if (args->length()) {
3096 // async ( Arguments ) => ...
3097 return impl()->ExpressionListToExpression(args);
3098 }
3099 // async () => ...
3100 return factory()->NewEmptyParentheses(pos);
3101 } else {
3102 impl()->AccumulateFormalParameterContainmentErrors();
3103 }
3104 } else {
3105 args = ParseArguments(&spread_pos, false, CHECK_OK);
3106 }
3107
3108 ArrowFormalParametersUnexpectedToken();
3109
3110 // Keep track of eval() calls since they disable all local variable
3111 // optimizations.
3112 // The calls that need special treatment are the
3113 // direct eval calls. These calls are all of the form eval(...), with
3114 // no explicit receiver.
3115 // These calls are marked as potentially direct eval calls. Whether
3116 // they are actually direct calls to eval is determined at run time.
3117 Call::PossiblyEval is_possibly_eval =
3118 CheckPossibleEvalCall(result, scope());
3119
3120 bool is_super_call = result->IsSuperCallReference();
3121 if (spread_pos.IsValid()) {
3122 args = impl()->PrepareSpreadArguments(args);
3123 result = impl()->SpreadCall(result, args, pos);
3124 } else {
3125 result = factory()->NewCall(result, args, pos, is_possibly_eval);
3126 }
3127
3128 // Explicit calls to the super constructor using super() perform an
3129 // implicit binding assignment to the 'this' variable.
3130 if (is_super_call) {
3131 result = impl()->RewriteSuperCall(result);
3132 ExpressionT this_expr = impl()->ThisExpression(pos);
3133 result =
3134 factory()->NewAssignment(Token::INIT, this_expr, result, pos);
3135 }
3136
3137 if (fni_ != NULL) fni_->RemoveLastFunction();
3138 break;
3139 }
3140
3141 case Token::PERIOD: {
3142 impl()->RewriteNonPattern(CHECK_OK);
3143 BindingPatternUnexpectedToken();
3144 ArrowFormalParametersUnexpectedToken();
3145 Consume(Token::PERIOD);
3146 int pos = position();
3147 IdentifierT name = ParseIdentifierName(CHECK_OK);
3148 result = factory()->NewProperty(
3149 result, factory()->NewStringLiteral(name, pos), pos);
3150 impl()->PushLiteralName(name);
3151 break;
3152 }
3153
3154 case Token::TEMPLATE_SPAN:
3155 case Token::TEMPLATE_TAIL: {
3156 impl()->RewriteNonPattern(CHECK_OK);
3157 BindingPatternUnexpectedToken();
3158 ArrowFormalParametersUnexpectedToken();
3159 result = ParseTemplateLiteral(result, position(), CHECK_OK);
3160 break;
3161 }
3162
3163 default:
3164 return result;
3165 }
3166 }
3167 }
3168
3169 template <typename Impl>
3170 typename ParserBase<Impl>::ExpressionT
ParseMemberWithNewPrefixesExpression(bool * is_async,bool * ok)3171 ParserBase<Impl>::ParseMemberWithNewPrefixesExpression(bool* is_async,
3172 bool* ok) {
3173 // NewExpression ::
3174 // ('new')+ MemberExpression
3175 //
3176 // NewTarget ::
3177 // 'new' '.' 'target'
3178
3179 // The grammar for new expressions is pretty warped. We can have several 'new'
3180 // keywords following each other, and then a MemberExpression. When we see '('
3181 // after the MemberExpression, it's associated with the rightmost unassociated
3182 // 'new' to create a NewExpression with arguments. However, a NewExpression
3183 // can also occur without arguments.
3184
3185 // Examples of new expression:
3186 // new foo.bar().baz means (new (foo.bar)()).baz
3187 // new foo()() means (new foo())()
3188 // new new foo()() means (new (new foo())())
3189 // new new foo means new (new foo)
3190 // new new foo() means new (new foo())
3191 // new new foo().bar().baz means (new (new foo()).bar()).baz
3192
3193 if (peek() == Token::NEW) {
3194 BindingPatternUnexpectedToken();
3195 ArrowFormalParametersUnexpectedToken();
3196 Consume(Token::NEW);
3197 int new_pos = position();
3198 ExpressionT result;
3199 if (peek() == Token::SUPER) {
3200 const bool is_new = true;
3201 result = ParseSuperExpression(is_new, CHECK_OK);
3202 } else if (peek() == Token::PERIOD) {
3203 return ParseNewTargetExpression(CHECK_OK);
3204 } else {
3205 result = ParseMemberWithNewPrefixesExpression(is_async, CHECK_OK);
3206 }
3207 impl()->RewriteNonPattern(CHECK_OK);
3208 if (peek() == Token::LPAREN) {
3209 // NewExpression with arguments.
3210 Scanner::Location spread_pos;
3211 ExpressionListT args = ParseArguments(&spread_pos, CHECK_OK);
3212
3213 if (spread_pos.IsValid()) {
3214 args = impl()->PrepareSpreadArguments(args);
3215 result = impl()->SpreadCallNew(result, args, new_pos);
3216 } else {
3217 result = factory()->NewCallNew(result, args, new_pos);
3218 }
3219 // The expression can still continue with . or [ after the arguments.
3220 result = ParseMemberExpressionContinuation(result, is_async, CHECK_OK);
3221 return result;
3222 }
3223 // NewExpression without arguments.
3224 return factory()->NewCallNew(result, impl()->NewExpressionList(0), new_pos);
3225 }
3226 // No 'new' or 'super' keyword.
3227 return ParseMemberExpression(is_async, ok);
3228 }
3229
3230 template <typename Impl>
ParseMemberExpression(bool * is_async,bool * ok)3231 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression(
3232 bool* is_async, bool* ok) {
3233 // MemberExpression ::
3234 // (PrimaryExpression | FunctionLiteral | ClassLiteral)
3235 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
3236
3237 // The '[' Expression ']' and '.' Identifier parts are parsed by
3238 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
3239 // caller.
3240
3241 // Parse the initial primary or function expression.
3242 ExpressionT result;
3243 if (peek() == Token::FUNCTION) {
3244 BindingPatternUnexpectedToken();
3245 ArrowFormalParametersUnexpectedToken();
3246
3247 Consume(Token::FUNCTION);
3248 int function_token_position = position();
3249
3250 if (allow_harmony_function_sent() && peek() == Token::PERIOD) {
3251 // function.sent
3252 int pos = position();
3253 ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK);
3254
3255 if (!is_generator()) {
3256 // TODO(neis): allow escaping into closures?
3257 impl()->ReportMessageAt(scanner()->location(),
3258 MessageTemplate::kUnexpectedFunctionSent);
3259 *ok = false;
3260 return impl()->EmptyExpression();
3261 }
3262
3263 return impl()->FunctionSentExpression(pos);
3264 }
3265
3266 FunctionKind function_kind = Check(Token::MUL)
3267 ? FunctionKind::kGeneratorFunction
3268 : FunctionKind::kNormalFunction;
3269 IdentifierT name = impl()->EmptyIdentifier();
3270 bool is_strict_reserved_name = false;
3271 Scanner::Location function_name_location = Scanner::Location::invalid();
3272 FunctionLiteral::FunctionType function_type =
3273 FunctionLiteral::kAnonymousExpression;
3274 if (peek_any_identifier()) {
3275 name = ParseIdentifierOrStrictReservedWord(
3276 function_kind, &is_strict_reserved_name, CHECK_OK);
3277 function_name_location = scanner()->location();
3278 function_type = FunctionLiteral::kNamedExpression;
3279 }
3280 result = impl()->ParseFunctionLiteral(
3281 name, function_name_location,
3282 is_strict_reserved_name ? kFunctionNameIsStrictReserved
3283 : kFunctionNameValidityUnknown,
3284 function_kind, function_token_position, function_type, language_mode(),
3285 CHECK_OK);
3286 } else if (peek() == Token::SUPER) {
3287 const bool is_new = false;
3288 result = ParseSuperExpression(is_new, CHECK_OK);
3289 } else {
3290 result = ParsePrimaryExpression(is_async, CHECK_OK);
3291 }
3292
3293 result = ParseMemberExpressionContinuation(result, is_async, CHECK_OK);
3294 return result;
3295 }
3296
3297 template <typename Impl>
ParseSuperExpression(bool is_new,bool * ok)3298 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression(
3299 bool is_new, bool* ok) {
3300 Expect(Token::SUPER, CHECK_OK);
3301 int pos = position();
3302
3303 DeclarationScope* scope = GetReceiverScope();
3304 FunctionKind kind = scope->function_kind();
3305 if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
3306 IsClassConstructor(kind)) {
3307 if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
3308 scope->RecordSuperPropertyUsage();
3309 return impl()->NewSuperPropertyReference(pos);
3310 }
3311 // new super() is never allowed.
3312 // super() is only allowed in derived constructor
3313 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
3314 // TODO(rossberg): This might not be the correct FunctionState for the
3315 // method here.
3316 return impl()->NewSuperCallReference(pos);
3317 }
3318 }
3319
3320 impl()->ReportMessageAt(scanner()->location(),
3321 MessageTemplate::kUnexpectedSuper);
3322 *ok = false;
3323 return impl()->EmptyExpression();
3324 }
3325
3326 template <typename Impl>
ExpectMetaProperty(Vector<const char> property_name,const char * full_name,int pos,bool * ok)3327 void ParserBase<Impl>::ExpectMetaProperty(Vector<const char> property_name,
3328 const char* full_name, int pos,
3329 bool* ok) {
3330 Consume(Token::PERIOD);
3331 ExpectContextualKeyword(property_name, CHECK_OK_CUSTOM(Void));
3332 if (scanner()->literal_contains_escapes()) {
3333 impl()->ReportMessageAt(
3334 Scanner::Location(pos, scanner()->location().end_pos),
3335 MessageTemplate::kInvalidEscapedMetaProperty, full_name);
3336 *ok = false;
3337 }
3338 }
3339
3340 template <typename Impl>
3341 typename ParserBase<Impl>::ExpressionT
ParseNewTargetExpression(bool * ok)3342 ParserBase<Impl>::ParseNewTargetExpression(bool* ok) {
3343 int pos = position();
3344 ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK);
3345
3346 if (!GetReceiverScope()->is_function_scope()) {
3347 impl()->ReportMessageAt(scanner()->location(),
3348 MessageTemplate::kUnexpectedNewTarget);
3349 *ok = false;
3350 return impl()->EmptyExpression();
3351 }
3352
3353 return impl()->NewTargetExpression(pos);
3354 }
3355
3356 template <typename Impl>
3357 typename ParserBase<Impl>::ExpressionT
ParseMemberExpressionContinuation(ExpressionT expression,bool * is_async,bool * ok)3358 ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression,
3359 bool* is_async, bool* ok) {
3360 // Parses this part of MemberExpression:
3361 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
3362 while (true) {
3363 switch (peek()) {
3364 case Token::LBRACK: {
3365 *is_async = false;
3366 impl()->RewriteNonPattern(CHECK_OK);
3367 BindingPatternUnexpectedToken();
3368 ArrowFormalParametersUnexpectedToken();
3369
3370 Consume(Token::LBRACK);
3371 int pos = position();
3372 ExpressionT index = ParseExpressionCoverGrammar(true, CHECK_OK);
3373 impl()->RewriteNonPattern(CHECK_OK);
3374 expression = factory()->NewProperty(expression, index, pos);
3375 impl()->PushPropertyName(index);
3376 Expect(Token::RBRACK, CHECK_OK);
3377 break;
3378 }
3379 case Token::PERIOD: {
3380 *is_async = false;
3381 impl()->RewriteNonPattern(CHECK_OK);
3382 BindingPatternUnexpectedToken();
3383 ArrowFormalParametersUnexpectedToken();
3384
3385 Consume(Token::PERIOD);
3386 int pos = position();
3387 IdentifierT name = ParseIdentifierName(CHECK_OK);
3388 expression = factory()->NewProperty(
3389 expression, factory()->NewStringLiteral(name, pos), pos);
3390 impl()->PushLiteralName(name);
3391 break;
3392 }
3393 case Token::TEMPLATE_SPAN:
3394 case Token::TEMPLATE_TAIL: {
3395 *is_async = false;
3396 impl()->RewriteNonPattern(CHECK_OK);
3397 BindingPatternUnexpectedToken();
3398 ArrowFormalParametersUnexpectedToken();
3399 int pos;
3400 if (scanner()->current_token() == Token::IDENTIFIER) {
3401 pos = position();
3402 } else {
3403 pos = peek_position();
3404 if (expression->IsFunctionLiteral()) {
3405 // If the tag function looks like an IIFE, set_parenthesized() to
3406 // force eager compilation.
3407 expression->AsFunctionLiteral()->SetShouldEagerCompile();
3408 }
3409 }
3410 expression = ParseTemplateLiteral(expression, pos, CHECK_OK);
3411 break;
3412 }
3413 case Token::ILLEGAL: {
3414 ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL);
3415 *ok = false;
3416 return impl()->EmptyExpression();
3417 }
3418 default:
3419 return expression;
3420 }
3421 }
3422 DCHECK(false);
3423 return impl()->EmptyExpression();
3424 }
3425
3426 template <typename Impl>
ParseFormalParameter(FormalParametersT * parameters,bool * ok)3427 void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters,
3428 bool* ok) {
3429 // FormalParameter[Yield,GeneratorParameter] :
3430 // BindingElement[?Yield, ?GeneratorParameter]
3431 bool is_rest = parameters->has_rest;
3432
3433 ExpressionT pattern = ParsePrimaryExpression(CHECK_OK_CUSTOM(Void));
3434 ValidateBindingPattern(CHECK_OK_CUSTOM(Void));
3435
3436 if (!impl()->IsIdentifier(pattern)) {
3437 parameters->is_simple = false;
3438 ValidateFormalParameterInitializer(CHECK_OK_CUSTOM(Void));
3439 classifier()->RecordNonSimpleParameter();
3440 }
3441
3442 ExpressionT initializer = impl()->EmptyExpression();
3443 if (!is_rest && Check(Token::ASSIGN)) {
3444 ExpressionClassifier init_classifier(this);
3445 initializer = ParseAssignmentExpression(true, CHECK_OK_CUSTOM(Void));
3446 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(Void));
3447 ValidateFormalParameterInitializer(CHECK_OK_CUSTOM(Void));
3448 parameters->is_simple = false;
3449 impl()->Discard();
3450 classifier()->RecordNonSimpleParameter();
3451
3452 impl()->SetFunctionNameFromIdentifierRef(initializer, pattern);
3453 }
3454
3455 impl()->AddFormalParameter(parameters, pattern, initializer,
3456 scanner()->location().end_pos, is_rest);
3457 }
3458
3459 template <typename Impl>
ParseFormalParameterList(FormalParametersT * parameters,bool * ok)3460 void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters,
3461 bool* ok) {
3462 // FormalParameters[Yield] :
3463 // [empty]
3464 // FunctionRestParameter[?Yield]
3465 // FormalParameterList[?Yield]
3466 // FormalParameterList[?Yield] ,
3467 // FormalParameterList[?Yield] , FunctionRestParameter[?Yield]
3468 //
3469 // FormalParameterList[Yield] :
3470 // FormalParameter[?Yield]
3471 // FormalParameterList[?Yield] , FormalParameter[?Yield]
3472
3473 DCHECK_EQ(0, parameters->arity);
3474
3475 if (peek() != Token::RPAREN) {
3476 while (true) {
3477 if (parameters->arity > Code::kMaxArguments) {
3478 ReportMessage(MessageTemplate::kTooManyParameters);
3479 *ok = false;
3480 return;
3481 }
3482 parameters->has_rest = Check(Token::ELLIPSIS);
3483 ParseFormalParameter(parameters, CHECK_OK_CUSTOM(Void));
3484
3485 if (parameters->has_rest) {
3486 parameters->is_simple = false;
3487 classifier()->RecordNonSimpleParameter();
3488 if (peek() == Token::COMMA) {
3489 impl()->ReportMessageAt(scanner()->peek_location(),
3490 MessageTemplate::kParamAfterRest);
3491 *ok = false;
3492 return;
3493 }
3494 break;
3495 }
3496 if (!Check(Token::COMMA)) break;
3497 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) {
3498 // allow the trailing comma
3499 break;
3500 }
3501 }
3502 }
3503
3504 for (int i = 0; i < parameters->arity; ++i) {
3505 auto parameter = parameters->at(i);
3506 impl()->DeclareFormalParameter(parameters->scope, parameter);
3507 }
3508 }
3509
3510 template <typename Impl>
ParseVariableDeclarations(VariableDeclarationContext var_context,DeclarationParsingResult * parsing_result,ZoneList<const AstRawString * > * names,bool * ok)3511 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseVariableDeclarations(
3512 VariableDeclarationContext var_context,
3513 DeclarationParsingResult* parsing_result,
3514 ZoneList<const AstRawString*>* names, bool* ok) {
3515 // VariableDeclarations ::
3516 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
3517 //
3518 // ES6:
3519 // FIXME(marja, nikolaos): Add an up-to-date comment about ES6 variable
3520 // declaration syntax.
3521
3522 DCHECK_NOT_NULL(parsing_result);
3523 parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
3524 parsing_result->descriptor.declaration_pos = peek_position();
3525 parsing_result->descriptor.initialization_pos = peek_position();
3526
3527 BlockT init_block = impl()->NullBlock();
3528 if (var_context != kForStatement) {
3529 init_block = factory()->NewBlock(
3530 nullptr, 1, true, parsing_result->descriptor.declaration_pos);
3531 }
3532
3533 switch (peek()) {
3534 case Token::VAR:
3535 parsing_result->descriptor.mode = VAR;
3536 Consume(Token::VAR);
3537 break;
3538 case Token::CONST:
3539 Consume(Token::CONST);
3540 DCHECK(var_context != kStatement);
3541 parsing_result->descriptor.mode = CONST;
3542 break;
3543 case Token::LET:
3544 Consume(Token::LET);
3545 DCHECK(var_context != kStatement);
3546 parsing_result->descriptor.mode = LET;
3547 break;
3548 default:
3549 UNREACHABLE(); // by current callers
3550 break;
3551 }
3552
3553 parsing_result->descriptor.scope = scope();
3554 parsing_result->descriptor.hoist_scope = nullptr;
3555
3556 // The scope of a var/const declared variable anywhere inside a function
3557 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
3558 // of a let declared variable is the scope of the immediately enclosing
3559 // block.
3560 int bindings_start = peek_position();
3561 do {
3562 // Parse binding pattern.
3563 FuncNameInferrer::State fni_state(fni_);
3564
3565 ExpressionT pattern = impl()->EmptyExpression();
3566 int decl_pos = peek_position();
3567 {
3568 ExpressionClassifier pattern_classifier(this);
3569 pattern = ParsePrimaryExpression(CHECK_OK_CUSTOM(NullBlock));
3570
3571 ValidateBindingPattern(CHECK_OK_CUSTOM(NullBlock));
3572 if (IsLexicalVariableMode(parsing_result->descriptor.mode)) {
3573 ValidateLetPattern(CHECK_OK_CUSTOM(NullBlock));
3574 }
3575 }
3576
3577 Scanner::Location variable_loc = scanner()->location();
3578 bool single_name = impl()->IsIdentifier(pattern);
3579
3580 if (single_name) {
3581 impl()->PushVariableName(impl()->AsIdentifier(pattern));
3582 }
3583
3584 ExpressionT value = impl()->EmptyExpression();
3585 int initializer_position = kNoSourcePosition;
3586 if (Check(Token::ASSIGN)) {
3587 ExpressionClassifier classifier(this);
3588 value = ParseAssignmentExpression(var_context != kForStatement,
3589 CHECK_OK_CUSTOM(NullBlock));
3590 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullBlock));
3591 variable_loc.end_pos = scanner()->location().end_pos;
3592
3593 if (!parsing_result->first_initializer_loc.IsValid()) {
3594 parsing_result->first_initializer_loc = variable_loc;
3595 }
3596
3597 // Don't infer if it is "a = function(){...}();"-like expression.
3598 if (single_name && fni_ != nullptr) {
3599 if (!value->IsCall() && !value->IsCallNew()) {
3600 fni_->Infer();
3601 } else {
3602 fni_->RemoveLastFunction();
3603 }
3604 }
3605
3606 impl()->SetFunctionNameFromIdentifierRef(value, pattern);
3607
3608 // End position of the initializer is after the assignment expression.
3609 initializer_position = scanner()->location().end_pos;
3610 } else {
3611 if (var_context != kForStatement || !PeekInOrOf()) {
3612 // ES6 'const' and binding patterns require initializers.
3613 if (parsing_result->descriptor.mode == CONST ||
3614 !impl()->IsIdentifier(pattern)) {
3615 impl()->ReportMessageAt(
3616 Scanner::Location(decl_pos, scanner()->location().end_pos),
3617 MessageTemplate::kDeclarationMissingInitializer,
3618 !impl()->IsIdentifier(pattern) ? "destructuring" : "const");
3619 *ok = false;
3620 return impl()->NullBlock();
3621 }
3622 // 'let x' initializes 'x' to undefined.
3623 if (parsing_result->descriptor.mode == LET) {
3624 value = impl()->GetLiteralUndefined(position());
3625 }
3626 }
3627
3628 // End position of the initializer is after the variable.
3629 initializer_position = position();
3630 }
3631
3632 typename DeclarationParsingResult::Declaration decl(
3633 pattern, initializer_position, value);
3634 if (var_context == kForStatement) {
3635 // Save the declaration for further handling in ParseForStatement.
3636 parsing_result->declarations.Add(decl);
3637 } else {
3638 // Immediately declare the variable otherwise. This avoids O(N^2)
3639 // behavior (where N is the number of variables in a single
3640 // declaration) in the PatternRewriter having to do with removing
3641 // and adding VariableProxies to the Scope (see bug 4699).
3642 impl()->DeclareAndInitializeVariables(init_block,
3643 &parsing_result->descriptor, &decl,
3644 names, CHECK_OK_CUSTOM(NullBlock));
3645 }
3646 } while (Check(Token::COMMA));
3647
3648 parsing_result->bindings_loc =
3649 Scanner::Location(bindings_start, scanner()->location().end_pos);
3650
3651 DCHECK(*ok);
3652 return init_block;
3653 }
3654
3655 template <typename Impl>
3656 typename ParserBase<Impl>::StatementT
ParseFunctionDeclaration(bool * ok)3657 ParserBase<Impl>::ParseFunctionDeclaration(bool* ok) {
3658 Consume(Token::FUNCTION);
3659 int pos = position();
3660 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
3661 if (Check(Token::MUL)) {
3662 impl()->ReportMessageAt(scanner()->location(),
3663 MessageTemplate::kGeneratorInLegacyContext);
3664 *ok = false;
3665 return impl()->NullStatement();
3666 }
3667 return ParseHoistableDeclaration(pos, flags, nullptr, false, ok);
3668 }
3669
3670 template <typename Impl>
3671 typename ParserBase<Impl>::StatementT
ParseHoistableDeclaration(ZoneList<const AstRawString * > * names,bool default_export,bool * ok)3672 ParserBase<Impl>::ParseHoistableDeclaration(
3673 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
3674 Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement));
3675 int pos = position();
3676 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
3677 if (Check(Token::MUL)) {
3678 flags |= ParseFunctionFlags::kIsGenerator;
3679 }
3680 return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
3681 }
3682
3683 template <typename Impl>
3684 typename ParserBase<Impl>::StatementT
ParseHoistableDeclaration(int pos,ParseFunctionFlags flags,ZoneList<const AstRawString * > * names,bool default_export,bool * ok)3685 ParserBase<Impl>::ParseHoistableDeclaration(
3686 int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names,
3687 bool default_export, bool* ok) {
3688 // FunctionDeclaration ::
3689 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
3690 // 'function' '(' FormalParameters ')' '{' FunctionBody '}'
3691 // GeneratorDeclaration ::
3692 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
3693 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}'
3694 //
3695 // The anonymous forms are allowed iff [default_export] is true.
3696 //
3697 // 'function' and '*' (if present) have been consumed by the caller.
3698
3699 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator;
3700 const bool is_async = flags & ParseFunctionFlags::kIsAsync;
3701 DCHECK(!is_generator || !is_async);
3702
3703 IdentifierT name;
3704 FunctionNameValidity name_validity;
3705 IdentifierT variable_name;
3706 if (default_export && peek() == Token::LPAREN) {
3707 impl()->GetDefaultStrings(&name, &variable_name);
3708 name_validity = kSkipFunctionNameCheck;
3709 } else {
3710 bool is_strict_reserved;
3711 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
3712 CHECK_OK_CUSTOM(NullStatement));
3713 name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved
3714 : kFunctionNameValidityUnknown;
3715 variable_name = name;
3716 }
3717
3718 FuncNameInferrer::State fni_state(fni_);
3719 impl()->PushEnclosingName(name);
3720 FunctionLiteralT function = impl()->ParseFunctionLiteral(
3721 name, scanner()->location(), name_validity,
3722 is_generator ? FunctionKind::kGeneratorFunction
3723 : is_async ? FunctionKind::kAsyncFunction
3724 : FunctionKind::kNormalFunction,
3725 pos, FunctionLiteral::kDeclaration, language_mode(),
3726 CHECK_OK_CUSTOM(NullStatement));
3727
3728 return impl()->DeclareFunction(variable_name, function, pos, is_generator,
3729 is_async, names, ok);
3730 }
3731
3732 template <typename Impl>
ParseClassDeclaration(ZoneList<const AstRawString * > * names,bool default_export,bool * ok)3733 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseClassDeclaration(
3734 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
3735 // ClassDeclaration ::
3736 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
3737 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
3738 //
3739 // The anonymous form is allowed iff [default_export] is true.
3740 //
3741 // 'class' is expected to be consumed by the caller.
3742 //
3743 // A ClassDeclaration
3744 //
3745 // class C { ... }
3746 //
3747 // has the same semantics as:
3748 //
3749 // let C = class C { ... };
3750 //
3751 // so rewrite it as such.
3752
3753 int class_token_pos = position();
3754 IdentifierT name = impl()->EmptyIdentifier();
3755 bool is_strict_reserved = false;
3756 IdentifierT variable_name = impl()->EmptyIdentifier();
3757 if (default_export && (peek() == Token::EXTENDS || peek() == Token::LBRACE)) {
3758 impl()->GetDefaultStrings(&name, &variable_name);
3759 } else {
3760 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
3761 CHECK_OK_CUSTOM(NullStatement));
3762 variable_name = name;
3763 }
3764
3765 ExpressionClassifier no_classifier(this);
3766 ExpressionT value =
3767 ParseClassLiteral(name, scanner()->location(), is_strict_reserved,
3768 class_token_pos, CHECK_OK_CUSTOM(NullStatement));
3769 int end_pos = position();
3770 return impl()->DeclareClass(variable_name, value, names, class_token_pos,
3771 end_pos, ok);
3772 }
3773
3774 // Language extension which is only enabled for source files loaded
3775 // through the API's extension mechanism. A native function
3776 // declaration is resolved by looking up the function through a
3777 // callback provided by the extension.
3778 template <typename Impl>
ParseNativeDeclaration(bool * ok)3779 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseNativeDeclaration(
3780 bool* ok) {
3781 int pos = peek_position();
3782 Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement));
3783 // Allow "eval" or "arguments" for backward compatibility.
3784 IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers,
3785 CHECK_OK_CUSTOM(NullStatement));
3786 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullStatement));
3787 if (peek() != Token::RPAREN) {
3788 do {
3789 ParseIdentifier(kAllowRestrictedIdentifiers,
3790 CHECK_OK_CUSTOM(NullStatement));
3791 } while (Check(Token::COMMA));
3792 }
3793 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullStatement));
3794 Expect(Token::SEMICOLON, CHECK_OK_CUSTOM(NullStatement));
3795 return impl()->DeclareNative(name, pos, ok);
3796 }
3797
3798 template <typename Impl>
3799 typename ParserBase<Impl>::StatementT
ParseAsyncFunctionDeclaration(ZoneList<const AstRawString * > * names,bool default_export,bool * ok)3800 ParserBase<Impl>::ParseAsyncFunctionDeclaration(
3801 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) {
3802 // AsyncFunctionDeclaration ::
3803 // async [no LineTerminator here] function BindingIdentifier[Await]
3804 // ( FormalParameters[Await] ) { AsyncFunctionBody }
3805 DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
3806 int pos = position();
3807 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
3808 *ok = false;
3809 impl()->ReportUnexpectedToken(scanner()->current_token());
3810 return impl()->NullStatement();
3811 }
3812 Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement));
3813 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
3814 return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
3815 }
3816
3817 template <typename Impl>
CheckArityRestrictions(int param_count,FunctionKind function_kind,bool has_rest,int formals_start_pos,int formals_end_pos,bool * ok)3818 void ParserBase<Impl>::CheckArityRestrictions(int param_count,
3819 FunctionKind function_kind,
3820 bool has_rest,
3821 int formals_start_pos,
3822 int formals_end_pos, bool* ok) {
3823 if (IsGetterFunction(function_kind)) {
3824 if (param_count != 0) {
3825 impl()->ReportMessageAt(
3826 Scanner::Location(formals_start_pos, formals_end_pos),
3827 MessageTemplate::kBadGetterArity);
3828 *ok = false;
3829 }
3830 } else if (IsSetterFunction(function_kind)) {
3831 if (param_count != 1) {
3832 impl()->ReportMessageAt(
3833 Scanner::Location(formals_start_pos, formals_end_pos),
3834 MessageTemplate::kBadSetterArity);
3835 *ok = false;
3836 }
3837 if (has_rest) {
3838 impl()->ReportMessageAt(
3839 Scanner::Location(formals_start_pos, formals_end_pos),
3840 MessageTemplate::kBadSetterRestParameter);
3841 *ok = false;
3842 }
3843 }
3844 }
3845
3846 template <typename Impl>
IsNextLetKeyword()3847 bool ParserBase<Impl>::IsNextLetKeyword() {
3848 DCHECK(peek() == Token::LET);
3849 Token::Value next_next = PeekAhead();
3850 switch (next_next) {
3851 case Token::LBRACE:
3852 case Token::LBRACK:
3853 case Token::IDENTIFIER:
3854 case Token::STATIC:
3855 case Token::LET: // `let let;` is disallowed by static semantics, but the
3856 // token must be first interpreted as a keyword in order
3857 // for those semantics to apply. This ensures that ASI is
3858 // not honored when a LineTerminator separates the
3859 // tokens.
3860 case Token::YIELD:
3861 case Token::AWAIT:
3862 case Token::ASYNC:
3863 return true;
3864 case Token::FUTURE_STRICT_RESERVED_WORD:
3865 return is_sloppy(language_mode());
3866 default:
3867 return false;
3868 }
3869 }
3870
3871 template <typename Impl>
IsTrivialExpression()3872 bool ParserBase<Impl>::IsTrivialExpression() {
3873 Token::Value peek_token = peek();
3874 if (peek_token == Token::SMI || peek_token == Token::NUMBER ||
3875 peek_token == Token::NULL_LITERAL || peek_token == Token::TRUE_LITERAL ||
3876 peek_token == Token::FALSE_LITERAL || peek_token == Token::STRING ||
3877 peek_token == Token::IDENTIFIER || peek_token == Token::THIS) {
3878 // PeekAhead() is expensive & may not always be called, so we only call it
3879 // after checking peek().
3880 Token::Value peek_ahead = PeekAhead();
3881 if (peek_ahead == Token::COMMA || peek_ahead == Token::RPAREN ||
3882 peek_ahead == Token::SEMICOLON || peek_ahead == Token::RBRACK) {
3883 return true;
3884 }
3885 }
3886 return false;
3887 }
3888
3889 template <typename Impl>
3890 typename ParserBase<Impl>::ExpressionT
ParseArrowFunctionLiteral(bool accept_IN,const FormalParametersT & formal_parameters,bool * ok)3891 ParserBase<Impl>::ParseArrowFunctionLiteral(
3892 bool accept_IN, const FormalParametersT& formal_parameters, bool* ok) {
3893 RuntimeCallTimerScope runtime_timer(
3894 runtime_call_stats_,
3895 Impl::IsPreParser() ? &RuntimeCallStats::ParseArrowFunctionLiteral
3896 : &RuntimeCallStats::PreParseArrowFunctionLiteral);
3897
3898 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
3899 // ASI inserts `;` after arrow parameters if a line terminator is found.
3900 // `=> ...` is never a valid expression, so report as syntax error.
3901 // If next token is not `=>`, it's a syntax error anyways.
3902 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
3903 *ok = false;
3904 return impl()->EmptyExpression();
3905 }
3906
3907 StatementListT body = impl()->NullStatementList();
3908 int materialized_literal_count = -1;
3909 int expected_property_count = -1;
3910
3911 FunctionKind kind = formal_parameters.scope->function_kind();
3912 FunctionLiteral::EagerCompileHint eager_compile_hint =
3913 default_eager_compile_hint_;
3914 bool can_preparse = impl()->parse_lazily() &&
3915 eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
3916 // TODO(marja): consider lazy-parsing inner arrow functions too. is_this
3917 // handling in Scope::ResolveVariable needs to change.
3918 bool is_lazy_top_level_function =
3919 can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables();
3920 bool should_be_used_once_hint = false;
3921 bool has_braces = true;
3922 {
3923 FunctionState function_state(&function_state_, &scope_state_,
3924 formal_parameters.scope);
3925
3926 function_state.SkipMaterializedLiterals(
3927 formal_parameters.materialized_literals_count);
3928
3929 impl()->ReindexLiterals(formal_parameters);
3930
3931 Expect(Token::ARROW, CHECK_OK);
3932
3933 if (peek() == Token::LBRACE) {
3934 // Multiple statement body
3935 DCHECK_EQ(scope(), formal_parameters.scope);
3936 if (is_lazy_top_level_function) {
3937 // FIXME(marja): Arrow function parameters will be parsed even if the
3938 // body is preparsed; move relevant parts of parameter handling to
3939 // simulate consistent parameter handling.
3940 Scanner::BookmarkScope bookmark(scanner());
3941 bookmark.Set();
3942 // For arrow functions, we don't need to retrieve data about function
3943 // parameters.
3944 int dummy_num_parameters = -1;
3945 int dummy_function_length = -1;
3946 bool dummy_has_duplicate_parameters = false;
3947 DCHECK((kind & FunctionKind::kArrowFunction) != 0);
3948 LazyParsingResult result = impl()->SkipFunction(
3949 kind, formal_parameters.scope, &dummy_num_parameters,
3950 &dummy_function_length, &dummy_has_duplicate_parameters,
3951 &materialized_literal_count, &expected_property_count, false, true,
3952 CHECK_OK);
3953 formal_parameters.scope->ResetAfterPreparsing(
3954 ast_value_factory_, result == kLazyParsingAborted);
3955
3956 if (formal_parameters.materialized_literals_count > 0) {
3957 materialized_literal_count +=
3958 formal_parameters.materialized_literals_count;
3959 }
3960
3961 if (result == kLazyParsingAborted) {
3962 bookmark.Apply();
3963 // Trigger eager (re-)parsing, just below this block.
3964 is_lazy_top_level_function = false;
3965
3966 // This is probably an initialization function. Inform the compiler it
3967 // should also eager-compile this function, and that we expect it to
3968 // be used once.
3969 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
3970 should_be_used_once_hint = true;
3971 }
3972 }
3973 if (!is_lazy_top_level_function) {
3974 Consume(Token::LBRACE);
3975 body = impl()->ParseEagerFunctionBody(
3976 impl()->EmptyIdentifier(), kNoSourcePosition, formal_parameters,
3977 kind, FunctionLiteral::kAnonymousExpression, CHECK_OK);
3978 materialized_literal_count =
3979 function_state.materialized_literal_count();
3980 expected_property_count = function_state.expected_property_count();
3981 }
3982 } else {
3983 // Single-expression body
3984 has_braces = false;
3985 int pos = position();
3986 DCHECK(ReturnExprContext::kInsideValidBlock ==
3987 function_state_->return_expr_context());
3988 ReturnExprScope allow_tail_calls(
3989 function_state_, ReturnExprContext::kInsideValidReturnStatement);
3990 body = impl()->NewStatementList(1);
3991 impl()->AddParameterInitializationBlock(
3992 formal_parameters, body, kind == kAsyncArrowFunction, CHECK_OK);
3993 ExpressionClassifier classifier(this);
3994 if (kind == kAsyncArrowFunction) {
3995 ParseAsyncFunctionBody(scope(), body, kAsyncArrowFunction,
3996 FunctionBodyType::kSingleExpression, accept_IN,
3997 pos, CHECK_OK);
3998 impl()->RewriteNonPattern(CHECK_OK);
3999 } else {
4000 ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK);
4001 impl()->RewriteNonPattern(CHECK_OK);
4002 body->Add(
4003 factory()->NewReturnStatement(expression, expression->position()),
4004 zone());
4005 if (allow_tailcalls() && !is_sloppy(language_mode())) {
4006 // ES6 14.6.1 Static Semantics: IsInTailPosition
4007 impl()->MarkTailPosition(expression);
4008 }
4009 }
4010 materialized_literal_count = function_state.materialized_literal_count();
4011 expected_property_count = function_state.expected_property_count();
4012 impl()->MarkCollectedTailCallExpressions();
4013 }
4014
4015 formal_parameters.scope->set_end_position(scanner()->location().end_pos);
4016
4017 // Arrow function formal parameters are parsed as StrictFormalParameterList,
4018 // which is not the same as "parameters of a strict function"; it only means
4019 // that duplicates are not allowed. Of course, the arrow function may
4020 // itself be strict as well.
4021 const bool allow_duplicate_parameters = false;
4022 ValidateFormalParameters(language_mode(), allow_duplicate_parameters,
4023 CHECK_OK);
4024
4025 // Validate strict mode.
4026 if (is_strict(language_mode())) {
4027 CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
4028 scanner()->location().end_pos, CHECK_OK);
4029 }
4030 impl()->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
4031
4032 impl()->RewriteDestructuringAssignments();
4033 }
4034
4035 if (FLAG_trace_preparse) {
4036 Scope* scope = formal_parameters.scope;
4037 PrintF(" [%s]: %i-%i (arrow function)\n",
4038 is_lazy_top_level_function ? "Preparse no-resolution" : "Full parse",
4039 scope->start_position(), scope->end_position());
4040 }
4041 FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
4042 impl()->EmptyIdentifierString(), formal_parameters.scope, body,
4043 materialized_literal_count, expected_property_count,
4044 formal_parameters.num_parameters(), formal_parameters.function_length,
4045 FunctionLiteral::kNoDuplicateParameters,
4046 FunctionLiteral::kAnonymousExpression, eager_compile_hint,
4047 formal_parameters.scope->start_position(), has_braces);
4048
4049 function_literal->set_function_token_position(
4050 formal_parameters.scope->start_position());
4051 if (should_be_used_once_hint) {
4052 function_literal->set_should_be_used_once_hint();
4053 }
4054
4055 impl()->AddFunctionForNameInference(function_literal);
4056
4057 return function_literal;
4058 }
4059
4060 template <typename Impl>
ParseClassLiteral(IdentifierT name,Scanner::Location class_name_location,bool name_is_strict_reserved,int class_token_pos,bool * ok)4061 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
4062 IdentifierT name, Scanner::Location class_name_location,
4063 bool name_is_strict_reserved, int class_token_pos, bool* ok) {
4064 // All parts of a ClassDeclaration and ClassExpression are strict code.
4065 if (name_is_strict_reserved) {
4066 impl()->ReportMessageAt(class_name_location,
4067 MessageTemplate::kUnexpectedStrictReserved);
4068 *ok = false;
4069 return impl()->EmptyExpression();
4070 }
4071 if (impl()->IsEvalOrArguments(name)) {
4072 impl()->ReportMessageAt(class_name_location,
4073 MessageTemplate::kStrictEvalArguments);
4074 *ok = false;
4075 return impl()->EmptyExpression();
4076 }
4077
4078 BlockState block_state(zone(), &scope_state_);
4079 RaiseLanguageMode(STRICT);
4080
4081 ClassInfo class_info(this);
4082 impl()->DeclareClassVariable(name, block_state.scope(), &class_info,
4083 class_token_pos, CHECK_OK);
4084
4085 if (Check(Token::EXTENDS)) {
4086 block_state.set_start_position(scanner()->location().end_pos);
4087 ExpressionClassifier extends_classifier(this);
4088 class_info.extends = ParseLeftHandSideExpression(CHECK_OK);
4089 impl()->RewriteNonPattern(CHECK_OK);
4090 impl()->AccumulateFormalParameterContainmentErrors();
4091 } else {
4092 block_state.set_start_position(scanner()->location().end_pos);
4093 }
4094
4095 ClassLiteralChecker checker(this);
4096
4097 Expect(Token::LBRACE, CHECK_OK);
4098
4099 const bool has_extends = !impl()->IsEmptyExpression(class_info.extends);
4100 while (peek() != Token::RBRACE) {
4101 if (Check(Token::SEMICOLON)) continue;
4102 FuncNameInferrer::State fni_state(fni_);
4103 bool is_computed_name = false; // Classes do not care about computed
4104 // property names here.
4105 ExpressionClassifier property_classifier(this);
4106 ClassLiteralPropertyT property = ParseClassPropertyDefinition(
4107 &checker, has_extends, &is_computed_name,
4108 &class_info.has_seen_constructor, CHECK_OK);
4109 impl()->RewriteNonPattern(CHECK_OK);
4110 impl()->AccumulateFormalParameterContainmentErrors();
4111
4112 impl()->DeclareClassProperty(name, property, &class_info, CHECK_OK);
4113 impl()->InferFunctionName();
4114 }
4115
4116 Expect(Token::RBRACE, CHECK_OK);
4117 return impl()->RewriteClassLiteral(name, &class_info, class_token_pos, ok);
4118 }
4119
4120 template <typename Impl>
ParseAsyncFunctionBody(Scope * scope,StatementListT body,FunctionKind kind,FunctionBodyType body_type,bool accept_IN,int pos,bool * ok)4121 void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope, StatementListT body,
4122 FunctionKind kind,
4123 FunctionBodyType body_type,
4124 bool accept_IN, int pos,
4125 bool* ok) {
4126 scope->ForceContextAllocation();
4127
4128 impl()->PrepareAsyncFunctionBody(body, kind, pos);
4129
4130 BlockT block = factory()->NewBlock(nullptr, 8, true, kNoSourcePosition);
4131
4132 ExpressionT return_value = impl()->EmptyExpression();
4133 if (body_type == FunctionBodyType::kNormal) {
4134 ParseStatementList(block->statements(), Token::RBRACE,
4135 CHECK_OK_CUSTOM(Void));
4136 return_value = factory()->NewUndefinedLiteral(kNoSourcePosition);
4137 } else {
4138 return_value = ParseAssignmentExpression(accept_IN, CHECK_OK_CUSTOM(Void));
4139 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(Void));
4140 }
4141
4142 impl()->RewriteAsyncFunctionBody(body, block, return_value,
4143 CHECK_OK_CUSTOM(Void));
4144 scope->set_end_position(scanner()->location().end_pos);
4145 }
4146
4147 template <typename Impl>
4148 typename ParserBase<Impl>::ExpressionT
ParseAsyncFunctionLiteral(bool * ok)4149 ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) {
4150 // AsyncFunctionLiteral ::
4151 // async [no LineTerminator here] function ( FormalParameters[Await] )
4152 // { AsyncFunctionBody }
4153 //
4154 // async [no LineTerminator here] function BindingIdentifier[Await]
4155 // ( FormalParameters[Await] ) { AsyncFunctionBody }
4156 DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
4157 int pos = position();
4158 Expect(Token::FUNCTION, CHECK_OK);
4159 bool is_strict_reserved = false;
4160 IdentifierT name = impl()->EmptyIdentifier();
4161 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression;
4162
4163 if (peek_any_identifier()) {
4164 type = FunctionLiteral::kNamedExpression;
4165 name = ParseIdentifierOrStrictReservedWord(FunctionKind::kAsyncFunction,
4166 &is_strict_reserved, CHECK_OK);
4167 }
4168 return impl()->ParseFunctionLiteral(
4169 name, scanner()->location(),
4170 is_strict_reserved ? kFunctionNameIsStrictReserved
4171 : kFunctionNameValidityUnknown,
4172 FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK);
4173 }
4174
4175 template <typename Impl>
ParseTemplateLiteral(ExpressionT tag,int start,bool * ok)4176 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
4177 ExpressionT tag, int start, bool* ok) {
4178 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
4179 // text followed by a substitution expression), finalized by a single
4180 // TEMPLATE_TAIL.
4181 //
4182 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
4183 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
4184 // NoSubstitutionTemplate.
4185 //
4186 // When parsing a TemplateLiteral, we must have scanned either an initial
4187 // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
4188 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
4189
4190 // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
4191 // In this case we may simply consume the token and build a template with a
4192 // single TEMPLATE_SPAN and no expressions.
4193 if (peek() == Token::TEMPLATE_TAIL) {
4194 Consume(Token::TEMPLATE_TAIL);
4195 int pos = position();
4196 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
4197 typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
4198 impl()->AddTemplateSpan(&ts, true);
4199 return impl()->CloseTemplateLiteral(&ts, start, tag);
4200 }
4201
4202 Consume(Token::TEMPLATE_SPAN);
4203 int pos = position();
4204 typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
4205 impl()->AddTemplateSpan(&ts, false);
4206 Token::Value next;
4207
4208 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
4209 // and repeat if the following token is a TEMPLATE_SPAN as well (in this
4210 // case, representing a TemplateMiddle).
4211
4212 do {
4213 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
4214 next = peek();
4215 if (next == Token::EOS) {
4216 impl()->ReportMessageAt(Scanner::Location(start, peek_position()),
4217 MessageTemplate::kUnterminatedTemplate);
4218 *ok = false;
4219 return impl()->EmptyExpression();
4220 } else if (next == Token::ILLEGAL) {
4221 impl()->ReportMessageAt(
4222 Scanner::Location(position() + 1, peek_position()),
4223 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
4224 *ok = false;
4225 return impl()->EmptyExpression();
4226 }
4227
4228 int expr_pos = peek_position();
4229 ExpressionT expression = ParseExpressionCoverGrammar(true, CHECK_OK);
4230 impl()->RewriteNonPattern(CHECK_OK);
4231 impl()->AddTemplateExpression(&ts, expression);
4232
4233 if (peek() != Token::RBRACE) {
4234 impl()->ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
4235 MessageTemplate::kUnterminatedTemplateExpr);
4236 *ok = false;
4237 return impl()->EmptyExpression();
4238 }
4239
4240 // If we didn't die parsing that expression, our next token should be a
4241 // TEMPLATE_SPAN or TEMPLATE_TAIL.
4242 next = scanner()->ScanTemplateContinuation();
4243 Next();
4244 pos = position();
4245
4246 if (next == Token::EOS) {
4247 impl()->ReportMessageAt(Scanner::Location(start, pos),
4248 MessageTemplate::kUnterminatedTemplate);
4249 *ok = false;
4250 return impl()->EmptyExpression();
4251 } else if (next == Token::ILLEGAL) {
4252 impl()->ReportMessageAt(
4253 Scanner::Location(position() + 1, peek_position()),
4254 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
4255 *ok = false;
4256 return impl()->EmptyExpression();
4257 }
4258
4259 impl()->AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL);
4260 } while (next == Token::TEMPLATE_SPAN);
4261
4262 DCHECK_EQ(next, Token::TEMPLATE_TAIL);
4263 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
4264 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
4265 return impl()->CloseTemplateLiteral(&ts, start, tag);
4266 }
4267
4268 template <typename Impl>
4269 typename ParserBase<Impl>::ExpressionT
CheckAndRewriteReferenceExpression(ExpressionT expression,int beg_pos,int end_pos,MessageTemplate::Template message,bool * ok)4270 ParserBase<Impl>::CheckAndRewriteReferenceExpression(
4271 ExpressionT expression, int beg_pos, int end_pos,
4272 MessageTemplate::Template message, bool* ok) {
4273 return CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
4274 message, kReferenceError, ok);
4275 }
4276
4277 template <typename Impl>
4278 typename ParserBase<Impl>::ExpressionT
CheckAndRewriteReferenceExpression(ExpressionT expression,int beg_pos,int end_pos,MessageTemplate::Template message,ParseErrorType type,bool * ok)4279 ParserBase<Impl>::CheckAndRewriteReferenceExpression(
4280 ExpressionT expression, int beg_pos, int end_pos,
4281 MessageTemplate::Template message, ParseErrorType type, bool* ok) {
4282 if (impl()->IsIdentifier(expression) && is_strict(language_mode()) &&
4283 impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) {
4284 ReportMessageAt(Scanner::Location(beg_pos, end_pos),
4285 MessageTemplate::kStrictEvalArguments, kSyntaxError);
4286 *ok = false;
4287 return impl()->EmptyExpression();
4288 }
4289 if (expression->IsValidReferenceExpression()) {
4290 return expression;
4291 }
4292 if (expression->IsCall()) {
4293 // If it is a call, make it a runtime error for legacy web compatibility.
4294 // Rewrite `expr' to `expr[throw ReferenceError]'.
4295 ExpressionT error = impl()->NewThrowReferenceError(message, beg_pos);
4296 return factory()->NewProperty(expression, error, beg_pos);
4297 }
4298 ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type);
4299 *ok = false;
4300 return impl()->EmptyExpression();
4301 }
4302
4303 template <typename Impl>
IsValidReferenceExpression(ExpressionT expression)4304 bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) {
4305 return IsAssignableIdentifier(expression) || expression->IsProperty();
4306 }
4307
4308 template <typename Impl>
CheckDestructuringElement(ExpressionT expression,int begin,int end)4309 void ParserBase<Impl>::CheckDestructuringElement(ExpressionT expression,
4310 int begin, int end) {
4311 if (!IsValidPattern(expression) && !expression->IsAssignment() &&
4312 !IsValidReferenceExpression(expression)) {
4313 classifier()->RecordAssignmentPatternError(
4314 Scanner::Location(begin, end),
4315 MessageTemplate::kInvalidDestructuringTarget);
4316 }
4317 }
4318
4319 template <typename Impl>
ParseV8Intrinsic(bool * ok)4320 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseV8Intrinsic(
4321 bool* ok) {
4322 // CallRuntime ::
4323 // '%' Identifier Arguments
4324
4325 int pos = peek_position();
4326 Expect(Token::MOD, CHECK_OK);
4327 // Allow "eval" or "arguments" for backward compatibility.
4328 IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
4329 Scanner::Location spread_pos;
4330 ExpressionClassifier classifier(this);
4331 ExpressionListT args = ParseArguments(&spread_pos, CHECK_OK);
4332
4333 DCHECK(!spread_pos.IsValid());
4334
4335 return impl()->NewV8Intrinsic(name, args, pos, ok);
4336 }
4337
4338 template <typename Impl>
ParseDoExpression(bool * ok)4339 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseDoExpression(
4340 bool* ok) {
4341 // AssignmentExpression ::
4342 // do '{' StatementList '}'
4343
4344 int pos = peek_position();
4345 Expect(Token::DO, CHECK_OK);
4346 BlockT block = ParseBlock(nullptr, CHECK_OK);
4347 return impl()->RewriteDoExpression(block, pos, ok);
4348 }
4349
4350 // Redefinition of CHECK_OK for parsing statements.
4351 #undef CHECK_OK
4352 #define CHECK_OK CHECK_OK_CUSTOM(NullStatement)
4353
4354 template <typename Impl>
4355 typename ParserBase<Impl>::LazyParsingResult
ParseStatementList(StatementListT body,int end_token,bool may_abort,bool * ok)4356 ParserBase<Impl>::ParseStatementList(StatementListT body, int end_token,
4357 bool may_abort, bool* ok) {
4358 // StatementList ::
4359 // (StatementListItem)* <end_token>
4360
4361 // Allocate a target stack to use for this set of source
4362 // elements. This way, all scripts and functions get their own
4363 // target stack thus avoiding illegal breaks and continues across
4364 // functions.
4365 typename Types::TargetScope target_scope(this);
4366 int count_statements = 0;
4367
4368 DCHECK(!impl()->IsNullStatementList(body));
4369 bool directive_prologue = true; // Parsing directive prologue.
4370
4371 while (peek() != end_token) {
4372 if (directive_prologue && peek() != Token::STRING) {
4373 directive_prologue = false;
4374 }
4375
4376 bool starts_with_identifier = peek() == Token::IDENTIFIER;
4377 Scanner::Location token_loc = scanner()->peek_location();
4378 StatementT stat =
4379 ParseStatementListItem(CHECK_OK_CUSTOM(Return, kLazyParsingComplete));
4380
4381 if (impl()->IsNullStatement(stat) || impl()->IsEmptyStatement(stat)) {
4382 directive_prologue = false; // End of directive prologue.
4383 continue;
4384 }
4385
4386 if (directive_prologue) {
4387 // The length of the token is used to distinguish between strings literals
4388 // that evaluate equal to directives but contain either escape sequences
4389 // (e.g., "use \x73trict") or line continuations (e.g., "use \(newline)
4390 // strict").
4391 if (impl()->IsUseStrictDirective(stat) &&
4392 token_loc.end_pos - token_loc.beg_pos == sizeof("use strict") + 1) {
4393 // Directive "use strict" (ES5 14.1).
4394 RaiseLanguageMode(STRICT);
4395 if (!scope()->HasSimpleParameters()) {
4396 // TC39 deemed "use strict" directives to be an error when occurring
4397 // in the body of a function with non-simple parameter list, on
4398 // 29/7/2015. https://goo.gl/ueA7Ln
4399 impl()->ReportMessageAt(
4400 token_loc, MessageTemplate::kIllegalLanguageModeDirective,
4401 "use strict");
4402 *ok = false;
4403 return kLazyParsingComplete;
4404 }
4405 } else if (impl()->IsUseAsmDirective(stat) &&
4406 token_loc.end_pos - token_loc.beg_pos ==
4407 sizeof("use asm") + 1) {
4408 // Directive "use asm".
4409 impl()->SetAsmModule();
4410 } else if (impl()->IsStringLiteral(stat)) {
4411 // Possibly an unknown directive.
4412 // Should not change mode, but will increment usage counters
4413 // as appropriate. Ditto usages below.
4414 RaiseLanguageMode(SLOPPY);
4415 } else {
4416 // End of the directive prologue.
4417 directive_prologue = false;
4418 RaiseLanguageMode(SLOPPY);
4419 }
4420 } else {
4421 RaiseLanguageMode(SLOPPY);
4422 }
4423
4424 // If we're allowed to abort, we will do so when we see a "long and
4425 // trivial" function. Our current definition of "long and trivial" is:
4426 // - over kLazyParseTrialLimit statements
4427 // - all starting with an identifier (i.e., no if, for, while, etc.)
4428 if (may_abort) {
4429 if (!starts_with_identifier) {
4430 may_abort = false;
4431 } else if (++count_statements > kLazyParseTrialLimit) {
4432 return kLazyParsingAborted;
4433 }
4434 }
4435
4436 body->Add(stat, zone());
4437 }
4438 return kLazyParsingComplete;
4439 }
4440
4441 template <typename Impl>
ParseStatementListItem(bool * ok)4442 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatementListItem(
4443 bool* ok) {
4444 // ECMA 262 6th Edition
4445 // StatementListItem[Yield, Return] :
4446 // Statement[?Yield, ?Return]
4447 // Declaration[?Yield]
4448 //
4449 // Declaration[Yield] :
4450 // HoistableDeclaration[?Yield]
4451 // ClassDeclaration[?Yield]
4452 // LexicalDeclaration[In, ?Yield]
4453 //
4454 // HoistableDeclaration[Yield, Default] :
4455 // FunctionDeclaration[?Yield, ?Default]
4456 // GeneratorDeclaration[?Yield, ?Default]
4457 //
4458 // LexicalDeclaration[In, Yield] :
4459 // LetOrConst BindingList[?In, ?Yield] ;
4460
4461 switch (peek()) {
4462 case Token::FUNCTION:
4463 return ParseHoistableDeclaration(nullptr, false, ok);
4464 case Token::CLASS:
4465 Consume(Token::CLASS);
4466 return ParseClassDeclaration(nullptr, false, ok);
4467 case Token::VAR:
4468 case Token::CONST:
4469 return ParseVariableStatement(kStatementListItem, nullptr, ok);
4470 case Token::LET:
4471 if (IsNextLetKeyword()) {
4472 return ParseVariableStatement(kStatementListItem, nullptr, ok);
4473 }
4474 break;
4475 case Token::ASYNC:
4476 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
4477 !scanner()->HasAnyLineTerminatorAfterNext()) {
4478 Consume(Token::ASYNC);
4479 return ParseAsyncFunctionDeclaration(nullptr, false, ok);
4480 }
4481 /* falls through */
4482 default:
4483 break;
4484 }
4485 return ParseStatement(nullptr, kAllowLabelledFunctionStatement, ok);
4486 }
4487
4488 template <typename Impl>
ParseStatement(ZoneList<const AstRawString * > * labels,AllowLabelledFunctionStatement allow_function,bool * ok)4489 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement(
4490 ZoneList<const AstRawString*>* labels,
4491 AllowLabelledFunctionStatement allow_function, bool* ok) {
4492 // Statement ::
4493 // Block
4494 // VariableStatement
4495 // EmptyStatement
4496 // ExpressionStatement
4497 // IfStatement
4498 // IterationStatement
4499 // ContinueStatement
4500 // BreakStatement
4501 // ReturnStatement
4502 // WithStatement
4503 // LabelledStatement
4504 // SwitchStatement
4505 // ThrowStatement
4506 // TryStatement
4507 // DebuggerStatement
4508
4509 // Note: Since labels can only be used by 'break' and 'continue'
4510 // statements, which themselves are only valid within blocks,
4511 // iterations or 'switch' statements (i.e., BreakableStatements),
4512 // labels can be simply ignored in all other cases; except for
4513 // trivial labeled break statements 'label: break label' which is
4514 // parsed into an empty statement.
4515 switch (peek()) {
4516 case Token::LBRACE:
4517 return ParseBlock(labels, ok);
4518 case Token::SEMICOLON:
4519 Next();
4520 return factory()->NewEmptyStatement(kNoSourcePosition);
4521 case Token::IF:
4522 return ParseIfStatement(labels, ok);
4523 case Token::DO:
4524 return ParseDoWhileStatement(labels, ok);
4525 case Token::WHILE:
4526 return ParseWhileStatement(labels, ok);
4527 case Token::FOR:
4528 return ParseForStatement(labels, ok);
4529 case Token::CONTINUE:
4530 case Token::BREAK:
4531 case Token::RETURN:
4532 case Token::THROW:
4533 case Token::TRY: {
4534 // These statements must have their labels preserved in an enclosing
4535 // block, as the corresponding AST nodes do not currently store their
4536 // labels.
4537 // TODO(nikolaos, marja): Consider adding the labels to the AST nodes.
4538 if (labels == nullptr) {
4539 return ParseStatementAsUnlabelled(labels, ok);
4540 } else {
4541 BlockT result =
4542 factory()->NewBlock(labels, 1, false, kNoSourcePosition);
4543 typename Types::Target target(this, result);
4544 StatementT statement = ParseStatementAsUnlabelled(labels, CHECK_OK);
4545 result->statements()->Add(statement, zone());
4546 return result;
4547 }
4548 }
4549 case Token::WITH:
4550 return ParseWithStatement(labels, ok);
4551 case Token::SWITCH:
4552 return ParseSwitchStatement(labels, ok);
4553 case Token::FUNCTION:
4554 // FunctionDeclaration only allowed as a StatementListItem, not in
4555 // an arbitrary Statement position. Exceptions such as
4556 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
4557 // are handled by calling ParseScopedStatement rather than
4558 // ParseStatement directly.
4559 impl()->ReportMessageAt(scanner()->peek_location(),
4560 is_strict(language_mode())
4561 ? MessageTemplate::kStrictFunction
4562 : MessageTemplate::kSloppyFunction);
4563 *ok = false;
4564 return impl()->NullStatement();
4565 case Token::DEBUGGER:
4566 return ParseDebuggerStatement(ok);
4567 case Token::VAR:
4568 return ParseVariableStatement(kStatement, nullptr, ok);
4569 default:
4570 return ParseExpressionOrLabelledStatement(labels, allow_function, ok);
4571 }
4572 }
4573
4574 // This method parses a subset of statements (break, continue, return, throw,
4575 // try) which are to be grouped because they all require their labeles to be
4576 // preserved in an enclosing block.
4577 template <typename Impl>
4578 typename ParserBase<Impl>::StatementT
ParseStatementAsUnlabelled(ZoneList<const AstRawString * > * labels,bool * ok)4579 ParserBase<Impl>::ParseStatementAsUnlabelled(
4580 ZoneList<const AstRawString*>* labels, bool* ok) {
4581 switch (peek()) {
4582 case Token::CONTINUE:
4583 return ParseContinueStatement(ok);
4584 case Token::BREAK:
4585 return ParseBreakStatement(labels, ok);
4586 case Token::RETURN:
4587 return ParseReturnStatement(ok);
4588 case Token::THROW:
4589 return ParseThrowStatement(ok);
4590 case Token::TRY:
4591 return ParseTryStatement(ok);
4592 default:
4593 UNREACHABLE();
4594 return impl()->NullStatement();
4595 }
4596 }
4597
4598 template <typename Impl>
ParseBlock(ZoneList<const AstRawString * > * labels,bool * ok)4599 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock(
4600 ZoneList<const AstRawString*>* labels, bool* ok) {
4601 // Block ::
4602 // '{' StatementList '}'
4603
4604 // Construct block expecting 16 statements.
4605 BlockT body = factory()->NewBlock(labels, 16, false, kNoSourcePosition);
4606
4607 // Parse the statements and collect escaping labels.
4608 Expect(Token::LBRACE, CHECK_OK_CUSTOM(NullBlock));
4609 {
4610 BlockState block_state(zone(), &scope_state_);
4611 block_state.set_start_position(scanner()->location().beg_pos);
4612 typename Types::Target target(this, body);
4613
4614 while (peek() != Token::RBRACE) {
4615 StatementT stat = ParseStatementListItem(CHECK_OK_CUSTOM(NullBlock));
4616 if (!impl()->IsNullStatement(stat) && !impl()->IsEmptyStatement(stat)) {
4617 body->statements()->Add(stat, zone());
4618 }
4619 }
4620
4621 Expect(Token::RBRACE, CHECK_OK_CUSTOM(NullBlock));
4622 block_state.set_end_position(scanner()->location().end_pos);
4623 body->set_scope(block_state.FinalizedBlockScope());
4624 }
4625 return body;
4626 }
4627
4628 template <typename Impl>
ParseScopedStatement(ZoneList<const AstRawString * > * labels,bool legacy,bool * ok)4629 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseScopedStatement(
4630 ZoneList<const AstRawString*>* labels, bool legacy, bool* ok) {
4631 if (is_strict(language_mode()) || peek() != Token::FUNCTION || legacy) {
4632 return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok);
4633 } else {
4634 if (legacy) {
4635 impl()->CountUsage(v8::Isolate::kLegacyFunctionDeclaration);
4636 }
4637 // Make a block around the statement for a lexical binding
4638 // is introduced by a FunctionDeclaration.
4639 BlockState block_state(zone(), &scope_state_);
4640 block_state.set_start_position(scanner()->location().beg_pos);
4641 BlockT block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition);
4642 StatementT body = ParseFunctionDeclaration(CHECK_OK);
4643 block->statements()->Add(body, zone());
4644 block_state.set_end_position(scanner()->location().end_pos);
4645 block->set_scope(block_state.FinalizedBlockScope());
4646 return block;
4647 }
4648 }
4649
4650 template <typename Impl>
ParseVariableStatement(VariableDeclarationContext var_context,ZoneList<const AstRawString * > * names,bool * ok)4651 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseVariableStatement(
4652 VariableDeclarationContext var_context,
4653 ZoneList<const AstRawString*>* names, bool* ok) {
4654 // VariableStatement ::
4655 // VariableDeclarations ';'
4656
4657 // The scope of a var declared variable anywhere inside a function
4658 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
4659 // transform a source-level var declaration into a (Function) Scope
4660 // declaration, and rewrite the source-level initialization into an assignment
4661 // statement. We use a block to collect multiple assignments.
4662 //
4663 // We mark the block as initializer block because we don't want the
4664 // rewriter to add a '.result' assignment to such a block (to get compliant
4665 // behavior for code such as print(eval('var x = 7')), and for cosmetic
4666 // reasons when pretty-printing. Also, unless an assignment (initialization)
4667 // is inside an initializer block, it is ignored.
4668
4669 DeclarationParsingResult parsing_result;
4670 StatementT result =
4671 ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK);
4672 ExpectSemicolon(CHECK_OK);
4673 return result;
4674 }
4675
4676 template <typename Impl>
ParseDebuggerStatement(bool * ok)4677 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseDebuggerStatement(
4678 bool* ok) {
4679 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
4680 // contexts this is used as a statement which invokes the debugger as i a
4681 // break point is present.
4682 // DebuggerStatement ::
4683 // 'debugger' ';'
4684
4685 int pos = peek_position();
4686 Expect(Token::DEBUGGER, CHECK_OK);
4687 ExpectSemicolon(CHECK_OK);
4688 return factory()->NewDebuggerStatement(pos);
4689 }
4690
4691 template <typename Impl>
4692 typename ParserBase<Impl>::StatementT
ParseExpressionOrLabelledStatement(ZoneList<const AstRawString * > * labels,AllowLabelledFunctionStatement allow_function,bool * ok)4693 ParserBase<Impl>::ParseExpressionOrLabelledStatement(
4694 ZoneList<const AstRawString*>* labels,
4695 AllowLabelledFunctionStatement allow_function, bool* ok) {
4696 // ExpressionStatement | LabelledStatement ::
4697 // Expression ';'
4698 // Identifier ':' Statement
4699 //
4700 // ExpressionStatement[Yield] :
4701 // [lookahead notin {{, function, class, let [}] Expression[In, ?Yield] ;
4702
4703 int pos = peek_position();
4704
4705 switch (peek()) {
4706 case Token::FUNCTION:
4707 case Token::LBRACE:
4708 UNREACHABLE(); // Always handled by the callers.
4709 case Token::CLASS:
4710 ReportUnexpectedToken(Next());
4711 *ok = false;
4712 return impl()->NullStatement();
4713 default:
4714 break;
4715 }
4716
4717 bool starts_with_identifier = peek_any_identifier();
4718 ExpressionT expr = ParseExpression(true, CHECK_OK);
4719 if (peek() == Token::COLON && starts_with_identifier &&
4720 impl()->IsIdentifier(expr)) {
4721 // The whole expression was a single identifier, and not, e.g.,
4722 // something starting with an identifier or a parenthesized identifier.
4723 labels = impl()->DeclareLabel(labels, impl()->AsIdentifierExpression(expr),
4724 CHECK_OK);
4725 Consume(Token::COLON);
4726 // ES#sec-labelled-function-declarations Labelled Function Declarations
4727 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) {
4728 if (allow_function == kAllowLabelledFunctionStatement) {
4729 return ParseFunctionDeclaration(ok);
4730 } else {
4731 return ParseScopedStatement(labels, true, ok);
4732 }
4733 }
4734 return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok);
4735 }
4736
4737 // If we have an extension, we allow a native function declaration.
4738 // A native function declaration starts with "native function" with
4739 // no line-terminator between the two words.
4740 if (extension_ != nullptr && peek() == Token::FUNCTION &&
4741 !scanner()->HasAnyLineTerminatorBeforeNext() && impl()->IsNative(expr) &&
4742 !scanner()->literal_contains_escapes()) {
4743 return ParseNativeDeclaration(ok);
4744 }
4745
4746 // Parsed expression statement, followed by semicolon.
4747 ExpectSemicolon(CHECK_OK);
4748 return factory()->NewExpressionStatement(expr, pos);
4749 }
4750
4751 template <typename Impl>
ParseIfStatement(ZoneList<const AstRawString * > * labels,bool * ok)4752 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseIfStatement(
4753 ZoneList<const AstRawString*>* labels, bool* ok) {
4754 // IfStatement ::
4755 // 'if' '(' Expression ')' Statement ('else' Statement)?
4756
4757 int pos = peek_position();
4758 Expect(Token::IF, CHECK_OK);
4759 Expect(Token::LPAREN, CHECK_OK);
4760 ExpressionT condition = ParseExpression(true, CHECK_OK);
4761 Expect(Token::RPAREN, CHECK_OK);
4762 StatementT then_statement = ParseScopedStatement(labels, false, CHECK_OK);
4763 StatementT else_statement = impl()->NullStatement();
4764 if (Check(Token::ELSE)) {
4765 else_statement = ParseScopedStatement(labels, false, CHECK_OK);
4766 } else {
4767 else_statement = factory()->NewEmptyStatement(kNoSourcePosition);
4768 }
4769 return factory()->NewIfStatement(condition, then_statement, else_statement,
4770 pos);
4771 }
4772
4773 template <typename Impl>
ParseContinueStatement(bool * ok)4774 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseContinueStatement(
4775 bool* ok) {
4776 // ContinueStatement ::
4777 // 'continue' Identifier? ';'
4778
4779 int pos = peek_position();
4780 Expect(Token::CONTINUE, CHECK_OK);
4781 IdentifierT label = impl()->EmptyIdentifier();
4782 Token::Value tok = peek();
4783 if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON &&
4784 tok != Token::RBRACE && tok != Token::EOS) {
4785 // ECMA allows "eval" or "arguments" as labels even in strict mode.
4786 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
4787 }
4788 typename Types::IterationStatement target =
4789 impl()->LookupContinueTarget(label, CHECK_OK);
4790 if (impl()->IsNullStatement(target)) {
4791 // Illegal continue statement.
4792 MessageTemplate::Template message = MessageTemplate::kIllegalContinue;
4793 if (!impl()->IsEmptyIdentifier(label)) {
4794 message = MessageTemplate::kUnknownLabel;
4795 }
4796 ReportMessage(message, label);
4797 *ok = false;
4798 return impl()->NullStatement();
4799 }
4800 ExpectSemicolon(CHECK_OK);
4801 return factory()->NewContinueStatement(target, pos);
4802 }
4803
4804 template <typename Impl>
ParseBreakStatement(ZoneList<const AstRawString * > * labels,bool * ok)4805 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseBreakStatement(
4806 ZoneList<const AstRawString*>* labels, bool* ok) {
4807 // BreakStatement ::
4808 // 'break' Identifier? ';'
4809
4810 int pos = peek_position();
4811 Expect(Token::BREAK, CHECK_OK);
4812 IdentifierT label = impl()->EmptyIdentifier();
4813 Token::Value tok = peek();
4814 if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON &&
4815 tok != Token::RBRACE && tok != Token::EOS) {
4816 // ECMA allows "eval" or "arguments" as labels even in strict mode.
4817 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
4818 }
4819 // Parse labeled break statements that target themselves into
4820 // empty statements, e.g. 'l1: l2: l3: break l2;'
4821 if (!impl()->IsEmptyIdentifier(label) &&
4822 impl()->ContainsLabel(labels, label)) {
4823 ExpectSemicolon(CHECK_OK);
4824 return factory()->NewEmptyStatement(pos);
4825 }
4826 typename Types::BreakableStatement target =
4827 impl()->LookupBreakTarget(label, CHECK_OK);
4828 if (impl()->IsNullStatement(target)) {
4829 // Illegal break statement.
4830 MessageTemplate::Template message = MessageTemplate::kIllegalBreak;
4831 if (!impl()->IsEmptyIdentifier(label)) {
4832 message = MessageTemplate::kUnknownLabel;
4833 }
4834 ReportMessage(message, label);
4835 *ok = false;
4836 return impl()->NullStatement();
4837 }
4838 ExpectSemicolon(CHECK_OK);
4839 return factory()->NewBreakStatement(target, pos);
4840 }
4841
4842 template <typename Impl>
ParseReturnStatement(bool * ok)4843 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseReturnStatement(
4844 bool* ok) {
4845 // ReturnStatement ::
4846 // 'return' [no line terminator] Expression? ';'
4847
4848 // Consume the return token. It is necessary to do that before
4849 // reporting any errors on it, because of the way errors are
4850 // reported (underlining).
4851 Expect(Token::RETURN, CHECK_OK);
4852 Scanner::Location loc = scanner()->location();
4853
4854 switch (GetDeclarationScope()->scope_type()) {
4855 case SCRIPT_SCOPE:
4856 case EVAL_SCOPE:
4857 case MODULE_SCOPE:
4858 impl()->ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
4859 *ok = false;
4860 return impl()->NullStatement();
4861 default:
4862 break;
4863 }
4864
4865 Token::Value tok = peek();
4866 ExpressionT return_value = impl()->EmptyExpression();
4867 if (scanner()->HasAnyLineTerminatorBeforeNext() || tok == Token::SEMICOLON ||
4868 tok == Token::RBRACE || tok == Token::EOS) {
4869 if (IsSubclassConstructor(function_state_->kind())) {
4870 return_value = impl()->ThisExpression(loc.beg_pos);
4871 } else {
4872 return_value = impl()->GetLiteralUndefined(position());
4873 }
4874 } else {
4875 if (IsSubclassConstructor(function_state_->kind())) {
4876 // Because of the return code rewriting that happens in case of a subclass
4877 // constructor we don't want to accept tail calls, therefore we don't set
4878 // ReturnExprScope to kInsideValidReturnStatement here.
4879 return_value = ParseExpression(true, CHECK_OK);
4880 } else {
4881 ReturnExprScope maybe_allow_tail_calls(
4882 function_state_, ReturnExprContext::kInsideValidReturnStatement);
4883 return_value = ParseExpression(true, CHECK_OK);
4884
4885 if (allow_tailcalls() && !is_sloppy(language_mode()) && !is_resumable()) {
4886 // ES6 14.6.1 Static Semantics: IsInTailPosition
4887 function_state_->AddImplicitTailCallExpression(return_value);
4888 }
4889 }
4890 }
4891 ExpectSemicolon(CHECK_OK);
4892 return_value = impl()->RewriteReturn(return_value, loc.beg_pos);
4893 return factory()->NewReturnStatement(return_value, loc.beg_pos);
4894 }
4895
4896 template <typename Impl>
ParseWithStatement(ZoneList<const AstRawString * > * labels,bool * ok)4897 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWithStatement(
4898 ZoneList<const AstRawString*>* labels, bool* ok) {
4899 // WithStatement ::
4900 // 'with' '(' Expression ')' Statement
4901
4902 Expect(Token::WITH, CHECK_OK);
4903 int pos = position();
4904
4905 if (is_strict(language_mode())) {
4906 ReportMessage(MessageTemplate::kStrictWith);
4907 *ok = false;
4908 return impl()->NullStatement();
4909 }
4910
4911 Expect(Token::LPAREN, CHECK_OK);
4912 ExpressionT expr = ParseExpression(true, CHECK_OK);
4913 Expect(Token::RPAREN, CHECK_OK);
4914
4915 Scope* with_scope = NewScope(WITH_SCOPE);
4916 StatementT body = impl()->NullStatement();
4917 {
4918 BlockState block_state(&scope_state_, with_scope);
4919 with_scope->set_start_position(scanner()->peek_location().beg_pos);
4920 body = ParseScopedStatement(labels, true, CHECK_OK);
4921 with_scope->set_end_position(scanner()->location().end_pos);
4922 }
4923 return factory()->NewWithStatement(with_scope, expr, body, pos);
4924 }
4925
4926 template <typename Impl>
ParseDoWhileStatement(ZoneList<const AstRawString * > * labels,bool * ok)4927 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseDoWhileStatement(
4928 ZoneList<const AstRawString*>* labels, bool* ok) {
4929 // DoStatement ::
4930 // 'do' Statement 'while' '(' Expression ')' ';'
4931
4932 auto loop = factory()->NewDoWhileStatement(labels, peek_position());
4933 typename Types::Target target(this, loop);
4934
4935 Expect(Token::DO, CHECK_OK);
4936 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK);
4937 Expect(Token::WHILE, CHECK_OK);
4938 Expect(Token::LPAREN, CHECK_OK);
4939
4940 ExpressionT cond = ParseExpression(true, CHECK_OK);
4941 Expect(Token::RPAREN, CHECK_OK);
4942
4943 // Allow do-statements to be terminated with and without
4944 // semi-colons. This allows code such as 'do;while(0)return' to
4945 // parse, which would not be the case if we had used the
4946 // ExpectSemicolon() functionality here.
4947 Check(Token::SEMICOLON);
4948
4949 loop->Initialize(cond, body);
4950 return loop;
4951 }
4952
4953 template <typename Impl>
ParseWhileStatement(ZoneList<const AstRawString * > * labels,bool * ok)4954 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWhileStatement(
4955 ZoneList<const AstRawString*>* labels, bool* ok) {
4956 // WhileStatement ::
4957 // 'while' '(' Expression ')' Statement
4958
4959 auto loop = factory()->NewWhileStatement(labels, peek_position());
4960 typename Types::Target target(this, loop);
4961
4962 Expect(Token::WHILE, CHECK_OK);
4963 Expect(Token::LPAREN, CHECK_OK);
4964 ExpressionT cond = ParseExpression(true, CHECK_OK);
4965 Expect(Token::RPAREN, CHECK_OK);
4966 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK);
4967
4968 loop->Initialize(cond, body);
4969 return loop;
4970 }
4971
4972 template <typename Impl>
ParseThrowStatement(bool * ok)4973 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseThrowStatement(
4974 bool* ok) {
4975 // ThrowStatement ::
4976 // 'throw' Expression ';'
4977
4978 Expect(Token::THROW, CHECK_OK);
4979 int pos = position();
4980 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
4981 ReportMessage(MessageTemplate::kNewlineAfterThrow);
4982 *ok = false;
4983 return impl()->NullStatement();
4984 }
4985 ExpressionT exception = ParseExpression(true, CHECK_OK);
4986 ExpectSemicolon(CHECK_OK);
4987
4988 return impl()->NewThrowStatement(exception, pos);
4989 }
4990
4991 template <typename Impl>
ParseSwitchStatement(ZoneList<const AstRawString * > * labels,bool * ok)4992 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseSwitchStatement(
4993 ZoneList<const AstRawString*>* labels, bool* ok) {
4994 // SwitchStatement ::
4995 // 'switch' '(' Expression ')' '{' CaseClause* '}'
4996 // CaseClause ::
4997 // 'case' Expression ':' StatementList
4998 // 'default' ':' StatementList
4999
5000 int switch_pos = peek_position();
5001
5002 Expect(Token::SWITCH, CHECK_OK);
5003 Expect(Token::LPAREN, CHECK_OK);
5004 ExpressionT tag = ParseExpression(true, CHECK_OK);
5005 Expect(Token::RPAREN, CHECK_OK);
5006
5007 auto switch_statement = factory()->NewSwitchStatement(labels, switch_pos);
5008
5009 {
5010 BlockState cases_block_state(zone(), &scope_state_);
5011 cases_block_state.set_start_position(scanner()->location().beg_pos);
5012 cases_block_state.SetNonlinear();
5013 typename Types::Target target(this, switch_statement);
5014
5015 bool default_seen = false;
5016 auto cases = impl()->NewCaseClauseList(4);
5017 Expect(Token::LBRACE, CHECK_OK);
5018 while (peek() != Token::RBRACE) {
5019 // An empty label indicates the default case.
5020 ExpressionT label = impl()->EmptyExpression();
5021 if (Check(Token::CASE)) {
5022 label = ParseExpression(true, CHECK_OK);
5023 } else {
5024 Expect(Token::DEFAULT, CHECK_OK);
5025 if (default_seen) {
5026 ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
5027 *ok = false;
5028 return impl()->NullStatement();
5029 }
5030 default_seen = true;
5031 }
5032 Expect(Token::COLON, CHECK_OK);
5033 int clause_pos = position();
5034 StatementListT statements = impl()->NewStatementList(5);
5035 while (peek() != Token::CASE && peek() != Token::DEFAULT &&
5036 peek() != Token::RBRACE) {
5037 StatementT stat = ParseStatementListItem(CHECK_OK);
5038 statements->Add(stat, zone());
5039 }
5040 auto clause = factory()->NewCaseClause(label, statements, clause_pos);
5041 cases->Add(clause, zone());
5042 }
5043 Expect(Token::RBRACE, CHECK_OK);
5044
5045 cases_block_state.set_end_position(scanner()->location().end_pos);
5046 return impl()->RewriteSwitchStatement(
5047 tag, switch_statement, cases, cases_block_state.FinalizedBlockScope());
5048 }
5049 }
5050
5051 template <typename Impl>
ParseTryStatement(bool * ok)5052 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseTryStatement(
5053 bool* ok) {
5054 // TryStatement ::
5055 // 'try' Block Catch
5056 // 'try' Block Finally
5057 // 'try' Block Catch Finally
5058 //
5059 // Catch ::
5060 // 'catch' '(' Identifier ')' Block
5061 //
5062 // Finally ::
5063 // 'finally' Block
5064
5065 Expect(Token::TRY, CHECK_OK);
5066 int pos = position();
5067
5068 BlockT try_block = impl()->NullBlock();
5069 {
5070 ReturnExprScope no_tail_calls(function_state_,
5071 ReturnExprContext::kInsideTryBlock);
5072 try_block = ParseBlock(nullptr, CHECK_OK);
5073 }
5074
5075 CatchInfo catch_info(this);
5076 catch_info.for_promise_reject = allow_natives() && Check(Token::MOD);
5077
5078 if (peek() != Token::CATCH && peek() != Token::FINALLY) {
5079 ReportMessage(MessageTemplate::kNoCatchOrFinally);
5080 *ok = false;
5081 return impl()->NullStatement();
5082 }
5083
5084 BlockT catch_block = impl()->NullBlock();
5085 if (Check(Token::CATCH)) {
5086 Expect(Token::LPAREN, CHECK_OK);
5087 catch_info.scope = NewScope(CATCH_SCOPE);
5088 catch_info.scope->set_start_position(scanner()->location().beg_pos);
5089
5090 {
5091 CollectExpressionsInTailPositionToListScope
5092 collect_tail_call_expressions_scope(
5093 function_state_, &catch_info.tail_call_expressions);
5094 BlockState catch_block_state(&scope_state_, catch_info.scope);
5095
5096 catch_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition);
5097
5098 // Create a block scope to hold any lexical declarations created
5099 // as part of destructuring the catch parameter.
5100 {
5101 BlockState catch_variable_block_state(zone(), &scope_state_);
5102 catch_variable_block_state.set_start_position(
5103 scanner()->location().beg_pos);
5104 typename Types::Target target(this, catch_block);
5105
5106 // This does not simply call ParsePrimaryExpression to avoid
5107 // ExpressionFromIdentifier from being called in the first
5108 // branch, which would introduce an unresolved symbol and mess
5109 // with arrow function names.
5110 if (peek_any_identifier()) {
5111 catch_info.name =
5112 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
5113 } else {
5114 ExpressionClassifier pattern_classifier(this);
5115 catch_info.pattern = ParsePrimaryExpression(CHECK_OK);
5116 ValidateBindingPattern(CHECK_OK);
5117 }
5118
5119 Expect(Token::RPAREN, CHECK_OK);
5120 impl()->RewriteCatchPattern(&catch_info, CHECK_OK);
5121 if (!impl()->IsNullStatement(catch_info.init_block)) {
5122 catch_block->statements()->Add(catch_info.init_block, zone());
5123 }
5124
5125 catch_info.inner_block = ParseBlock(nullptr, CHECK_OK);
5126 catch_block->statements()->Add(catch_info.inner_block, zone());
5127 impl()->ValidateCatchBlock(catch_info, CHECK_OK);
5128 catch_variable_block_state.set_end_position(
5129 scanner()->location().end_pos);
5130 catch_block->set_scope(
5131 catch_variable_block_state.FinalizedBlockScope());
5132 }
5133 }
5134
5135 catch_info.scope->set_end_position(scanner()->location().end_pos);
5136 }
5137
5138 BlockT finally_block = impl()->NullBlock();
5139 DCHECK(peek() == Token::FINALLY || !impl()->IsNullStatement(catch_block));
5140 if (Check(Token::FINALLY)) {
5141 finally_block = ParseBlock(nullptr, CHECK_OK);
5142 }
5143
5144 return impl()->RewriteTryStatement(try_block, catch_block, finally_block,
5145 catch_info, pos);
5146 }
5147
5148 template <typename Impl>
ParseForStatement(ZoneList<const AstRawString * > * labels,bool * ok)5149 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
5150 ZoneList<const AstRawString*>* labels, bool* ok) {
5151 int stmt_pos = peek_position();
5152 ForInfo for_info(this);
5153 bool bound_names_are_lexical = false;
5154
5155 // Create an in-between scope for let-bound iteration variables.
5156 BlockState for_state(zone(), &scope_state_);
5157 Expect(Token::FOR, CHECK_OK);
5158 Expect(Token::LPAREN, CHECK_OK);
5159 for_state.set_start_position(scanner()->location().beg_pos);
5160 for_state.set_is_hidden();
5161
5162 StatementT init = impl()->NullStatement();
5163 if (peek() != Token::SEMICOLON) {
5164 // An initializer is present.
5165 if (peek() == Token::VAR || peek() == Token::CONST ||
5166 (peek() == Token::LET && IsNextLetKeyword())) {
5167 // The initializer contains declarations.
5168 ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
5169 nullptr, CHECK_OK);
5170 bound_names_are_lexical =
5171 IsLexicalVariableMode(for_info.parsing_result.descriptor.mode);
5172 for_info.position = scanner()->location().beg_pos;
5173
5174 if (CheckInOrOf(&for_info.mode)) {
5175 // Just one declaration followed by in/of.
5176 if (for_info.parsing_result.declarations.length() != 1) {
5177 impl()->ReportMessageAt(
5178 for_info.parsing_result.bindings_loc,
5179 MessageTemplate::kForInOfLoopMultiBindings,
5180 ForEachStatement::VisitModeString(for_info.mode));
5181 *ok = false;
5182 return impl()->NullStatement();
5183 }
5184 if (for_info.parsing_result.first_initializer_loc.IsValid() &&
5185 (is_strict(language_mode()) ||
5186 for_info.mode == ForEachStatement::ITERATE ||
5187 bound_names_are_lexical ||
5188 !impl()->IsIdentifier(
5189 for_info.parsing_result.declarations[0].pattern))) {
5190 impl()->ReportMessageAt(
5191 for_info.parsing_result.first_initializer_loc,
5192 MessageTemplate::kForInOfLoopInitializer,
5193 ForEachStatement::VisitModeString(for_info.mode));
5194 *ok = false;
5195 return impl()->NullStatement();
5196 }
5197
5198 BlockT init_block = impl()->RewriteForVarInLegacy(for_info);
5199
5200 auto loop =
5201 factory()->NewForEachStatement(for_info.mode, labels, stmt_pos);
5202 typename Types::Target target(this, loop);
5203
5204 int each_keyword_pos = scanner()->location().beg_pos;
5205
5206 ExpressionT enumerable = impl()->EmptyExpression();
5207 if (for_info.mode == ForEachStatement::ITERATE) {
5208 ExpressionClassifier classifier(this);
5209 enumerable = ParseAssignmentExpression(true, CHECK_OK);
5210 impl()->RewriteNonPattern(CHECK_OK);
5211 } else {
5212 enumerable = ParseExpression(true, CHECK_OK);
5213 }
5214
5215 Expect(Token::RPAREN, CHECK_OK);
5216
5217 StatementT final_loop = impl()->NullStatement();
5218 {
5219 ReturnExprScope no_tail_calls(function_state_,
5220 ReturnExprContext::kInsideForInOfBody);
5221 BlockState block_state(zone(), &scope_state_);
5222 block_state.set_start_position(scanner()->location().beg_pos);
5223
5224 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK);
5225
5226 BlockT body_block = impl()->NullBlock();
5227 ExpressionT each_variable = impl()->EmptyExpression();
5228 impl()->DesugarBindingInForEachStatement(&for_info, &body_block,
5229 &each_variable, CHECK_OK);
5230 body_block->statements()->Add(body, zone());
5231 final_loop = impl()->InitializeForEachStatement(
5232 loop, each_variable, enumerable, body_block, each_keyword_pos);
5233
5234 block_state.set_end_position(scanner()->location().end_pos);
5235 body_block->set_scope(block_state.FinalizedBlockScope());
5236 }
5237
5238 init_block =
5239 impl()->CreateForEachStatementTDZ(init_block, for_info, ok);
5240
5241 for_state.set_end_position(scanner()->location().end_pos);
5242 Scope* for_scope = for_state.FinalizedBlockScope();
5243 // Parsed for-in loop w/ variable declarations.
5244 if (!impl()->IsNullStatement(init_block)) {
5245 init_block->statements()->Add(final_loop, zone());
5246 init_block->set_scope(for_scope);
5247 return init_block;
5248 } else {
5249 DCHECK_NULL(for_scope);
5250 return final_loop;
5251 }
5252 } else {
5253 // One or more declaration not followed by in/of.
5254 init = impl()->BuildInitializationBlock(
5255 &for_info.parsing_result,
5256 bound_names_are_lexical ? &for_info.bound_names : nullptr,
5257 CHECK_OK);
5258 }
5259 } else {
5260 // The initializer does not contain declarations.
5261 int lhs_beg_pos = peek_position();
5262 ExpressionClassifier classifier(this);
5263 ExpressionT expression = ParseExpressionCoverGrammar(false, CHECK_OK);
5264 int lhs_end_pos = scanner()->location().end_pos;
5265
5266 bool is_for_each = CheckInOrOf(&for_info.mode);
5267 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() ||
5268 expression->IsObjectLiteral());
5269
5270 if (is_destructuring) {
5271 ValidateAssignmentPattern(CHECK_OK);
5272 } else {
5273 impl()->RewriteNonPattern(CHECK_OK);
5274 }
5275
5276 if (is_for_each) {
5277 // Initializer is reference followed by in/of.
5278 if (!is_destructuring) {
5279 expression = impl()->CheckAndRewriteReferenceExpression(
5280 expression, lhs_beg_pos, lhs_end_pos,
5281 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
5282 }
5283
5284 auto loop =
5285 factory()->NewForEachStatement(for_info.mode, labels, stmt_pos);
5286 typename Types::Target target(this, loop);
5287
5288 int each_keyword_pos = scanner()->location().beg_pos;
5289
5290 ExpressionT enumerable = impl()->EmptyExpression();
5291 if (for_info.mode == ForEachStatement::ITERATE) {
5292 ExpressionClassifier classifier(this);
5293 enumerable = ParseAssignmentExpression(true, CHECK_OK);
5294 impl()->RewriteNonPattern(CHECK_OK);
5295 } else {
5296 enumerable = ParseExpression(true, CHECK_OK);
5297 }
5298
5299 Expect(Token::RPAREN, CHECK_OK);
5300
5301 {
5302 ReturnExprScope no_tail_calls(function_state_,
5303 ReturnExprContext::kInsideForInOfBody);
5304 BlockState block_state(zone(), &scope_state_);
5305 block_state.set_start_position(scanner()->location().beg_pos);
5306
5307 // For legacy compat reasons, give for loops similar treatment to
5308 // if statements in allowing a function declaration for a body
5309 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK);
5310 block_state.set_end_position(scanner()->location().end_pos);
5311 StatementT final_loop = impl()->InitializeForEachStatement(
5312 loop, expression, enumerable, body, each_keyword_pos);
5313
5314 Scope* for_scope = for_state.FinalizedBlockScope();
5315 DCHECK_NULL(for_scope);
5316 USE(for_scope);
5317 Scope* block_scope = block_state.FinalizedBlockScope();
5318 DCHECK_NULL(block_scope);
5319 USE(block_scope);
5320 return final_loop;
5321 }
5322 } else {
5323 // Initializer is just an expression.
5324 init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
5325 }
5326 }
5327 }
5328
5329 // Standard 'for' loop, we have parsed the initializer at this point.
5330 auto loop = factory()->NewForStatement(labels, stmt_pos);
5331 typename Types::Target target(this, loop);
5332
5333 Expect(Token::SEMICOLON, CHECK_OK);
5334
5335 ExpressionT cond = impl()->EmptyExpression();
5336 StatementT next = impl()->NullStatement();
5337 StatementT body = impl()->NullStatement();
5338
5339 // If there are let bindings, then condition and the next statement of the
5340 // for loop must be parsed in a new scope.
5341 Scope* inner_scope = scope();
5342 // TODO(verwaest): Allocate this through a ScopeState as well.
5343 if (bound_names_are_lexical && for_info.bound_names.length() > 0) {
5344 inner_scope = NewScopeWithParent(inner_scope, BLOCK_SCOPE);
5345 inner_scope->set_start_position(scanner()->location().beg_pos);
5346 }
5347 {
5348 BlockState block_state(&scope_state_, inner_scope);
5349
5350 if (peek() != Token::SEMICOLON) {
5351 cond = ParseExpression(true, CHECK_OK);
5352 }
5353 Expect(Token::SEMICOLON, CHECK_OK);
5354
5355 if (peek() != Token::RPAREN) {
5356 ExpressionT exp = ParseExpression(true, CHECK_OK);
5357 next = factory()->NewExpressionStatement(exp, exp->position());
5358 }
5359 Expect(Token::RPAREN, CHECK_OK);
5360
5361 body = ParseScopedStatement(nullptr, true, CHECK_OK);
5362 }
5363
5364 if (bound_names_are_lexical && for_info.bound_names.length() > 0) {
5365 auto result = impl()->DesugarLexicalBindingsInForStatement(
5366 loop, init, cond, next, body, inner_scope, for_info, CHECK_OK);
5367 for_state.set_end_position(scanner()->location().end_pos);
5368 return result;
5369 } else {
5370 for_state.set_end_position(scanner()->location().end_pos);
5371 Scope* for_scope = for_state.FinalizedBlockScope();
5372 if (for_scope != nullptr) {
5373 // Rewrite a for statement of the form
5374 // for (const x = i; c; n) b
5375 //
5376 // into
5377 //
5378 // {
5379 // const x = i;
5380 // for (; c; n) b
5381 // }
5382 //
5383 // or, desugar
5384 // for (; c; n) b
5385 // into
5386 // {
5387 // for (; c; n) b
5388 // }
5389 // just in case b introduces a lexical binding some other way, e.g., if b
5390 // is a FunctionDeclaration.
5391 BlockT block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition);
5392 if (!impl()->IsNullStatement(init)) {
5393 block->statements()->Add(init, zone());
5394 }
5395 block->statements()->Add(loop, zone());
5396 block->set_scope(for_scope);
5397 loop->Initialize(init, cond, next, body);
5398 return block;
5399 } else {
5400 loop->Initialize(init, cond, next, body);
5401 return loop;
5402 }
5403 }
5404 }
5405
5406 #undef CHECK_OK
5407 #undef CHECK_OK_CUSTOM
5408
5409 template <typename Impl>
CheckDuplicateProto(Token::Value property)5410 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto(
5411 Token::Value property) {
5412 if (property == Token::SMI || property == Token::NUMBER) return;
5413
5414 if (IsProto()) {
5415 if (has_seen_proto_) {
5416 this->parser()->classifier()->RecordExpressionError(
5417 this->scanner()->location(), MessageTemplate::kDuplicateProto);
5418 return;
5419 }
5420 has_seen_proto_ = true;
5421 }
5422 }
5423
5424 template <typename Impl>
CheckClassMethodName(Token::Value property,PropertyKind type,bool is_generator,bool is_async,bool is_static,bool * ok)5425 void ParserBase<Impl>::ClassLiteralChecker::CheckClassMethodName(
5426 Token::Value property, PropertyKind type, bool is_generator, bool is_async,
5427 bool is_static, bool* ok) {
5428 DCHECK(type == PropertyKind::kMethodProperty ||
5429 type == PropertyKind::kAccessorProperty);
5430
5431 if (property == Token::SMI || property == Token::NUMBER) return;
5432
5433 if (is_static) {
5434 if (IsPrototype()) {
5435 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
5436 *ok = false;
5437 return;
5438 }
5439 } else if (IsConstructor()) {
5440 if (is_generator || is_async || type == PropertyKind::kAccessorProperty) {
5441 MessageTemplate::Template msg =
5442 is_generator ? MessageTemplate::kConstructorIsGenerator
5443 : is_async ? MessageTemplate::kConstructorIsAsync
5444 : MessageTemplate::kConstructorIsAccessor;
5445 this->parser()->ReportMessage(msg);
5446 *ok = false;
5447 return;
5448 }
5449 if (has_seen_constructor_) {
5450 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
5451 *ok = false;
5452 return;
5453 }
5454 has_seen_constructor_ = true;
5455 return;
5456 }
5457 }
5458
5459
5460 } // namespace internal
5461 } // namespace v8
5462
5463 #endif // V8_PARSING_PARSER_BASE_H
5464