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
14namespace v8 {
15namespace 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
25class PreParserIdentifier {
26 public:
27  PreParserIdentifier() : type_(kUnknownIdentifier) {}
28  static PreParserIdentifier Default() {
29    return PreParserIdentifier(kUnknownIdentifier);
30  }
31  static PreParserIdentifier Empty() {
32    return PreParserIdentifier(kEmptyIdentifier);
33  }
34  static PreParserIdentifier Eval() {
35    return PreParserIdentifier(kEvalIdentifier);
36  }
37  static PreParserIdentifier Arguments() {
38    return PreParserIdentifier(kArgumentsIdentifier);
39  }
40  static PreParserIdentifier Undefined() {
41    return PreParserIdentifier(kUndefinedIdentifier);
42  }
43  static PreParserIdentifier FutureReserved() {
44    return PreParserIdentifier(kFutureReservedIdentifier);
45  }
46  static PreParserIdentifier FutureStrictReserved() {
47    return PreParserIdentifier(kFutureStrictReservedIdentifier);
48  }
49  static PreParserIdentifier Let() {
50    return PreParserIdentifier(kLetIdentifier);
51  }
52  static PreParserIdentifier Static() {
53    return PreParserIdentifier(kStaticIdentifier);
54  }
55  static PreParserIdentifier Yield() {
56    return PreParserIdentifier(kYieldIdentifier);
57  }
58  static PreParserIdentifier Prototype() {
59    return PreParserIdentifier(kPrototypeIdentifier);
60  }
61  static PreParserIdentifier Constructor() {
62    return PreParserIdentifier(kConstructorIdentifier);
63  }
64  static PreParserIdentifier Enum() {
65    return PreParserIdentifier(kEnumIdentifier);
66  }
67  static PreParserIdentifier Await() {
68    return PreParserIdentifier(kAwaitIdentifier);
69  }
70  static PreParserIdentifier Async() {
71    return PreParserIdentifier(kAsyncIdentifier);
72  }
73  static PreParserIdentifier Name() {
74    return PreParserIdentifier(kNameIdentifier);
75  }
76  bool IsEmpty() const { return type_ == kEmptyIdentifier; }
77  bool IsEval() const { return type_ == kEvalIdentifier; }
78  bool IsArguments() const { return type_ == kArgumentsIdentifier; }
79  bool IsEvalOrArguments() const { return IsEval() || IsArguments(); }
80  bool IsUndefined() const { return type_ == kUndefinedIdentifier; }
81  bool IsLet() const { return type_ == kLetIdentifier; }
82  bool IsStatic() const { return type_ == kStaticIdentifier; }
83  bool IsYield() const { return type_ == kYieldIdentifier; }
84  bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
85  bool IsConstructor() const { return type_ == kConstructorIdentifier; }
86  bool IsEnum() const { return type_ == kEnumIdentifier; }
87  bool IsAwait() const { return type_ == kAwaitIdentifier; }
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; }
93  const PreParserIdentifier raw_name() const { return *this; }
94
95  int position() const { return 0; }
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
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
128class PreParserExpression {
129 public:
130  PreParserExpression()
131      : code_(TypeField::encode(kEmpty)), variables_(nullptr) {}
132
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
140  static PreParserExpression Spread(PreParserExpression expression) {
141    return PreParserExpression(TypeField::encode(kSpreadExpression),
142                               expression.variables_);
143  }
144
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
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
175  static PreParserExpression Assignment(ZoneList<VariableProxy*>* variables) {
176    return PreParserExpression(TypeField::encode(kExpression) |
177                                   ExpressionTypeField::encode(kAssignment),
178                               variables);
179  }
180
181  static PreParserExpression ObjectLiteral(
182      ZoneList<VariableProxy*>* variables) {
183    return PreParserExpression(TypeField::encode(kObjectLiteralExpression),
184                               variables);
185  }
186
187  static PreParserExpression ArrayLiteral(ZoneList<VariableProxy*>* variables) {
188    return PreParserExpression(TypeField::encode(kArrayLiteralExpression),
189                               variables);
190  }
191
192  static PreParserExpression StringLiteral() {
193    return PreParserExpression(TypeField::encode(kStringLiteralExpression));
194  }
195
196  static PreParserExpression UseStrictStringLiteral() {
197    return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
198                               IsUseStrictField::encode(true));
199  }
200
201  static PreParserExpression UseAsmStringLiteral() {
202    return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
203                               IsUseAsmField::encode(true));
204  }
205
206  static PreParserExpression This(ZoneList<VariableProxy*>* variables) {
207    return PreParserExpression(TypeField::encode(kExpression) |
208                                   ExpressionTypeField::encode(kThisExpression),
209                               variables);
210  }
211
212  static PreParserExpression ThisProperty() {
213    return PreParserExpression(
214        TypeField::encode(kExpression) |
215        ExpressionTypeField::encode(kThisPropertyExpression));
216  }
217
218  static PreParserExpression Property() {
219    return PreParserExpression(
220        TypeField::encode(kExpression) |
221        ExpressionTypeField::encode(kPropertyExpression));
222  }
223
224  static PreParserExpression Call() {
225    return PreParserExpression(TypeField::encode(kExpression) |
226                               ExpressionTypeField::encode(kCallExpression));
227  }
228
229  static PreParserExpression CallEval() {
230    return PreParserExpression(
231        TypeField::encode(kExpression) |
232        ExpressionTypeField::encode(kCallEvalExpression));
233  }
234
235  static PreParserExpression SuperCallReference() {
236    return PreParserExpression(
237        TypeField::encode(kExpression) |
238        ExpressionTypeField::encode(kSuperCallReference));
239  }
240
241  static PreParserExpression NoTemplateTag() {
242    return PreParserExpression(
243        TypeField::encode(kExpression) |
244        ExpressionTypeField::encode(kNoTemplateTagExpression));
245  }
246
247  bool IsEmpty() const { return TypeField::decode(code_) == kEmpty; }
248
249  bool IsIdentifier() const {
250    return TypeField::decode(code_) == kIdentifierExpression;
251  }
252
253  PreParserIdentifier AsIdentifier() const {
254    DCHECK(IsIdentifier());
255    return PreParserIdentifier(IdentifierTypeField::decode(code_));
256  }
257
258  bool IsAssignment() const {
259    return TypeField::decode(code_) == kExpression &&
260           ExpressionTypeField::decode(code_) == kAssignment;
261  }
262
263  bool IsObjectLiteral() const {
264    return TypeField::decode(code_) == kObjectLiteralExpression;
265  }
266
267  bool IsArrayLiteral() const {
268    return TypeField::decode(code_) == kArrayLiteralExpression;
269  }
270
271  bool IsStringLiteral() const {
272    return TypeField::decode(code_) == kStringLiteralExpression;
273  }
274
275  bool IsUseStrictLiteral() const {
276    return TypeField::decode(code_) == kStringLiteralExpression &&
277           IsUseStrictField::decode(code_);
278  }
279
280  bool IsUseAsmLiteral() const {
281    return TypeField::decode(code_) == kStringLiteralExpression &&
282           IsUseAsmField::decode(code_);
283  }
284
285  bool IsThis() const {
286    return TypeField::decode(code_) == kExpression &&
287           ExpressionTypeField::decode(code_) == kThisExpression;
288  }
289
290  bool IsThisProperty() const {
291    return TypeField::decode(code_) == kExpression &&
292           ExpressionTypeField::decode(code_) == kThisPropertyExpression;
293  }
294
295  bool IsProperty() const {
296    return TypeField::decode(code_) == kExpression &&
297           (ExpressionTypeField::decode(code_) == kPropertyExpression ||
298            ExpressionTypeField::decode(code_) == kThisPropertyExpression);
299  }
300
301  bool IsCall() const {
302    return TypeField::decode(code_) == kExpression &&
303           (ExpressionTypeField::decode(code_) == kCallExpression ||
304            ExpressionTypeField::decode(code_) == kCallEvalExpression);
305  }
306
307  bool IsSuperCallReference() const {
308    return TypeField::decode(code_) == kExpression &&
309           ExpressionTypeField::decode(code_) == kSuperCallReference;
310  }
311
312  bool IsValidReferenceExpression() const {
313    return IsIdentifier() || IsProperty();
314  }
315
316  // At the moment PreParser doesn't track these expression types.
317  bool IsFunctionLiteral() const { return false; }
318  bool IsCallNew() const { return false; }
319
320  bool IsNoTemplateTag() const {
321    return TypeField::decode(code_) == kExpression &&
322           ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
323  }
324
325  bool IsSpread() const {
326    return TypeField::decode(code_) == kSpreadExpression;
327  }
328
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:
336  void set_index(int index) {}  // For YieldExpressions
337  void SetShouldEagerCompile() {}
338  void set_should_be_used_once_hint() {}
339
340  int position() const { return kNoSourcePosition; }
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)
367      : code_(expression_code), variables_(variables) {}
368
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.
413template <typename T>
414class PreParserList {
415 public:
416  // These functions make list->Add(some_expression) work (and do nothing).
417  PreParserList() : length_(0), variables_(nullptr) {}
418  PreParserList* operator->() { return this; }
419  void Add(const T& element, Zone* zone);
420  int length() const { return length_; }
421  static PreParserList Null() { return PreParserList(-1); }
422  bool IsNull() const { return length_ == -1; }
423  void Set(int index, const T& element) {}
424
425 private:
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
434template <>
435inline 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
450template <typename T>
451void PreParserList<T>::Add(const T& element, Zone* zone) {
452  ++length_;
453}
454
455typedef PreParserList<PreParserExpression> PreParserExpressionList;
456
457class PreParserStatement;
458typedef PreParserList<PreParserStatement> PreParserStatementList;
459
460class PreParserStatement {
461 public:
462  static PreParserStatement Default() {
463    return PreParserStatement(kUnknownStatement);
464  }
465
466  static PreParserStatement Null() {
467    return PreParserStatement(kNullStatement);
468  }
469
470  static PreParserStatement Empty() {
471    return PreParserStatement(kEmptyStatement);
472  }
473
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".
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
495  bool IsStringLiteral() {
496    return code_ == kStringLiteralExpressionStatement || IsUseStrictLiteral() ||
497           IsUseAsmLiteral();
498  }
499
500  bool IsUseStrictLiteral() {
501    return code_ == kUseStrictExpressionStatement;
502  }
503
504  bool IsUseAsmLiteral() { return code_ == kUseAsmExpressionStatement; }
505
506  bool IsJumpStatement() {
507    return code_ == kJumpStatement;
508  }
509
510  bool IsNullStatement() { return code_ == kNullStatement; }
511
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
518  PreParserStatementList statements() { return PreParserStatementList(); }
519  void set_scope(Scope* scope) {}
520  void Initialize(PreParserExpression cond, 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
535  explicit PreParserStatement(Type code) : code_(code) {}
536  Type code_;
537};
538
539
540class PreParserFactory {
541 public:
542  explicit PreParserFactory(AstValueFactory* ast_value_factory)
543      : ast_value_factory_(ast_value_factory),
544        zone_(ast_value_factory->zone()) {}
545
546  void set_zone(Zone* zone) { zone_ = zone; }
547
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  }
563  PreParserExpression NewNumberLiteral(double number,
564                                       int pos) {
565    return PreParserExpression::Default();
566  }
567  PreParserExpression NewUndefinedLiteral(int pos) {
568    return PreParserExpression::Default();
569  }
570  PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
571                                       int js_flags, int pos) {
572    return PreParserExpression::Default();
573  }
574  PreParserExpression NewArrayLiteral(PreParserExpressionList values,
575                                      int first_spread_index, int pos) {
576    return PreParserExpression::ArrayLiteral(values.variables_);
577  }
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  }
585  PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
586                                               PreParserExpression value,
587                                               ObjectLiteralProperty::Kind kind,
588                                               bool is_computed_name) {
589    return PreParserExpression::Default(value.variables_);
590  }
591  PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
592                                               PreParserExpression value,
593                                               bool is_computed_name) {
594    return PreParserExpression::Default(value.variables_);
595  }
596  PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
597                                       int boilerplate_properties, int pos,
598                                       bool has_rest_property) {
599    return PreParserExpression::ObjectLiteral(properties.variables_);
600  }
601  PreParserExpression NewVariableProxy(void* variable) {
602    return PreParserExpression::Default();
603  }
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  }
612  PreParserExpression NewUnaryOperation(Token::Value op,
613                                        PreParserExpression expression,
614                                        int pos) {
615    return PreParserExpression::Default();
616  }
617  PreParserExpression NewBinaryOperation(Token::Value op,
618                                         PreParserExpression left,
619                                         PreParserExpression right, int pos) {
620    return PreParserExpression::BinaryOperation(left, op, right, zone_);
621  }
622  PreParserExpression NewCompareOperation(Token::Value op,
623                                          PreParserExpression left,
624                                          PreParserExpression right, int pos) {
625    return PreParserExpression::Default();
626  }
627  PreParserExpression NewRewritableExpression(PreParserExpression expression) {
628    return expression;
629  }
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  }
638  PreParserExpression NewYield(PreParserExpression generator_object,
639                               PreParserExpression expression, int pos,
640                               Yield::OnException on_exception) {
641    return PreParserExpression::Default();
642  }
643  PreParserExpression NewConditional(PreParserExpression condition,
644                                     PreParserExpression then_expression,
645                                     PreParserExpression else_expression,
646                                     int pos) {
647    return PreParserExpression::Default();
648  }
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  }
664  PreParserExpression NewCallNew(PreParserExpression expression,
665                                 PreParserExpressionList arguments,
666                                 int pos) {
667    return PreParserExpression::Default();
668  }
669  PreParserStatement NewReturnStatement(PreParserExpression expression,
670                                        int pos) {
671    return PreParserStatement::Jump();
672  }
673  PreParserStatement NewAsyncReturnStatement(PreParserExpression expression,
674                                             int pos) {
675    return PreParserStatement::Jump();
676  }
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
687  PreParserExpression NewSpread(PreParserExpression expression, int pos,
688                                int expr_pos) {
689    return PreParserExpression::Spread(expression);
690  }
691
692  PreParserExpression NewEmptyParentheses(int pos) {
693    return PreParserExpression::Default();
694  }
695
696  PreParserStatement NewEmptyStatement(int pos) {
697    return PreParserStatement::Default();
698  }
699
700  PreParserStatement NewBlock(ZoneList<const AstRawString*>* labels,
701                              int capacity, bool ignore_completion_value,
702                              int pos) {
703    return PreParserStatement::Default();
704  }
705
706  PreParserStatement NewDebuggerStatement(int pos) {
707    return PreParserStatement::Default();
708  }
709
710  PreParserStatement NewExpressionStatement(PreParserExpression expr, int pos) {
711    return PreParserStatement::ExpressionStatement(expr);
712  }
713
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
722  PreParserStatement NewBreakStatement(PreParserStatement target, int pos) {
723    return PreParserStatement::Jump();
724  }
725
726  PreParserStatement NewContinueStatement(PreParserStatement target, int pos) {
727    return PreParserStatement::Jump();
728  }
729
730  PreParserStatement NewWithStatement(Scope* scope,
731                                      PreParserExpression expression,
732                                      PreParserStatement statement, int pos) {
733    return PreParserStatement::Default();
734  }
735
736  PreParserStatement NewDoWhileStatement(ZoneList<const AstRawString*>* labels,
737                                         int pos) {
738    return PreParserStatement::Default();
739  }
740
741  PreParserStatement NewWhileStatement(ZoneList<const AstRawString*>* labels,
742                                       int pos) {
743    return PreParserStatement::Default();
744  }
745
746  PreParserStatement NewSwitchStatement(ZoneList<const AstRawString*>* labels,
747                                        int pos) {
748    return PreParserStatement::Default();
749  }
750
751  PreParserStatement NewCaseClause(PreParserExpression label,
752                                   PreParserStatementList statements, int pos) {
753    return PreParserStatement::Default();
754  }
755
756  PreParserStatement NewForStatement(ZoneList<const AstRawString*>* labels,
757                                     int pos) {
758    return PreParserStatement::Default();
759  }
760
761  PreParserStatement NewForEachStatement(ForEachStatement::VisitMode visit_mode,
762                                         ZoneList<const AstRawString*>* labels,
763                                         int pos) {
764    return PreParserStatement::Default();
765  }
766
767  PreParserStatement NewForOfStatement(ZoneList<const AstRawString*>* labels,
768                                       int pos) {
769    return PreParserStatement::Default();
770  }
771
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.
780  PreParserFactory* visitor() { return this; }
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
792struct PreParserFormalParameters : FormalParametersBase {
793  struct Parameter : public ZoneObject {
794    Parameter(PreParserExpression pattern, bool is_destructuring, bool is_rest)
795        : pattern(pattern),
796          is_destructuring(is_destructuring),
797          is_rest(is_rest) {}
798    Parameter** next() { return &next_parameter; }
799    Parameter* const* next() const { return &next_parameter; }
800
801    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  };
809  explicit PreParserFormalParameters(DeclarationScope* scope)
810      : FormalParametersBase(scope) {}
811
812  ThreadedList<Parameter> params;
813};
814
815
816class PreParser;
817
818class PreParserTarget {
819 public:
820  PreParserTarget(ParserBase<PreParser>* preparser,
821                  PreParserStatement statement) {}
822};
823
824class PreParserTargetScope {
825 public:
826  explicit PreParserTargetScope(ParserBase<PreParser>* preparser) {}
827};
828
829template <>
830struct 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.
873class 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
1705PreParserExpression 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
1711PreParserExpression PreParser::SpreadCallNew(PreParserExpression function,
1712                                             PreParserExpressionList args,
1713                                             int pos) {
1714  return factory()->NewCallNew(function, args, pos);
1715}
1716
1717PreParserExpression 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