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_PREPARSER_H
6 #define V8_PARSING_PREPARSER_H
7 
8 #include "src/ast/scopes.h"
9 #include "src/parsing/parser-base.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 // Whereas the Parser generates AST during the recursive descent,
15 // the PreParser doesn't create a tree. Instead, it passes around minimal
16 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
17 // just enough data for the upper layer functions. PreParserFactory is
18 // responsible for creating these dummy objects. It provides a similar kind of
19 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is
20 // used.
21 
22 class PreParserIdentifier {
23  public:
PreParserIdentifier()24   PreParserIdentifier() : type_(kUnknownIdentifier) {}
Default()25   static PreParserIdentifier Default() {
26     return PreParserIdentifier(kUnknownIdentifier);
27   }
Empty()28   static PreParserIdentifier Empty() {
29     return PreParserIdentifier(kEmptyIdentifier);
30   }
Eval()31   static PreParserIdentifier Eval() {
32     return PreParserIdentifier(kEvalIdentifier);
33   }
Arguments()34   static PreParserIdentifier Arguments() {
35     return PreParserIdentifier(kArgumentsIdentifier);
36   }
Undefined()37   static PreParserIdentifier Undefined() {
38     return PreParserIdentifier(kUndefinedIdentifier);
39   }
FutureReserved()40   static PreParserIdentifier FutureReserved() {
41     return PreParserIdentifier(kFutureReservedIdentifier);
42   }
FutureStrictReserved()43   static PreParserIdentifier FutureStrictReserved() {
44     return PreParserIdentifier(kFutureStrictReservedIdentifier);
45   }
Let()46   static PreParserIdentifier Let() {
47     return PreParserIdentifier(kLetIdentifier);
48   }
Static()49   static PreParserIdentifier Static() {
50     return PreParserIdentifier(kStaticIdentifier);
51   }
Yield()52   static PreParserIdentifier Yield() {
53     return PreParserIdentifier(kYieldIdentifier);
54   }
Prototype()55   static PreParserIdentifier Prototype() {
56     return PreParserIdentifier(kPrototypeIdentifier);
57   }
Constructor()58   static PreParserIdentifier Constructor() {
59     return PreParserIdentifier(kConstructorIdentifier);
60   }
Enum()61   static PreParserIdentifier Enum() {
62     return PreParserIdentifier(kEnumIdentifier);
63   }
Await()64   static PreParserIdentifier Await() {
65     return PreParserIdentifier(kAwaitIdentifier);
66   }
Async()67   static PreParserIdentifier Async() {
68     return PreParserIdentifier(kAsyncIdentifier);
69   }
IsEmpty()70   bool IsEmpty() const { return type_ == kEmptyIdentifier; }
IsEval()71   bool IsEval() const { return type_ == kEvalIdentifier; }
IsArguments()72   bool IsArguments() const { return type_ == kArgumentsIdentifier; }
IsEvalOrArguments()73   bool IsEvalOrArguments() const { return IsEval() || IsArguments(); }
IsUndefined()74   bool IsUndefined() const { return type_ == kUndefinedIdentifier; }
IsLet()75   bool IsLet() const { return type_ == kLetIdentifier; }
IsStatic()76   bool IsStatic() const { return type_ == kStaticIdentifier; }
IsYield()77   bool IsYield() const { return type_ == kYieldIdentifier; }
IsPrototype()78   bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
IsConstructor()79   bool IsConstructor() const { return type_ == kConstructorIdentifier; }
IsEnum()80   bool IsEnum() const { return type_ == kEnumIdentifier; }
IsAwait()81   bool IsAwait() const { return type_ == kAwaitIdentifier; }
IsFutureStrictReserved()82   bool IsFutureStrictReserved() const {
83     return type_ == kFutureStrictReservedIdentifier ||
84            type_ == kLetIdentifier || type_ == kStaticIdentifier ||
85            type_ == kYieldIdentifier;
86   }
87 
88   // Allow identifier->name()[->length()] to work. The preparser
89   // does not need the actual positions/lengths of the identifiers.
90   const PreParserIdentifier* operator->() const { return this; }
raw_name()91   const PreParserIdentifier raw_name() const { return *this; }
92 
position()93   int position() const { return 0; }
length()94   int length() const { return 0; }
95 
96  private:
97   enum Type {
98     kEmptyIdentifier,
99     kUnknownIdentifier,
100     kFutureReservedIdentifier,
101     kFutureStrictReservedIdentifier,
102     kLetIdentifier,
103     kStaticIdentifier,
104     kYieldIdentifier,
105     kEvalIdentifier,
106     kArgumentsIdentifier,
107     kUndefinedIdentifier,
108     kPrototypeIdentifier,
109     kConstructorIdentifier,
110     kEnumIdentifier,
111     kAwaitIdentifier,
112     kAsyncIdentifier
113   };
114 
PreParserIdentifier(Type type)115   explicit PreParserIdentifier(Type type) : type_(type), string_(nullptr) {}
116   Type type_;
117   // Only non-nullptr when PreParser.track_unresolved_variables_ is true.
118   const AstRawString* string_;
119   friend class PreParserExpression;
120   friend class PreParser;
121   friend class PreParserFactory;
122 };
123 
124 
125 class PreParserExpression {
126  public:
PreParserExpression()127   PreParserExpression()
128       : code_(TypeField::encode(kEmpty)), identifiers_(nullptr) {}
129 
Empty()130   static PreParserExpression Empty() { return PreParserExpression(); }
131 
132   static PreParserExpression Default(
133       ZoneList<const AstRawString*>* identifiers = nullptr) {
134     return PreParserExpression(TypeField::encode(kExpression), identifiers);
135   }
136 
Spread(PreParserExpression expression)137   static PreParserExpression Spread(PreParserExpression expression) {
138     return PreParserExpression(TypeField::encode(kSpreadExpression),
139                                expression.identifiers_);
140   }
141 
FromIdentifier(PreParserIdentifier id,Zone * zone)142   static PreParserExpression FromIdentifier(PreParserIdentifier id,
143                                             Zone* zone) {
144     PreParserExpression expression(TypeField::encode(kIdentifierExpression) |
145                                    IdentifierTypeField::encode(id.type_));
146     expression.AddIdentifier(id.string_, zone);
147     return expression;
148   }
149 
BinaryOperation(PreParserExpression left,Token::Value op,PreParserExpression right)150   static PreParserExpression BinaryOperation(PreParserExpression left,
151                                              Token::Value op,
152                                              PreParserExpression right) {
153     return PreParserExpression(TypeField::encode(kBinaryOperationExpression));
154   }
155 
Assignment()156   static PreParserExpression Assignment() {
157     return PreParserExpression(TypeField::encode(kExpression) |
158                                ExpressionTypeField::encode(kAssignment));
159   }
160 
161   static PreParserExpression ObjectLiteral(
162       ZoneList<const AstRawString*>* identifiers = nullptr) {
163     return PreParserExpression(TypeField::encode(kObjectLiteralExpression),
164                                identifiers);
165   }
166 
167   static PreParserExpression ArrayLiteral(
168       ZoneList<const AstRawString*>* identifiers = nullptr) {
169     return PreParserExpression(TypeField::encode(kArrayLiteralExpression),
170                                identifiers);
171   }
172 
StringLiteral()173   static PreParserExpression StringLiteral() {
174     return PreParserExpression(TypeField::encode(kStringLiteralExpression));
175   }
176 
UseStrictStringLiteral()177   static PreParserExpression UseStrictStringLiteral() {
178     return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
179                                IsUseStrictField::encode(true));
180   }
181 
UseAsmStringLiteral()182   static PreParserExpression UseAsmStringLiteral() {
183     return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
184                                IsUseAsmField::encode(true));
185   }
186 
This()187   static PreParserExpression This() {
188     return PreParserExpression(TypeField::encode(kExpression) |
189                                ExpressionTypeField::encode(kThisExpression));
190   }
191 
ThisProperty()192   static PreParserExpression ThisProperty() {
193     return PreParserExpression(
194         TypeField::encode(kExpression) |
195         ExpressionTypeField::encode(kThisPropertyExpression));
196   }
197 
Property()198   static PreParserExpression Property() {
199     return PreParserExpression(
200         TypeField::encode(kExpression) |
201         ExpressionTypeField::encode(kPropertyExpression));
202   }
203 
Call()204   static PreParserExpression Call() {
205     return PreParserExpression(TypeField::encode(kExpression) |
206                                ExpressionTypeField::encode(kCallExpression));
207   }
208 
CallEval()209   static PreParserExpression CallEval() {
210     return PreParserExpression(
211         TypeField::encode(kExpression) |
212         ExpressionTypeField::encode(kCallEvalExpression));
213   }
214 
SuperCallReference()215   static PreParserExpression SuperCallReference() {
216     return PreParserExpression(
217         TypeField::encode(kExpression) |
218         ExpressionTypeField::encode(kSuperCallReference));
219   }
220 
NoTemplateTag()221   static PreParserExpression NoTemplateTag() {
222     return PreParserExpression(
223         TypeField::encode(kExpression) |
224         ExpressionTypeField::encode(kNoTemplateTagExpression));
225   }
226 
IsEmpty()227   bool IsEmpty() const { return TypeField::decode(code_) == kEmpty; }
228 
IsIdentifier()229   bool IsIdentifier() const {
230     return TypeField::decode(code_) == kIdentifierExpression;
231   }
232 
AsIdentifier()233   PreParserIdentifier AsIdentifier() const {
234     DCHECK(IsIdentifier());
235     return PreParserIdentifier(IdentifierTypeField::decode(code_));
236   }
237 
IsAssignment()238   bool IsAssignment() const {
239     return TypeField::decode(code_) == kExpression &&
240            ExpressionTypeField::decode(code_) == kAssignment;
241   }
242 
IsObjectLiteral()243   bool IsObjectLiteral() const {
244     return TypeField::decode(code_) == kObjectLiteralExpression;
245   }
246 
IsArrayLiteral()247   bool IsArrayLiteral() const {
248     return TypeField::decode(code_) == kArrayLiteralExpression;
249   }
250 
IsStringLiteral()251   bool IsStringLiteral() const {
252     return TypeField::decode(code_) == kStringLiteralExpression;
253   }
254 
IsUseStrictLiteral()255   bool IsUseStrictLiteral() const {
256     return TypeField::decode(code_) == kStringLiteralExpression &&
257            IsUseStrictField::decode(code_);
258   }
259 
IsUseAsmLiteral()260   bool IsUseAsmLiteral() const {
261     return TypeField::decode(code_) == kStringLiteralExpression &&
262            IsUseAsmField::decode(code_);
263   }
264 
IsThis()265   bool IsThis() const {
266     return TypeField::decode(code_) == kExpression &&
267            ExpressionTypeField::decode(code_) == kThisExpression;
268   }
269 
IsThisProperty()270   bool IsThisProperty() const {
271     return TypeField::decode(code_) == kExpression &&
272            ExpressionTypeField::decode(code_) == kThisPropertyExpression;
273   }
274 
IsProperty()275   bool IsProperty() const {
276     return TypeField::decode(code_) == kExpression &&
277            (ExpressionTypeField::decode(code_) == kPropertyExpression ||
278             ExpressionTypeField::decode(code_) == kThisPropertyExpression);
279   }
280 
IsCall()281   bool IsCall() const {
282     return TypeField::decode(code_) == kExpression &&
283            (ExpressionTypeField::decode(code_) == kCallExpression ||
284             ExpressionTypeField::decode(code_) == kCallEvalExpression);
285   }
286 
IsDirectEvalCall()287   bool IsDirectEvalCall() const {
288     return TypeField::decode(code_) == kExpression &&
289            ExpressionTypeField::decode(code_) == kCallEvalExpression;
290   }
291 
IsSuperCallReference()292   bool IsSuperCallReference() const {
293     return TypeField::decode(code_) == kExpression &&
294            ExpressionTypeField::decode(code_) == kSuperCallReference;
295   }
296 
IsValidReferenceExpression()297   bool IsValidReferenceExpression() const {
298     return IsIdentifier() || IsProperty();
299   }
300 
301   // At the moment PreParser doesn't track these expression types.
IsFunctionLiteral()302   bool IsFunctionLiteral() const { return false; }
IsCallNew()303   bool IsCallNew() const { return false; }
304 
IsNoTemplateTag()305   bool IsNoTemplateTag() const {
306     return TypeField::decode(code_) == kExpression &&
307            ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
308   }
309 
IsSpread()310   bool IsSpread() const {
311     return TypeField::decode(code_) == kSpreadExpression;
312   }
313 
AsFunctionLiteral()314   PreParserExpression AsFunctionLiteral() { return *this; }
315 
IsBinaryOperation()316   bool IsBinaryOperation() const {
317     return TypeField::decode(code_) == kBinaryOperationExpression;
318   }
319 
320   // Dummy implementation for making expression->somefunc() work in both Parser
321   // and PreParser.
322   PreParserExpression* operator->() { return this; }
323 
324   // More dummy implementations of things PreParser doesn't need to track:
set_index(int index)325   void set_index(int index) {}  // For YieldExpressions
SetShouldEagerCompile()326   void SetShouldEagerCompile() {}
set_should_be_used_once_hint()327   void set_should_be_used_once_hint() {}
328 
position()329   int position() const { return kNoSourcePosition; }
set_function_token_position(int position)330   void set_function_token_position(int position) {}
331 
set_is_class_field_initializer(bool is_class_field_initializer)332   void set_is_class_field_initializer(bool is_class_field_initializer) {}
333 
334  private:
335   enum Type {
336     kEmpty,
337     kExpression,
338     kIdentifierExpression,
339     kStringLiteralExpression,
340     kBinaryOperationExpression,
341     kSpreadExpression,
342     kObjectLiteralExpression,
343     kArrayLiteralExpression
344   };
345 
346   enum ExpressionType {
347     kThisExpression,
348     kThisPropertyExpression,
349     kPropertyExpression,
350     kCallExpression,
351     kCallEvalExpression,
352     kSuperCallReference,
353     kNoTemplateTagExpression,
354     kAssignment
355   };
356 
357   explicit PreParserExpression(
358       uint32_t expression_code,
359       ZoneList<const AstRawString*>* identifiers = nullptr)
code_(expression_code)360       : code_(expression_code), identifiers_(identifiers) {}
361 
AddIdentifier(const AstRawString * identifier,Zone * zone)362   void AddIdentifier(const AstRawString* identifier, Zone* zone) {
363     if (identifier == nullptr) {
364       return;
365     }
366     if (identifiers_ == nullptr) {
367       identifiers_ = new (zone) ZoneList<const AstRawString*>(1, zone);
368     }
369     identifiers_->Add(identifier, zone);
370   }
371 
372   // The first three bits are for the Type.
373   typedef BitField<Type, 0, 3> TypeField;
374 
375   // The high order bit applies only to nodes which would inherit from the
376   // Expression ASTNode --- This is by necessity, due to the fact that
377   // Expression nodes may be represented as multiple Types, not exclusively
378   // through kExpression.
379   // TODO(caitp, adamk): clean up PreParserExpression bitfields.
380   typedef BitField<bool, 31, 1> ParenthesizedField;
381 
382   // The rest of the bits are interpreted depending on the value
383   // of the Type field, so they can share the storage.
384   typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField;
385   typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField;
386   typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseAsmField;
387   typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10>
388       IdentifierTypeField;
389   typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField;
390 
391   uint32_t code_;
392   // If the PreParser is used in the identifier tracking mode,
393   // PreParserExpression accumulates identifiers in that expression.
394   ZoneList<const AstRawString*>* identifiers_;
395 
396   friend class PreParser;
397   friend class PreParserFactory;
398   template <typename T>
399   friend class PreParserList;
400 };
401 
402 
403 // The pre-parser doesn't need to build lists of expressions, identifiers, or
404 // the like. If the PreParser is used in identifier tracking mode, it needs to
405 // build lists of identifiers though.
406 template <typename T>
407 class PreParserList {
408  public:
409   // These functions make list->Add(some_expression) work (and do nothing).
PreParserList()410   PreParserList() : length_(0), identifiers_(nullptr) {}
411   PreParserList* operator->() { return this; }
412   void Add(T, Zone* zone);
length()413   int length() const { return length_; }
Null()414   static PreParserList Null() { return PreParserList(-1); }
IsNull()415   bool IsNull() const { return length_ == -1; }
416 
417  private:
PreParserList(int n)418   explicit PreParserList(int n) : length_(n), identifiers_(nullptr) {}
419   int length_;
420   ZoneList<const AstRawString*>* identifiers_;
421 
422   friend class PreParser;
423   friend class PreParserFactory;
424 };
425 
426 template <>
Add(PreParserExpression expression,Zone * zone)427 inline void PreParserList<PreParserExpression>::Add(
428     PreParserExpression expression, Zone* zone) {
429   if (expression.identifiers_ != nullptr) {
430     DCHECK(FLAG_lazy_inner_functions);
431     DCHECK(zone != nullptr);
432     if (identifiers_ == nullptr) {
433       identifiers_ = new (zone) ZoneList<const AstRawString*>(1, zone);
434     }
435     for (auto identifier : (*expression.identifiers_)) {
436       identifiers_->Add(identifier, zone);
437     }
438   }
439   ++length_;
440 }
441 
442 template <typename T>
Add(T,Zone * zone)443 void PreParserList<T>::Add(T, Zone* zone) {
444   ++length_;
445 }
446 
447 typedef PreParserList<PreParserExpression> PreParserExpressionList;
448 
449 class PreParserStatement;
450 typedef PreParserList<PreParserStatement> PreParserStatementList;
451 
452 class PreParserStatement {
453  public:
Default()454   static PreParserStatement Default() {
455     return PreParserStatement(kUnknownStatement);
456   }
457 
Null()458   static PreParserStatement Null() {
459     return PreParserStatement(kNullStatement);
460   }
461 
Empty()462   static PreParserStatement Empty() {
463     return PreParserStatement(kEmptyStatement);
464   }
465 
Jump()466   static PreParserStatement Jump() {
467     return PreParserStatement(kJumpStatement);
468   }
469 
470   // Creates expression statement from expression.
471   // Preserves being an unparenthesized string literal, possibly
472   // "use strict".
ExpressionStatement(PreParserExpression expression)473   static PreParserStatement ExpressionStatement(
474       PreParserExpression expression) {
475     if (expression.IsUseStrictLiteral()) {
476       return PreParserStatement(kUseStrictExpressionStatement);
477     }
478     if (expression.IsUseAsmLiteral()) {
479       return PreParserStatement(kUseAsmExpressionStatement);
480     }
481     if (expression.IsStringLiteral()) {
482       return PreParserStatement(kStringLiteralExpressionStatement);
483     }
484     return Default();
485   }
486 
IsStringLiteral()487   bool IsStringLiteral() {
488     return code_ == kStringLiteralExpressionStatement || IsUseStrictLiteral() ||
489            IsUseAsmLiteral();
490   }
491 
IsUseStrictLiteral()492   bool IsUseStrictLiteral() {
493     return code_ == kUseStrictExpressionStatement;
494   }
495 
IsUseAsmLiteral()496   bool IsUseAsmLiteral() { return code_ == kUseAsmExpressionStatement; }
497 
IsJumpStatement()498   bool IsJumpStatement() {
499     return code_ == kJumpStatement;
500   }
501 
IsNullStatement()502   bool IsNullStatement() { return code_ == kNullStatement; }
503 
IsEmptyStatement()504   bool IsEmptyStatement() { return code_ == kEmptyStatement; }
505 
506   // Dummy implementation for making statement->somefunc() work in both Parser
507   // and PreParser.
508   PreParserStatement* operator->() { return this; }
509 
statements()510   PreParserStatementList statements() { return PreParserStatementList(); }
set_scope(Scope * scope)511   void set_scope(Scope* scope) {}
Initialize(PreParserExpression cond,PreParserStatement body)512   void Initialize(PreParserExpression cond, PreParserStatement body) {}
Initialize(PreParserStatement init,PreParserExpression cond,PreParserStatement next,PreParserStatement body)513   void Initialize(PreParserStatement init, PreParserExpression cond,
514                   PreParserStatement next, PreParserStatement body) {}
515 
516  private:
517   enum Type {
518     kNullStatement,
519     kEmptyStatement,
520     kUnknownStatement,
521     kJumpStatement,
522     kStringLiteralExpressionStatement,
523     kUseStrictExpressionStatement,
524     kUseAsmExpressionStatement,
525   };
526 
PreParserStatement(Type code)527   explicit PreParserStatement(Type code) : code_(code) {}
528   Type code_;
529 };
530 
531 
532 class PreParserFactory {
533  public:
PreParserFactory(AstValueFactory * ast_value_factory)534   explicit PreParserFactory(AstValueFactory* ast_value_factory)
535       : zone_(ast_value_factory->zone()) {}
536 
set_zone(Zone * zone)537   void set_zone(Zone* zone) { zone_ = zone; }
538 
NewStringLiteral(PreParserIdentifier identifier,int pos)539   PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
540                                        int pos) {
541     // This is needed for object literal property names. Property names are
542     // normalized to string literals during object literal parsing.
543     PreParserExpression expression = PreParserExpression::Default();
544     expression.AddIdentifier(identifier.string_, zone_);
545     return expression;
546   }
NewNumberLiteral(double number,int pos)547   PreParserExpression NewNumberLiteral(double number,
548                                        int pos) {
549     return PreParserExpression::Default();
550   }
NewUndefinedLiteral(int pos)551   PreParserExpression NewUndefinedLiteral(int pos) {
552     return PreParserExpression::Default();
553   }
NewRegExpLiteral(PreParserIdentifier js_pattern,int js_flags,int literal_index,int pos)554   PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
555                                        int js_flags, int literal_index,
556                                        int pos) {
557     return PreParserExpression::Default();
558   }
NewArrayLiteral(PreParserExpressionList values,int first_spread_index,int literal_index,int pos)559   PreParserExpression NewArrayLiteral(PreParserExpressionList values,
560                                       int first_spread_index, int literal_index,
561                                       int pos) {
562     return PreParserExpression::ArrayLiteral(values.identifiers_);
563   }
NewClassLiteralProperty(PreParserExpression key,PreParserExpression value,ClassLiteralProperty::Kind kind,bool is_static,bool is_computed_name)564   PreParserExpression NewClassLiteralProperty(PreParserExpression key,
565                                               PreParserExpression value,
566                                               ClassLiteralProperty::Kind kind,
567                                               bool is_static,
568                                               bool is_computed_name) {
569     return PreParserExpression::Default();
570   }
NewObjectLiteralProperty(PreParserExpression key,PreParserExpression value,ObjectLiteralProperty::Kind kind,bool is_computed_name)571   PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
572                                                PreParserExpression value,
573                                                ObjectLiteralProperty::Kind kind,
574                                                bool is_computed_name) {
575     return PreParserExpression::Default(value.identifiers_);
576   }
NewObjectLiteralProperty(PreParserExpression key,PreParserExpression value,bool is_computed_name)577   PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
578                                                PreParserExpression value,
579                                                bool is_computed_name) {
580     return PreParserExpression::Default(value.identifiers_);
581   }
NewObjectLiteral(PreParserExpressionList properties,int literal_index,int boilerplate_properties,int pos)582   PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
583                                        int literal_index,
584                                        int boilerplate_properties,
585                                        int pos) {
586     return PreParserExpression::ObjectLiteral(properties.identifiers_);
587   }
NewVariableProxy(void * variable)588   PreParserExpression NewVariableProxy(void* variable) {
589     return PreParserExpression::Default();
590   }
NewProperty(PreParserExpression obj,PreParserExpression key,int pos)591   PreParserExpression NewProperty(PreParserExpression obj,
592                                   PreParserExpression key,
593                                   int pos) {
594     if (obj.IsThis()) {
595       return PreParserExpression::ThisProperty();
596     }
597     return PreParserExpression::Property();
598   }
NewUnaryOperation(Token::Value op,PreParserExpression expression,int pos)599   PreParserExpression NewUnaryOperation(Token::Value op,
600                                         PreParserExpression expression,
601                                         int pos) {
602     return PreParserExpression::Default();
603   }
NewBinaryOperation(Token::Value op,PreParserExpression left,PreParserExpression right,int pos)604   PreParserExpression NewBinaryOperation(Token::Value op,
605                                          PreParserExpression left,
606                                          PreParserExpression right, int pos) {
607     return PreParserExpression::BinaryOperation(left, op, right);
608   }
NewCompareOperation(Token::Value op,PreParserExpression left,PreParserExpression right,int pos)609   PreParserExpression NewCompareOperation(Token::Value op,
610                                           PreParserExpression left,
611                                           PreParserExpression right, int pos) {
612     return PreParserExpression::Default();
613   }
NewRewritableExpression(PreParserExpression expression)614   PreParserExpression NewRewritableExpression(PreParserExpression expression) {
615     return expression;
616   }
NewAssignment(Token::Value op,PreParserExpression left,PreParserExpression right,int pos)617   PreParserExpression NewAssignment(Token::Value op,
618                                     PreParserExpression left,
619                                     PreParserExpression right,
620                                     int pos) {
621     return PreParserExpression::Assignment();
622   }
NewYield(PreParserExpression generator_object,PreParserExpression expression,int pos,Yield::OnException on_exception)623   PreParserExpression NewYield(PreParserExpression generator_object,
624                                PreParserExpression expression, int pos,
625                                Yield::OnException on_exception) {
626     return PreParserExpression::Default();
627   }
NewConditional(PreParserExpression condition,PreParserExpression then_expression,PreParserExpression else_expression,int pos)628   PreParserExpression NewConditional(PreParserExpression condition,
629                                      PreParserExpression then_expression,
630                                      PreParserExpression else_expression,
631                                      int pos) {
632     return PreParserExpression::Default();
633   }
NewCountOperation(Token::Value op,bool is_prefix,PreParserExpression expression,int pos)634   PreParserExpression NewCountOperation(Token::Value op,
635                                         bool is_prefix,
636                                         PreParserExpression expression,
637                                         int pos) {
638     return PreParserExpression::Default();
639   }
640   PreParserExpression NewCall(
641       PreParserExpression expression, PreParserExpressionList arguments,
642       int pos, Call::PossiblyEval possibly_eval = Call::NOT_EVAL) {
643     if (possibly_eval == Call::IS_POSSIBLY_EVAL) {
644       DCHECK(expression.IsIdentifier() && expression.AsIdentifier().IsEval());
645       return PreParserExpression::CallEval();
646     }
647     return PreParserExpression::Call();
648   }
NewCallNew(PreParserExpression expression,PreParserExpressionList arguments,int pos)649   PreParserExpression NewCallNew(PreParserExpression expression,
650                                  PreParserExpressionList arguments,
651                                  int pos) {
652     return PreParserExpression::Default();
653   }
NewReturnStatement(PreParserExpression expression,int pos)654   PreParserStatement NewReturnStatement(PreParserExpression expression,
655                                         int pos) {
656     return PreParserStatement::Jump();
657   }
NewFunctionLiteral(PreParserIdentifier name,Scope * scope,PreParserStatementList body,int materialized_literal_count,int expected_property_count,int parameter_count,int function_length,FunctionLiteral::ParameterFlag has_duplicate_parameters,FunctionLiteral::FunctionType function_type,FunctionLiteral::EagerCompileHint eager_compile_hint,int position,bool has_braces)658   PreParserExpression NewFunctionLiteral(
659       PreParserIdentifier name, Scope* scope, PreParserStatementList body,
660       int materialized_literal_count, int expected_property_count,
661       int parameter_count, int function_length,
662       FunctionLiteral::ParameterFlag has_duplicate_parameters,
663       FunctionLiteral::FunctionType function_type,
664       FunctionLiteral::EagerCompileHint eager_compile_hint, int position,
665       bool has_braces) {
666     return PreParserExpression::Default();
667   }
668 
NewSpread(PreParserExpression expression,int pos,int expr_pos)669   PreParserExpression NewSpread(PreParserExpression expression, int pos,
670                                 int expr_pos) {
671     return PreParserExpression::Spread(expression);
672   }
673 
NewEmptyParentheses(int pos)674   PreParserExpression NewEmptyParentheses(int pos) {
675     return PreParserExpression::Default();
676   }
677 
NewEmptyStatement(int pos)678   PreParserStatement NewEmptyStatement(int pos) {
679     return PreParserStatement::Default();
680   }
681 
NewBlock(ZoneList<const AstRawString * > * labels,int capacity,bool ignore_completion_value,int pos)682   PreParserStatement NewBlock(ZoneList<const AstRawString*>* labels,
683                               int capacity, bool ignore_completion_value,
684                               int pos) {
685     return PreParserStatement::Default();
686   }
687 
NewDebuggerStatement(int pos)688   PreParserStatement NewDebuggerStatement(int pos) {
689     return PreParserStatement::Default();
690   }
691 
NewExpressionStatement(PreParserExpression expr,int pos)692   PreParserStatement NewExpressionStatement(PreParserExpression expr, int pos) {
693     return PreParserStatement::ExpressionStatement(expr);
694   }
695 
NewIfStatement(PreParserExpression condition,PreParserStatement then_statement,PreParserStatement else_statement,int pos)696   PreParserStatement NewIfStatement(PreParserExpression condition,
697                                     PreParserStatement then_statement,
698                                     PreParserStatement else_statement,
699                                     int pos) {
700     // This must return a jump statement iff both clauses are jump statements.
701     return else_statement.IsJumpStatement() ? then_statement : else_statement;
702   }
703 
NewBreakStatement(PreParserStatement target,int pos)704   PreParserStatement NewBreakStatement(PreParserStatement target, int pos) {
705     return PreParserStatement::Jump();
706   }
707 
NewContinueStatement(PreParserStatement target,int pos)708   PreParserStatement NewContinueStatement(PreParserStatement target, int pos) {
709     return PreParserStatement::Jump();
710   }
711 
NewWithStatement(Scope * scope,PreParserExpression expression,PreParserStatement statement,int pos)712   PreParserStatement NewWithStatement(Scope* scope,
713                                       PreParserExpression expression,
714                                       PreParserStatement statement, int pos) {
715     return PreParserStatement::Default();
716   }
717 
NewDoWhileStatement(ZoneList<const AstRawString * > * labels,int pos)718   PreParserStatement NewDoWhileStatement(ZoneList<const AstRawString*>* labels,
719                                          int pos) {
720     return PreParserStatement::Default();
721   }
722 
NewWhileStatement(ZoneList<const AstRawString * > * labels,int pos)723   PreParserStatement NewWhileStatement(ZoneList<const AstRawString*>* labels,
724                                        int pos) {
725     return PreParserStatement::Default();
726   }
727 
NewSwitchStatement(ZoneList<const AstRawString * > * labels,int pos)728   PreParserStatement NewSwitchStatement(ZoneList<const AstRawString*>* labels,
729                                         int pos) {
730     return PreParserStatement::Default();
731   }
732 
NewCaseClause(PreParserExpression label,PreParserStatementList statements,int pos)733   PreParserStatement NewCaseClause(PreParserExpression label,
734                                    PreParserStatementList statements, int pos) {
735     return PreParserStatement::Default();
736   }
737 
NewForStatement(ZoneList<const AstRawString * > * labels,int pos)738   PreParserStatement NewForStatement(ZoneList<const AstRawString*>* labels,
739                                      int pos) {
740     return PreParserStatement::Default();
741   }
742 
NewForEachStatement(ForEachStatement::VisitMode visit_mode,ZoneList<const AstRawString * > * labels,int pos)743   PreParserStatement NewForEachStatement(ForEachStatement::VisitMode visit_mode,
744                                          ZoneList<const AstRawString*>* labels,
745                                          int pos) {
746     return PreParserStatement::Default();
747   }
748 
749   // Return the object itself as AstVisitor and implement the needed
750   // dummy method right in this class.
visitor()751   PreParserFactory* visitor() { return this; }
ast_properties()752   int* ast_properties() {
753     static int dummy = 42;
754     return &dummy;
755   }
756 
757  private:
758   Zone* zone_;
759 };
760 
761 
762 struct PreParserFormalParameters : FormalParametersBase {
PreParserFormalParametersPreParserFormalParameters763   explicit PreParserFormalParameters(DeclarationScope* scope)
764       : FormalParametersBase(scope) {}
atPreParserFormalParameters765   PreParserIdentifier at(int i) { return PreParserIdentifier(); }  // Dummy
766 };
767 
768 
769 class PreParser;
770 
771 class PreParserTarget {
772  public:
PreParserTarget(ParserBase<PreParser> * preparser,PreParserStatement statement)773   PreParserTarget(ParserBase<PreParser>* preparser,
774                   PreParserStatement statement) {}
775 };
776 
777 class PreParserTargetScope {
778  public:
PreParserTargetScope(ParserBase<PreParser> * preparser)779   explicit PreParserTargetScope(ParserBase<PreParser>* preparser) {}
780 };
781 
782 template <>
783 struct ParserTypes<PreParser> {
784   typedef ParserBase<PreParser> Base;
785   typedef PreParser Impl;
786 
787   // PreParser doesn't need to store generator variables.
788   typedef void Variable;
789 
790   // Return types for traversing functions.
791   typedef PreParserIdentifier Identifier;
792   typedef PreParserExpression Expression;
793   typedef PreParserExpression FunctionLiteral;
794   typedef PreParserExpression ObjectLiteralProperty;
795   typedef PreParserExpression ClassLiteralProperty;
796   typedef PreParserExpressionList ExpressionList;
797   typedef PreParserExpressionList ObjectPropertyList;
798   typedef PreParserExpressionList ClassPropertyList;
799   typedef PreParserFormalParameters FormalParameters;
800   typedef PreParserStatement Statement;
801   typedef PreParserStatementList StatementList;
802   typedef PreParserStatement Block;
803   typedef PreParserStatement BreakableStatement;
804   typedef PreParserStatement IterationStatement;
805 
806   // For constructing objects returned by the traversing functions.
807   typedef PreParserFactory Factory;
808 
809   typedef PreParserTarget Target;
810   typedef PreParserTargetScope TargetScope;
811 };
812 
813 
814 // Preparsing checks a JavaScript program and emits preparse-data that helps
815 // a later parsing to be faster.
816 // See preparse-data-format.h for the data format.
817 
818 // The PreParser checks that the syntax follows the grammar for JavaScript,
819 // and collects some information about the program along the way.
820 // The grammar check is only performed in order to understand the program
821 // sufficiently to deduce some information about it, that can be used
822 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
823 // rather it is to speed up properly written and correct programs.
824 // That means that contextual checks (like a label being declared where
825 // it is used) are generally omitted.
826 class PreParser : public ParserBase<PreParser> {
827   friend class ParserBase<PreParser>;
828   friend class v8::internal::ExpressionClassifier<ParserTypes<PreParser>>;
829 
830  public:
831   typedef PreParserIdentifier Identifier;
832   typedef PreParserExpression Expression;
833   typedef PreParserStatement Statement;
834 
835   enum PreParseResult {
836     kPreParseStackOverflow,
837     kPreParseAbort,
838     kPreParseSuccess
839   };
840 
841   PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
842             PendingCompilationErrorHandler* pending_error_handler,
843             RuntimeCallStats* runtime_call_stats, uintptr_t stack_limit)
844       : ParserBase<PreParser>(zone, scanner, stack_limit, nullptr,
845                               ast_value_factory, runtime_call_stats),
846         use_counts_(nullptr),
847         track_unresolved_variables_(false),
848         pending_error_handler_(pending_error_handler) {}
849 
850   static bool const IsPreParser() { return true; }
851 
852   PreParserLogger* logger() { return &log_; }
853 
854   // Pre-parse the program from the character stream; returns true on
855   // success (even if parsing failed, the pre-parse data successfully
856   // captured the syntax error), and false if a stack-overflow happened
857   // during parsing.
858   PreParseResult PreParseProgram(int* materialized_literals = 0,
859                                  bool is_module = false) {
860     DCHECK_NULL(scope_state_);
861     DeclarationScope* scope = NewScriptScope();
862 
863     // ModuleDeclarationInstantiation for Source Text Module Records creates a
864     // new Module Environment Record whose outer lexical environment record is
865     // the global scope.
866     if (is_module) scope = NewModuleScope(scope);
867 
868     FunctionState top_scope(&function_state_, &scope_state_, scope);
869     bool ok = true;
870     int start_position = scanner()->peek_location().beg_pos;
871     parsing_module_ = is_module;
872     PreParserStatementList body;
873     ParseStatementList(body, Token::EOS, &ok);
874     if (stack_overflow()) return kPreParseStackOverflow;
875     if (!ok) {
876       ReportUnexpectedToken(scanner()->current_token());
877     } else if (is_strict(this->scope()->language_mode())) {
878       CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
879                               &ok);
880       CheckDecimalLiteralWithLeadingZero(start_position,
881                                          scanner()->location().end_pos);
882     }
883     if (materialized_literals) {
884       *materialized_literals = function_state_->materialized_literal_count();
885     }
886     return kPreParseSuccess;
887   }
888 
889   // Parses a single function literal, from the opening parentheses before
890   // parameters to the closing brace after the body.
891   // Returns a FunctionEntry describing the body of the function in enough
892   // detail that it can be lazily compiled.
893   // The scanner is expected to have matched the "function" or "function*"
894   // keyword and parameters, and have consumed the initial '{'.
895   // At return, unless an error occurred, the scanner is positioned before the
896   // the final '}'.
897   PreParseResult PreParseFunction(FunctionKind kind,
898                                   DeclarationScope* function_scope,
899                                   bool parsing_module,
900                                   bool track_unresolved_variables,
901                                   bool may_abort, int* use_counts);
902 
903  private:
904   // These types form an algebra over syntactic categories that is just
905   // rich enough to let us recognize and propagate the constructs that
906   // are either being counted in the preparser data, or is important
907   // to throw the correct syntax error exceptions.
908 
909   // All ParseXXX functions take as the last argument an *ok parameter
910   // which is set to false if parsing failed; it is unchanged otherwise.
911   // By making the 'exception handling' explicit, we are forced to check
912   // for failure at the call sites.
913 
914   V8_INLINE PreParserStatementList ParseEagerFunctionBody(
915       PreParserIdentifier function_name, int pos,
916       const PreParserFormalParameters& parameters, FunctionKind kind,
917       FunctionLiteral::FunctionType function_type, bool* ok);
918 
919   // Indicates that we won't switch from the preparser to the preparser; we'll
920   // just stay where we are.
921   bool AllowsLazyParsingWithoutUnresolvedVariables() const { return false; }
922   bool parse_lazily() const { return false; }
923 
924   V8_INLINE LazyParsingResult SkipFunction(
925       FunctionKind kind, DeclarationScope* function_scope, int* num_parameters,
926       int* function_length, bool* has_duplicate_parameters,
927       int* materialized_literal_count, int* expected_property_count,
928       bool is_inner_function, bool may_abort, bool* ok) {
929     UNREACHABLE();
930     return kLazyParsingComplete;
931   }
932   Expression ParseFunctionLiteral(
933       Identifier name, Scanner::Location function_name_location,
934       FunctionNameValidity function_name_validity, FunctionKind kind,
935       int function_token_pos, FunctionLiteral::FunctionType function_type,
936       LanguageMode language_mode, bool* ok);
937   LazyParsingResult ParseStatementListAndLogFunction(
938       PreParserFormalParameters* formals, bool has_duplicate_parameters,
939       bool maybe_abort, bool* ok);
940 
941   struct TemplateLiteralState {};
942 
943   V8_INLINE TemplateLiteralState OpenTemplateLiteral(int pos) {
944     return TemplateLiteralState();
945   }
946   V8_INLINE void AddTemplateExpression(TemplateLiteralState* state,
947                                        PreParserExpression expression) {}
948   V8_INLINE void AddTemplateSpan(TemplateLiteralState* state, bool tail) {}
949   V8_INLINE PreParserExpression CloseTemplateLiteral(
950       TemplateLiteralState* state, int start, PreParserExpression tag);
951   V8_INLINE void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
952 
953   V8_INLINE void SetLanguageMode(Scope* scope, LanguageMode mode) {
954     scope->SetLanguageMode(mode);
955   }
956   V8_INLINE void SetAsmModule() {}
957 
958   V8_INLINE void MarkCollectedTailCallExpressions() {}
959   V8_INLINE void MarkTailPosition(PreParserExpression expression) {}
960 
961   V8_INLINE PreParserExpressionList
962   PrepareSpreadArguments(PreParserExpressionList list) {
963     return list;
964   }
965 
966   V8_INLINE PreParserExpression SpreadCall(PreParserExpression function,
967                                            PreParserExpressionList args,
968                                            int pos);
969   V8_INLINE PreParserExpression SpreadCallNew(PreParserExpression function,
970                                               PreParserExpressionList args,
971                                               int pos);
972 
973   V8_INLINE PreParserExpression
974   RewriteSuperCall(PreParserExpression call_expression) {
975     return call_expression;
976   }
977 
978   V8_INLINE void RewriteDestructuringAssignments() {}
979 
980   V8_INLINE PreParserExpression RewriteExponentiation(PreParserExpression left,
981                                                       PreParserExpression right,
982                                                       int pos) {
983     return left;
984   }
985   V8_INLINE PreParserExpression RewriteAssignExponentiation(
986       PreParserExpression left, PreParserExpression right, int pos) {
987     return left;
988   }
989 
990   V8_INLINE PreParserExpression
991   RewriteAwaitExpression(PreParserExpression value, int pos) {
992     return value;
993   }
994   V8_INLINE void PrepareAsyncFunctionBody(PreParserStatementList body,
995                                           FunctionKind kind, int pos) {}
996   V8_INLINE void RewriteAsyncFunctionBody(PreParserStatementList body,
997                                           PreParserStatement block,
998                                           PreParserExpression return_value,
999                                           bool* ok) {}
1000   V8_INLINE PreParserExpression RewriteYieldStar(PreParserExpression generator,
1001                                                  PreParserExpression expression,
1002                                                  int pos) {
1003     return PreParserExpression::Default();
1004   }
1005   V8_INLINE void RewriteNonPattern(bool* ok) { ValidateExpression(ok); }
1006 
1007   void DeclareAndInitializeVariables(
1008       PreParserStatement block,
1009       const DeclarationDescriptor* declaration_descriptor,
1010       const DeclarationParsingResult::Declaration* declaration,
1011       ZoneList<const AstRawString*>* names, bool* ok);
1012 
1013   V8_INLINE ZoneList<const AstRawString*>* DeclareLabel(
1014       ZoneList<const AstRawString*>* labels, PreParserExpression expr,
1015       bool* ok) {
1016     DCHECK(!expr.AsIdentifier().IsEnum());
1017     DCHECK(!parsing_module_ || !expr.AsIdentifier().IsAwait());
1018     DCHECK(is_sloppy(language_mode()) ||
1019            !IsFutureStrictReserved(expr.AsIdentifier()));
1020     return labels;
1021   }
1022 
1023   // TODO(nikolaos): The preparser currently does not keep track of labels.
1024   V8_INLINE bool ContainsLabel(ZoneList<const AstRawString*>* labels,
1025                                PreParserIdentifier label) {
1026     return false;
1027   }
1028 
1029   V8_INLINE PreParserExpression RewriteReturn(PreParserExpression return_value,
1030                                               int pos) {
1031     return return_value;
1032   }
1033   V8_INLINE PreParserStatement RewriteSwitchStatement(
1034       PreParserExpression tag, PreParserStatement switch_statement,
1035       PreParserStatementList cases, Scope* scope) {
1036     return PreParserStatement::Default();
1037   }
1038   V8_INLINE void RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {}
1039   V8_INLINE void ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {}
1040   V8_INLINE PreParserStatement RewriteTryStatement(
1041       PreParserStatement try_block, PreParserStatement catch_block,
1042       PreParserStatement finally_block, const CatchInfo& catch_info, int pos) {
1043     return PreParserStatement::Default();
1044   }
1045 
1046   V8_INLINE PreParserExpression RewriteDoExpression(PreParserStatement body,
1047                                                     int pos, bool* ok) {
1048     return PreParserExpression::Default();
1049   }
1050 
1051   // TODO(nikolaos): The preparser currently does not keep track of labels
1052   // and targets.
1053   V8_INLINE PreParserStatement LookupBreakTarget(PreParserIdentifier label,
1054                                                  bool* ok) {
1055     return PreParserStatement::Default();
1056   }
1057   V8_INLINE PreParserStatement LookupContinueTarget(PreParserIdentifier label,
1058                                                     bool* ok) {
1059     return PreParserStatement::Default();
1060   }
1061 
1062   V8_INLINE PreParserStatement DeclareFunction(
1063       PreParserIdentifier variable_name, PreParserExpression function, int pos,
1064       bool is_generator, bool is_async, ZoneList<const AstRawString*>* names,
1065       bool* ok) {
1066     return Statement::Default();
1067   }
1068 
1069   V8_INLINE PreParserStatement
1070   DeclareClass(PreParserIdentifier variable_name, PreParserExpression value,
1071                ZoneList<const AstRawString*>* names, int class_token_pos,
1072                int end_pos, bool* ok) {
1073     return PreParserStatement::Default();
1074   }
1075   V8_INLINE void DeclareClassVariable(PreParserIdentifier name,
1076                                       Scope* block_scope, ClassInfo* class_info,
1077                                       int class_token_pos, bool* ok) {}
1078   V8_INLINE void DeclareClassProperty(PreParserIdentifier class_name,
1079                                       PreParserExpression property,
1080                                       ClassInfo* class_info, bool* ok) {}
1081   V8_INLINE PreParserExpression RewriteClassLiteral(PreParserIdentifier name,
1082                                                     ClassInfo* class_info,
1083                                                     int pos, bool* ok) {
1084     return PreParserExpression::Default();
1085   }
1086 
1087   V8_INLINE PreParserStatement DeclareNative(PreParserIdentifier name, int pos,
1088                                              bool* ok) {
1089     return PreParserStatement::Default();
1090   }
1091 
1092   V8_INLINE void QueueDestructuringAssignmentForRewriting(
1093       PreParserExpression assignment) {}
1094   V8_INLINE void QueueNonPatternForRewriting(PreParserExpression expr,
1095                                              bool* ok) {}
1096 
1097   // Helper functions for recursive descent.
1098   V8_INLINE bool IsEval(PreParserIdentifier identifier) const {
1099     return identifier.IsEval();
1100   }
1101 
1102   V8_INLINE bool IsArguments(PreParserIdentifier identifier) const {
1103     return identifier.IsArguments();
1104   }
1105 
1106   V8_INLINE bool IsEvalOrArguments(PreParserIdentifier identifier) const {
1107     return identifier.IsEvalOrArguments();
1108   }
1109 
1110   V8_INLINE bool IsUndefined(PreParserIdentifier identifier) const {
1111     return identifier.IsUndefined();
1112   }
1113 
1114   V8_INLINE bool IsAwait(PreParserIdentifier identifier) const {
1115     return identifier.IsAwait();
1116   }
1117 
1118   V8_INLINE bool IsFutureStrictReserved(PreParserIdentifier identifier) const {
1119     return identifier.IsFutureStrictReserved();
1120   }
1121 
1122   // Returns true if the expression is of type "this.foo".
1123   V8_INLINE static bool IsThisProperty(PreParserExpression expression) {
1124     return expression.IsThisProperty();
1125   }
1126 
1127   V8_INLINE static bool IsIdentifier(PreParserExpression expression) {
1128     return expression.IsIdentifier();
1129   }
1130 
1131   V8_INLINE static PreParserIdentifier AsIdentifier(
1132       PreParserExpression expression) {
1133     return expression.AsIdentifier();
1134   }
1135 
1136   V8_INLINE static PreParserExpression AsIdentifierExpression(
1137       PreParserExpression expression) {
1138     return expression;
1139   }
1140 
1141   V8_INLINE bool IsPrototype(PreParserIdentifier identifier) const {
1142     return identifier.IsPrototype();
1143   }
1144 
1145   V8_INLINE bool IsConstructor(PreParserIdentifier identifier) const {
1146     return identifier.IsConstructor();
1147   }
1148 
1149   V8_INLINE bool IsDirectEvalCall(PreParserExpression expression) const {
1150     return expression.IsDirectEvalCall();
1151   }
1152 
1153   V8_INLINE static bool IsBoilerplateProperty(PreParserExpression property) {
1154     // PreParser doesn't count boilerplate properties.
1155     return false;
1156   }
1157 
1158   V8_INLINE bool IsNative(PreParserExpression expr) const {
1159     // Preparsing is disabled for extensions (because the extension
1160     // details aren't passed to lazily compiled functions), so we
1161     // don't accept "native function" in the preparser and there is
1162     // no need to keep track of "native".
1163     return false;
1164   }
1165 
1166   V8_INLINE static bool IsArrayIndex(PreParserIdentifier string,
1167                                      uint32_t* index) {
1168     return false;
1169   }
1170 
1171   V8_INLINE bool IsUseStrictDirective(PreParserStatement statement) const {
1172     return statement.IsUseStrictLiteral();
1173   }
1174 
1175   V8_INLINE bool IsUseAsmDirective(PreParserStatement statement) const {
1176     return statement.IsUseAsmLiteral();
1177   }
1178 
1179   V8_INLINE bool IsStringLiteral(PreParserStatement statement) const {
1180     return statement.IsStringLiteral();
1181   }
1182 
1183   V8_INLINE static PreParserExpression GetPropertyValue(
1184       PreParserExpression property) {
1185     return PreParserExpression::Default();
1186   }
1187 
1188   V8_INLINE static void GetDefaultStrings(
1189       PreParserIdentifier* default_string,
1190       PreParserIdentifier* star_default_star_string) {}
1191 
1192   // Functions for encapsulating the differences between parsing and preparsing;
1193   // operations interleaved with the recursive descent.
1194   V8_INLINE static void PushLiteralName(PreParserIdentifier id) {}
1195   V8_INLINE static void PushVariableName(PreParserIdentifier id) {}
1196   V8_INLINE void PushPropertyName(PreParserExpression expression) {}
1197   V8_INLINE void PushEnclosingName(PreParserIdentifier name) {}
1198   V8_INLINE static void AddFunctionForNameInference(
1199       PreParserExpression expression) {}
1200   V8_INLINE static void InferFunctionName() {}
1201 
1202   V8_INLINE static void CheckAssigningFunctionLiteralToProperty(
1203       PreParserExpression left, PreParserExpression right) {}
1204 
1205   V8_INLINE static PreParserExpression MarkExpressionAsAssigned(
1206       PreParserExpression expression) {
1207     // TODO(marja): To be able to produce the same errors, the preparser needs
1208     // to start tracking which expressions are variables and which are assigned.
1209     return expression;
1210   }
1211 
1212   V8_INLINE bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
1213                                                         PreParserExpression y,
1214                                                         Token::Value op,
1215                                                         int pos) {
1216     return false;
1217   }
1218 
1219   V8_INLINE PreParserExpression BuildUnaryExpression(
1220       PreParserExpression expression, Token::Value op, int pos) {
1221     return PreParserExpression::Default();
1222   }
1223 
1224   V8_INLINE PreParserExpression BuildIteratorResult(PreParserExpression value,
1225                                                     bool done) {
1226     return PreParserExpression::Default();
1227   }
1228 
1229   V8_INLINE PreParserStatement
1230   BuildInitializationBlock(DeclarationParsingResult* parsing_result,
1231                            ZoneList<const AstRawString*>* names, bool* ok) {
1232     return PreParserStatement::Default();
1233   }
1234 
1235   V8_INLINE PreParserStatement
1236   InitializeForEachStatement(PreParserStatement stmt, PreParserExpression each,
1237                              PreParserExpression subject,
1238                              PreParserStatement body, int each_keyword_pos) {
1239     return stmt;
1240   }
1241 
1242   V8_INLINE PreParserStatement RewriteForVarInLegacy(const ForInfo& for_info) {
1243     return PreParserStatement::Null();
1244   }
1245   V8_INLINE void DesugarBindingInForEachStatement(
1246       ForInfo* for_info, PreParserStatement* body_block,
1247       PreParserExpression* each_variable, bool* ok) {}
1248   V8_INLINE PreParserStatement CreateForEachStatementTDZ(
1249       PreParserStatement init_block, const ForInfo& for_info, bool* ok) {
1250     return init_block;
1251   }
1252 
1253   V8_INLINE StatementT DesugarLexicalBindingsInForStatement(
1254       PreParserStatement loop, PreParserStatement init,
1255       PreParserExpression cond, PreParserStatement next,
1256       PreParserStatement body, Scope* inner_scope, const ForInfo& for_info,
1257       bool* ok) {
1258     return loop;
1259   }
1260 
1261   V8_INLINE PreParserExpression
1262   NewThrowReferenceError(MessageTemplate::Template message, int pos) {
1263     return PreParserExpression::Default();
1264   }
1265 
1266   V8_INLINE PreParserExpression NewThrowSyntaxError(
1267       MessageTemplate::Template message, PreParserIdentifier arg, int pos) {
1268     return PreParserExpression::Default();
1269   }
1270 
1271   V8_INLINE PreParserExpression NewThrowTypeError(
1272       MessageTemplate::Template message, PreParserIdentifier arg, int pos) {
1273     return PreParserExpression::Default();
1274   }
1275 
1276   // Reporting errors.
1277   V8_INLINE void ReportMessageAt(Scanner::Location source_location,
1278                                  MessageTemplate::Template message,
1279                                  const char* arg = NULL,
1280                                  ParseErrorType error_type = kSyntaxError) {
1281     pending_error_handler_->ReportMessageAt(source_location.beg_pos,
1282                                             source_location.end_pos, message,
1283                                             arg, error_type);
1284   }
1285 
1286   V8_INLINE void ReportMessageAt(Scanner::Location source_location,
1287                                  MessageTemplate::Template message,
1288                                  PreParserIdentifier arg,
1289                                  ParseErrorType error_type = kSyntaxError) {
1290     UNREACHABLE();
1291   }
1292 
1293   // "null" return type creators.
1294   V8_INLINE static PreParserIdentifier EmptyIdentifier() {
1295     return PreParserIdentifier::Empty();
1296   }
1297   V8_INLINE static bool IsEmptyIdentifier(PreParserIdentifier name) {
1298     return name.IsEmpty();
1299   }
1300   V8_INLINE static PreParserExpression EmptyExpression() {
1301     return PreParserExpression::Empty();
1302   }
1303   V8_INLINE static PreParserExpression EmptyLiteral() {
1304     return PreParserExpression::Default();
1305   }
1306   V8_INLINE static PreParserExpression EmptyObjectLiteralProperty() {
1307     return PreParserExpression::Default();
1308   }
1309   V8_INLINE static PreParserExpression EmptyClassLiteralProperty() {
1310     return PreParserExpression::Default();
1311   }
1312   V8_INLINE static PreParserExpression EmptyFunctionLiteral() {
1313     return PreParserExpression::Default();
1314   }
1315 
1316   V8_INLINE static bool IsEmptyExpression(PreParserExpression expr) {
1317     return expr.IsEmpty();
1318   }
1319 
1320   V8_INLINE static PreParserExpressionList NullExpressionList() {
1321     return PreParserExpressionList::Null();
1322   }
1323 
1324   V8_INLINE static bool IsNullExpressionList(PreParserExpressionList exprs) {
1325     return exprs.IsNull();
1326   }
1327 
1328   V8_INLINE static PreParserStatementList NullStatementList() {
1329     return PreParserStatementList::Null();
1330   }
1331 
1332   V8_INLINE static bool IsNullStatementList(PreParserStatementList stmts) {
1333     return stmts.IsNull();
1334   }
1335 
1336   V8_INLINE static PreParserStatement NullStatement() {
1337     return PreParserStatement::Null();
1338   }
1339 
1340   V8_INLINE bool IsNullStatement(PreParserStatement stmt) {
1341     return stmt.IsNullStatement();
1342   }
1343 
1344   V8_INLINE bool IsEmptyStatement(PreParserStatement stmt) {
1345     return stmt.IsEmptyStatement();
1346   }
1347 
1348   V8_INLINE static PreParserStatement NullBlock() {
1349     return PreParserStatement::Null();
1350   }
1351 
1352   V8_INLINE PreParserIdentifier EmptyIdentifierString() const {
1353     return PreParserIdentifier::Default();
1354   }
1355 
1356   // Odd-ball literal creators.
1357   V8_INLINE PreParserExpression GetLiteralTheHole(int position) {
1358     return PreParserExpression::Default();
1359   }
1360 
1361   V8_INLINE PreParserExpression GetLiteralUndefined(int position) {
1362     return PreParserExpression::Default();
1363   }
1364 
1365   // Producing data during the recursive descent.
1366   PreParserIdentifier GetSymbol() const;
1367 
1368   V8_INLINE PreParserIdentifier GetNextSymbol() const {
1369     return PreParserIdentifier::Default();
1370   }
1371 
1372   V8_INLINE PreParserIdentifier GetNumberAsSymbol() const {
1373     return PreParserIdentifier::Default();
1374   }
1375 
1376   V8_INLINE PreParserExpression ThisExpression(int pos = kNoSourcePosition) {
1377     return PreParserExpression::This();
1378   }
1379 
1380   V8_INLINE PreParserExpression NewSuperPropertyReference(int pos) {
1381     return PreParserExpression::Default();
1382   }
1383 
1384   V8_INLINE PreParserExpression NewSuperCallReference(int pos) {
1385     return PreParserExpression::SuperCallReference();
1386   }
1387 
1388   V8_INLINE PreParserExpression NewTargetExpression(int pos) {
1389     return PreParserExpression::Default();
1390   }
1391 
1392   V8_INLINE PreParserExpression FunctionSentExpression(int pos) {
1393     return PreParserExpression::Default();
1394   }
1395 
1396   V8_INLINE PreParserExpression ExpressionFromLiteral(Token::Value token,
1397                                                       int pos) {
1398     return PreParserExpression::Default();
1399   }
1400 
1401   PreParserExpression ExpressionFromIdentifier(
1402       PreParserIdentifier name, int start_position,
1403       InferName infer = InferName::kYes);
1404 
1405   V8_INLINE PreParserExpression ExpressionFromString(int pos) {
1406     if (scanner()->UnescapedLiteralMatches("use strict", 10)) {
1407       return PreParserExpression::UseStrictStringLiteral();
1408     }
1409     return PreParserExpression::StringLiteral();
1410   }
1411 
1412   V8_INLINE PreParserExpressionList NewExpressionList(int size) const {
1413     return PreParserExpressionList();
1414   }
1415 
1416   V8_INLINE PreParserExpressionList NewObjectPropertyList(int size) const {
1417     return PreParserExpressionList();
1418   }
1419 
1420   V8_INLINE PreParserExpressionList NewClassPropertyList(int size) const {
1421     return PreParserExpressionList();
1422   }
1423 
1424   V8_INLINE PreParserStatementList NewStatementList(int size) const {
1425     return PreParserStatementList();
1426   }
1427 
1428   PreParserStatementList NewCaseClauseList(int size) {
1429     return PreParserStatementList();
1430   }
1431 
1432   V8_INLINE PreParserExpression
1433   NewV8Intrinsic(PreParserIdentifier name, PreParserExpressionList arguments,
1434                  int pos, bool* ok) {
1435     return PreParserExpression::Default();
1436   }
1437 
1438   V8_INLINE PreParserStatement NewThrowStatement(PreParserExpression exception,
1439                                                  int pos) {
1440     return PreParserStatement::Jump();
1441   }
1442 
1443   V8_INLINE void AddParameterInitializationBlock(
1444       const PreParserFormalParameters& parameters, PreParserStatementList body,
1445       bool is_async, bool* ok) {}
1446 
1447   V8_INLINE void AddFormalParameter(PreParserFormalParameters* parameters,
1448                                     PreParserExpression pattern,
1449                                     PreParserExpression initializer,
1450                                     int initializer_end_position,
1451                                     bool is_rest) {
1452     parameters->UpdateArityAndFunctionLength(!initializer.IsEmpty(), is_rest);
1453   }
1454 
1455   V8_INLINE void DeclareFormalParameter(DeclarationScope* scope,
1456                                         PreParserIdentifier parameter) {
1457     if (!classifier()->is_simple_parameter_list()) {
1458       scope->SetHasNonSimpleParameters();
1459     }
1460   }
1461 
1462   V8_INLINE void DeclareArrowFunctionFormalParameters(
1463       PreParserFormalParameters* parameters, PreParserExpression params,
1464       const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
1465       bool* ok) {
1466     // TODO(wingo): Detect duplicated identifiers in paramlists.  Detect
1467     // parameter lists that are too long.
1468   }
1469 
1470   V8_INLINE void ReindexLiterals(const PreParserFormalParameters& parameters) {}
1471 
1472   V8_INLINE PreParserExpression NoTemplateTag() {
1473     return PreParserExpression::NoTemplateTag();
1474   }
1475 
1476   V8_INLINE static bool IsTaggedTemplate(const PreParserExpression tag) {
1477     return !tag.IsNoTemplateTag();
1478   }
1479 
1480   V8_INLINE void MaterializeUnspreadArgumentsLiterals(int count) {
1481     for (int i = 0; i < count; ++i) {
1482       function_state_->NextMaterializedLiteralIndex();
1483     }
1484   }
1485 
1486   V8_INLINE PreParserExpression
1487   ExpressionListToExpression(PreParserExpressionList args) {
1488     return PreParserExpression::Default(args.identifiers_);
1489   }
1490 
1491   V8_INLINE void AddAccessorPrefixToFunctionName(bool is_get,
1492                                                  PreParserExpression function,
1493                                                  PreParserIdentifier name) {}
1494   V8_INLINE void SetFunctionNameFromPropertyName(PreParserExpression property,
1495                                                  PreParserIdentifier name) {}
1496   V8_INLINE void SetFunctionNameFromIdentifierRef(
1497       PreParserExpression value, PreParserExpression identifier) {}
1498 
1499   V8_INLINE ZoneList<typename ExpressionClassifier::Error>*
1500   GetReportedErrorList() const {
1501     return function_state_->GetReportedErrorList();
1502   }
1503 
1504   V8_INLINE ZoneList<PreParserExpression>* GetNonPatternList() const {
1505     return function_state_->non_patterns_to_rewrite();
1506   }
1507 
1508   V8_INLINE void CountUsage(v8::Isolate::UseCounterFeature feature) {
1509     if (use_counts_ != nullptr) ++use_counts_[feature];
1510   }
1511 
1512   // Preparser's private field members.
1513 
1514   int* use_counts_;
1515   bool track_unresolved_variables_;
1516   PreParserLogger log_;
1517   PendingCompilationErrorHandler* pending_error_handler_;
1518 };
1519 
1520 PreParserExpression PreParser::SpreadCall(PreParserExpression function,
1521                                           PreParserExpressionList args,
1522                                           int pos) {
1523   return factory()->NewCall(function, args, pos);
1524 }
1525 
1526 PreParserExpression PreParser::SpreadCallNew(PreParserExpression function,
1527                                              PreParserExpressionList args,
1528                                              int pos) {
1529   return factory()->NewCallNew(function, args, pos);
1530 }
1531 
1532 PreParserStatementList PreParser::ParseEagerFunctionBody(
1533     PreParserIdentifier function_name, int pos,
1534     const PreParserFormalParameters& parameters, FunctionKind kind,
1535     FunctionLiteral::FunctionType function_type, bool* ok) {
1536   PreParserStatementList result;
1537 
1538   Scope* inner_scope = scope();
1539   if (!parameters.is_simple) inner_scope = NewScope(BLOCK_SCOPE);
1540 
1541   {
1542     BlockState block_state(&scope_state_, inner_scope);
1543     ParseStatementList(result, Token::RBRACE, ok);
1544     if (!*ok) return PreParserStatementList();
1545   }
1546 
1547   Expect(Token::RBRACE, ok);
1548   return result;
1549 }
1550 
1551 PreParserExpression PreParser::CloseTemplateLiteral(TemplateLiteralState* state,
1552                                                     int start,
1553                                                     PreParserExpression tag) {
1554   if (IsTaggedTemplate(tag)) {
1555     // Emulate generation of array literals for tag callsite
1556     // 1st is array of cooked strings, second is array of raw strings
1557     function_state_->NextMaterializedLiteralIndex();
1558     function_state_->NextMaterializedLiteralIndex();
1559   }
1560   return EmptyExpression();
1561 }
1562 
1563 }  // namespace internal
1564 }  // namespace v8
1565 
1566 #endif  // V8_PARSING_PREPARSER_H
1567