• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&parameters.materialized_literals_count);
2294 
2295     scope->set_start_position(lhs_beg_pos);
2296     Scanner::Location duplicate_loc = Scanner::Location::invalid();
2297     this->ParseArrowFunctionFormalParameterList(&parameters, 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