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/scopes.h"
9 #include "src/bailout-reason.h"
10 #include "src/base/hashmap.h"
11 #include "src/messages.h"
12 #include "src/parsing/expression-classifier.h"
13 #include "src/parsing/func-name-inferrer.h"
14 #include "src/parsing/scanner.h"
15 #include "src/parsing/token.h"
16
17 namespace v8 {
18 namespace internal {
19
20
21 enum FunctionNameValidity {
22 kFunctionNameIsStrictReserved,
23 kSkipFunctionNameCheck,
24 kFunctionNameValidityUnknown
25 };
26
27 enum AllowLabelledFunctionStatement {
28 kAllowLabelledFunctionStatement,
29 kDisallowLabelledFunctionStatement,
30 };
31
32 enum class FunctionBody { Normal, SingleExpression };
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 enum class MethodKind {
61 Normal = 0,
62 Static = 1 << 0,
63 Generator = 1 << 1,
64 StaticGenerator = Static | Generator,
65 Async = 1 << 2,
66 StaticAsync = Static | Async,
67
68 /* Any non-ordinary method kinds */
69 SpecialMask = Generator | Async
70 };
71
IsValidMethodKind(MethodKind kind)72 inline bool IsValidMethodKind(MethodKind kind) {
73 return kind == MethodKind::Normal || kind == MethodKind::Static ||
74 kind == MethodKind::Generator || kind == MethodKind::StaticGenerator ||
75 kind == MethodKind::Async || kind == MethodKind::StaticAsync;
76 }
77
78 static inline MethodKind operator|(MethodKind lhs, MethodKind rhs) {
79 typedef unsigned char T;
80 return static_cast<MethodKind>(static_cast<T>(lhs) | static_cast<T>(rhs));
81 }
82
83 static inline MethodKind& operator|=(MethodKind& lhs, const MethodKind& rhs) {
84 lhs = lhs | rhs;
85 DCHECK(IsValidMethodKind(lhs));
86 return lhs;
87 }
88
89 static inline bool operator&(MethodKind bitfield, MethodKind mask) {
90 typedef unsigned char T;
91 return static_cast<T>(bitfield) & static_cast<T>(mask);
92 }
93
IsNormalMethod(MethodKind kind)94 inline bool IsNormalMethod(MethodKind kind) {
95 return kind == MethodKind::Normal;
96 }
97
IsSpecialMethod(MethodKind kind)98 inline bool IsSpecialMethod(MethodKind kind) {
99 return kind & MethodKind::SpecialMask;
100 }
101
IsStaticMethod(MethodKind kind)102 inline bool IsStaticMethod(MethodKind kind) {
103 return kind & MethodKind::Static;
104 }
105
IsGeneratorMethod(MethodKind kind)106 inline bool IsGeneratorMethod(MethodKind kind) {
107 return kind & MethodKind::Generator;
108 }
109
IsAsyncMethod(MethodKind kind)110 inline bool IsAsyncMethod(MethodKind kind) { return kind & MethodKind::Async; }
111
112 struct FormalParametersBase {
FormalParametersBaseFormalParametersBase113 explicit FormalParametersBase(Scope* scope) : scope(scope) {}
114 Scope* scope;
115 bool has_rest = false;
116 bool is_simple = true;
117 int materialized_literals_count = 0;
118 };
119
120
121 // Common base class shared between parser and pre-parser. Traits encapsulate
122 // the differences between Parser and PreParser:
123
124 // - Return types: For example, Parser functions return Expression* and
125 // PreParser functions return PreParserExpression.
126
127 // - Creating parse tree nodes: Parser generates an AST during the recursive
128 // descent. PreParser doesn't create a tree. Instead, it passes around minimal
129 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
130 // just enough data for the upper layer functions. PreParserFactory is
131 // responsible for creating these dummy objects. It provides a similar kind of
132 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is
133 // used.
134
135 // - Miscellaneous other tasks interleaved with the recursive descent. For
136 // example, Parser keeps track of which function literals should be marked as
137 // pretenured, and PreParser doesn't care.
138
139 // The traits are expected to contain the following typedefs:
140 // struct Traits {
141 // // In particular...
142 // struct Type {
143 // // Used by FunctionState and BlockState.
144 // typedef Scope;
145 // typedef GeneratorVariable;
146 // // Return types for traversing functions.
147 // typedef Identifier;
148 // typedef Expression;
149 // typedef FunctionLiteral;
150 // typedef ClassLiteral;
151 // typedef ObjectLiteralProperty;
152 // typedef Literal;
153 // typedef ExpressionList;
154 // typedef PropertyList;
155 // typedef FormalParameter;
156 // typedef FormalParameters;
157 // // For constructing objects returned by the traversing functions.
158 // typedef Factory;
159 // };
160 // // ...
161 // };
162
163 template <typename Traits>
164 class ParserBase : public Traits {
165 public:
166 // Shorten type names defined by Traits.
167 typedef typename Traits::Type::Expression ExpressionT;
168 typedef typename Traits::Type::Identifier IdentifierT;
169 typedef typename Traits::Type::FormalParameter FormalParameterT;
170 typedef typename Traits::Type::FormalParameters FormalParametersT;
171 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
172 typedef typename Traits::Type::Literal LiteralT;
173 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
174 typedef typename Traits::Type::StatementList StatementListT;
175 typedef typename Traits::Type::ExpressionClassifier ExpressionClassifier;
176
ParserBase(Zone * zone,Scanner * scanner,uintptr_t stack_limit,v8::Extension * extension,AstValueFactory * ast_value_factory,ParserRecorder * log,typename Traits::Type::Parser this_object)177 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
178 v8::Extension* extension, AstValueFactory* ast_value_factory,
179 ParserRecorder* log, typename Traits::Type::Parser this_object)
180 : Traits(this_object),
181 scope_(NULL),
182 function_state_(NULL),
183 extension_(extension),
184 fni_(NULL),
185 ast_value_factory_(ast_value_factory),
186 log_(log),
187 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
188 parsing_module_(false),
189 stack_limit_(stack_limit),
190 zone_(zone),
191 scanner_(scanner),
192 stack_overflow_(false),
193 allow_lazy_(false),
194 allow_natives_(false),
195 allow_tailcalls_(false),
196 allow_harmony_restrictive_declarations_(false),
197 allow_harmony_do_expressions_(false),
198 allow_harmony_for_in_(false),
199 allow_harmony_function_sent_(false),
200 allow_harmony_async_await_(false),
201 allow_harmony_restrictive_generators_(false) {}
202
203 #define ALLOW_ACCESSORS(name) \
204 bool allow_##name() const { return allow_##name##_; } \
205 void set_allow_##name(bool allow) { allow_##name##_ = allow; }
206
207 #define SCANNER_ACCESSORS(name) \
208 bool allow_##name() const { return scanner_->allow_##name(); } \
209 void set_allow_##name(bool allow) { \
210 return scanner_->set_allow_##name(allow); \
211 }
212
213 ALLOW_ACCESSORS(lazy);
214 ALLOW_ACCESSORS(natives);
215 ALLOW_ACCESSORS(tailcalls);
216 ALLOW_ACCESSORS(harmony_restrictive_declarations);
217 ALLOW_ACCESSORS(harmony_do_expressions);
218 ALLOW_ACCESSORS(harmony_for_in);
219 ALLOW_ACCESSORS(harmony_function_sent);
220 ALLOW_ACCESSORS(harmony_async_await);
221 ALLOW_ACCESSORS(harmony_restrictive_generators);
222 SCANNER_ACCESSORS(harmony_exponentiation_operator);
223
224 #undef SCANNER_ACCESSORS
225 #undef ALLOW_ACCESSORS
226
stack_limit()227 uintptr_t stack_limit() const { return stack_limit_; }
228
229 protected:
230 enum AllowRestrictedIdentifiers {
231 kAllowRestrictedIdentifiers,
232 kDontAllowRestrictedIdentifiers
233 };
234
235 enum Mode {
236 PARSE_LAZILY,
237 PARSE_EAGERLY
238 };
239
240 enum VariableDeclarationContext {
241 kStatementListItem,
242 kStatement,
243 kForStatement
244 };
245
246 class Checkpoint;
247 class ObjectLiteralCheckerBase;
248
249 // ---------------------------------------------------------------------------
250 // FunctionState and BlockState together implement the parser's scope stack.
251 // The parser's current scope is in scope_. BlockState and FunctionState
252 // constructors push on the scope stack and the destructors pop. They are also
253 // used to hold the parser's per-function and per-block state.
254 class BlockState BASE_EMBEDDED {
255 public:
BlockState(Scope ** scope_stack,Scope * scope)256 BlockState(Scope** scope_stack, Scope* scope)
257 : scope_stack_(scope_stack), outer_scope_(*scope_stack) {
258 *scope_stack_ = scope;
259 }
~BlockState()260 ~BlockState() { *scope_stack_ = outer_scope_; }
261
262 private:
263 Scope** scope_stack_;
264 Scope* outer_scope_;
265 };
266
267 struct DestructuringAssignment {
268 public:
DestructuringAssignmentDestructuringAssignment269 DestructuringAssignment(ExpressionT expression, Scope* scope)
270 : assignment(expression), scope(scope) {}
271
272 ExpressionT assignment;
273 Scope* scope;
274 };
275
276 class TailCallExpressionList {
277 public:
TailCallExpressionList(Zone * zone)278 explicit TailCallExpressionList(Zone* zone)
279 : zone_(zone), expressions_(0, zone), has_explicit_tail_calls_(false) {}
280
expressions()281 const ZoneList<ExpressionT>& expressions() const { return expressions_; }
location()282 const Scanner::Location& location() const { return loc_; }
283
has_explicit_tail_calls()284 bool has_explicit_tail_calls() const { return has_explicit_tail_calls_; }
285
Swap(TailCallExpressionList & other)286 void Swap(TailCallExpressionList& other) {
287 expressions_.Swap(&other.expressions_);
288 std::swap(loc_, other.loc_);
289 std::swap(has_explicit_tail_calls_, other.has_explicit_tail_calls_);
290 }
291
AddImplicitTailCall(ExpressionT expr)292 void AddImplicitTailCall(ExpressionT expr) {
293 expressions_.Add(expr, zone_);
294 }
295
AddExplicitTailCall(ExpressionT expr,const Scanner::Location & loc)296 void AddExplicitTailCall(ExpressionT expr, const Scanner::Location& loc) {
297 if (!has_explicit_tail_calls()) {
298 loc_ = loc;
299 has_explicit_tail_calls_ = true;
300 }
301 expressions_.Add(expr, zone_);
302 }
303
Append(const TailCallExpressionList & other)304 void Append(const TailCallExpressionList& other) {
305 if (!has_explicit_tail_calls()) {
306 loc_ = other.loc_;
307 has_explicit_tail_calls_ = other.has_explicit_tail_calls_;
308 }
309 expressions_.AddAll(other.expressions_, zone_);
310 }
311
312 private:
313 Zone* zone_;
314 ZoneList<ExpressionT> expressions_;
315 Scanner::Location loc_;
316 bool has_explicit_tail_calls_;
317 };
318
319 // Defines whether tail call expressions are allowed or not.
320 enum class ReturnExprContext {
321 // We are inside return statement which is allowed to contain tail call
322 // expressions. Tail call expressions are allowed.
323 kInsideValidReturnStatement,
324
325 // We are inside a block in which tail call expressions are allowed but
326 // not yet inside a return statement.
327 kInsideValidBlock,
328
329 // Tail call expressions are not allowed in the following blocks.
330 kInsideTryBlock,
331 kInsideForInOfBody,
332 };
333
334 class FunctionState BASE_EMBEDDED {
335 public:
336 FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
337 Scope* scope, FunctionKind kind,
338 typename Traits::Type::Factory* factory);
339 ~FunctionState();
340
NextMaterializedLiteralIndex()341 int NextMaterializedLiteralIndex() {
342 return next_materialized_literal_index_++;
343 }
materialized_literal_count()344 int materialized_literal_count() {
345 return next_materialized_literal_index_;
346 }
347
SkipMaterializedLiterals(int count)348 void SkipMaterializedLiterals(int count) {
349 next_materialized_literal_index_ += count;
350 }
351
AddProperty()352 void AddProperty() { expected_property_count_++; }
expected_property_count()353 int expected_property_count() { return expected_property_count_; }
354
this_location()355 Scanner::Location this_location() const { return this_location_; }
super_location()356 Scanner::Location super_location() const { return super_location_; }
return_location()357 Scanner::Location return_location() const { return return_location_; }
set_this_location(Scanner::Location location)358 void set_this_location(Scanner::Location location) {
359 this_location_ = location;
360 }
set_super_location(Scanner::Location location)361 void set_super_location(Scanner::Location location) {
362 super_location_ = location;
363 }
set_return_location(Scanner::Location location)364 void set_return_location(Scanner::Location location) {
365 return_location_ = location;
366 }
367
is_generator()368 bool is_generator() const { return IsGeneratorFunction(kind_); }
is_async_function()369 bool is_async_function() const { return IsAsyncFunction(kind_); }
is_resumable()370 bool is_resumable() const { return is_generator() || is_async_function(); }
371
kind()372 FunctionKind kind() const { return kind_; }
outer()373 FunctionState* outer() const { return outer_function_state_; }
374
set_generator_object_variable(typename Traits::Type::GeneratorVariable * variable)375 void set_generator_object_variable(
376 typename Traits::Type::GeneratorVariable* variable) {
377 DCHECK(variable != NULL);
378 DCHECK(is_resumable());
379 generator_object_variable_ = variable;
380 }
generator_object_variable()381 typename Traits::Type::GeneratorVariable* generator_object_variable()
382 const {
383 return generator_object_variable_;
384 }
385
factory()386 typename Traits::Type::Factory* factory() { return factory_; }
387
388 const ZoneList<DestructuringAssignment>&
destructuring_assignments_to_rewrite()389 destructuring_assignments_to_rewrite() const {
390 return destructuring_assignments_to_rewrite_;
391 }
392
tail_call_expressions()393 TailCallExpressionList& tail_call_expressions() {
394 return tail_call_expressions_;
395 }
AddImplicitTailCallExpression(ExpressionT expression)396 void AddImplicitTailCallExpression(ExpressionT expression) {
397 if (return_expr_context() ==
398 ReturnExprContext::kInsideValidReturnStatement) {
399 tail_call_expressions_.AddImplicitTailCall(expression);
400 }
401 }
AddExplicitTailCallExpression(ExpressionT expression,const Scanner::Location & loc)402 void AddExplicitTailCallExpression(ExpressionT expression,
403 const Scanner::Location& loc) {
404 DCHECK(expression->IsCall());
405 if (return_expr_context() ==
406 ReturnExprContext::kInsideValidReturnStatement) {
407 tail_call_expressions_.AddExplicitTailCall(expression, loc);
408 }
409 }
410
GetReportedErrorList()411 ZoneList<typename ExpressionClassifier::Error>* GetReportedErrorList() {
412 return &reported_errors_;
413 }
414
return_expr_context()415 ReturnExprContext return_expr_context() const {
416 return return_expr_context_;
417 }
set_return_expr_context(ReturnExprContext context)418 void set_return_expr_context(ReturnExprContext context) {
419 return_expr_context_ = context;
420 }
421
non_patterns_to_rewrite()422 ZoneList<ExpressionT>* non_patterns_to_rewrite() {
423 return &non_patterns_to_rewrite_;
424 }
425
next_function_is_parenthesized(bool parenthesized)426 void next_function_is_parenthesized(bool parenthesized) {
427 next_function_is_parenthesized_ = parenthesized;
428 }
429
this_function_is_parenthesized()430 bool this_function_is_parenthesized() const {
431 return this_function_is_parenthesized_;
432 }
433
434 private:
AddDestructuringAssignment(DestructuringAssignment pair)435 void AddDestructuringAssignment(DestructuringAssignment pair) {
436 destructuring_assignments_to_rewrite_.Add(pair, (*scope_stack_)->zone());
437 }
438
scope()439 V8_INLINE Scope* scope() { return *scope_stack_; }
440
AddNonPatternForRewriting(ExpressionT expr,bool * ok)441 void AddNonPatternForRewriting(ExpressionT expr, bool* ok) {
442 non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone());
443 if (non_patterns_to_rewrite_.length() >=
444 std::numeric_limits<uint16_t>::max())
445 *ok = false;
446 }
447
448 // Used to assign an index to each literal that needs materialization in
449 // the function. Includes regexp literals, and boilerplate for object and
450 // array literals.
451 int next_materialized_literal_index_;
452
453 // Properties count estimation.
454 int expected_property_count_;
455
456 // Location of most recent use of 'this' (invalid if none).
457 Scanner::Location this_location_;
458
459 // Location of most recent 'return' statement (invalid if none).
460 Scanner::Location return_location_;
461
462 // Location of call to the "super" constructor (invalid if none).
463 Scanner::Location super_location_;
464
465 FunctionKind kind_;
466 // For generators, this variable may hold the generator object. It variable
467 // is used by yield expressions and return statements. It is not necessary
468 // for generator functions to have this variable set.
469 Variable* generator_object_variable_;
470
471 FunctionState** function_state_stack_;
472 FunctionState* outer_function_state_;
473 Scope** scope_stack_;
474 Scope* outer_scope_;
475
476 ZoneList<DestructuringAssignment> destructuring_assignments_to_rewrite_;
477 TailCallExpressionList tail_call_expressions_;
478 ReturnExprContext return_expr_context_;
479 ZoneList<ExpressionT> non_patterns_to_rewrite_;
480
481 ZoneList<typename ExpressionClassifier::Error> reported_errors_;
482
483 typename Traits::Type::Factory* factory_;
484
485 // If true, the next (and immediately following) function literal is
486 // preceded by a parenthesis.
487 bool next_function_is_parenthesized_;
488
489 // The value of the parents' next_function_is_parenthesized_, as it applies
490 // to this function. Filled in by constructor.
491 bool this_function_is_parenthesized_;
492
493 friend class ParserTraits;
494 friend class PreParserTraits;
495 friend class Checkpoint;
496 };
497
498 // This scope sets current ReturnExprContext to given value.
499 class ReturnExprScope {
500 public:
ReturnExprScope(FunctionState * function_state,ReturnExprContext return_expr_context)501 explicit ReturnExprScope(FunctionState* function_state,
502 ReturnExprContext return_expr_context)
503 : function_state_(function_state),
504 sav_return_expr_context_(function_state->return_expr_context()) {
505 // Don't update context if we are requested to enable tail call
506 // expressions but current block does not allow them.
507 if (return_expr_context !=
508 ReturnExprContext::kInsideValidReturnStatement ||
509 sav_return_expr_context_ == ReturnExprContext::kInsideValidBlock) {
510 function_state->set_return_expr_context(return_expr_context);
511 }
512 }
~ReturnExprScope()513 ~ReturnExprScope() {
514 function_state_->set_return_expr_context(sav_return_expr_context_);
515 }
516
517 private:
518 FunctionState* function_state_;
519 ReturnExprContext sav_return_expr_context_;
520 };
521
522 // Collects all return expressions at tail call position in this scope
523 // to a separate list.
524 class CollectExpressionsInTailPositionToListScope {
525 public:
CollectExpressionsInTailPositionToListScope(FunctionState * function_state,TailCallExpressionList * list)526 CollectExpressionsInTailPositionToListScope(FunctionState* function_state,
527 TailCallExpressionList* list)
528 : function_state_(function_state), list_(list) {
529 function_state->tail_call_expressions().Swap(*list_);
530 }
~CollectExpressionsInTailPositionToListScope()531 ~CollectExpressionsInTailPositionToListScope() {
532 function_state_->tail_call_expressions().Swap(*list_);
533 }
534
535 private:
536 FunctionState* function_state_;
537 TailCallExpressionList* list_;
538 };
539
540 // Annoyingly, arrow functions first parse as comma expressions, then when we
541 // see the => we have to go back and reinterpret the arguments as being formal
542 // parameters. To do so we need to reset some of the parser state back to
543 // what it was before the arguments were first seen.
544 class Checkpoint BASE_EMBEDDED {
545 public:
Checkpoint(ParserBase * parser)546 explicit Checkpoint(ParserBase* parser) {
547 function_state_ = parser->function_state_;
548 next_materialized_literal_index_ =
549 function_state_->next_materialized_literal_index_;
550 expected_property_count_ = function_state_->expected_property_count_;
551 }
552
Restore(int * materialized_literal_index_delta)553 void Restore(int* materialized_literal_index_delta) {
554 *materialized_literal_index_delta =
555 function_state_->next_materialized_literal_index_ -
556 next_materialized_literal_index_;
557 function_state_->next_materialized_literal_index_ =
558 next_materialized_literal_index_;
559 function_state_->expected_property_count_ = expected_property_count_;
560 }
561
562 private:
563 FunctionState* function_state_;
564 int next_materialized_literal_index_;
565 int expected_property_count_;
566 };
567
568 class ParsingModeScope BASE_EMBEDDED {
569 public:
ParsingModeScope(ParserBase * parser,Mode mode)570 ParsingModeScope(ParserBase* parser, Mode mode)
571 : parser_(parser),
572 old_mode_(parser->mode()) {
573 parser_->mode_ = mode;
574 }
~ParsingModeScope()575 ~ParsingModeScope() {
576 parser_->mode_ = old_mode_;
577 }
578
579 private:
580 ParserBase* parser_;
581 Mode old_mode_;
582 };
583
NewScope(Scope * parent,ScopeType scope_type)584 Scope* NewScope(Scope* parent, ScopeType scope_type) {
585 // Must always pass the function kind for FUNCTION_SCOPE.
586 DCHECK(scope_type != FUNCTION_SCOPE);
587 return NewScope(parent, scope_type, kNormalFunction);
588 }
589
NewScope(Scope * parent,ScopeType scope_type,FunctionKind kind)590 Scope* NewScope(Scope* parent, ScopeType scope_type, FunctionKind kind) {
591 DCHECK(ast_value_factory());
592 Scope* result = new (zone())
593 Scope(zone(), parent, scope_type, ast_value_factory(), kind);
594 result->Initialize();
595 return result;
596 }
597
scanner()598 Scanner* scanner() const { return scanner_; }
ast_value_factory()599 AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
position()600 int position() { return scanner_->location().beg_pos; }
peek_position()601 int peek_position() { return scanner_->peek_location().beg_pos; }
stack_overflow()602 bool stack_overflow() const { return stack_overflow_; }
set_stack_overflow()603 void set_stack_overflow() { stack_overflow_ = true; }
mode()604 Mode mode() const { return mode_; }
zone()605 Zone* zone() const { return zone_; }
606
INLINE(Token::Value peek ())607 INLINE(Token::Value peek()) {
608 if (stack_overflow_) return Token::ILLEGAL;
609 return scanner()->peek();
610 }
611
INLINE(Token::Value PeekAhead ())612 INLINE(Token::Value PeekAhead()) {
613 if (stack_overflow_) return Token::ILLEGAL;
614 return scanner()->PeekAhead();
615 }
616
INLINE(Token::Value Next ())617 INLINE(Token::Value Next()) {
618 if (stack_overflow_) return Token::ILLEGAL;
619 {
620 if (GetCurrentStackPosition() < stack_limit_) {
621 // Any further calls to Next or peek will return the illegal token.
622 // The current call must return the next token, which might already
623 // have been peek'ed.
624 stack_overflow_ = true;
625 }
626 }
627 return scanner()->Next();
628 }
629
Consume(Token::Value token)630 void Consume(Token::Value token) {
631 Token::Value next = Next();
632 USE(next);
633 USE(token);
634 DCHECK(next == token);
635 }
636
Check(Token::Value token)637 bool Check(Token::Value token) {
638 Token::Value next = peek();
639 if (next == token) {
640 Consume(next);
641 return true;
642 }
643 return false;
644 }
645
Expect(Token::Value token,bool * ok)646 void Expect(Token::Value token, bool* ok) {
647 Token::Value next = Next();
648 if (next != token) {
649 ReportUnexpectedToken(next);
650 *ok = false;
651 }
652 }
653
ExpectSemicolon(bool * ok)654 void ExpectSemicolon(bool* ok) {
655 // Check for automatic semicolon insertion according to
656 // the rules given in ECMA-262, section 7.9, page 21.
657 Token::Value tok = peek();
658 if (tok == Token::SEMICOLON) {
659 Next();
660 return;
661 }
662 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
663 tok == Token::RBRACE ||
664 tok == Token::EOS) {
665 return;
666 }
667 Expect(Token::SEMICOLON, ok);
668 }
669
is_any_identifier(Token::Value token)670 bool is_any_identifier(Token::Value token) {
671 return token == Token::IDENTIFIER || token == Token::ENUM ||
672 token == Token::AWAIT || token == Token::ASYNC ||
673 token == Token::FUTURE_STRICT_RESERVED_WORD || token == Token::LET ||
674 token == Token::STATIC || token == Token::YIELD;
675 }
peek_any_identifier()676 bool peek_any_identifier() { return is_any_identifier(peek()); }
677
CheckContextualKeyword(Vector<const char> keyword)678 bool CheckContextualKeyword(Vector<const char> keyword) {
679 if (PeekContextualKeyword(keyword)) {
680 Consume(Token::IDENTIFIER);
681 return true;
682 }
683 return false;
684 }
685
PeekContextualKeyword(Vector<const char> keyword)686 bool PeekContextualKeyword(Vector<const char> keyword) {
687 return peek() == Token::IDENTIFIER &&
688 scanner()->is_next_contextual_keyword(keyword);
689 }
690
691 void ExpectMetaProperty(Vector<const char> property_name,
692 const char* full_name, int pos, bool* ok);
693
ExpectContextualKeyword(Vector<const char> keyword,bool * ok)694 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
695 Expect(Token::IDENTIFIER, ok);
696 if (!*ok) return;
697 if (!scanner()->is_literal_contextual_keyword(keyword)) {
698 ReportUnexpectedToken(scanner()->current_token());
699 *ok = false;
700 }
701 }
702
CheckInOrOf(ForEachStatement::VisitMode * visit_mode,bool * ok)703 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) {
704 if (Check(Token::IN)) {
705 *visit_mode = ForEachStatement::ENUMERATE;
706 return true;
707 } else if (CheckContextualKeyword(CStrVector("of"))) {
708 *visit_mode = ForEachStatement::ITERATE;
709 return true;
710 }
711 return false;
712 }
713
PeekInOrOf()714 bool PeekInOrOf() {
715 return peek() == Token::IN || PeekContextualKeyword(CStrVector("of"));
716 }
717
718 // Checks whether an octal literal was last seen between beg_pos and end_pos.
719 // 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)720 void CheckOctalLiteral(int beg_pos, int end_pos,
721 MessageTemplate::Template message, bool* ok) {
722 Scanner::Location octal = scanner()->octal_position();
723 if (octal.IsValid() && beg_pos <= octal.beg_pos &&
724 octal.end_pos <= end_pos) {
725 ReportMessageAt(octal, message);
726 scanner()->clear_octal_position();
727 *ok = false;
728 }
729 }
730 // for now, this check just collects statistics.
CheckDecimalLiteralWithLeadingZero(int * use_counts,int beg_pos,int end_pos)731 void CheckDecimalLiteralWithLeadingZero(int* use_counts, int beg_pos,
732 int end_pos) {
733 Scanner::Location token_location =
734 scanner()->decimal_with_leading_zero_position();
735 if (token_location.IsValid() && beg_pos <= token_location.beg_pos &&
736 token_location.end_pos <= end_pos) {
737 scanner()->clear_decimal_with_leading_zero_position();
738 if (use_counts != nullptr)
739 ++use_counts[v8::Isolate::kDecimalWithLeadingZeroInStrictMode];
740 }
741 }
742
CheckStrictOctalLiteral(int beg_pos,int end_pos,bool * ok)743 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
744 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral,
745 ok);
746 }
747
CheckTemplateOctalLiteral(int beg_pos,int end_pos,bool * ok)748 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
749 CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kTemplateOctalLiteral,
750 ok);
751 }
752
753 void CheckDestructuringElement(ExpressionT element,
754 ExpressionClassifier* classifier, int beg_pos,
755 int end_pos);
756
757 // Checking the name of a function literal. This has to be done after parsing
758 // 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)759 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
760 FunctionNameValidity function_name_validity,
761 const Scanner::Location& function_name_loc, bool* ok) {
762 if (function_name_validity == kSkipFunctionNameCheck) return;
763 // The function name needs to be checked in strict mode.
764 if (is_sloppy(language_mode)) return;
765
766 if (this->IsEvalOrArguments(function_name)) {
767 Traits::ReportMessageAt(function_name_loc,
768 MessageTemplate::kStrictEvalArguments);
769 *ok = false;
770 return;
771 }
772 if (function_name_validity == kFunctionNameIsStrictReserved) {
773 Traits::ReportMessageAt(function_name_loc,
774 MessageTemplate::kUnexpectedStrictReserved);
775 *ok = false;
776 return;
777 }
778 }
779
780 // Determine precedence of given token.
Precedence(Token::Value token,bool accept_IN)781 static int Precedence(Token::Value token, bool accept_IN) {
782 if (token == Token::IN && !accept_IN)
783 return 0; // 0 precedence will terminate binary expression parsing
784 return Token::Precedence(token);
785 }
786
factory()787 typename Traits::Type::Factory* factory() {
788 return function_state_->factory();
789 }
790
language_mode()791 LanguageMode language_mode() { return scope_->language_mode(); }
is_generator()792 bool is_generator() const { return function_state_->is_generator(); }
is_async_function()793 bool is_async_function() const {
794 return function_state_->is_async_function();
795 }
is_resumable()796 bool is_resumable() const { return function_state_->is_resumable(); }
797
798 // Report syntax errors.
799 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL,
800 ParseErrorType error_type = kSyntaxError) {
801 Scanner::Location source_location = scanner()->location();
802 Traits::ReportMessageAt(source_location, message, arg, error_type);
803 }
804
805 void ReportMessageAt(Scanner::Location location,
806 MessageTemplate::Template message,
807 ParseErrorType error_type = kSyntaxError) {
808 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0),
809 error_type);
810 }
811
812 void GetUnexpectedTokenMessage(
813 Token::Value token, MessageTemplate::Template* message,
814 Scanner::Location* location, const char** arg,
815 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken);
816
817 void ReportUnexpectedToken(Token::Value token);
818 void ReportUnexpectedTokenAt(
819 Scanner::Location location, Token::Value token,
820 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken);
821
ReportClassifierError(const typename ExpressionClassifier::Error & error)822 void ReportClassifierError(
823 const typename ExpressionClassifier::Error& error) {
824 Traits::ReportMessageAt(error.location, error.message, error.arg,
825 error.type);
826 }
827
ValidateExpression(const ExpressionClassifier * classifier,bool * ok)828 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) {
829 if (!classifier->is_valid_expression() ||
830 classifier->has_cover_initialized_name()) {
831 const Scanner::Location& a = classifier->expression_error().location;
832 const Scanner::Location& b =
833 classifier->cover_initialized_name_error().location;
834 if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) {
835 ReportClassifierError(classifier->cover_initialized_name_error());
836 } else {
837 ReportClassifierError(classifier->expression_error());
838 }
839 *ok = false;
840 }
841 }
842
ValidateFormalParameterInitializer(const ExpressionClassifier * classifier,bool * ok)843 void ValidateFormalParameterInitializer(
844 const ExpressionClassifier* classifier, bool* ok) {
845 if (!classifier->is_valid_formal_parameter_initializer()) {
846 ReportClassifierError(classifier->formal_parameter_initializer_error());
847 *ok = false;
848 }
849 }
850
ValidateBindingPattern(const ExpressionClassifier * classifier,bool * ok)851 void ValidateBindingPattern(const ExpressionClassifier* classifier,
852 bool* ok) {
853 if (!classifier->is_valid_binding_pattern() ||
854 !classifier->is_valid_async_binding_pattern()) {
855 const Scanner::Location& a = classifier->binding_pattern_error().location;
856 const Scanner::Location& b =
857 classifier->async_binding_pattern_error().location;
858 if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) {
859 ReportClassifierError(classifier->async_binding_pattern_error());
860 } else {
861 ReportClassifierError(classifier->binding_pattern_error());
862 }
863 *ok = false;
864 }
865 }
866
ValidateAssignmentPattern(const ExpressionClassifier * classifier,bool * ok)867 void ValidateAssignmentPattern(const ExpressionClassifier* classifier,
868 bool* ok) {
869 if (!classifier->is_valid_assignment_pattern()) {
870 ReportClassifierError(classifier->assignment_pattern_error());
871 *ok = false;
872 }
873 }
874
ValidateFormalParameters(const ExpressionClassifier * classifier,LanguageMode language_mode,bool allow_duplicates,bool * ok)875 void ValidateFormalParameters(const ExpressionClassifier* classifier,
876 LanguageMode language_mode,
877 bool allow_duplicates, bool* ok) {
878 if (!allow_duplicates &&
879 !classifier->is_valid_formal_parameter_list_without_duplicates()) {
880 ReportClassifierError(classifier->duplicate_formal_parameter_error());
881 *ok = false;
882 } else if (is_strict(language_mode) &&
883 !classifier->is_valid_strict_mode_formal_parameters()) {
884 ReportClassifierError(classifier->strict_mode_formal_parameter_error());
885 *ok = false;
886 }
887 }
888
IsValidArrowFormalParametersStart(Token::Value token)889 bool IsValidArrowFormalParametersStart(Token::Value token) {
890 return is_any_identifier(token) || token == Token::LPAREN;
891 }
892
ValidateArrowFormalParameters(const ExpressionClassifier * classifier,ExpressionT expr,bool parenthesized_formals,bool is_async,bool * ok)893 void ValidateArrowFormalParameters(const ExpressionClassifier* classifier,
894 ExpressionT expr,
895 bool parenthesized_formals, bool is_async,
896 bool* ok) {
897 if (classifier->is_valid_binding_pattern()) {
898 // A simple arrow formal parameter: IDENTIFIER => BODY.
899 if (!this->IsIdentifier(expr)) {
900 Traits::ReportMessageAt(scanner()->location(),
901 MessageTemplate::kUnexpectedToken,
902 Token::String(scanner()->current_token()));
903 *ok = false;
904 }
905 } else if (!classifier->is_valid_arrow_formal_parameters()) {
906 // If after parsing the expr, we see an error but the expression is
907 // neither a valid binding pattern nor a valid parenthesized formal
908 // parameter list, show the "arrow formal parameters" error if the formals
909 // started with a parenthesis, and the binding pattern error otherwise.
910 const typename ExpressionClassifier::Error& error =
911 parenthesized_formals ? classifier->arrow_formal_parameters_error()
912 : classifier->binding_pattern_error();
913 ReportClassifierError(error);
914 *ok = false;
915 }
916 if (is_async && !classifier->is_valid_async_arrow_formal_parameters()) {
917 const typename ExpressionClassifier::Error& error =
918 classifier->async_arrow_formal_parameters_error();
919 ReportClassifierError(error);
920 *ok = false;
921 }
922 }
923
ValidateLetPattern(const ExpressionClassifier * classifier,bool * ok)924 void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) {
925 if (!classifier->is_valid_let_pattern()) {
926 ReportClassifierError(classifier->let_pattern_error());
927 *ok = false;
928 }
929 }
930
CheckNoTailCallExpressions(const ExpressionClassifier * classifier,bool * ok)931 void CheckNoTailCallExpressions(const ExpressionClassifier* classifier,
932 bool* ok) {
933 if (FLAG_harmony_explicit_tailcalls &&
934 classifier->has_tail_call_expression()) {
935 ReportClassifierError(classifier->tail_call_expression_error());
936 *ok = false;
937 }
938 }
939
ExpressionUnexpectedToken(ExpressionClassifier * classifier)940 void ExpressionUnexpectedToken(ExpressionClassifier* classifier) {
941 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
942 const char* arg;
943 Scanner::Location location = scanner()->peek_location();
944 GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
945 classifier->RecordExpressionError(location, message, arg);
946 }
947
BindingPatternUnexpectedToken(ExpressionClassifier * classifier)948 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) {
949 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
950 const char* arg;
951 Scanner::Location location = scanner()->peek_location();
952 GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
953 classifier->RecordBindingPatternError(location, message, arg);
954 }
955
ArrowFormalParametersUnexpectedToken(ExpressionClassifier * classifier)956 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) {
957 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
958 const char* arg;
959 Scanner::Location location = scanner()->peek_location();
960 GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
961 classifier->RecordArrowFormalParametersError(location, message, arg);
962 }
963
964 // Recursive descent functions:
965
966 // Parses an identifier that is valid for the current scope, in particular it
967 // fails on strict mode future reserved keywords in a strict scope. If
968 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
969 // "arguments" as identifier even in strict mode (this is needed in cases like
970 // "var foo = eval;").
971 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok);
972 IdentifierT ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
973 bool* ok);
974 // Parses an identifier or a strict mode future reserved word, and indicate
975 // whether it is strict mode future reserved. Allows passing in is_generator
976 // for the case of parsing the identifier in a function expression, where the
977 // relevant "is_generator" bit is of the function being parsed, not the
978 // containing
979 // function.
980 IdentifierT ParseIdentifierOrStrictReservedWord(bool is_generator,
981 bool* is_strict_reserved,
982 bool* ok);
ParseIdentifierOrStrictReservedWord(bool * is_strict_reserved,bool * ok)983 IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
984 bool* ok) {
985 return ParseIdentifierOrStrictReservedWord(this->is_generator(),
986 is_strict_reserved, ok);
987 }
988
989 IdentifierT ParseIdentifierName(bool* ok);
990
991 ExpressionT ParseRegExpLiteral(bool seen_equal,
992 ExpressionClassifier* classifier, bool* ok);
993
994 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
995 bool* is_async, bool* ok);
ParsePrimaryExpression(ExpressionClassifier * classifier,bool * ok)996 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
997 bool* ok) {
998 bool is_async;
999 return ParsePrimaryExpression(classifier, &is_async, ok);
1000 }
1001 ExpressionT ParseExpression(bool accept_IN, bool* ok);
1002 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
1003 bool* ok);
1004 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
1005 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
1006 bool* is_await, bool* is_computed_name,
1007 ExpressionClassifier* classifier, bool* ok);
1008 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
1009 ObjectLiteralPropertyT ParsePropertyDefinition(
1010 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
1011 MethodKind kind, bool* is_computed_name, bool* has_seen_constructor,
1012 ExpressionClassifier* classifier, IdentifierT* name, bool* ok);
1013 typename Traits::Type::ExpressionList ParseArguments(
1014 Scanner::Location* first_spread_pos, bool maybe_arrow,
1015 ExpressionClassifier* classifier, bool* ok);
ParseArguments(Scanner::Location * first_spread_pos,ExpressionClassifier * classifier,bool * ok)1016 typename Traits::Type::ExpressionList ParseArguments(
1017 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
1018 bool* ok) {
1019 return ParseArguments(first_spread_pos, false, classifier, ok);
1020 }
1021
1022 ExpressionT ParseAssignmentExpression(bool accept_IN,
1023 ExpressionClassifier* classifier,
1024 bool* ok);
1025 ExpressionT ParseYieldExpression(bool accept_IN,
1026 ExpressionClassifier* classifier, bool* ok);
1027 ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier,
1028 bool* ok);
1029 ExpressionT ParseConditionalExpression(bool accept_IN,
1030 ExpressionClassifier* classifier,
1031 bool* ok);
1032 ExpressionT ParseBinaryExpression(int prec, bool accept_IN,
1033 ExpressionClassifier* classifier, bool* ok);
1034 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok);
1035 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier,
1036 bool* ok);
1037 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier,
1038 bool* ok);
1039 ExpressionT ParseMemberWithNewPrefixesExpression(
1040 ExpressionClassifier* classifier, bool* is_async, bool* ok);
1041 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier,
1042 bool* is_async, bool* ok);
1043 ExpressionT ParseMemberExpressionContinuation(
1044 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier,
1045 bool* ok);
1046 ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
1047 const FormalParametersT& parameters,
1048 bool is_async,
1049 const ExpressionClassifier& classifier,
1050 bool* ok);
1051 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start,
1052 ExpressionClassifier* classifier, bool* ok);
1053 void AddTemplateExpression(ExpressionT);
1054 ExpressionT ParseSuperExpression(bool is_new,
1055 ExpressionClassifier* classifier, bool* ok);
1056 ExpressionT ParseNewTargetExpression(bool* ok);
1057
1058 void ParseFormalParameter(FormalParametersT* parameters,
1059 ExpressionClassifier* classifier, bool* ok);
1060 void ParseFormalParameterList(FormalParametersT* parameters,
1061 ExpressionClassifier* classifier, bool* ok);
1062 void CheckArityRestrictions(int param_count, FunctionKind function_type,
1063 bool has_rest, int formals_start_pos,
1064 int formals_end_pos, bool* ok);
1065
1066 bool IsNextLetKeyword();
1067
1068 // Checks if the expression is a valid reference expression (e.g., on the
1069 // left-hand side of assignments). Although ruled out by ECMA as early errors,
1070 // we allow calls for web compatibility and rewrite them to a runtime throw.
1071 ExpressionT CheckAndRewriteReferenceExpression(
1072 ExpressionT expression, int beg_pos, int end_pos,
1073 MessageTemplate::Template message, bool* ok);
1074 ExpressionT CheckAndRewriteReferenceExpression(
1075 ExpressionT expression, int beg_pos, int end_pos,
1076 MessageTemplate::Template message, ParseErrorType type, bool* ok);
1077
1078 bool IsValidReferenceExpression(ExpressionT expression);
1079
IsAssignableIdentifier(ExpressionT expression)1080 bool IsAssignableIdentifier(ExpressionT expression) {
1081 if (!Traits::IsIdentifier(expression)) return false;
1082 if (is_strict(language_mode()) &&
1083 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) {
1084 return false;
1085 }
1086 return true;
1087 }
1088
IsValidPattern(ExpressionT expression)1089 bool IsValidPattern(ExpressionT expression) {
1090 return expression->IsObjectLiteral() || expression->IsArrayLiteral();
1091 }
1092
1093 // Keep track of eval() calls since they disable all local variable
1094 // optimizations. This checks if expression is an eval call, and if yes,
1095 // forwards the information to scope.
CheckPossibleEvalCall(ExpressionT expression,Scope * scope)1096 void CheckPossibleEvalCall(ExpressionT expression, Scope* scope) {
1097 if (Traits::IsIdentifier(expression) &&
1098 Traits::IsEval(Traits::AsIdentifier(expression))) {
1099 scope->RecordEvalCall();
1100 if (is_sloppy(scope->language_mode())) {
1101 // For sloppy scopes we also have to record the call at function level,
1102 // in case it includes declarations that will be hoisted.
1103 scope->DeclarationScope()->RecordEvalCall();
1104 }
1105 }
1106 }
1107
1108 // Used to validate property names in object literals and class literals
1109 enum PropertyKind {
1110 kAccessorProperty,
1111 kValueProperty,
1112 kMethodProperty
1113 };
1114
1115 class ObjectLiteralCheckerBase {
1116 public:
ObjectLiteralCheckerBase(ParserBase * parser)1117 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
1118
1119 virtual void CheckProperty(Token::Value property, PropertyKind type,
1120 MethodKind method_type, bool* ok) = 0;
1121
~ObjectLiteralCheckerBase()1122 virtual ~ObjectLiteralCheckerBase() {}
1123
1124 protected:
parser()1125 ParserBase* parser() const { return parser_; }
scanner()1126 Scanner* scanner() const { return parser_->scanner(); }
1127
1128 private:
1129 ParserBase* parser_;
1130 };
1131
1132 // Validation per ES6 object literals.
1133 class ObjectLiteralChecker : public ObjectLiteralCheckerBase {
1134 public:
ObjectLiteralChecker(ParserBase * parser)1135 explicit ObjectLiteralChecker(ParserBase* parser)
1136 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {}
1137
1138 void CheckProperty(Token::Value property, PropertyKind type,
1139 MethodKind method_type, bool* ok) override;
1140
1141 private:
IsProto()1142 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
1143
1144 bool has_seen_proto_;
1145 };
1146
1147 // Validation per ES6 class literals.
1148 class ClassLiteralChecker : public ObjectLiteralCheckerBase {
1149 public:
ClassLiteralChecker(ParserBase * parser)1150 explicit ClassLiteralChecker(ParserBase* parser)
1151 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {}
1152
1153 void CheckProperty(Token::Value property, PropertyKind type,
1154 MethodKind method_type, bool* ok) override;
1155
1156 private:
IsConstructor()1157 bool IsConstructor() {
1158 return this->scanner()->LiteralMatches("constructor", 11);
1159 }
IsPrototype()1160 bool IsPrototype() {
1161 return this->scanner()->LiteralMatches("prototype", 9);
1162 }
1163
1164 bool has_seen_constructor_;
1165 };
1166
1167 Scope* scope_; // Scope stack.
1168 FunctionState* function_state_; // Function state stack.
1169 v8::Extension* extension_;
1170 FuncNameInferrer* fni_;
1171 AstValueFactory* ast_value_factory_; // Not owned.
1172 ParserRecorder* log_;
1173 Mode mode_;
1174 bool parsing_module_;
1175 uintptr_t stack_limit_;
1176
1177 private:
1178 Zone* zone_;
1179
1180 Scanner* scanner_;
1181 bool stack_overflow_;
1182
1183 bool allow_lazy_;
1184 bool allow_natives_;
1185 bool allow_tailcalls_;
1186 bool allow_harmony_restrictive_declarations_;
1187 bool allow_harmony_do_expressions_;
1188 bool allow_harmony_for_in_;
1189 bool allow_harmony_function_sent_;
1190 bool allow_harmony_async_await_;
1191 bool allow_harmony_restrictive_generators_;
1192 };
1193
1194 template <class Traits>
FunctionState(FunctionState ** function_state_stack,Scope ** scope_stack,Scope * scope,FunctionKind kind,typename Traits::Type::Factory * factory)1195 ParserBase<Traits>::FunctionState::FunctionState(
1196 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope,
1197 FunctionKind kind, typename Traits::Type::Factory* factory)
1198 : next_materialized_literal_index_(0),
1199 expected_property_count_(0),
1200 this_location_(Scanner::Location::invalid()),
1201 return_location_(Scanner::Location::invalid()),
1202 super_location_(Scanner::Location::invalid()),
1203 kind_(kind),
1204 generator_object_variable_(NULL),
1205 function_state_stack_(function_state_stack),
1206 outer_function_state_(*function_state_stack),
1207 scope_stack_(scope_stack),
1208 outer_scope_(*scope_stack),
1209 destructuring_assignments_to_rewrite_(16, scope->zone()),
1210 tail_call_expressions_(scope->zone()),
1211 return_expr_context_(ReturnExprContext::kInsideValidBlock),
1212 non_patterns_to_rewrite_(0, scope->zone()),
1213 reported_errors_(16, scope->zone()),
1214 factory_(factory),
1215 next_function_is_parenthesized_(false),
1216 this_function_is_parenthesized_(false) {
1217 *scope_stack_ = scope;
1218 *function_state_stack = this;
1219 if (outer_function_state_) {
1220 this_function_is_parenthesized_ =
1221 outer_function_state_->next_function_is_parenthesized_;
1222 outer_function_state_->next_function_is_parenthesized_ = false;
1223 }
1224 }
1225
1226
1227 template <class Traits>
~FunctionState()1228 ParserBase<Traits>::FunctionState::~FunctionState() {
1229 *scope_stack_ = outer_scope_;
1230 *function_state_stack_ = outer_function_state_;
1231 }
1232
1233 template <class Traits>
GetUnexpectedTokenMessage(Token::Value token,MessageTemplate::Template * message,Scanner::Location * location,const char ** arg,MessageTemplate::Template default_)1234 void ParserBase<Traits>::GetUnexpectedTokenMessage(
1235 Token::Value token, MessageTemplate::Template* message,
1236 Scanner::Location* location, const char** arg,
1237 MessageTemplate::Template default_) {
1238 *arg = nullptr;
1239 switch (token) {
1240 case Token::EOS:
1241 *message = MessageTemplate::kUnexpectedEOS;
1242 break;
1243 case Token::SMI:
1244 case Token::NUMBER:
1245 *message = MessageTemplate::kUnexpectedTokenNumber;
1246 break;
1247 case Token::STRING:
1248 *message = MessageTemplate::kUnexpectedTokenString;
1249 break;
1250 case Token::IDENTIFIER:
1251 *message = MessageTemplate::kUnexpectedTokenIdentifier;
1252 break;
1253 case Token::AWAIT:
1254 case Token::ENUM:
1255 *message = MessageTemplate::kUnexpectedReserved;
1256 break;
1257 case Token::LET:
1258 case Token::STATIC:
1259 case Token::YIELD:
1260 case Token::FUTURE_STRICT_RESERVED_WORD:
1261 *message = is_strict(language_mode())
1262 ? MessageTemplate::kUnexpectedStrictReserved
1263 : MessageTemplate::kUnexpectedTokenIdentifier;
1264 break;
1265 case Token::TEMPLATE_SPAN:
1266 case Token::TEMPLATE_TAIL:
1267 *message = MessageTemplate::kUnexpectedTemplateString;
1268 break;
1269 case Token::ESCAPED_STRICT_RESERVED_WORD:
1270 case Token::ESCAPED_KEYWORD:
1271 *message = MessageTemplate::kInvalidEscapedReservedWord;
1272 break;
1273 case Token::ILLEGAL:
1274 if (scanner()->has_error()) {
1275 *message = scanner()->error();
1276 *location = scanner()->error_location();
1277 } else {
1278 *message = MessageTemplate::kInvalidOrUnexpectedToken;
1279 }
1280 break;
1281 default:
1282 const char* name = Token::String(token);
1283 DCHECK(name != NULL);
1284 *arg = name;
1285 break;
1286 }
1287 }
1288
1289
1290 template <class Traits>
ReportUnexpectedToken(Token::Value token)1291 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1292 return ReportUnexpectedTokenAt(scanner_->location(), token);
1293 }
1294
1295
1296 template <class Traits>
ReportUnexpectedTokenAt(Scanner::Location source_location,Token::Value token,MessageTemplate::Template message)1297 void ParserBase<Traits>::ReportUnexpectedTokenAt(
1298 Scanner::Location source_location, Token::Value token,
1299 MessageTemplate::Template message) {
1300 const char* arg;
1301 GetUnexpectedTokenMessage(token, &message, &source_location, &arg);
1302 Traits::ReportMessageAt(source_location, message, arg);
1303 }
1304
1305
1306 template <class Traits>
ParseIdentifier(AllowRestrictedIdentifiers allow_restricted_identifiers,bool * ok)1307 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1308 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
1309 ExpressionClassifier classifier(this);
1310 auto result = ParseAndClassifyIdentifier(&classifier, ok);
1311 if (!*ok) return Traits::EmptyIdentifier();
1312
1313 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
1314 ValidateAssignmentPattern(&classifier, ok);
1315 if (!*ok) return Traits::EmptyIdentifier();
1316 ValidateBindingPattern(&classifier, ok);
1317 if (!*ok) return Traits::EmptyIdentifier();
1318 }
1319
1320 return result;
1321 }
1322
1323
1324 template <class Traits>
1325 typename ParserBase<Traits>::IdentifierT
ParseAndClassifyIdentifier(ExpressionClassifier * classifier,bool * ok)1326 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
1327 bool* ok) {
1328 Token::Value next = Next();
1329 if (next == Token::IDENTIFIER || next == Token::ASYNC ||
1330 (next == Token::AWAIT && !parsing_module_)) {
1331 IdentifierT name = this->GetSymbol(scanner());
1332 // When this function is used to read a formal parameter, we don't always
1333 // know whether the function is going to be strict or sloppy. Indeed for
1334 // arrow functions we don't always know that the identifier we are reading
1335 // is actually a formal parameter. Therefore besides the errors that we
1336 // must detect because we know we're in strict mode, we also record any
1337 // error that we might make in the future once we know the language mode.
1338 if (this->IsEval(name)) {
1339 classifier->RecordStrictModeFormalParameterError(
1340 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1341 if (is_strict(language_mode())) {
1342 classifier->RecordBindingPatternError(
1343 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1344 }
1345 }
1346 if (this->IsArguments(name)) {
1347 scope_->RecordArgumentsUsage();
1348 classifier->RecordStrictModeFormalParameterError(
1349 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1350 if (is_strict(language_mode())) {
1351 classifier->RecordBindingPatternError(
1352 scanner()->location(), MessageTemplate::kStrictEvalArguments);
1353 }
1354 }
1355 if (this->IsAwait(name)) {
1356 if (is_async_function()) {
1357 classifier->RecordPatternError(
1358 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
1359 }
1360 classifier->RecordAsyncArrowFormalParametersError(
1361 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
1362 }
1363
1364 if (classifier->duplicate_finder() != nullptr &&
1365 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
1366 classifier->RecordDuplicateFormalParameterError(scanner()->location());
1367 }
1368 return name;
1369 } else if (is_sloppy(language_mode()) &&
1370 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1371 next == Token::ESCAPED_STRICT_RESERVED_WORD ||
1372 next == Token::LET || next == Token::STATIC ||
1373 (next == Token::YIELD && !is_generator()))) {
1374 classifier->RecordStrictModeFormalParameterError(
1375 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
1376 if (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
1377 is_strict(language_mode())) {
1378 ReportUnexpectedToken(next);
1379 *ok = false;
1380 return Traits::EmptyIdentifier();
1381 }
1382 if (next == Token::LET ||
1383 (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
1384 scanner()->is_literal_contextual_keyword(CStrVector("let")))) {
1385 classifier->RecordLetPatternError(scanner()->location(),
1386 MessageTemplate::kLetInLexicalBinding);
1387 }
1388 return this->GetSymbol(scanner());
1389 } else {
1390 this->ReportUnexpectedToken(next);
1391 *ok = false;
1392 return Traits::EmptyIdentifier();
1393 }
1394 }
1395
1396
1397 template <class Traits>
1398 typename ParserBase<Traits>::IdentifierT
ParseIdentifierOrStrictReservedWord(bool is_generator,bool * is_strict_reserved,bool * ok)1399 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord(
1400 bool is_generator, bool* is_strict_reserved, bool* ok) {
1401 Token::Value next = Next();
1402 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_) ||
1403 next == Token::ASYNC) {
1404 *is_strict_reserved = false;
1405 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
1406 next == Token::STATIC || (next == Token::YIELD && !is_generator)) {
1407 *is_strict_reserved = true;
1408 } else {
1409 ReportUnexpectedToken(next);
1410 *ok = false;
1411 return Traits::EmptyIdentifier();
1412 }
1413
1414 IdentifierT name = this->GetSymbol(scanner());
1415 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1416 return name;
1417 }
1418
1419 template <class Traits>
1420 typename ParserBase<Traits>::IdentifierT
ParseIdentifierName(bool * ok)1421 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
1422 Token::Value next = Next();
1423 if (next != Token::IDENTIFIER && next != Token::ASYNC &&
1424 next != Token::ENUM && next != Token::AWAIT && next != Token::LET &&
1425 next != Token::STATIC && next != Token::YIELD &&
1426 next != Token::FUTURE_STRICT_RESERVED_WORD &&
1427 next != Token::ESCAPED_KEYWORD &&
1428 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1429 this->ReportUnexpectedToken(next);
1430 *ok = false;
1431 return Traits::EmptyIdentifier();
1432 }
1433
1434 IdentifierT name = this->GetSymbol(scanner());
1435 if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
1436 return name;
1437 }
1438
1439
1440 template <class Traits>
ParseRegExpLiteral(bool seen_equal,ExpressionClassifier * classifier,bool * ok)1441 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
1442 bool seen_equal, ExpressionClassifier* classifier, bool* ok) {
1443 int pos = peek_position();
1444 if (!scanner()->ScanRegExpPattern(seen_equal)) {
1445 Next();
1446 ReportMessage(MessageTemplate::kUnterminatedRegExp);
1447 *ok = false;
1448 return Traits::EmptyExpression();
1449 }
1450
1451 int literal_index = function_state_->NextMaterializedLiteralIndex();
1452
1453 IdentifierT js_pattern = this->GetNextSymbol(scanner());
1454 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags();
1455 if (flags.IsNothing()) {
1456 Next();
1457 ReportMessage(MessageTemplate::kMalformedRegExpFlags);
1458 *ok = false;
1459 return Traits::EmptyExpression();
1460 }
1461 int js_flags = flags.FromJust();
1462 Next();
1463 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
1464 }
1465
1466
1467 #define CHECK_OK ok); \
1468 if (!*ok) return this->EmptyExpression(); \
1469 ((void)0
1470 #define DUMMY ) // to make indentation work
1471 #undef DUMMY
1472
1473 // Used in functions where the return type is not ExpressionT.
1474 #define CHECK_OK_CUSTOM(x) ok); \
1475 if (!*ok) return this->x(); \
1476 ((void)0
1477 #define DUMMY ) // to make indentation work
1478 #undef DUMMY
1479
1480 template <class Traits>
1481 typename ParserBase<Traits>::ExpressionT
ParsePrimaryExpression(ExpressionClassifier * classifier,bool * is_async,bool * ok)1482 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
1483 bool* is_async, bool* ok) {
1484 // PrimaryExpression ::
1485 // 'this'
1486 // 'null'
1487 // 'true'
1488 // 'false'
1489 // Identifier
1490 // Number
1491 // String
1492 // ArrayLiteral
1493 // ObjectLiteral
1494 // RegExpLiteral
1495 // ClassLiteral
1496 // '(' Expression ')'
1497 // TemplateLiteral
1498 // do Block
1499 // AsyncFunctionExpression
1500
1501 int beg_pos = peek_position();
1502 switch (peek()) {
1503 case Token::THIS: {
1504 BindingPatternUnexpectedToken(classifier);
1505 Consume(Token::THIS);
1506 return this->ThisExpression(scope_, factory(), beg_pos);
1507 }
1508
1509 case Token::NULL_LITERAL:
1510 case Token::TRUE_LITERAL:
1511 case Token::FALSE_LITERAL:
1512 BindingPatternUnexpectedToken(classifier);
1513 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1514 case Token::SMI:
1515 case Token::NUMBER:
1516 BindingPatternUnexpectedToken(classifier);
1517 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
1518
1519 case Token::ASYNC:
1520 if (allow_harmony_async_await() &&
1521 !scanner()->HasAnyLineTerminatorAfterNext() &&
1522 PeekAhead() == Token::FUNCTION) {
1523 Consume(Token::ASYNC);
1524 return this->ParseAsyncFunctionExpression(CHECK_OK);
1525 }
1526 // CoverCallExpressionAndAsyncArrowHead
1527 *is_async = true;
1528 /* falls through */
1529 case Token::IDENTIFIER:
1530 case Token::LET:
1531 case Token::STATIC:
1532 case Token::YIELD:
1533 case Token::AWAIT:
1534 case Token::ESCAPED_STRICT_RESERVED_WORD:
1535 case Token::FUTURE_STRICT_RESERVED_WORD: {
1536 // Using eval or arguments in this context is OK even in strict mode.
1537 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
1538 return this->ExpressionFromIdentifier(
1539 name, beg_pos, scanner()->location().end_pos, scope_, factory());
1540 }
1541
1542 case Token::STRING: {
1543 BindingPatternUnexpectedToken(classifier);
1544 Consume(Token::STRING);
1545 return this->ExpressionFromString(beg_pos, scanner(), factory());
1546 }
1547
1548 case Token::ASSIGN_DIV:
1549 classifier->RecordBindingPatternError(
1550 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
1551 return this->ParseRegExpLiteral(true, classifier, ok);
1552
1553 case Token::DIV:
1554 classifier->RecordBindingPatternError(
1555 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
1556 return this->ParseRegExpLiteral(false, classifier, ok);
1557
1558 case Token::LBRACK:
1559 return this->ParseArrayLiteral(classifier, ok);
1560
1561 case Token::LBRACE:
1562 return this->ParseObjectLiteral(classifier, ok);
1563
1564 case Token::LPAREN: {
1565 // Arrow function formal parameters are either a single identifier or a
1566 // list of BindingPattern productions enclosed in parentheses.
1567 // Parentheses are not valid on the LHS of a BindingPattern, so we use the
1568 // is_valid_binding_pattern() check to detect multiple levels of
1569 // parenthesization.
1570 bool pattern_error = !classifier->is_valid_binding_pattern();
1571 classifier->RecordPatternError(scanner()->peek_location(),
1572 MessageTemplate::kUnexpectedToken,
1573 Token::String(Token::LPAREN));
1574 if (pattern_error) ArrowFormalParametersUnexpectedToken(classifier);
1575 Consume(Token::LPAREN);
1576 if (Check(Token::RPAREN)) {
1577 // ()=>x. The continuation that looks for the => is in
1578 // ParseAssignmentExpression.
1579 classifier->RecordExpressionError(scanner()->location(),
1580 MessageTemplate::kUnexpectedToken,
1581 Token::String(Token::RPAREN));
1582 return factory()->NewEmptyParentheses(beg_pos);
1583 } else if (Check(Token::ELLIPSIS)) {
1584 // (...x)=>x. The continuation that looks for the => is in
1585 // ParseAssignmentExpression.
1586 int ellipsis_pos = position();
1587 int expr_pos = peek_position();
1588 classifier->RecordExpressionError(scanner()->location(),
1589 MessageTemplate::kUnexpectedToken,
1590 Token::String(Token::ELLIPSIS));
1591 classifier->RecordNonSimpleParameter();
1592 ExpressionClassifier binding_classifier(this);
1593 ExpressionT expr = this->ParseAssignmentExpression(
1594 true, &binding_classifier, CHECK_OK);
1595 classifier->Accumulate(&binding_classifier,
1596 ExpressionClassifier::AllProductions);
1597 if (!this->IsIdentifier(expr) && !IsValidPattern(expr)) {
1598 classifier->RecordArrowFormalParametersError(
1599 Scanner::Location(ellipsis_pos, scanner()->location().end_pos),
1600 MessageTemplate::kInvalidRestParameter);
1601 }
1602 if (peek() == Token::COMMA) {
1603 ReportMessageAt(scanner()->peek_location(),
1604 MessageTemplate::kParamAfterRest);
1605 *ok = false;
1606 return this->EmptyExpression();
1607 }
1608 Expect(Token::RPAREN, CHECK_OK);
1609 return factory()->NewSpread(expr, ellipsis_pos, expr_pos);
1610 }
1611 // Heuristically try to detect immediately called functions before
1612 // seeing the call parentheses.
1613 function_state_->next_function_is_parenthesized(peek() ==
1614 Token::FUNCTION);
1615 ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK);
1616 Expect(Token::RPAREN, CHECK_OK);
1617 return expr;
1618 }
1619
1620 case Token::CLASS: {
1621 BindingPatternUnexpectedToken(classifier);
1622 Consume(Token::CLASS);
1623 int class_token_position = position();
1624 IdentifierT name = this->EmptyIdentifier();
1625 bool is_strict_reserved_name = false;
1626 Scanner::Location class_name_location = Scanner::Location::invalid();
1627 if (peek_any_identifier()) {
1628 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1629 CHECK_OK);
1630 class_name_location = scanner()->location();
1631 }
1632 return this->ParseClassLiteral(classifier, name, class_name_location,
1633 is_strict_reserved_name,
1634 class_token_position, ok);
1635 }
1636
1637 case Token::TEMPLATE_SPAN:
1638 case Token::TEMPLATE_TAIL:
1639 BindingPatternUnexpectedToken(classifier);
1640 return this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
1641 classifier, ok);
1642
1643 case Token::MOD:
1644 if (allow_natives() || extension_ != NULL) {
1645 BindingPatternUnexpectedToken(classifier);
1646 return this->ParseV8Intrinsic(ok);
1647 }
1648 break;
1649
1650 case Token::DO:
1651 if (allow_harmony_do_expressions()) {
1652 BindingPatternUnexpectedToken(classifier);
1653 return Traits::ParseDoExpression(ok);
1654 }
1655 break;
1656
1657 default:
1658 break;
1659 }
1660
1661 ReportUnexpectedToken(Next());
1662 *ok = false;
1663 return this->EmptyExpression();
1664 }
1665
1666
1667 template <class Traits>
ParseExpression(bool accept_IN,bool * ok)1668 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1669 bool accept_IN, bool* ok) {
1670 ExpressionClassifier classifier(this);
1671 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
1672 Traits::RewriteNonPattern(&classifier, CHECK_OK);
1673 return result;
1674 }
1675
1676 template <class Traits>
ParseExpression(bool accept_IN,ExpressionClassifier * classifier,bool * ok)1677 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1678 bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
1679 // Expression ::
1680 // AssignmentExpression
1681 // Expression ',' AssignmentExpression
1682
1683 ExpressionT result = this->EmptyExpression();
1684 {
1685 ExpressionClassifier binding_classifier(this);
1686 result = this->ParseAssignmentExpression(accept_IN, &binding_classifier,
1687 CHECK_OK);
1688 classifier->Accumulate(&binding_classifier,
1689 ExpressionClassifier::AllProductions);
1690 }
1691 bool is_simple_parameter_list = this->IsIdentifier(result);
1692 bool seen_rest = false;
1693 while (peek() == Token::COMMA) {
1694 CheckNoTailCallExpressions(classifier, CHECK_OK);
1695 if (seen_rest) {
1696 // At this point the production can't possibly be valid, but we don't know
1697 // which error to signal.
1698 classifier->RecordArrowFormalParametersError(
1699 scanner()->peek_location(), MessageTemplate::kParamAfterRest);
1700 }
1701 Consume(Token::COMMA);
1702 bool is_rest = false;
1703 if (peek() == Token::ELLIPSIS) {
1704 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
1705 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
1706 // valid expression or binding pattern.
1707 ExpressionUnexpectedToken(classifier);
1708 BindingPatternUnexpectedToken(classifier);
1709 Consume(Token::ELLIPSIS);
1710 seen_rest = is_rest = true;
1711 }
1712 int pos = position(), expr_pos = peek_position();
1713 ExpressionClassifier binding_classifier(this);
1714 ExpressionT right = this->ParseAssignmentExpression(
1715 accept_IN, &binding_classifier, CHECK_OK);
1716 classifier->Accumulate(&binding_classifier,
1717 ExpressionClassifier::AllProductions);
1718 if (is_rest) {
1719 if (!this->IsIdentifier(right) && !IsValidPattern(right)) {
1720 classifier->RecordArrowFormalParametersError(
1721 Scanner::Location(pos, scanner()->location().end_pos),
1722 MessageTemplate::kInvalidRestParameter);
1723 }
1724 right = factory()->NewSpread(right, pos, expr_pos);
1725 }
1726 is_simple_parameter_list =
1727 is_simple_parameter_list && this->IsIdentifier(right);
1728 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
1729 }
1730 if (!is_simple_parameter_list || seen_rest) {
1731 classifier->RecordNonSimpleParameter();
1732 }
1733
1734 return result;
1735 }
1736
1737
1738 template <class Traits>
ParseArrayLiteral(ExpressionClassifier * classifier,bool * ok)1739 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
1740 ExpressionClassifier* classifier, bool* ok) {
1741 // ArrayLiteral ::
1742 // '[' Expression? (',' Expression?)* ']'
1743
1744 int pos = peek_position();
1745 typename Traits::Type::ExpressionList values =
1746 this->NewExpressionList(4, zone_);
1747 int first_spread_index = -1;
1748 Expect(Token::LBRACK, CHECK_OK);
1749 while (peek() != Token::RBRACK) {
1750 ExpressionT elem = this->EmptyExpression();
1751 if (peek() == Token::COMMA) {
1752 elem = this->GetLiteralTheHole(peek_position(), factory());
1753 } else if (peek() == Token::ELLIPSIS) {
1754 int start_pos = peek_position();
1755 Consume(Token::ELLIPSIS);
1756 int expr_pos = peek_position();
1757 ExpressionT argument =
1758 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
1759 CheckNoTailCallExpressions(classifier, CHECK_OK);
1760 elem = factory()->NewSpread(argument, start_pos, expr_pos);
1761
1762 if (first_spread_index < 0) {
1763 first_spread_index = values->length();
1764 }
1765
1766 if (argument->IsAssignment()) {
1767 classifier->RecordPatternError(
1768 Scanner::Location(start_pos, scanner()->location().end_pos),
1769 MessageTemplate::kInvalidDestructuringTarget);
1770 } else {
1771 CheckDestructuringElement(argument, classifier, start_pos,
1772 scanner()->location().end_pos);
1773 }
1774
1775 if (peek() == Token::COMMA) {
1776 classifier->RecordPatternError(
1777 Scanner::Location(start_pos, scanner()->location().end_pos),
1778 MessageTemplate::kElementAfterRest);
1779 }
1780 } else {
1781 int beg_pos = peek_position();
1782 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
1783 CheckNoTailCallExpressions(classifier, CHECK_OK);
1784 CheckDestructuringElement(elem, classifier, beg_pos,
1785 scanner()->location().end_pos);
1786 }
1787 values->Add(elem, zone_);
1788 if (peek() != Token::RBRACK) {
1789 Expect(Token::COMMA, CHECK_OK);
1790 }
1791 }
1792 Expect(Token::RBRACK, CHECK_OK);
1793
1794 // Update the scope information before the pre-parsing bailout.
1795 int literal_index = function_state_->NextMaterializedLiteralIndex();
1796
1797 ExpressionT result = factory()->NewArrayLiteral(values, first_spread_index,
1798 literal_index, pos);
1799 if (first_spread_index >= 0) {
1800 result = factory()->NewRewritableExpression(result);
1801 Traits::QueueNonPatternForRewriting(result, ok);
1802 if (!*ok) {
1803 // If the non-pattern rewriting mechanism is used in the future for
1804 // rewriting other things than spreads, this error message will have
1805 // to change. Also, this error message will never appear while pre-
1806 // parsing (this is OK, as it is an implementation limitation).
1807 ReportMessage(MessageTemplate::kTooManySpreads);
1808 return this->EmptyExpression();
1809 }
1810 }
1811 return result;
1812 }
1813
1814 template <class Traits>
ParsePropertyName(IdentifierT * name,bool * is_get,bool * is_set,bool * is_await,bool * is_computed_name,ExpressionClassifier * classifier,bool * ok)1815 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
1816 IdentifierT* name, bool* is_get, bool* is_set, bool* is_await,
1817 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) {
1818 Token::Value token = peek();
1819 int pos = peek_position();
1820
1821 // For non computed property names we normalize the name a bit:
1822 //
1823 // "12" -> 12
1824 // 12.3 -> "12.3"
1825 // 12.30 -> "12.3"
1826 // identifier -> "identifier"
1827 //
1828 // This is important because we use the property name as a key in a hash
1829 // table when we compute constant properties.
1830 switch (token) {
1831 case Token::STRING:
1832 Consume(Token::STRING);
1833 *name = this->GetSymbol(scanner());
1834 break;
1835
1836 case Token::SMI:
1837 Consume(Token::SMI);
1838 *name = this->GetNumberAsSymbol(scanner());
1839 break;
1840
1841 case Token::NUMBER:
1842 Consume(Token::NUMBER);
1843 *name = this->GetNumberAsSymbol(scanner());
1844 break;
1845
1846 case Token::LBRACK: {
1847 *is_computed_name = true;
1848 Consume(Token::LBRACK);
1849 ExpressionClassifier computed_name_classifier(this);
1850 ExpressionT expression =
1851 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK);
1852 Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK);
1853 classifier->Accumulate(&computed_name_classifier,
1854 ExpressionClassifier::ExpressionProductions);
1855 Expect(Token::RBRACK, CHECK_OK);
1856 return expression;
1857 }
1858
1859 default:
1860 *name = ParseIdentifierName(CHECK_OK);
1861 scanner()->IsGetOrSet(is_get, is_set);
1862 if (this->IsAwait(*name)) {
1863 *is_await = true;
1864 }
1865 break;
1866 }
1867
1868 uint32_t index;
1869 return this->IsArrayIndex(*name, &index)
1870 ? factory()->NewNumberLiteral(index, pos)
1871 : factory()->NewStringLiteral(*name, pos);
1872 }
1873
1874 template <class Traits>
1875 typename ParserBase<Traits>::ObjectLiteralPropertyT
ParsePropertyDefinition(ObjectLiteralCheckerBase * checker,bool in_class,bool has_extends,MethodKind method_kind,bool * is_computed_name,bool * has_seen_constructor,ExpressionClassifier * classifier,IdentifierT * name,bool * ok)1876 ParserBase<Traits>::ParsePropertyDefinition(
1877 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
1878 MethodKind method_kind, bool* is_computed_name, bool* has_seen_constructor,
1879 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) {
1880 DCHECK(!in_class || IsStaticMethod(method_kind) ||
1881 has_seen_constructor != nullptr);
1882 ExpressionT value = this->EmptyExpression();
1883 bool is_get = false;
1884 bool is_set = false;
1885 bool is_await = false;
1886 bool is_generator = Check(Token::MUL);
1887 bool is_async = false;
1888 const bool is_static = IsStaticMethod(method_kind);
1889
1890 Token::Value name_token = peek();
1891
1892 if (is_generator) {
1893 method_kind |= MethodKind::Generator;
1894 } else if (allow_harmony_async_await() && name_token == Token::ASYNC &&
1895 !scanner()->HasAnyLineTerminatorAfterNext() &&
1896 PeekAhead() != Token::LPAREN && PeekAhead()) {
1897 is_async = true;
1898 }
1899
1900 int next_beg_pos = scanner()->peek_location().beg_pos;
1901 int next_end_pos = scanner()->peek_location().end_pos;
1902 ExpressionT name_expression = ParsePropertyName(
1903 name, &is_get, &is_set, &is_await, is_computed_name, classifier,
1904 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1905
1906 if (fni_ != nullptr && !*is_computed_name) {
1907 this->PushLiteralName(fni_, *name);
1908 }
1909
1910 if (!in_class && !is_generator) {
1911 DCHECK(!IsStaticMethod(method_kind));
1912
1913 if (peek() == Token::COLON) {
1914 // PropertyDefinition
1915 // PropertyName ':' AssignmentExpression
1916 if (!*is_computed_name) {
1917 checker->CheckProperty(name_token, kValueProperty, MethodKind::Normal,
1918 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1919 }
1920 Consume(Token::COLON);
1921 int beg_pos = peek_position();
1922 value = this->ParseAssignmentExpression(
1923 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1924 CheckDestructuringElement(value, classifier, beg_pos,
1925 scanner()->location().end_pos);
1926
1927 return factory()->NewObjectLiteralProperty(name_expression, value,
1928 is_static, *is_computed_name);
1929 }
1930
1931 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(),
1932 parsing_module_) &&
1933 (peek() == Token::COMMA || peek() == Token::RBRACE ||
1934 peek() == Token::ASSIGN)) {
1935 // PropertyDefinition
1936 // IdentifierReference
1937 // CoverInitializedName
1938 //
1939 // CoverInitializedName
1940 // IdentifierReference Initializer?
1941 if (classifier->duplicate_finder() != nullptr &&
1942 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
1943 classifier->RecordDuplicateFormalParameterError(scanner()->location());
1944 }
1945 if (name_token == Token::LET) {
1946 classifier->RecordLetPatternError(
1947 scanner()->location(), MessageTemplate::kLetInLexicalBinding);
1948 }
1949 if (is_await) {
1950 if (is_async_function()) {
1951 classifier->RecordPatternError(
1952 Scanner::Location(next_beg_pos, next_end_pos),
1953 MessageTemplate::kAwaitBindingIdentifier);
1954 } else {
1955 classifier->RecordAsyncArrowFormalParametersError(
1956 Scanner::Location(next_beg_pos, next_end_pos),
1957 MessageTemplate::kAwaitBindingIdentifier);
1958 }
1959 }
1960 ExpressionT lhs = this->ExpressionFromIdentifier(
1961 *name, next_beg_pos, next_end_pos, scope_, factory());
1962 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos);
1963
1964 if (peek() == Token::ASSIGN) {
1965 Consume(Token::ASSIGN);
1966 ExpressionClassifier rhs_classifier(this);
1967 ExpressionT rhs = this->ParseAssignmentExpression(
1968 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1969 Traits::RewriteNonPattern(&rhs_classifier,
1970 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1971 classifier->Accumulate(&rhs_classifier,
1972 ExpressionClassifier::ExpressionProductions);
1973 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
1974 RelocInfo::kNoPosition);
1975 classifier->RecordCoverInitializedNameError(
1976 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
1977 MessageTemplate::kInvalidCoverInitializedName);
1978
1979 Traits::SetFunctionNameFromIdentifierRef(rhs, lhs);
1980 } else {
1981 value = lhs;
1982 }
1983
1984 return factory()->NewObjectLiteralProperty(
1985 name_expression, value, ObjectLiteralProperty::COMPUTED, is_static,
1986 false);
1987 }
1988 }
1989
1990 // Method definitions are never valid in patterns.
1991 classifier->RecordPatternError(
1992 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
1993 MessageTemplate::kInvalidDestructuringTarget);
1994
1995 if (is_async && !IsSpecialMethod(method_kind)) {
1996 DCHECK(!is_get);
1997 DCHECK(!is_set);
1998 bool dont_care;
1999 name_expression = ParsePropertyName(
2000 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
2001 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2002 method_kind |= MethodKind::Async;
2003 }
2004
2005 if (is_generator || peek() == Token::LPAREN) {
2006 // MethodDefinition
2007 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2008 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2009 if (!*is_computed_name) {
2010 checker->CheckProperty(name_token, kMethodProperty, method_kind,
2011 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2012 }
2013
2014 FunctionKind kind = is_generator
2015 ? FunctionKind::kConciseGeneratorMethod
2016 : is_async ? FunctionKind::kAsyncConciseMethod
2017 : FunctionKind::kConciseMethod;
2018
2019 if (in_class && !IsStaticMethod(method_kind) &&
2020 this->IsConstructor(*name)) {
2021 *has_seen_constructor = true;
2022 kind = has_extends ? FunctionKind::kSubclassConstructor
2023 : FunctionKind::kBaseConstructor;
2024 }
2025
2026 value = this->ParseFunctionLiteral(
2027 *name, scanner()->location(), kSkipFunctionNameCheck, kind,
2028 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod,
2029 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2030
2031 return factory()->NewObjectLiteralProperty(name_expression, value,
2032 ObjectLiteralProperty::COMPUTED,
2033 is_static, *is_computed_name);
2034 }
2035
2036 if (in_class && name_token == Token::STATIC && IsNormalMethod(method_kind)) {
2037 // ClassElement (static)
2038 // 'static' MethodDefinition
2039 *name = this->EmptyIdentifier();
2040 ObjectLiteralPropertyT property = ParsePropertyDefinition(
2041 checker, true, has_extends, MethodKind::Static, is_computed_name,
2042 nullptr, classifier, name, ok);
2043 Traits::RewriteNonPattern(classifier, ok);
2044 return property;
2045 }
2046
2047 if (is_get || is_set) {
2048 // MethodDefinition (Accessors)
2049 // get PropertyName '(' ')' '{' FunctionBody '}'
2050 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}'
2051 *name = this->EmptyIdentifier();
2052 bool dont_care = false;
2053 name_token = peek();
2054
2055 name_expression = ParsePropertyName(
2056 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
2057 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2058
2059 if (!*is_computed_name) {
2060 checker->CheckProperty(name_token, kAccessorProperty, method_kind,
2061 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2062 }
2063
2064 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
2065 *name, scanner()->location(), kSkipFunctionNameCheck,
2066 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction,
2067 RelocInfo::kNoPosition, FunctionLiteral::kAccessorOrMethod,
2068 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2069
2070 // Make sure the name expression is a string since we need a Name for
2071 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
2072 // statically we can skip the extra runtime check.
2073 if (!*is_computed_name) {
2074 name_expression =
2075 factory()->NewStringLiteral(*name, name_expression->position());
2076 }
2077
2078 return factory()->NewObjectLiteralProperty(
2079 name_expression, value,
2080 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
2081 is_static, *is_computed_name);
2082 }
2083
2084 Token::Value next = Next();
2085 ReportUnexpectedToken(next);
2086 *ok = false;
2087 return this->EmptyObjectLiteralProperty();
2088 }
2089
2090
2091 template <class Traits>
ParseObjectLiteral(ExpressionClassifier * classifier,bool * ok)2092 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
2093 ExpressionClassifier* classifier, bool* ok) {
2094 // ObjectLiteral ::
2095 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2096
2097 int pos = peek_position();
2098 typename Traits::Type::PropertyList properties =
2099 this->NewPropertyList(4, zone_);
2100 int number_of_boilerplate_properties = 0;
2101 bool has_computed_names = false;
2102 ObjectLiteralChecker checker(this);
2103
2104 Expect(Token::LBRACE, CHECK_OK);
2105
2106 while (peek() != Token::RBRACE) {
2107 FuncNameInferrer::State fni_state(fni_);
2108
2109 const bool in_class = false;
2110 const bool has_extends = false;
2111 bool is_computed_name = false;
2112 IdentifierT name = this->EmptyIdentifier();
2113 ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
2114 &checker, in_class, has_extends, MethodKind::Normal, &is_computed_name,
2115 NULL, classifier, &name, CHECK_OK);
2116
2117 if (is_computed_name) {
2118 has_computed_names = true;
2119 }
2120
2121 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2122 if (!has_computed_names && this->IsBoilerplateProperty(property)) {
2123 number_of_boilerplate_properties++;
2124 }
2125 properties->Add(property, zone());
2126
2127 if (peek() != Token::RBRACE) {
2128 // Need {} because of the CHECK_OK macro.
2129 Expect(Token::COMMA, CHECK_OK);
2130 }
2131
2132 if (fni_ != nullptr) fni_->Infer();
2133
2134 Traits::SetFunctionNameFromPropertyName(property, name);
2135 }
2136 Expect(Token::RBRACE, CHECK_OK);
2137
2138 // Computation of literal_index must happen before pre parse bailout.
2139 int literal_index = function_state_->NextMaterializedLiteralIndex();
2140
2141 return factory()->NewObjectLiteral(properties,
2142 literal_index,
2143 number_of_boilerplate_properties,
2144 pos);
2145 }
2146
2147 template <class Traits>
ParseArguments(Scanner::Location * first_spread_arg_loc,bool maybe_arrow,ExpressionClassifier * classifier,bool * ok)2148 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
2149 Scanner::Location* first_spread_arg_loc, bool maybe_arrow,
2150 ExpressionClassifier* classifier, bool* ok) {
2151 // Arguments ::
2152 // '(' (AssignmentExpression)*[','] ')'
2153
2154 Scanner::Location spread_arg = Scanner::Location::invalid();
2155 typename Traits::Type::ExpressionList result =
2156 this->NewExpressionList(4, zone_);
2157 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
2158 bool done = (peek() == Token::RPAREN);
2159 bool was_unspread = false;
2160 int unspread_sequences_count = 0;
2161 while (!done) {
2162 int start_pos = peek_position();
2163 bool is_spread = Check(Token::ELLIPSIS);
2164 int expr_pos = peek_position();
2165
2166 ExpressionT argument = this->ParseAssignmentExpression(
2167 true, classifier, CHECK_OK_CUSTOM(NullExpressionList));
2168 CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList));
2169 if (!maybe_arrow) {
2170 Traits::RewriteNonPattern(classifier,
2171 CHECK_OK_CUSTOM(NullExpressionList));
2172 }
2173 if (is_spread) {
2174 if (!spread_arg.IsValid()) {
2175 spread_arg.beg_pos = start_pos;
2176 spread_arg.end_pos = peek_position();
2177 }
2178 argument = factory()->NewSpread(argument, start_pos, expr_pos);
2179 }
2180 result->Add(argument, zone_);
2181
2182 // unspread_sequences_count is the number of sequences of parameters which
2183 // are not prefixed with a spread '...' operator.
2184 if (is_spread) {
2185 was_unspread = false;
2186 } else if (!was_unspread) {
2187 was_unspread = true;
2188 unspread_sequences_count++;
2189 }
2190
2191 if (result->length() > Code::kMaxArguments) {
2192 ReportMessage(MessageTemplate::kTooManyArguments);
2193 *ok = false;
2194 return this->NullExpressionList();
2195 }
2196 done = (peek() != Token::COMMA);
2197 if (!done) {
2198 Next();
2199 }
2200 }
2201 Scanner::Location location = scanner_->location();
2202 if (Token::RPAREN != Next()) {
2203 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
2204 *ok = false;
2205 return this->NullExpressionList();
2206 }
2207 *first_spread_arg_loc = spread_arg;
2208
2209 if (!maybe_arrow || peek() != Token::ARROW) {
2210 if (maybe_arrow) {
2211 Traits::RewriteNonPattern(classifier,
2212 CHECK_OK_CUSTOM(NullExpressionList));
2213 }
2214 if (spread_arg.IsValid()) {
2215 // Unspread parameter sequences are translated into array literals in the
2216 // parser. Ensure that the number of materialized literals matches between
2217 // the parser and preparser
2218 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
2219 }
2220 }
2221
2222 return result;
2223 }
2224
2225 // Precedence = 2
2226 template <class Traits>
2227 typename ParserBase<Traits>::ExpressionT
ParseAssignmentExpression(bool accept_IN,ExpressionClassifier * classifier,bool * ok)2228 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
2229 ExpressionClassifier* classifier,
2230 bool* ok) {
2231 // AssignmentExpression ::
2232 // ConditionalExpression
2233 // ArrowFunction
2234 // YieldExpression
2235 // LeftHandSideExpression AssignmentOperator AssignmentExpression
2236 bool is_destructuring_assignment = false;
2237 int lhs_beg_pos = peek_position();
2238
2239 if (peek() == Token::YIELD && is_generator()) {
2240 return this->ParseYieldExpression(accept_IN, classifier, ok);
2241 }
2242
2243 FuncNameInferrer::State fni_state(fni_);
2244 ParserBase<Traits>::Checkpoint checkpoint(this);
2245 ExpressionClassifier arrow_formals_classifier(this,
2246 classifier->duplicate_finder());
2247
2248 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC &&
2249 !scanner()->HasAnyLineTerminatorAfterNext() &&
2250 IsValidArrowFormalParametersStart(PeekAhead());
2251
2252 bool parenthesized_formals = peek() == Token::LPAREN;
2253 if (!is_async && !parenthesized_formals) {
2254 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
2255 }
2256 ExpressionT expression = this->ParseConditionalExpression(
2257 accept_IN, &arrow_formals_classifier, CHECK_OK);
2258
2259 if (is_async && peek_any_identifier() && PeekAhead() == Token::ARROW) {
2260 // async Identifier => AsyncConciseBody
2261 IdentifierT name =
2262 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK);
2263 expression = this->ExpressionFromIdentifier(
2264 name, position(), scanner()->location().end_pos, scope_, factory());
2265 }
2266
2267 if (peek() == Token::ARROW) {
2268 Scanner::Location arrow_loc = scanner()->peek_location();
2269 ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
2270 parenthesized_formals, is_async, CHECK_OK);
2271 // This reads strangely, but is correct: it checks whether any
2272 // sub-expression of the parameter list failed to be a valid formal
2273 // parameter initializer. Since YieldExpressions are banned anywhere
2274 // in an arrow parameter list, this is correct.
2275 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to
2276 // "YieldExpression", which is its only use.
2277 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok);
2278
2279 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
2280 Scope* scope = this->NewScope(scope_, FUNCTION_SCOPE,
2281 is_async ? FunctionKind::kAsyncArrowFunction
2282 : FunctionKind::kArrowFunction);
2283 // Because the arrow's parameters were parsed in the outer scope, any
2284 // usage flags that might have been triggered there need to be copied
2285 // to the arrow scope.
2286 scope_->PropagateUsageFlagsToScope(scope);
2287 FormalParametersT parameters(scope);
2288 if (!arrow_formals_classifier.is_simple_parameter_list()) {
2289 scope->SetHasNonSimpleParameters();
2290 parameters.is_simple = false;
2291 }
2292
2293 checkpoint.Restore(¶meters.materialized_literals_count);
2294
2295 scope->set_start_position(lhs_beg_pos);
2296 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2297 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc,
2298 &duplicate_loc, CHECK_OK);
2299 if (duplicate_loc.IsValid()) {
2300 arrow_formals_classifier.RecordDuplicateFormalParameterError(
2301 duplicate_loc);
2302 }
2303 expression = this->ParseArrowFunctionLiteral(
2304 accept_IN, parameters, is_async, arrow_formals_classifier, CHECK_OK);
2305 arrow_formals_classifier.Discard();
2306 classifier->RecordPatternError(arrow_loc,
2307 MessageTemplate::kUnexpectedToken,
2308 Token::String(Token::ARROW));
2309
2310 if (fni_ != nullptr) fni_->Infer();
2311
2312 return expression;
2313 }
2314
2315 if (this->IsValidReferenceExpression(expression)) {
2316 arrow_formals_classifier.ForgiveAssignmentPatternError();
2317 }
2318
2319 // "expression" was not itself an arrow function parameter list, but it might
2320 // form part of one. Propagate speculative formal parameter error locations.
2321 // Do not merge pending non-pattern expressions yet!
2322 classifier->Accumulate(
2323 &arrow_formals_classifier,
2324 ExpressionClassifier::StandardProductions |
2325 ExpressionClassifier::FormalParametersProductions |
2326 ExpressionClassifier::CoverInitializedNameProduction |
2327 ExpressionClassifier::AsyncArrowFormalParametersProduction |
2328 ExpressionClassifier::AsyncBindingPatternProduction,
2329 false);
2330
2331 if (!Token::IsAssignmentOp(peek())) {
2332 // Parsed conditional expression only (no assignment).
2333 // Now pending non-pattern expressions must be merged.
2334 classifier->MergeNonPatterns(&arrow_formals_classifier);
2335 return expression;
2336 }
2337
2338 // Now pending non-pattern expressions must be discarded.
2339 arrow_formals_classifier.Discard();
2340
2341 CheckNoTailCallExpressions(classifier, CHECK_OK);
2342
2343 if (IsValidPattern(expression) && peek() == Token::ASSIGN) {
2344 classifier->ForgiveCoverInitializedNameError();
2345 ValidateAssignmentPattern(classifier, CHECK_OK);
2346 is_destructuring_assignment = true;
2347 } else {
2348 expression = this->CheckAndRewriteReferenceExpression(
2349 expression, lhs_beg_pos, scanner()->location().end_pos,
2350 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK);
2351 }
2352
2353 expression = this->MarkExpressionAsAssigned(expression);
2354
2355 Token::Value op = Next(); // Get assignment operator.
2356 if (op != Token::ASSIGN) {
2357 classifier->RecordPatternError(scanner()->location(),
2358 MessageTemplate::kUnexpectedToken,
2359 Token::String(op));
2360 }
2361 int pos = position();
2362
2363 ExpressionClassifier rhs_classifier(this);
2364
2365 ExpressionT right =
2366 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
2367 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK);
2368 Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK);
2369 classifier->Accumulate(
2370 &rhs_classifier,
2371 ExpressionClassifier::ExpressionProductions |
2372 ExpressionClassifier::CoverInitializedNameProduction |
2373 ExpressionClassifier::AsyncArrowFormalParametersProduction);
2374
2375 // TODO(1231235): We try to estimate the set of properties set by
2376 // constructors. We define a new property whenever there is an
2377 // assignment to a property of 'this'. We should probably only add
2378 // properties if we haven't seen them before. Otherwise we'll
2379 // probably overestimate the number of properties.
2380 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
2381 function_state_->AddProperty();
2382 }
2383
2384 this->CheckAssigningFunctionLiteralToProperty(expression, right);
2385
2386 if (fni_ != NULL) {
2387 // Check if the right hand side is a call to avoid inferring a
2388 // name if we're dealing with "a = function(){...}();"-like
2389 // expression.
2390 if ((op == Token::INIT || op == Token::ASSIGN) &&
2391 (!right->IsCall() && !right->IsCallNew())) {
2392 fni_->Infer();
2393 } else {
2394 fni_->RemoveLastFunction();
2395 }
2396 }
2397
2398 if (op == Token::ASSIGN) {
2399 Traits::SetFunctionNameFromIdentifierRef(right, expression);
2400 }
2401
2402 if (op == Token::ASSIGN_EXP) {
2403 DCHECK(!is_destructuring_assignment);
2404 return Traits::RewriteAssignExponentiation(expression, right, pos);
2405 }
2406
2407 ExpressionT result = factory()->NewAssignment(op, expression, right, pos);
2408
2409 if (is_destructuring_assignment) {
2410 result = factory()->NewRewritableExpression(result);
2411 Traits::QueueDestructuringAssignmentForRewriting(result);
2412 }
2413
2414 return result;
2415 }
2416
2417 template <class Traits>
2418 typename ParserBase<Traits>::ExpressionT
ParseYieldExpression(bool accept_IN,ExpressionClassifier * classifier,bool * ok)2419 ParserBase<Traits>::ParseYieldExpression(bool accept_IN,
2420 ExpressionClassifier* classifier,
2421 bool* ok) {
2422 // YieldExpression ::
2423 // 'yield' ([no line terminator] '*'? AssignmentExpression)?
2424 int pos = peek_position();
2425 classifier->RecordPatternError(scanner()->peek_location(),
2426 MessageTemplate::kInvalidDestructuringTarget);
2427 classifier->RecordFormalParameterInitializerError(
2428 scanner()->peek_location(), MessageTemplate::kYieldInParameter);
2429 Expect(Token::YIELD, CHECK_OK);
2430 ExpressionT generator_object =
2431 factory()->NewVariableProxy(function_state_->generator_object_variable());
2432 ExpressionT expression = Traits::EmptyExpression();
2433 bool delegating = false; // yield*
2434 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
2435 if (Check(Token::MUL)) delegating = true;
2436 switch (peek()) {
2437 case Token::EOS:
2438 case Token::SEMICOLON:
2439 case Token::RBRACE:
2440 case Token::RBRACK:
2441 case Token::RPAREN:
2442 case Token::COLON:
2443 case Token::COMMA:
2444 // The above set of tokens is the complete set of tokens that can appear
2445 // after an AssignmentExpression, and none of them can start an
2446 // AssignmentExpression. This allows us to avoid looking for an RHS for
2447 // a regular yield, given only one look-ahead token.
2448 if (!delegating) break;
2449 // Delegating yields require an RHS; fall through.
2450 default:
2451 expression = ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
2452 Traits::RewriteNonPattern(classifier, CHECK_OK);
2453 break;
2454 }
2455 }
2456
2457 if (delegating) {
2458 return Traits::RewriteYieldStar(generator_object, expression, pos);
2459 }
2460
2461 expression = Traits::BuildIteratorResult(expression, false);
2462 // Hackily disambiguate o from o.next and o [Symbol.iterator]().
2463 // TODO(verwaest): Come up with a better solution.
2464 typename Traits::Type::YieldExpression yield =
2465 factory()->NewYield(generator_object, expression, pos);
2466 return yield;
2467 }
2468
2469 template <class Traits>
2470 typename ParserBase<Traits>::ExpressionT
ParseTailCallExpression(ExpressionClassifier * classifier,bool * ok)2471 ParserBase<Traits>::ParseTailCallExpression(ExpressionClassifier* classifier,
2472 bool* ok) {
2473 // TailCallExpression::
2474 // 'continue' MemberExpression Arguments
2475 // 'continue' CallExpression Arguments
2476 // 'continue' MemberExpression TemplateLiteral
2477 // 'continue' CallExpression TemplateLiteral
2478 Expect(Token::CONTINUE, CHECK_OK);
2479 int pos = position();
2480 int sub_expression_pos = peek_position();
2481 ExpressionT expression =
2482 this->ParseLeftHandSideExpression(classifier, CHECK_OK);
2483 CheckNoTailCallExpressions(classifier, CHECK_OK);
2484
2485 Scanner::Location loc(pos, scanner()->location().end_pos);
2486 if (!expression->IsCall()) {
2487 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos);
2488 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedInsideTailCall);
2489 *ok = false;
2490 return Traits::EmptyExpression();
2491 }
2492 if (Traits::IsDirectEvalCall(expression)) {
2493 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos);
2494 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedTailCallOfEval);
2495 *ok = false;
2496 return Traits::EmptyExpression();
2497 }
2498 if (!is_strict(language_mode())) {
2499 ReportMessageAt(loc, MessageTemplate::kUnexpectedSloppyTailCall);
2500 *ok = false;
2501 return Traits::EmptyExpression();
2502 }
2503 if (is_resumable()) {
2504 Scanner::Location sub_loc(sub_expression_pos, loc.end_pos);
2505 ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedTailCall);
2506 *ok = false;
2507 return Traits::EmptyExpression();
2508 }
2509 ReturnExprContext return_expr_context =
2510 function_state_->return_expr_context();
2511 if (return_expr_context != ReturnExprContext::kInsideValidReturnStatement) {
2512 MessageTemplate::Template msg = MessageTemplate::kNone;
2513 switch (return_expr_context) {
2514 case ReturnExprContext::kInsideValidReturnStatement:
2515 UNREACHABLE();
2516 return Traits::EmptyExpression();
2517 case ReturnExprContext::kInsideValidBlock:
2518 msg = MessageTemplate::kUnexpectedTailCall;
2519 break;
2520 case ReturnExprContext::kInsideTryBlock:
2521 msg = MessageTemplate::kUnexpectedTailCallInTryBlock;
2522 break;
2523 case ReturnExprContext::kInsideForInOfBody:
2524 msg = MessageTemplate::kUnexpectedTailCallInForInOf;
2525 break;
2526 }
2527 ReportMessageAt(loc, msg);
2528 *ok = false;
2529 return Traits::EmptyExpression();
2530 }
2531 classifier->RecordTailCallExpressionError(
2532 loc, MessageTemplate::kUnexpectedTailCall);
2533 function_state_->AddExplicitTailCallExpression(expression, loc);
2534 return expression;
2535 }
2536
2537 // Precedence = 3
2538 template <class Traits>
2539 typename ParserBase<Traits>::ExpressionT
ParseConditionalExpression(bool accept_IN,ExpressionClassifier * classifier,bool * ok)2540 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
2541 ExpressionClassifier* classifier,
2542 bool* ok) {
2543 // ConditionalExpression ::
2544 // LogicalOrExpression
2545 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2546
2547 int pos = peek_position();
2548 // We start using the binary expression parser for prec >= 4 only!
2549 ExpressionT expression =
2550 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
2551 if (peek() != Token::CONDITIONAL) return expression;
2552 CheckNoTailCallExpressions(classifier, CHECK_OK);
2553 Traits::RewriteNonPattern(classifier, CHECK_OK);
2554 BindingPatternUnexpectedToken(classifier);
2555 ArrowFormalParametersUnexpectedToken(classifier);
2556 Consume(Token::CONDITIONAL);
2557 // In parsing the first assignment expression in conditional
2558 // expressions we always accept the 'in' keyword; see ECMA-262,
2559 // section 11.12, page 58.
2560 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK);
2561 Traits::RewriteNonPattern(classifier, CHECK_OK);
2562 Expect(Token::COLON, CHECK_OK);
2563 ExpressionT right =
2564 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
2565 Traits::RewriteNonPattern(classifier, CHECK_OK);
2566 return factory()->NewConditional(expression, left, right, pos);
2567 }
2568
2569
2570 // Precedence >= 4
2571 template <class Traits>
2572 typename ParserBase<Traits>::ExpressionT
ParseBinaryExpression(int prec,bool accept_IN,ExpressionClassifier * classifier,bool * ok)2573 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
2574 ExpressionClassifier* classifier,
2575 bool* ok) {
2576 DCHECK(prec >= 4);
2577 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK);
2578 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2579 // prec1 >= 4
2580 while (Precedence(peek(), accept_IN) == prec1) {
2581 CheckNoTailCallExpressions(classifier, CHECK_OK);
2582 Traits::RewriteNonPattern(classifier, CHECK_OK);
2583 BindingPatternUnexpectedToken(classifier);
2584 ArrowFormalParametersUnexpectedToken(classifier);
2585 Token::Value op = Next();
2586 int pos = position();
2587
2588 const bool is_right_associative = op == Token::EXP;
2589 const int next_prec = is_right_associative ? prec1 : prec1 + 1;
2590 ExpressionT y =
2591 ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK);
2592 if (op != Token::OR && op != Token::AND) {
2593 CheckNoTailCallExpressions(classifier, CHECK_OK);
2594 }
2595 Traits::RewriteNonPattern(classifier, CHECK_OK);
2596
2597 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
2598 factory())) {
2599 continue;
2600 }
2601
2602 // For now we distinguish between comparisons and other binary
2603 // operations. (We could combine the two and get rid of this
2604 // code and AST node eventually.)
2605 if (Token::IsCompareOp(op)) {
2606 // We have a comparison.
2607 Token::Value cmp = op;
2608 switch (op) {
2609 case Token::NE: cmp = Token::EQ; break;
2610 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2611 default: break;
2612 }
2613 x = factory()->NewCompareOperation(cmp, x, y, pos);
2614 if (cmp != op) {
2615 // The comparison was negated - add a NOT.
2616 x = factory()->NewUnaryOperation(Token::NOT, x, pos);
2617 }
2618 } else if (op == Token::EXP) {
2619 x = Traits::RewriteExponentiation(x, y, pos);
2620 } else {
2621 // We have a "normal" binary operation.
2622 x = factory()->NewBinaryOperation(op, x, y, pos);
2623 }
2624 }
2625 }
2626 return x;
2627 }
2628
2629
2630 template <class Traits>
2631 typename ParserBase<Traits>::ExpressionT
ParseUnaryExpression(ExpressionClassifier * classifier,bool * ok)2632 ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
2633 bool* ok) {
2634 // UnaryExpression ::
2635 // PostfixExpression
2636 // 'delete' UnaryExpression
2637 // 'void' UnaryExpression
2638 // 'typeof' UnaryExpression
2639 // '++' UnaryExpression
2640 // '--' UnaryExpression
2641 // '+' UnaryExpression
2642 // '-' UnaryExpression
2643 // '~' UnaryExpression
2644 // '!' UnaryExpression
2645 // [+Await] AwaitExpression[?Yield]
2646
2647 Token::Value op = peek();
2648 if (Token::IsUnaryOp(op)) {
2649 BindingPatternUnexpectedToken(classifier);
2650 ArrowFormalParametersUnexpectedToken(classifier);
2651
2652 op = Next();
2653 int pos = position();
2654 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
2655 CheckNoTailCallExpressions(classifier, CHECK_OK);
2656 Traits::RewriteNonPattern(classifier, CHECK_OK);
2657
2658 if (op == Token::DELETE && is_strict(language_mode())) {
2659 if (this->IsIdentifier(expression)) {
2660 // "delete identifier" is a syntax error in strict mode.
2661 ReportMessage(MessageTemplate::kStrictDelete);
2662 *ok = false;
2663 return this->EmptyExpression();
2664 }
2665 }
2666
2667 if (peek() == Token::EXP) {
2668 ReportUnexpectedToken(Next());
2669 *ok = false;
2670 return this->EmptyExpression();
2671 }
2672
2673 // Allow Traits do rewrite the expression.
2674 return this->BuildUnaryExpression(expression, op, pos, factory());
2675 } else if (Token::IsCountOp(op)) {
2676 BindingPatternUnexpectedToken(classifier);
2677 ArrowFormalParametersUnexpectedToken(classifier);
2678 op = Next();
2679 int beg_pos = peek_position();
2680 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
2681 CheckNoTailCallExpressions(classifier, CHECK_OK);
2682 expression = this->CheckAndRewriteReferenceExpression(
2683 expression, beg_pos, scanner()->location().end_pos,
2684 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
2685 this->MarkExpressionAsAssigned(expression);
2686 Traits::RewriteNonPattern(classifier, CHECK_OK);
2687
2688 return factory()->NewCountOperation(op,
2689 true /* prefix */,
2690 expression,
2691 position());
2692
2693 } else if (is_async_function() && peek() == Token::AWAIT) {
2694 int beg_pos = peek_position();
2695 switch (PeekAhead()) {
2696 case Token::RPAREN:
2697 case Token::RBRACK:
2698 case Token::RBRACE:
2699 case Token::ASSIGN:
2700 case Token::COMMA: {
2701 Next();
2702 IdentifierT name = this->GetSymbol(scanner());
2703
2704 // Possibly async arrow formals --- record ExpressionError just in case.
2705 ExpressionUnexpectedToken(classifier);
2706 classifier->RecordAsyncBindingPatternError(
2707 Scanner::Location(beg_pos, scanner()->location().end_pos),
2708 MessageTemplate::kAwaitBindingIdentifier);
2709 classifier->RecordAsyncArrowFormalParametersError(
2710 Scanner::Location(beg_pos, scanner()->location().end_pos),
2711 MessageTemplate::kAwaitBindingIdentifier);
2712
2713 return this->ExpressionFromIdentifier(
2714 name, beg_pos, scanner()->location().end_pos, scope_, factory());
2715 }
2716 default:
2717 break;
2718 }
2719
2720 int await_pos = peek_position();
2721 Consume(Token::AWAIT);
2722
2723 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK);
2724
2725 classifier->RecordFormalParameterInitializerError(
2726 Scanner::Location(beg_pos, scanner()->location().end_pos),
2727 MessageTemplate::kAwaitExpressionFormalParameter);
2728 return Traits::RewriteAwaitExpression(value, await_pos);
2729 } else {
2730 return this->ParsePostfixExpression(classifier, ok);
2731 }
2732 }
2733
2734
2735 template <class Traits>
2736 typename ParserBase<Traits>::ExpressionT
ParsePostfixExpression(ExpressionClassifier * classifier,bool * ok)2737 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
2738 bool* ok) {
2739 // PostfixExpression ::
2740 // LeftHandSideExpression ('++' | '--')?
2741
2742 int lhs_beg_pos = peek_position();
2743 ExpressionT expression =
2744 this->ParseLeftHandSideExpression(classifier, CHECK_OK);
2745 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2746 Token::IsCountOp(peek())) {
2747 CheckNoTailCallExpressions(classifier, CHECK_OK);
2748 BindingPatternUnexpectedToken(classifier);
2749 ArrowFormalParametersUnexpectedToken(classifier);
2750
2751 expression = this->CheckAndRewriteReferenceExpression(
2752 expression, lhs_beg_pos, scanner()->location().end_pos,
2753 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
2754 expression = this->MarkExpressionAsAssigned(expression);
2755 Traits::RewriteNonPattern(classifier, CHECK_OK);
2756
2757 Token::Value next = Next();
2758 expression =
2759 factory()->NewCountOperation(next,
2760 false /* postfix */,
2761 expression,
2762 position());
2763 }
2764 return expression;
2765 }
2766
2767 template <class Traits>
2768 typename ParserBase<Traits>::ExpressionT
ParseLeftHandSideExpression(ExpressionClassifier * classifier,bool * ok)2769 ParserBase<Traits>::ParseLeftHandSideExpression(
2770 ExpressionClassifier* classifier, bool* ok) {
2771 // LeftHandSideExpression ::
2772 // (NewExpression | MemberExpression) ...
2773
2774 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) {
2775 return this->ParseTailCallExpression(classifier, ok);
2776 }
2777
2778 bool is_async = false;
2779 ExpressionT result = this->ParseMemberWithNewPrefixesExpression(
2780 classifier, &is_async, CHECK_OK);
2781
2782 while (true) {
2783 switch (peek()) {
2784 case Token::LBRACK: {
2785 CheckNoTailCallExpressions(classifier, CHECK_OK);
2786 Traits::RewriteNonPattern(classifier, CHECK_OK);
2787 BindingPatternUnexpectedToken(classifier);
2788 ArrowFormalParametersUnexpectedToken(classifier);
2789 Consume(Token::LBRACK);
2790 int pos = position();
2791 ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
2792 Traits::RewriteNonPattern(classifier, CHECK_OK);
2793 result = factory()->NewProperty(result, index, pos);
2794 Expect(Token::RBRACK, CHECK_OK);
2795 break;
2796 }
2797
2798 case Token::LPAREN: {
2799 CheckNoTailCallExpressions(classifier, CHECK_OK);
2800 int pos;
2801 Traits::RewriteNonPattern(classifier, CHECK_OK);
2802 BindingPatternUnexpectedToken(classifier);
2803 if (scanner()->current_token() == Token::IDENTIFIER ||
2804 scanner()->current_token() == Token::SUPER ||
2805 scanner()->current_token() == Token::ASYNC) {
2806 // For call of an identifier we want to report position of
2807 // the identifier as position of the call in the stack trace.
2808 pos = position();
2809 } else {
2810 // For other kinds of calls we record position of the parenthesis as
2811 // position of the call. Note that this is extremely important for
2812 // expressions of the form function(){...}() for which call position
2813 // should not point to the closing brace otherwise it will intersect
2814 // with positions recorded for function literal and confuse debugger.
2815 pos = peek_position();
2816 // Also the trailing parenthesis are a hint that the function will
2817 // be called immediately. If we happen to have parsed a preceding
2818 // function literal eagerly, we can also compile it eagerly.
2819 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
2820 result->AsFunctionLiteral()->set_should_eager_compile();
2821 }
2822 }
2823 Scanner::Location spread_pos;
2824 typename Traits::Type::ExpressionList args =
2825 ParseArguments(&spread_pos, is_async, classifier, CHECK_OK);
2826
2827 if (V8_UNLIKELY(is_async && peek() == Token::ARROW)) {
2828 if (args->length()) {
2829 // async ( Arguments ) => ...
2830 return Traits::ExpressionListToExpression(args);
2831 }
2832 // async () => ...
2833 return factory()->NewEmptyParentheses(pos);
2834 }
2835
2836 ArrowFormalParametersUnexpectedToken(classifier);
2837
2838 // Keep track of eval() calls since they disable all local variable
2839 // optimizations.
2840 // The calls that need special treatment are the
2841 // direct eval calls. These calls are all of the form eval(...), with
2842 // no explicit receiver.
2843 // These calls are marked as potentially direct eval calls. Whether
2844 // they are actually direct calls to eval is determined at run time.
2845 this->CheckPossibleEvalCall(result, scope_);
2846
2847 bool is_super_call = result->IsSuperCallReference();
2848 if (spread_pos.IsValid()) {
2849 args = Traits::PrepareSpreadArguments(args);
2850 result = Traits::SpreadCall(result, args, pos);
2851 } else {
2852 result = factory()->NewCall(result, args, pos);
2853 }
2854
2855 // Explicit calls to the super constructor using super() perform an
2856 // implicit binding assignment to the 'this' variable.
2857 if (is_super_call) {
2858 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
2859 result =
2860 factory()->NewAssignment(Token::INIT, this_expr, result, pos);
2861 }
2862
2863 if (fni_ != NULL) fni_->RemoveLastFunction();
2864 break;
2865 }
2866
2867 case Token::PERIOD: {
2868 CheckNoTailCallExpressions(classifier, CHECK_OK);
2869 Traits::RewriteNonPattern(classifier, CHECK_OK);
2870 BindingPatternUnexpectedToken(classifier);
2871 ArrowFormalParametersUnexpectedToken(classifier);
2872 Consume(Token::PERIOD);
2873 int pos = position();
2874 IdentifierT name = ParseIdentifierName(CHECK_OK);
2875 result = factory()->NewProperty(
2876 result, factory()->NewStringLiteral(name, pos), pos);
2877 if (fni_ != NULL) this->PushLiteralName(fni_, name);
2878 break;
2879 }
2880
2881 case Token::TEMPLATE_SPAN:
2882 case Token::TEMPLATE_TAIL: {
2883 CheckNoTailCallExpressions(classifier, CHECK_OK);
2884 Traits::RewriteNonPattern(classifier, CHECK_OK);
2885 BindingPatternUnexpectedToken(classifier);
2886 ArrowFormalParametersUnexpectedToken(classifier);
2887 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK);
2888 break;
2889 }
2890
2891 default:
2892 return result;
2893 }
2894 }
2895 }
2896
2897 template <class Traits>
2898 typename ParserBase<Traits>::ExpressionT
ParseMemberWithNewPrefixesExpression(ExpressionClassifier * classifier,bool * is_async,bool * ok)2899 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
2900 ExpressionClassifier* classifier, bool* is_async, bool* ok) {
2901 // NewExpression ::
2902 // ('new')+ MemberExpression
2903 //
2904 // NewTarget ::
2905 // 'new' '.' 'target'
2906
2907 // The grammar for new expressions is pretty warped. We can have several 'new'
2908 // keywords following each other, and then a MemberExpression. When we see '('
2909 // after the MemberExpression, it's associated with the rightmost unassociated
2910 // 'new' to create a NewExpression with arguments. However, a NewExpression
2911 // can also occur without arguments.
2912
2913 // Examples of new expression:
2914 // new foo.bar().baz means (new (foo.bar)()).baz
2915 // new foo()() means (new foo())()
2916 // new new foo()() means (new (new foo())())
2917 // new new foo means new (new foo)
2918 // new new foo() means new (new foo())
2919 // new new foo().bar().baz means (new (new foo()).bar()).baz
2920
2921 if (peek() == Token::NEW) {
2922 BindingPatternUnexpectedToken(classifier);
2923 ArrowFormalParametersUnexpectedToken(classifier);
2924 Consume(Token::NEW);
2925 int new_pos = position();
2926 ExpressionT result = this->EmptyExpression();
2927 if (peek() == Token::SUPER) {
2928 const bool is_new = true;
2929 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
2930 } else if (peek() == Token::PERIOD) {
2931 return ParseNewTargetExpression(CHECK_OK);
2932 } else {
2933 result = this->ParseMemberWithNewPrefixesExpression(classifier, is_async,
2934 CHECK_OK);
2935 }
2936 Traits::RewriteNonPattern(classifier, CHECK_OK);
2937 if (peek() == Token::LPAREN) {
2938 // NewExpression with arguments.
2939 Scanner::Location spread_pos;
2940 typename Traits::Type::ExpressionList args =
2941 this->ParseArguments(&spread_pos, classifier, CHECK_OK);
2942
2943 if (spread_pos.IsValid()) {
2944 args = Traits::PrepareSpreadArguments(args);
2945 result = Traits::SpreadCallNew(result, args, new_pos);
2946 } else {
2947 result = factory()->NewCallNew(result, args, new_pos);
2948 }
2949 // The expression can still continue with . or [ after the arguments.
2950 result = this->ParseMemberExpressionContinuation(result, is_async,
2951 classifier, CHECK_OK);
2952 return result;
2953 }
2954 // NewExpression without arguments.
2955 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
2956 new_pos);
2957 }
2958 // No 'new' or 'super' keyword.
2959 return this->ParseMemberExpression(classifier, is_async, ok);
2960 }
2961
2962 template <class Traits>
2963 typename ParserBase<Traits>::ExpressionT
ParseMemberExpression(ExpressionClassifier * classifier,bool * is_async,bool * ok)2964 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
2965 bool* is_async, bool* ok) {
2966 // MemberExpression ::
2967 // (PrimaryExpression | FunctionLiteral | ClassLiteral)
2968 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
2969
2970 // The '[' Expression ']' and '.' Identifier parts are parsed by
2971 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
2972 // caller.
2973
2974 // Parse the initial primary or function expression.
2975 ExpressionT result = this->EmptyExpression();
2976 if (peek() == Token::FUNCTION) {
2977 BindingPatternUnexpectedToken(classifier);
2978 ArrowFormalParametersUnexpectedToken(classifier);
2979
2980 Consume(Token::FUNCTION);
2981 int function_token_position = position();
2982
2983 if (allow_harmony_function_sent() && peek() == Token::PERIOD) {
2984 // function.sent
2985 int pos = position();
2986 ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK);
2987
2988 if (!is_generator()) {
2989 // TODO(neis): allow escaping into closures?
2990 ReportMessageAt(scanner()->location(),
2991 MessageTemplate::kUnexpectedFunctionSent);
2992 *ok = false;
2993 return this->EmptyExpression();
2994 }
2995
2996 return this->FunctionSentExpression(scope_, factory(), pos);
2997 }
2998
2999 bool is_generator = Check(Token::MUL);
3000 IdentifierT name = this->EmptyIdentifier();
3001 bool is_strict_reserved_name = false;
3002 Scanner::Location function_name_location = Scanner::Location::invalid();
3003 FunctionLiteral::FunctionType function_type =
3004 FunctionLiteral::kAnonymousExpression;
3005 if (peek_any_identifier()) {
3006 name = ParseIdentifierOrStrictReservedWord(
3007 is_generator, &is_strict_reserved_name, CHECK_OK);
3008 function_name_location = scanner()->location();
3009 function_type = FunctionLiteral::kNamedExpression;
3010 }
3011 result = this->ParseFunctionLiteral(
3012 name, function_name_location,
3013 is_strict_reserved_name ? kFunctionNameIsStrictReserved
3014 : kFunctionNameValidityUnknown,
3015 is_generator ? FunctionKind::kGeneratorFunction
3016 : FunctionKind::kNormalFunction,
3017 function_token_position, function_type, language_mode(), CHECK_OK);
3018 } else if (peek() == Token::SUPER) {
3019 const bool is_new = false;
3020 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
3021 } else {
3022 result = ParsePrimaryExpression(classifier, is_async, CHECK_OK);
3023 }
3024
3025 result =
3026 ParseMemberExpressionContinuation(result, is_async, classifier, CHECK_OK);
3027 return result;
3028 }
3029
3030
3031 template <class Traits>
3032 typename ParserBase<Traits>::ExpressionT
ParseSuperExpression(bool is_new,ExpressionClassifier * classifier,bool * ok)3033 ParserBase<Traits>::ParseSuperExpression(bool is_new,
3034 ExpressionClassifier* classifier,
3035 bool* ok) {
3036 Expect(Token::SUPER, CHECK_OK);
3037 int pos = position();
3038
3039 Scope* scope = scope_->ReceiverScope();
3040 FunctionKind kind = scope->function_kind();
3041 if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
3042 IsClassConstructor(kind)) {
3043 if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
3044 scope->RecordSuperPropertyUsage();
3045 return this->SuperPropertyReference(scope_, factory(), pos);
3046 }
3047 // new super() is never allowed.
3048 // super() is only allowed in derived constructor
3049 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
3050 // TODO(rossberg): This might not be the correct FunctionState for the
3051 // method here.
3052 function_state_->set_super_location(scanner()->location());
3053 return this->SuperCallReference(scope_, factory(), pos);
3054 }
3055 }
3056
3057 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper);
3058 *ok = false;
3059 return this->EmptyExpression();
3060 }
3061
3062 template <class Traits>
ExpectMetaProperty(Vector<const char> property_name,const char * full_name,int pos,bool * ok)3063 void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name,
3064 const char* full_name, int pos,
3065 bool* ok) {
3066 Consume(Token::PERIOD);
3067 ExpectContextualKeyword(property_name, ok);
3068 if (!*ok) return;
3069 if (scanner()->literal_contains_escapes()) {
3070 Traits::ReportMessageAt(
3071 Scanner::Location(pos, scanner()->location().end_pos),
3072 MessageTemplate::kInvalidEscapedMetaProperty, full_name);
3073 *ok = false;
3074 }
3075 }
3076
3077 template <class Traits>
3078 typename ParserBase<Traits>::ExpressionT
ParseNewTargetExpression(bool * ok)3079 ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
3080 int pos = position();
3081 ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK);
3082
3083 if (!scope_->ReceiverScope()->is_function_scope()) {
3084 ReportMessageAt(scanner()->location(),
3085 MessageTemplate::kUnexpectedNewTarget);
3086 *ok = false;
3087 return this->EmptyExpression();
3088 }
3089
3090 return this->NewTargetExpression(scope_, factory(), pos);
3091 }
3092
3093 template <class Traits>
3094 typename ParserBase<Traits>::ExpressionT
ParseMemberExpressionContinuation(ExpressionT expression,bool * is_async,ExpressionClassifier * classifier,bool * ok)3095 ParserBase<Traits>::ParseMemberExpressionContinuation(
3096 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier,
3097 bool* ok) {
3098 // Parses this part of MemberExpression:
3099 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
3100 while (true) {
3101 switch (peek()) {
3102 case Token::LBRACK: {
3103 *is_async = false;
3104 Traits::RewriteNonPattern(classifier, CHECK_OK);
3105 BindingPatternUnexpectedToken(classifier);
3106 ArrowFormalParametersUnexpectedToken(classifier);
3107
3108 Consume(Token::LBRACK);
3109 int pos = position();
3110 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
3111 Traits::RewriteNonPattern(classifier, CHECK_OK);
3112 expression = factory()->NewProperty(expression, index, pos);
3113 if (fni_ != NULL) {
3114 this->PushPropertyName(fni_, index);
3115 }
3116 Expect(Token::RBRACK, CHECK_OK);
3117 break;
3118 }
3119 case Token::PERIOD: {
3120 *is_async = false;
3121 Traits::RewriteNonPattern(classifier, CHECK_OK);
3122 BindingPatternUnexpectedToken(classifier);
3123 ArrowFormalParametersUnexpectedToken(classifier);
3124
3125 Consume(Token::PERIOD);
3126 int pos = position();
3127 IdentifierT name = ParseIdentifierName(CHECK_OK);
3128 expression = factory()->NewProperty(
3129 expression, factory()->NewStringLiteral(name, pos), pos);
3130 if (fni_ != NULL) {
3131 this->PushLiteralName(fni_, name);
3132 }
3133 break;
3134 }
3135 case Token::TEMPLATE_SPAN:
3136 case Token::TEMPLATE_TAIL: {
3137 *is_async = false;
3138 Traits::RewriteNonPattern(classifier, CHECK_OK);
3139 BindingPatternUnexpectedToken(classifier);
3140 ArrowFormalParametersUnexpectedToken(classifier);
3141 int pos;
3142 if (scanner()->current_token() == Token::IDENTIFIER) {
3143 pos = position();
3144 } else {
3145 pos = peek_position();
3146 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3147 // If the tag function looks like an IIFE, set_parenthesized() to
3148 // force eager compilation.
3149 expression->AsFunctionLiteral()->set_should_eager_compile();
3150 }
3151 }
3152 expression =
3153 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK);
3154 break;
3155 }
3156 case Token::ILLEGAL: {
3157 ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL);
3158 *ok = false;
3159 return this->EmptyExpression();
3160 }
3161 default:
3162 return expression;
3163 }
3164 }
3165 DCHECK(false);
3166 return this->EmptyExpression();
3167 }
3168
3169
3170 template <class Traits>
ParseFormalParameter(FormalParametersT * parameters,ExpressionClassifier * classifier,bool * ok)3171 void ParserBase<Traits>::ParseFormalParameter(
3172 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3173 // FormalParameter[Yield,GeneratorParameter] :
3174 // BindingElement[?Yield, ?GeneratorParameter]
3175 bool is_rest = parameters->has_rest;
3176
3177 ExpressionT pattern = ParsePrimaryExpression(classifier, ok);
3178 if (!*ok) return;
3179
3180 ValidateBindingPattern(classifier, ok);
3181 if (!*ok) return;
3182
3183 if (!Traits::IsIdentifier(pattern)) {
3184 parameters->is_simple = false;
3185 ValidateFormalParameterInitializer(classifier, ok);
3186 if (!*ok) return;
3187 classifier->RecordNonSimpleParameter();
3188 }
3189
3190 ExpressionT initializer = Traits::EmptyExpression();
3191 if (!is_rest && Check(Token::ASSIGN)) {
3192 ExpressionClassifier init_classifier(this);
3193 initializer = ParseAssignmentExpression(true, &init_classifier, ok);
3194 if (!*ok) return;
3195 Traits::RewriteNonPattern(&init_classifier, ok);
3196 ValidateFormalParameterInitializer(&init_classifier, ok);
3197 if (!*ok) return;
3198 parameters->is_simple = false;
3199 init_classifier.Discard();
3200 classifier->RecordNonSimpleParameter();
3201
3202 Traits::SetFunctionNameFromIdentifierRef(initializer, pattern);
3203 }
3204
3205 Traits::AddFormalParameter(parameters, pattern, initializer,
3206 scanner()->location().end_pos, is_rest);
3207 }
3208
3209
3210 template <class Traits>
ParseFormalParameterList(FormalParametersT * parameters,ExpressionClassifier * classifier,bool * ok)3211 void ParserBase<Traits>::ParseFormalParameterList(
3212 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3213 // FormalParameters[Yield,GeneratorParameter] :
3214 // [empty]
3215 // FormalParameterList[?Yield, ?GeneratorParameter]
3216 //
3217 // FormalParameterList[Yield,GeneratorParameter] :
3218 // FunctionRestParameter[?Yield]
3219 // FormalsList[?Yield, ?GeneratorParameter]
3220 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield]
3221 //
3222 // FormalsList[Yield,GeneratorParameter] :
3223 // FormalParameter[?Yield, ?GeneratorParameter]
3224 // FormalsList[?Yield, ?GeneratorParameter] ,
3225 // FormalParameter[?Yield,?GeneratorParameter]
3226
3227 DCHECK_EQ(0, parameters->Arity());
3228
3229 if (peek() != Token::RPAREN) {
3230 do {
3231 if (parameters->Arity() > Code::kMaxArguments) {
3232 ReportMessage(MessageTemplate::kTooManyParameters);
3233 *ok = false;
3234 return;
3235 }
3236 parameters->has_rest = Check(Token::ELLIPSIS);
3237 ParseFormalParameter(parameters, classifier, ok);
3238 if (!*ok) return;
3239 } while (!parameters->has_rest && Check(Token::COMMA));
3240
3241 if (parameters->has_rest) {
3242 parameters->is_simple = false;
3243 classifier->RecordNonSimpleParameter();
3244 if (peek() == Token::COMMA) {
3245 ReportMessageAt(scanner()->peek_location(),
3246 MessageTemplate::kParamAfterRest);
3247 *ok = false;
3248 return;
3249 }
3250 }
3251 }
3252
3253 for (int i = 0; i < parameters->Arity(); ++i) {
3254 auto parameter = parameters->at(i);
3255 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier);
3256 }
3257 }
3258
3259 template <class Traits>
CheckArityRestrictions(int param_count,FunctionKind function_kind,bool has_rest,int formals_start_pos,int formals_end_pos,bool * ok)3260 void ParserBase<Traits>::CheckArityRestrictions(int param_count,
3261 FunctionKind function_kind,
3262 bool has_rest,
3263 int formals_start_pos,
3264 int formals_end_pos, bool* ok) {
3265 if (IsGetterFunction(function_kind)) {
3266 if (param_count != 0) {
3267 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3268 MessageTemplate::kBadGetterArity);
3269 *ok = false;
3270 }
3271 } else if (IsSetterFunction(function_kind)) {
3272 if (param_count != 1) {
3273 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3274 MessageTemplate::kBadSetterArity);
3275 *ok = false;
3276 }
3277 if (has_rest) {
3278 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
3279 MessageTemplate::kBadSetterRestParameter);
3280 *ok = false;
3281 }
3282 }
3283 }
3284
3285
3286 template <class Traits>
IsNextLetKeyword()3287 bool ParserBase<Traits>::IsNextLetKeyword() {
3288 DCHECK(peek() == Token::LET);
3289 Token::Value next_next = PeekAhead();
3290 switch (next_next) {
3291 case Token::LBRACE:
3292 case Token::LBRACK:
3293 case Token::IDENTIFIER:
3294 case Token::STATIC:
3295 case Token::LET: // `let let;` is disallowed by static semantics, but the
3296 // token must be first interpreted as a keyword in order
3297 // for those semantics to apply. This ensures that ASI is
3298 // not honored when a LineTerminator separates the
3299 // tokens.
3300 case Token::YIELD:
3301 case Token::AWAIT:
3302 case Token::ASYNC:
3303 return true;
3304 case Token::FUTURE_STRICT_RESERVED_WORD:
3305 return is_sloppy(language_mode());
3306 default:
3307 return false;
3308 }
3309 }
3310
3311 template <class Traits>
3312 typename ParserBase<Traits>::ExpressionT
ParseArrowFunctionLiteral(bool accept_IN,const FormalParametersT & formal_parameters,bool is_async,const ExpressionClassifier & formals_classifier,bool * ok)3313 ParserBase<Traits>::ParseArrowFunctionLiteral(
3314 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async,
3315 const ExpressionClassifier& formals_classifier, bool* ok) {
3316 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
3317 // ASI inserts `;` after arrow parameters if a line terminator is found.
3318 // `=> ...` is never a valid expression, so report as syntax error.
3319 // If next token is not `=>`, it's a syntax error anyways.
3320 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
3321 *ok = false;
3322 return this->EmptyExpression();
3323 }
3324
3325 typename Traits::Type::StatementList body;
3326 int num_parameters = formal_parameters.scope->num_parameters();
3327 int materialized_literal_count = -1;
3328 int expected_property_count = -1;
3329 Scanner::Location super_loc;
3330
3331 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction;
3332 {
3333 typename Traits::Type::Factory function_factory(ast_value_factory());
3334 FunctionState function_state(&function_state_, &scope_,
3335 formal_parameters.scope, arrow_kind,
3336 &function_factory);
3337
3338 function_state.SkipMaterializedLiterals(
3339 formal_parameters.materialized_literals_count);
3340
3341 this->ReindexLiterals(formal_parameters);
3342
3343 Expect(Token::ARROW, CHECK_OK);
3344
3345 if (peek() == Token::LBRACE) {
3346 // Multiple statement body
3347 Consume(Token::LBRACE);
3348 bool is_lazily_parsed =
3349 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing());
3350 if (is_lazily_parsed) {
3351 body = this->NewStatementList(0, zone());
3352 this->SkipLazyFunctionBody(&materialized_literal_count,
3353 &expected_property_count, CHECK_OK);
3354 if (formal_parameters.materialized_literals_count > 0) {
3355 materialized_literal_count +=
3356 formal_parameters.materialized_literals_count;
3357 }
3358 } else {
3359 body = this->ParseEagerFunctionBody(
3360 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters,
3361 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK);
3362 materialized_literal_count =
3363 function_state.materialized_literal_count();
3364 expected_property_count = function_state.expected_property_count();
3365 }
3366 } else {
3367 // Single-expression body
3368 int pos = position();
3369 DCHECK(ReturnExprContext::kInsideValidBlock ==
3370 function_state_->return_expr_context());
3371 ReturnExprScope allow_tail_calls(
3372 function_state_, ReturnExprContext::kInsideValidReturnStatement);
3373 body = this->NewStatementList(1, zone());
3374 this->AddParameterInitializationBlock(formal_parameters, body, is_async,
3375 CHECK_OK);
3376 ExpressionClassifier classifier(this);
3377 if (is_async) {
3378 this->ParseAsyncArrowSingleExpressionBody(body, accept_IN, &classifier,
3379 pos, CHECK_OK);
3380 Traits::RewriteNonPattern(&classifier, CHECK_OK);
3381 } else {
3382 ExpressionT expression =
3383 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK);
3384 Traits::RewriteNonPattern(&classifier, CHECK_OK);
3385 body->Add(factory()->NewReturnStatement(expression, pos), zone());
3386 if (allow_tailcalls() && !is_sloppy(language_mode())) {
3387 // ES6 14.6.1 Static Semantics: IsInTailPosition
3388 this->MarkTailPosition(expression);
3389 }
3390 }
3391 materialized_literal_count = function_state.materialized_literal_count();
3392 expected_property_count = function_state.expected_property_count();
3393 this->MarkCollectedTailCallExpressions();
3394 }
3395 super_loc = function_state.super_location();
3396
3397 formal_parameters.scope->set_end_position(scanner()->location().end_pos);
3398
3399 // Arrow function formal parameters are parsed as StrictFormalParameterList,
3400 // which is not the same as "parameters of a strict function"; it only means
3401 // that duplicates are not allowed. Of course, the arrow function may
3402 // itself be strict as well.
3403 const bool allow_duplicate_parameters = false;
3404 this->ValidateFormalParameters(&formals_classifier, language_mode(),
3405 allow_duplicate_parameters, CHECK_OK);
3406
3407 // Validate strict mode.
3408 if (is_strict(language_mode())) {
3409 CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
3410 scanner()->location().end_pos, CHECK_OK);
3411 }
3412 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
3413
3414 Traits::RewriteDestructuringAssignments();
3415 }
3416
3417 FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
3418 this->EmptyIdentifierString(), formal_parameters.scope, body,
3419 materialized_literal_count, expected_property_count, num_parameters,
3420 FunctionLiteral::kNoDuplicateParameters,
3421 FunctionLiteral::kAnonymousExpression,
3422 FunctionLiteral::kShouldLazyCompile, arrow_kind,
3423 formal_parameters.scope->start_position());
3424
3425 function_literal->set_function_token_position(
3426 formal_parameters.scope->start_position());
3427 if (super_loc.IsValid()) function_state_->set_super_location(super_loc);
3428
3429 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
3430
3431 return function_literal;
3432 }
3433
3434
3435 template <typename Traits>
3436 typename ParserBase<Traits>::ExpressionT
ParseTemplateLiteral(ExpressionT tag,int start,ExpressionClassifier * classifier,bool * ok)3437 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
3438 ExpressionClassifier* classifier,
3439 bool* ok) {
3440 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
3441 // text followed by a substitution expression), finalized by a single
3442 // TEMPLATE_TAIL.
3443 //
3444 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
3445 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
3446 // NoSubstitutionTemplate.
3447 //
3448 // When parsing a TemplateLiteral, we must have scanned either an initial
3449 // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
3450 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
3451
3452 // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
3453 // In this case we may simply consume the token and build a template with a
3454 // single TEMPLATE_SPAN and no expressions.
3455 if (peek() == Token::TEMPLATE_TAIL) {
3456 Consume(Token::TEMPLATE_TAIL);
3457 int pos = position();
3458 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3459 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
3460 Traits::AddTemplateSpan(&ts, true);
3461 return Traits::CloseTemplateLiteral(&ts, start, tag);
3462 }
3463
3464 Consume(Token::TEMPLATE_SPAN);
3465 int pos = position();
3466 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
3467 Traits::AddTemplateSpan(&ts, false);
3468 Token::Value next;
3469
3470 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
3471 // and repeat if the following token is a TEMPLATE_SPAN as well (in this
3472 // case, representing a TemplateMiddle).
3473
3474 do {
3475 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3476 next = peek();
3477 if (next == Token::EOS) {
3478 ReportMessageAt(Scanner::Location(start, peek_position()),
3479 MessageTemplate::kUnterminatedTemplate);
3480 *ok = false;
3481 return Traits::EmptyExpression();
3482 } else if (next == Token::ILLEGAL) {
3483 Traits::ReportMessageAt(
3484 Scanner::Location(position() + 1, peek_position()),
3485 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
3486 *ok = false;
3487 return Traits::EmptyExpression();
3488 }
3489
3490 int expr_pos = peek_position();
3491 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK);
3492 CheckNoTailCallExpressions(classifier, CHECK_OK);
3493 Traits::RewriteNonPattern(classifier, CHECK_OK);
3494 Traits::AddTemplateExpression(&ts, expression);
3495
3496 if (peek() != Token::RBRACE) {
3497 ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
3498 MessageTemplate::kUnterminatedTemplateExpr);
3499 *ok = false;
3500 return Traits::EmptyExpression();
3501 }
3502
3503 // If we didn't die parsing that expression, our next token should be a
3504 // TEMPLATE_SPAN or TEMPLATE_TAIL.
3505 next = scanner()->ScanTemplateContinuation();
3506 Next();
3507 pos = position();
3508
3509 if (next == Token::EOS) {
3510 ReportMessageAt(Scanner::Location(start, pos),
3511 MessageTemplate::kUnterminatedTemplate);
3512 *ok = false;
3513 return Traits::EmptyExpression();
3514 } else if (next == Token::ILLEGAL) {
3515 Traits::ReportMessageAt(
3516 Scanner::Location(position() + 1, peek_position()),
3517 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
3518 *ok = false;
3519 return Traits::EmptyExpression();
3520 }
3521
3522 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL);
3523 } while (next == Token::TEMPLATE_SPAN);
3524
3525 DCHECK_EQ(next, Token::TEMPLATE_TAIL);
3526 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
3527 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
3528 return Traits::CloseTemplateLiteral(&ts, start, tag);
3529 }
3530
3531
3532 template <typename Traits>
3533 typename ParserBase<Traits>::ExpressionT
CheckAndRewriteReferenceExpression(ExpressionT expression,int beg_pos,int end_pos,MessageTemplate::Template message,bool * ok)3534 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
3535 ExpressionT expression, int beg_pos, int end_pos,
3536 MessageTemplate::Template message, bool* ok) {
3537 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
3538 message, kReferenceError, ok);
3539 }
3540
3541
3542 template <typename Traits>
3543 typename ParserBase<Traits>::ExpressionT
CheckAndRewriteReferenceExpression(ExpressionT expression,int beg_pos,int end_pos,MessageTemplate::Template message,ParseErrorType type,bool * ok)3544 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
3545 ExpressionT expression, int beg_pos, int end_pos,
3546 MessageTemplate::Template message, ParseErrorType type, bool* ok) {
3547 if (this->IsIdentifier(expression) && is_strict(language_mode()) &&
3548 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
3549 ReportMessageAt(Scanner::Location(beg_pos, end_pos),
3550 MessageTemplate::kStrictEvalArguments, kSyntaxError);
3551 *ok = false;
3552 return this->EmptyExpression();
3553 }
3554 if (expression->IsValidReferenceExpression()) {
3555 return expression;
3556 }
3557 if (expression->IsCall()) {
3558 // If it is a call, make it a runtime error for legacy web compatibility.
3559 // Rewrite `expr' to `expr[throw ReferenceError]'.
3560 ExpressionT error = this->NewThrowReferenceError(message, beg_pos);
3561 return factory()->NewProperty(expression, error, beg_pos);
3562 }
3563 ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type);
3564 *ok = false;
3565 return this->EmptyExpression();
3566 }
3567
3568
3569 template <typename Traits>
IsValidReferenceExpression(ExpressionT expression)3570 bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) {
3571 return this->IsAssignableIdentifier(expression) || expression->IsProperty();
3572 }
3573
3574
3575 template <typename Traits>
CheckDestructuringElement(ExpressionT expression,ExpressionClassifier * classifier,int begin,int end)3576 void ParserBase<Traits>::CheckDestructuringElement(
3577 ExpressionT expression, ExpressionClassifier* classifier, int begin,
3578 int end) {
3579 if (!IsValidPattern(expression) && !expression->IsAssignment() &&
3580 !IsValidReferenceExpression(expression)) {
3581 classifier->RecordAssignmentPatternError(
3582 Scanner::Location(begin, end),
3583 MessageTemplate::kInvalidDestructuringTarget);
3584 }
3585 }
3586
3587
3588 #undef CHECK_OK
3589 #undef CHECK_OK_CUSTOM
3590
3591 template <typename Traits>
CheckProperty(Token::Value property,PropertyKind type,MethodKind method_type,bool * ok)3592 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
3593 Token::Value property, PropertyKind type, MethodKind method_type,
3594 bool* ok) {
3595 DCHECK(!IsStaticMethod(method_type));
3596 DCHECK(!IsSpecialMethod(method_type) || type == kMethodProperty);
3597
3598 if (property == Token::SMI || property == Token::NUMBER) return;
3599
3600 if (type == kValueProperty && IsProto()) {
3601 if (has_seen_proto_) {
3602 this->parser()->ReportMessage(MessageTemplate::kDuplicateProto);
3603 *ok = false;
3604 return;
3605 }
3606 has_seen_proto_ = true;
3607 return;
3608 }
3609 }
3610
3611 template <typename Traits>
CheckProperty(Token::Value property,PropertyKind type,MethodKind method_type,bool * ok)3612 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
3613 Token::Value property, PropertyKind type, MethodKind method_type,
3614 bool* ok) {
3615 DCHECK(type == kMethodProperty || type == kAccessorProperty);
3616
3617 if (property == Token::SMI || property == Token::NUMBER) return;
3618
3619 if (IsStaticMethod(method_type)) {
3620 if (IsPrototype()) {
3621 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
3622 *ok = false;
3623 return;
3624 }
3625 } else if (IsConstructor()) {
3626 const bool is_generator = IsGeneratorMethod(method_type);
3627 const bool is_async = IsAsyncMethod(method_type);
3628 if (is_generator || is_async || type == kAccessorProperty) {
3629 MessageTemplate::Template msg =
3630 is_generator ? MessageTemplate::kConstructorIsGenerator
3631 : is_async ? MessageTemplate::kConstructorIsAsync
3632 : MessageTemplate::kConstructorIsAccessor;
3633 this->parser()->ReportMessage(msg);
3634 *ok = false;
3635 return;
3636 }
3637 if (has_seen_constructor_) {
3638 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
3639 *ok = false;
3640 return;
3641 }
3642 has_seen_constructor_ = true;
3643 return;
3644 }
3645 }
3646
3647
3648 } // namespace internal
3649 } // namespace v8
3650
3651 #endif // V8_PARSING_PARSER_BASE_H
3652