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