preparser.h 60.4 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5 6
#ifndef V8_PARSING_PREPARSER_H
#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"
marja's avatar
marja committed
12
#include "src/pending-compilation-error-handler.h"
13

14
namespace v8 {
15
namespace internal {
16

17 18 19 20 21 22 23 24
// Whereas the Parser generates AST during the recursive descent,
// the PreParser doesn't create a tree. Instead, it passes around minimal
// data objects (PreParserExpression, PreParserIdentifier etc.) which contain
// just enough data for the upper layer functions. PreParserFactory is
// responsible for creating these dummy objects. It provides a similar kind of
// interface as AstNodeFactory, so ParserBase doesn't need to care which one is
// used.

25 26
class ProducedPreParsedScopeData;

27 28
class PreParserIdentifier {
 public:
29
  PreParserIdentifier() : type_(kUnknownIdentifier) {}
30 31 32
  static PreParserIdentifier Default() {
    return PreParserIdentifier(kUnknownIdentifier);
  }
33 34
  static PreParserIdentifier Null() {
    return PreParserIdentifier(kNullIdentifier);
35
  }
36 37 38 39 40 41
  static PreParserIdentifier Eval() {
    return PreParserIdentifier(kEvalIdentifier);
  }
  static PreParserIdentifier Arguments() {
    return PreParserIdentifier(kArgumentsIdentifier);
  }
arv@chromium.org's avatar
arv@chromium.org committed
42 43 44
  static PreParserIdentifier Constructor() {
    return PreParserIdentifier(kConstructorIdentifier);
  }
45 46 47
  static PreParserIdentifier Await() {
    return PreParserIdentifier(kAwaitIdentifier);
  }
48 49 50
  static PreParserIdentifier Async() {
    return PreParserIdentifier(kAsyncIdentifier);
  }
51 52 53
  static PreParserIdentifier Name() {
    return PreParserIdentifier(kNameIdentifier);
  }
54
  bool IsNull() const { return type_ == kNullIdentifier; }
55
  bool IsEval() const { return type_ == kEvalIdentifier; }
rossberg's avatar
rossberg committed
56 57
  bool IsArguments() const { return type_ == kArgumentsIdentifier; }
  bool IsEvalOrArguments() const { return IsEval() || IsArguments(); }
arv@chromium.org's avatar
arv@chromium.org committed
58
  bool IsConstructor() const { return type_ == kConstructorIdentifier; }
59
  bool IsAwait() const { return type_ == kAwaitIdentifier; }
60
  bool IsName() const { return type_ == kNameIdentifier; }
61

62 63
 private:
  enum Type {
64
    kNullIdentifier,
65 66
    kUnknownIdentifier,
    kEvalIdentifier,
arv@chromium.org's avatar
arv@chromium.org committed
67
    kArgumentsIdentifier,
68
    kConstructorIdentifier,
69
    kAwaitIdentifier,
70 71
    kAsyncIdentifier,
    kNameIdentifier
72
  };
73

74
  explicit PreParserIdentifier(Type type) : type_(type), string_(nullptr) {}
75
  Type type_;
76 77
  // Only non-nullptr when PreParser.track_unresolved_variables_ is true.
  const AstRawString* string_;
78
  friend class PreParserExpression;
79
  friend class PreParser;
80
  friend class PreParserFactory;
81 82 83 84 85
};


class PreParserExpression {
 public:
86
  PreParserExpression()
87
      : code_(TypeField::encode(kNull)), variables_(nullptr) {}
88

89
  static PreParserExpression Null() { return PreParserExpression(); }
90

91
  static PreParserExpression Default(
92 93
      ZoneList<VariableProxy*>* variables = nullptr) {
    return PreParserExpression(TypeField::encode(kExpression), variables);
94 95
  }

96
  static PreParserExpression Spread(const PreParserExpression& expression) {
97
    return PreParserExpression(TypeField::encode(kSpreadExpression),
98
                               expression.variables_);
99 100
  }

101
  static PreParserExpression FromIdentifier(const PreParserIdentifier& id,
102
                                            VariableProxy* variable,
103 104 105
                                            Zone* zone) {
    PreParserExpression expression(TypeField::encode(kIdentifierExpression) |
                                   IdentifierTypeField::encode(id.type_));
106
    expression.AddVariable(variable, zone);
107
    return expression;
108 109
  }

110
  static PreParserExpression BinaryOperation(const PreParserExpression& left,
111
                                             Token::Value op,
112
                                             const PreParserExpression& right,
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
                                             Zone* zone) {
    if (op == Token::COMMA) {
      // Possibly an arrow function parameter list.
      if (left.variables_ == nullptr) {
        return PreParserExpression(TypeField::encode(kExpression),
                                   right.variables_);
      }
      if (right.variables_ != nullptr) {
        for (auto variable : *right.variables_) {
          left.variables_->Add(variable, zone);
        }
      }
      return PreParserExpression(TypeField::encode(kExpression),
                                 left.variables_);
    }
128
    return PreParserExpression(TypeField::encode(kExpression));
129 130
  }

131
  static PreParserExpression Assignment(ZoneList<VariableProxy*>* variables) {
132
    return PreParserExpression(TypeField::encode(kExpression) |
133 134
                                   ExpressionTypeField::encode(kAssignment),
                               variables);
135 136
  }

137
  static PreParserExpression NewTargetExpression() {
138
    return PreParserExpression::Default();
139 140
  }

141
  static PreParserExpression ObjectLiteral(
142
      ZoneList<VariableProxy*>* variables) {
143
    return PreParserExpression(TypeField::encode(kObjectLiteralExpression),
144
                               variables);
145 146
  }

147
  static PreParserExpression ArrayLiteral(ZoneList<VariableProxy*>* variables) {
148
    return PreParserExpression(TypeField::encode(kArrayLiteralExpression),
149
                               variables);
150 151
  }

152
  static PreParserExpression StringLiteral() {
marja's avatar
marja committed
153
    return PreParserExpression(TypeField::encode(kStringLiteralExpression));
154 155 156
  }

  static PreParserExpression UseStrictStringLiteral() {
157 158
    return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
                               IsUseStrictField::encode(true));
159 160
  }

161 162 163 164 165
  static PreParserExpression UseAsmStringLiteral() {
    return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
                               IsUseAsmField::encode(true));
  }

166
  static PreParserExpression This(ZoneList<VariableProxy*>* variables) {
167
    return PreParserExpression(TypeField::encode(kExpression) |
168 169
                                   ExpressionTypeField::encode(kThisExpression),
                               variables);
170 171 172
  }

  static PreParserExpression ThisProperty() {
173 174 175
    return PreParserExpression(
        TypeField::encode(kExpression) |
        ExpressionTypeField::encode(kThisPropertyExpression));
176 177
  }

178
  static PreParserExpression Property() {
179 180 181
    return PreParserExpression(
        TypeField::encode(kExpression) |
        ExpressionTypeField::encode(kPropertyExpression));
182 183
  }

184
  static PreParserExpression Call() {
185 186
    return PreParserExpression(TypeField::encode(kExpression) |
                               ExpressionTypeField::encode(kCallExpression));
187 188
  }

189 190 191 192 193 194
  static PreParserExpression CallEval() {
    return PreParserExpression(
        TypeField::encode(kExpression) |
        ExpressionTypeField::encode(kCallEvalExpression));
  }

195 196 197 198 199 200
  static PreParserExpression SuperCallReference() {
    return PreParserExpression(
        TypeField::encode(kExpression) |
        ExpressionTypeField::encode(kSuperCallReference));
  }

201
  bool IsNull() const { return TypeField::decode(code_) == kNull; }
202

203 204 205
  bool IsIdentifier() const {
    return TypeField::decode(code_) == kIdentifierExpression;
  }
206

207
  PreParserIdentifier AsIdentifier() const {
208
    DCHECK(IsIdentifier());
209
    return PreParserIdentifier(IdentifierTypeField::decode(code_));
210 211
  }

212
  bool IsAssignment() const {
213
    return TypeField::decode(code_) == kExpression &&
214
           ExpressionTypeField::decode(code_) == kAssignment;
215 216
  }

217 218 219 220 221 222 223 224
  bool IsObjectLiteral() const {
    return TypeField::decode(code_) == kObjectLiteralExpression;
  }

  bool IsArrayLiteral() const {
    return TypeField::decode(code_) == kArrayLiteralExpression;
  }

225
  bool IsStringLiteral() const {
226
    return TypeField::decode(code_) == kStringLiteralExpression;
227
  }
228

229
  bool IsUseStrictLiteral() const {
230 231
    return TypeField::decode(code_) == kStringLiteralExpression &&
           IsUseStrictField::decode(code_);
232 233
  }

234 235 236 237 238
  bool IsUseAsmLiteral() const {
    return TypeField::decode(code_) == kStringLiteralExpression &&
           IsUseAsmField::decode(code_);
  }

239 240 241 242
  bool IsThis() const {
    return TypeField::decode(code_) == kExpression &&
           ExpressionTypeField::decode(code_) == kThisExpression;
  }
243

244
  bool IsThisProperty() const {
245 246
    return TypeField::decode(code_) == kExpression &&
           ExpressionTypeField::decode(code_) == kThisPropertyExpression;
247
  }
248

249
  bool IsProperty() const {
250 251 252
    return TypeField::decode(code_) == kExpression &&
           (ExpressionTypeField::decode(code_) == kPropertyExpression ||
            ExpressionTypeField::decode(code_) == kThisPropertyExpression);
253
  }
254

255 256
  bool IsCall() const {
    return TypeField::decode(code_) == kExpression &&
257 258 259 260
           (ExpressionTypeField::decode(code_) == kCallExpression ||
            ExpressionTypeField::decode(code_) == kCallEvalExpression);
  }

261 262 263 264 265
  bool IsSuperCallReference() const {
    return TypeField::decode(code_) == kExpression &&
           ExpressionTypeField::decode(code_) == kSuperCallReference;
  }

266
  bool IsValidReferenceExpression() const {
267 268 269
    return IsIdentifier() || IsProperty();
  }

270 271 272 273
  // At the moment PreParser doesn't track these expression types.
  bool IsFunctionLiteral() const { return false; }
  bool IsCallNew() const { return false; }

274
  bool IsSpread() const {
275 276 277
    return TypeField::decode(code_) == kSpreadExpression;
  }

278 279
  PreParserExpression AsFunctionLiteral() { return *this; }

280 281
  // Dummy implementation for making expression->somefunc() work in both Parser
  // and PreParser.
282 283
  PreParserExpression* operator->() { return this; }

284
  // More dummy implementations of things PreParser doesn't need to track:
285
  void SetShouldEagerCompile() {}
286

yangguo's avatar
yangguo committed
287
  int position() const { return kNoSourcePosition; }
288 289
  void set_function_token_position(int position) {}

290
 private:
291
  enum Type {
292
    kNull,
293 294 295
    kExpression,
    kIdentifierExpression,
    kStringLiteralExpression,
296 297 298
    kSpreadExpression,
    kObjectLiteralExpression,
    kArrayLiteralExpression
299 300
  };

301 302 303 304 305
  enum ExpressionType {
    kThisExpression,
    kThisPropertyExpression,
    kPropertyExpression,
    kCallExpression,
306
    kCallEvalExpression,
307
    kSuperCallReference,
308
    kAssignment
309 310
  };

311 312 313
  explicit PreParserExpression(uint32_t expression_code,
                               ZoneList<VariableProxy*>* variables = nullptr)
      : code_(expression_code), variables_(variables) {}
314

315 316
  void AddVariable(VariableProxy* variable, Zone* zone) {
    if (variable == nullptr) {
317 318
      return;
    }
319 320
    if (variables_ == nullptr) {
      variables_ = new (zone) ZoneList<VariableProxy*>(1, zone);
321
    }
322
    variables_->Add(variable, zone);
323
  }
324

325
  // The first three bits are for the Type.
326
  typedef BitField<Type, 0, 3> TypeField;
327

328 329 330 331 332 333 334
  // The high order bit applies only to nodes which would inherit from the
  // Expression ASTNode --- This is by necessity, due to the fact that
  // Expression nodes may be represented as multiple Types, not exclusively
  // through kExpression.
  // TODO(caitp, adamk): clean up PreParserExpression bitfields.
  typedef BitField<bool, 31, 1> ParenthesizedField;

335 336
  // The rest of the bits are interpreted depending on the value
  // of the Type field, so they can share the storage.
337
  typedef BitField<ExpressionType, TypeField::kNext, 4> ExpressionTypeField;
338
  typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField;
339
  typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseAsmField;
340
  typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10>
341
      IdentifierTypeField;
342
  typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField;
343 344

  uint32_t code_;
345 346 347
  // If the PreParser is used in the variable tracking mode, PreParserExpression
  // accumulates variables in that expression.
  ZoneList<VariableProxy*>* variables_;
348 349

  friend class PreParser;
350 351 352
  friend class PreParserFactory;
  template <typename T>
  friend class PreParserList;
353 354 355
};


356
// The pre-parser doesn't need to build lists of expressions, identifiers, or
357 358
// the like. If the PreParser is used in variable tracking mode, it needs to
// build lists of variables though.
359 360
template <typename T>
class PreParserList {
361 362
 public:
  // These functions make list->Add(some_expression) work (and do nothing).
363
  PreParserList() : length_(0), variables_(nullptr) {}
364
  PreParserList* operator->() { return this; }
365
  void Add(const T& element, Zone* zone);
366
  int length() const { return length_; }
367 368
  static PreParserList Null() { return PreParserList(-1); }
  bool IsNull() const { return length_ == -1; }
369
  void Set(int index, const T& element) {}
370

371
 private:
372
  explicit PreParserList(int n) : length_(n), variables_(nullptr) {}
373
  int length_;
374
  ZoneList<VariableProxy*>* variables_;
375 376 377

  friend class PreParser;
  friend class PreParserFactory;
378 379
};

380 381
template <>
inline void PreParserList<PreParserExpression>::Add(
382
    const PreParserExpression& expression, Zone* zone) {
383
  if (expression.variables_ != nullptr) {
384 385
    DCHECK(FLAG_lazy_inner_functions);
    DCHECK(zone != nullptr);
386 387
    if (variables_ == nullptr) {
      variables_ = new (zone) ZoneList<VariableProxy*>(1, zone);
388
    }
389 390
    for (auto identifier : (*expression.variables_)) {
      variables_->Add(identifier, zone);
391 392 393 394 395 396
    }
  }
  ++length_;
}

template <typename T>
397
void PreParserList<T>::Add(const T& element, Zone* zone) {
398 399 400
  ++length_;
}

401 402
typedef PreParserList<PreParserExpression> PreParserExpressionList;

403 404
class PreParserStatement;
typedef PreParserList<PreParserStatement> PreParserStatementList;
405

406 407 408 409 410 411
class PreParserStatement {
 public:
  static PreParserStatement Default() {
    return PreParserStatement(kUnknownStatement);
  }

412 413 414 415 416 417 418 419
  static PreParserStatement Null() {
    return PreParserStatement(kNullStatement);
  }

  static PreParserStatement Empty() {
    return PreParserStatement(kEmptyStatement);
  }

420 421 422 423
  static PreParserStatement Jump() {
    return PreParserStatement(kJumpStatement);
  }

424 425 426 427
  // Creates expression statement from expression.
  // Preserves being an unparenthesized string literal, possibly
  // "use strict".
  static PreParserStatement ExpressionStatement(
428
      const PreParserExpression& expression) {
429 430 431
    if (expression.IsUseStrictLiteral()) {
      return PreParserStatement(kUseStrictExpressionStatement);
    }
432 433 434
    if (expression.IsUseAsmLiteral()) {
      return PreParserStatement(kUseAsmExpressionStatement);
    }
435 436 437 438 439 440 441
    if (expression.IsStringLiteral()) {
      return PreParserStatement(kStringLiteralExpressionStatement);
    }
    return Default();
  }

  bool IsStringLiteral() {
442 443
    return code_ == kStringLiteralExpressionStatement || IsUseStrictLiteral() ||
           IsUseAsmLiteral();
444 445 446 447 448 449
  }

  bool IsUseStrictLiteral() {
    return code_ == kUseStrictExpressionStatement;
  }

450 451
  bool IsUseAsmLiteral() { return code_ == kUseAsmExpressionStatement; }

452 453 454 455
  bool IsJumpStatement() {
    return code_ == kJumpStatement;
  }

456
  bool IsNull() { return code_ == kNullStatement; }
457

458 459 460 461
  bool IsEmptyStatement() {
    DCHECK(!IsNull());
    return code_ == kEmptyStatement;
  }
462

463 464 465 466
  // Dummy implementation for making statement->somefunc() work in both Parser
  // and PreParser.
  PreParserStatement* operator->() { return this; }

467 468
  // TODO(adamk): These should return something even lighter-weight than
  // PreParserStatementList.
469
  PreParserStatementList statements() { return PreParserStatementList(); }
470 471
  PreParserStatementList cases() { return PreParserStatementList(); }

472
  void set_scope(Scope* scope) {}
473
  void Initialize(const PreParserExpression& cond, PreParserStatement body,
474
                  const SourceRange& body_range = {}) {}
475
  void Initialize(PreParserStatement init, const PreParserExpression& cond,
476 477
                  PreParserStatement next, PreParserStatement body,
                  const SourceRange& body_range = {}) {}
478

479 480
 private:
  enum Type {
481 482
    kNullStatement,
    kEmptyStatement,
483
    kUnknownStatement,
484
    kJumpStatement,
485 486
    kStringLiteralExpressionStatement,
    kUseStrictExpressionStatement,
487
    kUseAsmExpressionStatement,
488 489 490 491 492 493 494
  };

  explicit PreParserStatement(Type code) : code_(code) {}
  Type code_;
};


495 496
class PreParserFactory {
 public:
497 498
  explicit PreParserFactory(AstValueFactory* ast_value_factory, Zone* zone)
      : ast_node_factory_(ast_value_factory, zone), zone_(zone) {}
499

500 501 502 503 504 505
  void set_zone(Zone* zone) {
    ast_node_factory_.set_zone(zone);
    zone_ = zone;
  }

  AstNodeFactory* ast_node_factory() { return &ast_node_factory_; }
506

507
  PreParserExpression NewStringLiteral(const PreParserIdentifier& identifier,
508
                                       int pos) {
509 510 511
    // This is needed for object literal property names. Property names are
    // normalized to string literals during object literal parsing.
    PreParserExpression expression = PreParserExpression::Default();
512 513
    if (identifier.string_ != nullptr) {
      DCHECK(FLAG_lazy_inner_functions);
514 515
      VariableProxy* variable = ast_node_factory_.NewVariableProxy(
          identifier.string_, NORMAL_VARIABLE);
516 517
      expression.AddVariable(variable, zone_);
    }
518
    return expression;
519
  }
520 521
  PreParserExpression NewNumberLiteral(double number,
                                       int pos) {
522 523
    return PreParserExpression::Default();
  }
524 525 526
  PreParserExpression NewUndefinedLiteral(int pos) {
    return PreParserExpression::Default();
  }
527
  PreParserExpression NewRegExpLiteral(const PreParserIdentifier& js_pattern,
528
                                       int js_flags, int pos) {
529 530
    return PreParserExpression::Default();
  }
531
  PreParserExpression NewArrayLiteral(const PreParserExpressionList& values,
532
                                      int first_spread_index, int pos) {
533
    return PreParserExpression::ArrayLiteral(values.variables_);
534
  }
535 536
  PreParserExpression NewClassLiteralProperty(const PreParserExpression& key,
                                              const PreParserExpression& value,
537 538 539 540 541
                                              ClassLiteralProperty::Kind kind,
                                              bool is_static,
                                              bool is_computed_name) {
    return PreParserExpression::Default();
  }
542 543
  PreParserExpression NewObjectLiteralProperty(const PreParserExpression& key,
                                               const PreParserExpression& value,
544
                                               ObjectLiteralProperty::Kind kind,
arv's avatar
arv committed
545
                                               bool is_computed_name) {
546
    return PreParserExpression::Default(value.variables_);
547
  }
548 549
  PreParserExpression NewObjectLiteralProperty(const PreParserExpression& key,
                                               const PreParserExpression& value,
arv's avatar
arv committed
550
                                               bool is_computed_name) {
551
    return PreParserExpression::Default(value.variables_);
552
  }
553 554 555
  PreParserExpression NewObjectLiteral(
      const PreParserExpressionList& properties, int boilerplate_properties,
      int pos, bool has_rest_property) {
556
    return PreParserExpression::ObjectLiteral(properties.variables_);
557
  }
arv@chromium.org's avatar
arv@chromium.org committed
558
  PreParserExpression NewVariableProxy(void* variable) {
559 560
    return PreParserExpression::Default();
  }
561 562
  PreParserExpression NewProperty(const PreParserExpression& obj,
                                  const PreParserExpression& key, int pos) {
563 564 565 566 567 568
    if (obj.IsThis()) {
      return PreParserExpression::ThisProperty();
    }
    return PreParserExpression::Property();
  }
  PreParserExpression NewUnaryOperation(Token::Value op,
569
                                        const PreParserExpression& expression,
570 571 572 573
                                        int pos) {
    return PreParserExpression::Default();
  }
  PreParserExpression NewBinaryOperation(Token::Value op,
574 575 576
                                         const PreParserExpression& left,
                                         const PreParserExpression& right,
                                         int pos) {
577
    return PreParserExpression::BinaryOperation(left, op, right, zone_);
578 579
  }
  PreParserExpression NewCompareOperation(Token::Value op,
580 581 582
                                          const PreParserExpression& left,
                                          const PreParserExpression& right,
                                          int pos) {
583 584
    return PreParserExpression::Default();
  }
585 586
  PreParserExpression NewRewritableExpression(
      const PreParserExpression& expression) {
587 588
    return expression;
  }
589
  PreParserExpression NewAssignment(Token::Value op,
590 591
                                    const PreParserExpression& left,
                                    const PreParserExpression& right, int pos) {
592 593 594
    // Identifiers need to be tracked since this might be a parameter with a
    // default value inside an arrow function parameter list.
    return PreParserExpression::Assignment(left.variables_);
595
  }
596
  PreParserExpression NewYield(const PreParserExpression& expression, int pos,
597
                               Suspend::OnAbruptResume on_abrupt_resume) {
598 599
    return PreParserExpression::Default();
  }
600
  PreParserExpression NewAwait(const PreParserExpression& expression, int pos) {
601 602
    return PreParserExpression::Default();
  }
603 604
  PreParserExpression NewYieldStar(const PreParserExpression& iterable,
                                   int pos) {
605 606
    return PreParserExpression::Default();
  }
607 608 609
  PreParserExpression NewConditional(const PreParserExpression& condition,
                                     const PreParserExpression& then_expression,
                                     const PreParserExpression& else_expression,
610 611 612
                                     int pos) {
    return PreParserExpression::Default();
  }
613 614
  PreParserExpression NewCountOperation(Token::Value op, bool is_prefix,
                                        const PreParserExpression& expression,
615 616 617
                                        int pos) {
    return PreParserExpression::Default();
  }
618
  PreParserExpression NewCall(
619
      PreParserExpression expression, const PreParserExpressionList& arguments,
620 621 622
      int pos, Call::PossiblyEval possibly_eval = Call::NOT_EVAL) {
    if (possibly_eval == Call::IS_POSSIBLY_EVAL) {
      DCHECK(expression.IsIdentifier() && expression.AsIdentifier().IsEval());
623 624
      return PreParserExpression::CallEval();
    }
625
    return PreParserExpression::Call();
626
  }
627 628
  PreParserExpression NewCallNew(const PreParserExpression& expression,
                                 const PreParserExpressionList& arguments,
629 630 631
                                 int pos) {
    return PreParserExpression::Default();
  }
632
  PreParserStatement NewReturnStatement(
633
      const PreParserExpression& expression, int pos,
634
      int continuation_pos = kNoSourcePosition) {
635
    return PreParserStatement::Jump();
636
  }
637
  PreParserStatement NewAsyncReturnStatement(
638
      const PreParserExpression& expression, int pos,
639
      int continuation_pos = kNoSourcePosition) {
640 641
    return PreParserStatement::Jump();
  }
642
  PreParserExpression NewFunctionLiteral(
643 644 645
      const PreParserIdentifier& name, Scope* scope,
      PreParserStatementList body, int expected_property_count,
      int parameter_count, int function_length,
646 647
      FunctionLiteral::ParameterFlag has_duplicate_parameters,
      FunctionLiteral::FunctionType function_type,
648
      FunctionLiteral::EagerCompileHint eager_compile_hint, int position,
649 650 651
      bool has_braces, int function_literal_id,
      ProducedPreParsedScopeData* produced_preparsed_scope_data = nullptr) {
    DCHECK_NULL(produced_preparsed_scope_data);
652 653
    return PreParserExpression::Default();
  }
654

655
  PreParserExpression NewSpread(const PreParserExpression& expression, int pos,
nikolaos's avatar
nikolaos committed
656
                                int expr_pos) {
657 658 659
    return PreParserExpression::Spread(expression);
  }

660 661 662 663
  PreParserExpression NewEmptyParentheses(int pos) {
    return PreParserExpression::Default();
  }

664 665 666 667
  PreParserStatement NewEmptyStatement(int pos) {
    return PreParserStatement::Default();
  }

668 669
  PreParserStatement NewBlock(int capacity, bool ignore_completion_value,
                              ZoneList<const AstRawString*>* labels = nullptr) {
670 671 672
    return PreParserStatement::Default();
  }

673 674 675 676
  PreParserStatement NewDebuggerStatement(int pos) {
    return PreParserStatement::Default();
  }

677 678
  PreParserStatement NewExpressionStatement(const PreParserExpression& expr,
                                            int pos) {
679 680 681
    return PreParserStatement::ExpressionStatement(expr);
  }

682
  PreParserStatement NewIfStatement(const PreParserExpression& condition,
683
                                    PreParserStatement then_statement,
684 685 686
                                    PreParserStatement else_statement, int pos,
                                    SourceRange then_range = {},
                                    SourceRange else_range = {}) {
687 688 689 690
    // This must return a jump statement iff both clauses are jump statements.
    return else_statement.IsJumpStatement() ? then_statement : else_statement;
  }

691 692 693
  PreParserStatement NewBreakStatement(
      PreParserStatement target, int pos,
      int continuation_pos = kNoSourcePosition) {
694 695 696
    return PreParserStatement::Jump();
  }

697 698 699
  PreParserStatement NewContinueStatement(
      PreParserStatement target, int pos,
      int continuation_pos = kNoSourcePosition) {
700 701 702 703
    return PreParserStatement::Jump();
  }

  PreParserStatement NewWithStatement(Scope* scope,
704
                                      const PreParserExpression& expression,
705 706 707 708
                                      PreParserStatement statement, int pos) {
    return PreParserStatement::Default();
  }

709 710 711 712 713 714 715 716 717 718
  PreParserStatement NewDoWhileStatement(ZoneList<const AstRawString*>* labels,
                                         int pos) {
    return PreParserStatement::Default();
  }

  PreParserStatement NewWhileStatement(ZoneList<const AstRawString*>* labels,
                                       int pos) {
    return PreParserStatement::Default();
  }

719
  PreParserStatement NewSwitchStatement(ZoneList<const AstRawString*>* labels,
720
                                        const PreParserExpression& tag,
721 722 723 724
                                        int pos) {
    return PreParserStatement::Default();
  }

725
  PreParserStatement NewCaseClause(const PreParserExpression& label,
726
                                   PreParserStatementList statements) {
727 728 729
    return PreParserStatement::Default();
  }

730 731 732 733 734 735 736 737 738 739 740
  PreParserStatement NewForStatement(ZoneList<const AstRawString*>* labels,
                                     int pos) {
    return PreParserStatement::Default();
  }

  PreParserStatement NewForEachStatement(ForEachStatement::VisitMode visit_mode,
                                         ZoneList<const AstRawString*>* labels,
                                         int pos) {
    return PreParserStatement::Default();
  }

741 742 743 744 745
  PreParserStatement NewForOfStatement(ZoneList<const AstRawString*>* labels,
                                       int pos) {
    return PreParserStatement::Default();
  }

746 747 748 749 750 751
  PreParserExpression NewCallRuntime(Runtime::FunctionId id,
                                     ZoneList<PreParserExpression>* arguments,
                                     int pos) {
    return PreParserExpression::Default();
  }

752
  PreParserExpression NewImportCallExpression(const PreParserExpression& args,
753 754 755 756
                                              int pos) {
    return PreParserExpression::Default();
  }

757
 private:
758 759 760
  // For creating VariableProxy objects (if
  // PreParser::track_unresolved_variables_ is used).
  AstNodeFactory ast_node_factory_;
761
  Zone* zone_;
762 763 764
};


765
struct PreParserFormalParameters : FormalParametersBase {
766
  struct Parameter : public ZoneObject {
767 768
    Parameter(ZoneList<VariableProxy*>* variables, bool is_rest)
        : variables_(variables), is_rest(is_rest) {}
769 770
    Parameter** next() { return &next_parameter; }
    Parameter* const* next() const { return &next_parameter; }
771

772
    ZoneList<VariableProxy*>* variables_;
773
    Parameter* next_parameter = nullptr;
774
    bool is_rest : 1;
775
  };
776
  explicit PreParserFormalParameters(DeclarationScope* scope)
777
      : FormalParametersBase(scope) {}
778

779
  ThreadedList<Parameter> params;
780 781 782
};


783
class PreParser;
784

785 786 787 788 789 790 791 792 793 794 795
class PreParserTarget {
 public:
  PreParserTarget(ParserBase<PreParser>* preparser,
                  PreParserStatement statement) {}
};

class PreParserTargetScope {
 public:
  explicit PreParserTargetScope(ParserBase<PreParser>* preparser) {}
};

796
template <>
797 798 799 800 801 802 803 804 805
struct ParserTypes<PreParser> {
  typedef ParserBase<PreParser> Base;
  typedef PreParser Impl;

  // Return types for traversing functions.
  typedef PreParserIdentifier Identifier;
  typedef PreParserExpression Expression;
  typedef PreParserExpression FunctionLiteral;
  typedef PreParserExpression ObjectLiteralProperty;
806
  typedef PreParserExpression ClassLiteralProperty;
807
  typedef PreParserExpression Suspend;
808
  typedef PreParserExpressionList ExpressionList;
809 810
  typedef PreParserExpressionList ObjectPropertyList;
  typedef PreParserExpressionList ClassPropertyList;
811
  typedef PreParserFormalParameters FormalParameters;
812
  typedef PreParserStatement Statement;
813
  typedef PreParserStatementList StatementList;
814
  typedef PreParserStatement Block;
815 816
  typedef PreParserStatement BreakableStatement;
  typedef PreParserStatement IterationStatement;
817
  typedef PreParserStatement ForStatement;
818 819 820

  // For constructing objects returned by the traversing functions.
  typedef PreParserFactory Factory;
821 822 823

  typedef PreParserTarget Target;
  typedef PreParserTargetScope TargetScope;
824 825 826
};


827 828
// Preparsing checks a JavaScript program and emits preparse-data that helps
// a later parsing to be faster.
829
// See preparse-data-format.h for the data format.
830 831 832 833 834 835 836 837 838

// The PreParser checks that the syntax follows the grammar for JavaScript,
// and collects some information about the program along the way.
// The grammar check is only performed in order to understand the program
// sufficiently to deduce some information about it, that can be used
// to speed up later parsing. Finding errors is not the goal of pre-parsing,
// rather it is to speed up properly written and correct programs.
// That means that contextual checks (like a label being declared where
// it is used) are generally omitted.
839
class PreParser : public ParserBase<PreParser> {
840
  friend class ParserBase<PreParser>;
841
  friend class v8::internal::ExpressionClassifier<ParserTypes<PreParser>>;
842

843
 public:
844 845
  typedef PreParserIdentifier Identifier;
  typedef PreParserExpression Expression;
846
  typedef PreParserStatement Statement;
847

848 849
  enum PreParseResult {
    kPreParseStackOverflow,
850
    kPreParseAbort,
851 852 853
    kPreParseSuccess
  };

854 855
  PreParser(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
            AstValueFactory* ast_value_factory,
856
            PendingCompilationErrorHandler* pending_error_handler,
857 858
            RuntimeCallStats* runtime_call_stats,
            bool parsing_on_main_thread = true)
859
      : ParserBase<PreParser>(zone, scanner, stack_limit, nullptr,
860
                              ast_value_factory, runtime_call_stats,
861
                              parsing_on_main_thread),
862
        use_counts_(nullptr),
863
        track_unresolved_variables_(false),
864 865
        pending_error_handler_(pending_error_handler),
        produced_preparsed_scope_data_(nullptr) {}
866

867
  static bool IsPreParser() { return true; }
868

869 870
  PreParserLogger* logger() { return &log_; }

871 872 873 874
  // Pre-parse the program from the character stream; returns true on
  // success (even if parsing failed, the pre-parse data successfully
  // captured the syntax error), and false if a stack-overflow happened
  // during parsing.
875
  PreParseResult PreParseProgram(bool is_module = false);
876

877 878
  // Parses a single function literal, from the opening parentheses before
  // parameters to the closing brace after the body.
879
  // Returns a FunctionEntry describing the body of the function in enough
880
  // detail that it can be lazily compiled.
881 882
  // The scanner is expected to have matched the "function" or "function*"
  // keyword and parameters, and have consumed the initial '{'.
883
  // At return, unless an error occurred, the scanner is positioned before the
884
  // the final '}'.
885 886 887 888 889 890 891 892 893 894 895 896 897 898 899
  PreParseResult PreParseFunction(
      const AstRawString* function_name, FunctionKind kind,
      FunctionLiteral::FunctionType function_type,
      DeclarationScope* function_scope, bool parsing_module,
      bool track_unresolved_variables, bool may_abort, int* use_counts,
      ProducedPreParsedScopeData** produced_preparser_scope_data);

  ProducedPreParsedScopeData* produced_preparsed_scope_data() const {
    return produced_preparsed_scope_data_;
  }

  void set_produced_preparsed_scope_data(
      ProducedPreParsedScopeData* produced_preparsed_scope_data) {
    produced_preparsed_scope_data_ = produced_preparsed_scope_data;
  }
900

901
 private:
902 903 904 905 906
  // These types form an algebra over syntactic categories that is just
  // rich enough to let us recognize and propagate the constructs that
  // are either being counted in the preparser data, or is important
  // to throw the correct syntax error exceptions.

907 908 909 910 911
  // All ParseXXX functions take as the last argument an *ok parameter
  // which is set to false if parsing failed; it is unchanged otherwise.
  // By making the 'exception handling' explicit, we are forced to check
  // for failure at the call sites.

912 913
  // Indicates that we won't switch from the preparser to the preparser; we'll
  // just stay where we are.
914
  bool AllowsLazyParsingWithoutUnresolvedVariables() const { return false; }
915
  bool parse_lazily() const { return false; }
916

917 918 919 920
  V8_INLINE LazyParsingResult
  SkipFunction(const AstRawString* name, FunctionKind kind,
               FunctionLiteral::FunctionType function_type,
               DeclarationScope* function_scope, int* num_parameters,
921
               ProducedPreParsedScopeData** produced_preparsed_scope_data,
922
               bool is_inner_function, bool may_abort, bool* ok) {
923 924
    UNREACHABLE();
  }
925
  Expression ParseFunctionLiteral(
926
      Identifier name, Scanner::Location function_name_location,
927 928
      FunctionNameValidity function_name_validity, FunctionKind kind,
      int function_token_pos, FunctionLiteral::FunctionType function_type,
929
      LanguageMode language_mode, bool* ok);
930
  LazyParsingResult ParseStatementListAndLogFunction(
931
      PreParserFormalParameters* formals, bool maybe_abort, bool* ok);
932

933 934 935 936 937 938
  struct TemplateLiteralState {};

  V8_INLINE TemplateLiteralState OpenTemplateLiteral(int pos) {
    return TemplateLiteralState();
  }
  V8_INLINE void AddTemplateExpression(TemplateLiteralState* state,
939
                                       const PreParserExpression& expression) {}
940 941
  V8_INLINE void AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
                                 bool tail) {}
942
  V8_INLINE PreParserExpression CloseTemplateLiteral(
943
      TemplateLiteralState* state, int start, const PreParserExpression& tag) {
944 945
    return PreParserExpression::Default();
  }
946 947
  V8_INLINE void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}

948 949 950 951 952
  V8_INLINE void SetLanguageMode(Scope* scope, LanguageMode mode) {
    scope->SetLanguageMode(mode);
  }
  V8_INLINE void SetAsmModule() {}

953 954
  V8_INLINE PreParserExpression SpreadCall(const PreParserExpression& function,
                                           const PreParserExpressionList& args,
955 956
                                           int pos,
                                           Call::PossiblyEval possibly_eval);
957 958 959
  V8_INLINE PreParserExpression
  SpreadCallNew(const PreParserExpression& function,
                const PreParserExpressionList& args, int pos);
960 961 962

  V8_INLINE void RewriteDestructuringAssignments() {}

963 964 965
  V8_INLINE PreParserExpression
  RewriteExponentiation(const PreParserExpression& left,
                        const PreParserExpression& right, int pos) {
966 967
    return left;
  }
968 969 970
  V8_INLINE PreParserExpression
  RewriteAssignExponentiation(const PreParserExpression& left,
                              const PreParserExpression& right, int pos) {
971 972 973
    return left;
  }

974
  V8_INLINE void PrepareGeneratorVariables() {}
975 976 977
  V8_INLINE void RewriteAsyncFunctionBody(
      PreParserStatementList body, PreParserStatement block,
      const PreParserExpression& return_value, bool* ok) {}
978
  V8_INLINE void RewriteNonPattern(bool* ok) { ValidateExpression(ok); }
979

980
  void DeclareAndInitializeVariables(
981 982 983
      PreParserStatement block,
      const DeclarationDescriptor* declaration_descriptor,
      const DeclarationParsingResult::Declaration* declaration,
984 985
      ZoneList<const AstRawString*>* names, bool* ok);

986
  V8_INLINE ZoneList<const AstRawString*>* DeclareLabel(
987
      ZoneList<const AstRawString*>* labels, const PreParserExpression& expr,
988 989
      bool* ok) {
    DCHECK(!parsing_module_ || !expr.AsIdentifier().IsAwait());
990
    DCHECK(IsIdentifier(expr));
991 992 993 994 995
    return labels;
  }

  // TODO(nikolaos): The preparser currently does not keep track of labels.
  V8_INLINE bool ContainsLabel(ZoneList<const AstRawString*>* labels,
996
                               const PreParserIdentifier& label) {
997 998 999
    return false;
  }

1000 1001
  V8_INLINE PreParserExpression
  RewriteReturn(const PreParserExpression& return_value, int pos) {
1002 1003
    return return_value;
  }
1004 1005
  V8_INLINE PreParserStatement
  RewriteSwitchStatement(PreParserStatement switch_statement, Scope* scope) {
1006 1007
    return PreParserStatement::Default();
  }
1008 1009 1010

  V8_INLINE void RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {
    if (track_unresolved_variables_) {
1011 1012 1013
      const AstRawString* catch_name = catch_info->name.string_;
      if (catch_name == nullptr) {
        catch_name = ast_value_factory()->dot_catch_string();
1014
      }
1015
      catch_info->scope->DeclareCatchVariableName(catch_name);
1016

1017 1018 1019 1020 1021 1022 1023 1024
      if (catch_info->pattern.variables_ != nullptr) {
        for (auto variable : *catch_info->pattern.variables_) {
          scope()->DeclareVariableName(variable->raw_name(), LET);
        }
      }
    }
  }

1025 1026 1027
  V8_INLINE void ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {}
  V8_INLINE PreParserStatement RewriteTryStatement(
      PreParserStatement try_block, PreParserStatement catch_block,
1028 1029
      const SourceRange& catch_range, PreParserStatement finally_block,
      const SourceRange& finally_range, const CatchInfo& catch_info, int pos) {
1030 1031
    return PreParserStatement::Default();
  }
1032

1033 1034 1035 1036
  V8_INLINE void ParseAndRewriteGeneratorFunctionBody(
      int pos, FunctionKind kind, PreParserStatementList body, bool* ok) {
    ParseStatementList(body, Token::RBRACE, ok);
  }
1037 1038 1039 1040
  V8_INLINE void ParseAndRewriteAsyncGeneratorFunctionBody(
      int pos, FunctionKind kind, PreParserStatementList body, bool* ok) {
    ParseStatementList(body, Token::RBRACE, ok);
  }
1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054
  V8_INLINE void CreateFunctionNameAssignment(
      const AstRawString* function_name,
      FunctionLiteral::FunctionType function_type,
      DeclarationScope* function_scope) {
    if (track_unresolved_variables_ &&
        function_type == FunctionLiteral::kNamedExpression) {
      if (function_scope->LookupLocal(function_name) == nullptr) {
        DCHECK_EQ(function_scope, scope());
        Variable* fvar = function_scope->DeclareFunctionVar(function_name);
        fvar->set_is_used();
      }
    }
  }

1055
  V8_INLINE void CreateFunctionNameAssignment(
1056
      const PreParserIdentifier& function_name, int pos,
1057 1058
      FunctionLiteral::FunctionType function_type,
      DeclarationScope* function_scope, PreParserStatementList result,
1059 1060 1061 1062
      int index) {
    CreateFunctionNameAssignment(function_name.string_, function_type,
                                 function_scope);
  }
1063

1064 1065 1066 1067 1068
  V8_INLINE PreParserExpression RewriteDoExpression(PreParserStatement body,
                                                    int pos, bool* ok) {
    return PreParserExpression::Default();
  }

1069 1070
  // TODO(nikolaos): The preparser currently does not keep track of labels
  // and targets.
1071 1072
  V8_INLINE PreParserStatement
  LookupBreakTarget(const PreParserIdentifier& label, bool* ok) {
1073 1074
    return PreParserStatement::Default();
  }
1075 1076
  V8_INLINE PreParserStatement
  LookupContinueTarget(const PreParserIdentifier& label, bool* ok) {
1077 1078
    return PreParserStatement::Default();
  }
1079

1080 1081 1082 1083 1084
  V8_INLINE PreParserStatement
  DeclareFunction(const PreParserIdentifier& variable_name,
                  const PreParserExpression& function, VariableMode mode,
                  int pos, bool is_sloppy_block_function,
                  ZoneList<const AstRawString*>* names, bool* ok) {
1085 1086 1087 1088 1089 1090 1091 1092 1093
    DCHECK_NULL(names);
    if (variable_name.string_ != nullptr) {
      DCHECK(track_unresolved_variables_);
      scope()->DeclareVariableName(variable_name.string_, mode);
      if (is_sloppy_block_function) {
        GetDeclarationScope()->DeclareSloppyBlockFunction(variable_name.string_,
                                                          scope());
      }
    }
1094 1095 1096
    return Statement::Default();
  }

1097 1098 1099 1100
  V8_INLINE PreParserStatement DeclareClass(
      const PreParserIdentifier& variable_name,
      const PreParserExpression& value, ZoneList<const AstRawString*>* names,
      int class_token_pos, int end_pos, bool* ok) {
1101 1102 1103 1104 1105 1106
    // Preparser shouldn't be used in contexts where we need to track the names.
    DCHECK_NULL(names);
    if (variable_name.string_ != nullptr) {
      DCHECK(track_unresolved_variables_);
      scope()->DeclareVariableName(variable_name.string_, LET);
    }
1107 1108
    return PreParserStatement::Default();
  }
1109
  V8_INLINE void DeclareClassVariable(const PreParserIdentifier& name,
1110
                                      ClassInfo* class_info,
1111 1112 1113 1114 1115 1116
                                      int class_token_pos, bool* ok) {
    if (name.string_ != nullptr) {
      DCHECK(track_unresolved_variables_);
      scope()->DeclareVariableName(name.string_, CONST);
    }
  }
1117 1118
  V8_INLINE void DeclareClassProperty(const PreParserIdentifier& class_name,
                                      const PreParserExpression& property,
1119 1120
                                      ClassLiteralProperty::Kind kind,
                                      bool is_static, bool is_constructor,
1121 1122 1123 1124
                                      ClassInfo* class_info, bool* ok) {}
  V8_INLINE PreParserExpression
  RewriteClassLiteral(Scope* scope, const PreParserIdentifier& name,
                      ClassInfo* class_info, int pos, int end_pos, bool* ok) {
1125 1126 1127
    bool has_default_constructor = !class_info->has_seen_constructor;
    // Account for the default constructor.
    if (has_default_constructor) GetNextFunctionLiteralId();
1128 1129 1130
    return PreParserExpression::Default();
  }

1131 1132
  V8_INLINE PreParserStatement DeclareNative(const PreParserIdentifier& name,
                                             int pos, bool* ok) {
1133 1134 1135
    return PreParserStatement::Default();
  }

1136 1137
  V8_INLINE void QueueDestructuringAssignmentForRewriting(
      PreParserExpression assignment) {}
1138
  V8_INLINE void QueueNonPatternForRewriting(const PreParserExpression& expr,
1139 1140
                                             bool* ok) {}

1141
  // Helper functions for recursive descent.
1142
  V8_INLINE bool IsEval(const PreParserIdentifier& identifier) const {
1143 1144 1145
    return identifier.IsEval();
  }

1146
  V8_INLINE bool IsArguments(const PreParserIdentifier& identifier) const {
1147 1148 1149
    return identifier.IsArguments();
  }

1150 1151
  V8_INLINE bool IsEvalOrArguments(
      const PreParserIdentifier& identifier) const {
1152 1153 1154
    return identifier.IsEvalOrArguments();
  }

1155
  V8_INLINE bool IsAwait(const PreParserIdentifier& identifier) const {
1156 1157 1158 1159
    return identifier.IsAwait();
  }

  // Returns true if the expression is of type "this.foo".
1160
  V8_INLINE static bool IsThisProperty(const PreParserExpression& expression) {
1161 1162 1163
    return expression.IsThisProperty();
  }

1164
  V8_INLINE static bool IsIdentifier(const PreParserExpression& expression) {
1165 1166 1167 1168
    return expression.IsIdentifier();
  }

  V8_INLINE static PreParserIdentifier AsIdentifier(
1169
      const PreParserExpression& expression) {
1170 1171 1172
    return expression.AsIdentifier();
  }

1173
  V8_INLINE static PreParserExpression AsIdentifierExpression(
1174
      const PreParserExpression& expression) {
1175 1176 1177
    return expression;
  }

1178
  V8_INLINE bool IsConstructor(const PreParserIdentifier& identifier) const {
1179 1180 1181
    return identifier.IsConstructor();
  }

1182
  V8_INLINE bool IsName(const PreParserIdentifier& identifier) const {
1183 1184 1185
    return identifier.IsName();
  }

1186 1187
  V8_INLINE static bool IsBoilerplateProperty(
      const PreParserExpression& property) {
1188 1189 1190 1191
    // PreParser doesn't count boilerplate properties.
    return false;
  }

1192
  V8_INLINE bool IsNative(const PreParserExpression& expr) const {
1193 1194 1195 1196 1197 1198 1199
    // Preparsing is disabled for extensions (because the extension
    // details aren't passed to lazily compiled functions), so we
    // don't accept "native function" in the preparser and there is
    // no need to keep track of "native".
    return false;
  }

1200
  V8_INLINE static bool IsArrayIndex(const PreParserIdentifier& string,
1201 1202 1203 1204
                                     uint32_t* index) {
    return false;
  }

1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216
  V8_INLINE bool IsUseStrictDirective(PreParserStatement statement) const {
    return statement.IsUseStrictLiteral();
  }

  V8_INLINE bool IsUseAsmDirective(PreParserStatement statement) const {
    return statement.IsUseAsmLiteral();
  }

  V8_INLINE bool IsStringLiteral(PreParserStatement statement) const {
    return statement.IsStringLiteral();
  }

1217 1218 1219 1220
  V8_INLINE static void GetDefaultStrings(
      PreParserIdentifier* default_string,
      PreParserIdentifier* star_default_star_string) {}

1221 1222
  // Functions for encapsulating the differences between parsing and preparsing;
  // operations interleaved with the recursive descent.
1223 1224 1225 1226
  V8_INLINE static void PushLiteralName(const PreParserIdentifier& id) {}
  V8_INLINE static void PushVariableName(const PreParserIdentifier& id) {}
  V8_INLINE void PushPropertyName(const PreParserExpression& expression) {}
  V8_INLINE void PushEnclosingName(const PreParserIdentifier& name) {}
1227
  V8_INLINE static void AddFunctionForNameInference(
1228
      const PreParserExpression& expression) {}
1229
  V8_INLINE static void InferFunctionName() {}
1230 1231

  V8_INLINE static void CheckAssigningFunctionLiteralToProperty(
1232
      const PreParserExpression& left, const PreParserExpression& right) {}
1233

1234 1235
  V8_INLINE void MarkExpressionAsAssigned(
      const PreParserExpression& expression) {
1236 1237
    // TODO(marja): To be able to produce the same errors, the preparser needs
    // to start tracking which expressions are variables and which are assigned.
1238 1239 1240 1241 1242 1243 1244
    if (expression.variables_ != nullptr) {
      DCHECK(FLAG_lazy_inner_functions);
      DCHECK(track_unresolved_variables_);
      for (auto variable : *expression.variables_) {
        variable->set_is_assigned();
      }
    }
1245 1246
  }

1247 1248 1249
  V8_INLINE bool ShortcutNumericLiteralBinaryExpression(
      PreParserExpression* x, const PreParserExpression& y, Token::Value op,
      int pos) {
1250 1251 1252
    return false;
  }

1253
  V8_INLINE PreParserExpression BuildUnaryExpression(
1254
      const PreParserExpression& expression, Token::Value op, int pos) {
1255 1256 1257
    return PreParserExpression::Default();
  }

1258 1259 1260
  V8_INLINE PreParserStatement
  BuildInitializationBlock(DeclarationParsingResult* parsing_result,
                           ZoneList<const AstRawString*>* names, bool* ok) {
1261 1262 1263 1264 1265
    for (auto declaration : parsing_result->declarations) {
      DeclareAndInitializeVariables(PreParserStatement::Default(),
                                    &(parsing_result->descriptor), &declaration,
                                    names, ok);
    }
1266 1267 1268
    return PreParserStatement::Default();
  }

1269
  V8_INLINE PreParserStatement InitializeForEachStatement(
1270 1271
      PreParserStatement stmt, const PreParserExpression& each,
      const PreParserExpression& subject, PreParserStatement body) {
1272
    MarkExpressionAsAssigned(each);
1273 1274 1275
    return stmt;
  }

1276
  V8_INLINE PreParserStatement InitializeForOfStatement(
1277 1278 1279 1280
      PreParserStatement stmt, const PreParserExpression& each,
      const PreParserExpression& iterable, PreParserStatement body,
      bool finalize, IteratorType type,
      int next_result_pos = kNoSourcePosition) {
1281 1282 1283 1284
    MarkExpressionAsAssigned(each);
    return stmt;
  }

1285 1286 1287
  V8_INLINE PreParserStatement RewriteForVarInLegacy(const ForInfo& for_info) {
    return PreParserStatement::Null();
  }
1288

1289 1290
  V8_INLINE void DesugarBindingInForEachStatement(
      ForInfo* for_info, PreParserStatement* body_block,
1291 1292
      PreParserExpression* each_variable, bool* ok) {
    if (track_unresolved_variables_) {
1293
      DCHECK_EQ(1, for_info->parsing_result.declarations.size());
1294 1295 1296 1297 1298 1299 1300
      bool is_for_var_of =
          for_info->mode == ForEachStatement::ITERATE &&
          for_info->parsing_result.descriptor.mode == VariableMode::VAR;
      bool collect_names =
          IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
          is_for_var_of;

1301 1302
      DeclareAndInitializeVariables(
          PreParserStatement::Default(), &for_info->parsing_result.descriptor,
1303 1304
          &for_info->parsing_result.declarations[0],
          collect_names ? &for_info->bound_names : nullptr, ok);
1305 1306 1307
    }
  }

1308 1309
  V8_INLINE PreParserStatement CreateForEachStatementTDZ(
      PreParserStatement init_block, const ForInfo& for_info, bool* ok) {
1310 1311 1312 1313 1314 1315 1316 1317
    if (track_unresolved_variables_) {
      if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
        for (auto name : for_info.bound_names) {
          scope()->DeclareVariableName(name, LET);
        }
        return PreParserStatement::Default();
      }
    }
1318 1319 1320 1321 1322
    return init_block;
  }

  V8_INLINE StatementT DesugarLexicalBindingsInForStatement(
      PreParserStatement loop, PreParserStatement init,
1323
      const PreParserExpression& cond, PreParserStatement next,
1324 1325
      PreParserStatement body, Scope* inner_scope, const ForInfo& for_info,
      bool* ok) {
1326
    // See Parser::DesugarLexicalBindingsInForStatement.
1327 1328 1329 1330 1331
    if (track_unresolved_variables_) {
      for (auto name : for_info.bound_names) {
        inner_scope->DeclareVariableName(
            name, for_info.parsing_result.descriptor.mode);
      }
1332
    }
1333 1334 1335
    return loop;
  }

1336 1337
  PreParserStatement BuildParameterInitializationBlock(
      const PreParserFormalParameters& parameters, bool* ok);
1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350

  V8_INLINE PreParserStatement
  BuildRejectPromiseOnException(PreParserStatement init_block) {
    return PreParserStatement::Default();
  }

  V8_INLINE void InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
    scope->HoistSloppyBlockFunctions(nullptr);
  }

  V8_INLINE void InsertShadowingVarBindingInitializers(
      PreParserStatement block) {}

1351 1352 1353 1354 1355
  V8_INLINE PreParserExpression
  NewThrowReferenceError(MessageTemplate::Template message, int pos) {
    return PreParserExpression::Default();
  }

1356 1357 1358
  V8_INLINE PreParserExpression
  NewThrowSyntaxError(MessageTemplate::Template message,
                      const PreParserIdentifier& arg, int pos) {
1359 1360 1361
    return PreParserExpression::Default();
  }

1362 1363 1364
  V8_INLINE PreParserExpression
  NewThrowTypeError(MessageTemplate::Template message,
                    const PreParserIdentifier& arg, int pos) {
1365 1366 1367 1368 1369 1370 1371 1372
    return PreParserExpression::Default();
  }

  // Reporting errors.
  V8_INLINE void ReportMessageAt(Scanner::Location source_location,
                                 MessageTemplate::Template message,
                                 const char* arg = NULL,
                                 ParseErrorType error_type = kSyntaxError) {
1373 1374 1375
    pending_error_handler_->ReportMessageAt(source_location.beg_pos,
                                            source_location.end_pos, message,
                                            arg, error_type);
1376 1377 1378 1379
  }

  V8_INLINE void ReportMessageAt(Scanner::Location source_location,
                                 MessageTemplate::Template message,
1380
                                 const PreParserIdentifier& arg,
1381 1382 1383 1384 1385
                                 ParseErrorType error_type = kSyntaxError) {
    UNREACHABLE();
  }

  // "null" return type creators.
1386 1387
  V8_INLINE static PreParserIdentifier NullIdentifier() {
    return PreParserIdentifier::Null();
1388
  }
1389 1390
  V8_INLINE static PreParserExpression NullExpression() {
    return PreParserExpression::Null();
1391
  }
1392 1393
  V8_INLINE static PreParserExpression NullLiteralProperty() {
    return PreParserExpression::Null();
1394 1395
  }
  V8_INLINE static PreParserExpressionList NullExpressionList() {
1396 1397 1398
    return PreParserExpressionList::Null();
  }

1399
  V8_INLINE static PreParserStatementList NullStatementList() {
1400 1401 1402
    return PreParserStatementList::Null();
  }
  V8_INLINE static PreParserStatement NullStatement() {
1403
    return PreParserStatement::Null();
1404 1405
  }

1406 1407 1408
  template <typename T>
  V8_INLINE static bool IsNull(T subject) {
    return subject.IsNull();
1409 1410
  }

1411 1412 1413 1414 1415 1416 1417 1418 1419
  V8_INLINE PreParserIdentifier EmptyIdentifierString() const {
    return PreParserIdentifier::Default();
  }

  // Odd-ball literal creators.
  V8_INLINE PreParserExpression GetLiteralTheHole(int position) {
    return PreParserExpression::Default();
  }

1420 1421 1422 1423
  V8_INLINE PreParserExpression GetLiteralUndefined(int position) {
    return PreParserExpression::Default();
  }

1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435
  // Producing data during the recursive descent.
  PreParserIdentifier GetSymbol() const;

  V8_INLINE PreParserIdentifier GetNextSymbol() const {
    return PreParserIdentifier::Default();
  }

  V8_INLINE PreParserIdentifier GetNumberAsSymbol() const {
    return PreParserIdentifier::Default();
  }

  V8_INLINE PreParserExpression ThisExpression(int pos = kNoSourcePosition) {
1436 1437 1438
    ZoneList<VariableProxy*>* variables = nullptr;
    if (track_unresolved_variables_) {
      VariableProxy* proxy = scope()->NewUnresolved(
1439 1440
          factory()->ast_node_factory(), ast_value_factory()->this_string(),
          pos, THIS_VARIABLE);
1441 1442 1443 1444 1445

      variables = new (zone()) ZoneList<VariableProxy*>(1, zone());
      variables->Add(proxy, zone());
    }
    return PreParserExpression::This(variables);
1446 1447 1448
  }

  V8_INLINE PreParserExpression NewSuperPropertyReference(int pos) {
1449 1450 1451 1452 1453 1454 1455 1456
    if (track_unresolved_variables_) {
      scope()->NewUnresolved(factory()->ast_node_factory(),
                             ast_value_factory()->this_function_string(), pos,
                             NORMAL_VARIABLE);
      scope()->NewUnresolved(factory()->ast_node_factory(),
                             ast_value_factory()->this_string(), pos,
                             THIS_VARIABLE);
    }
1457 1458 1459 1460
    return PreParserExpression::Default();
  }

  V8_INLINE PreParserExpression NewSuperCallReference(int pos) {
1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471
    if (track_unresolved_variables_) {
      scope()->NewUnresolved(factory()->ast_node_factory(),
                             ast_value_factory()->this_function_string(), pos,
                             NORMAL_VARIABLE);
      scope()->NewUnresolved(factory()->ast_node_factory(),
                             ast_value_factory()->new_target_string(), pos,
                             NORMAL_VARIABLE);
      scope()->NewUnresolved(factory()->ast_node_factory(),
                             ast_value_factory()->this_string(), pos,
                             THIS_VARIABLE);
    }
1472 1473 1474 1475
    return PreParserExpression::SuperCallReference();
  }

  V8_INLINE PreParserExpression NewTargetExpression(int pos) {
1476
    return PreParserExpression::NewTargetExpression();
1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487
  }

  V8_INLINE PreParserExpression FunctionSentExpression(int pos) {
    return PreParserExpression::Default();
  }

  V8_INLINE PreParserExpression ExpressionFromLiteral(Token::Value token,
                                                      int pos) {
    return PreParserExpression::Default();
  }

1488
  PreParserExpression ExpressionFromIdentifier(
1489
      const PreParserIdentifier& name, int start_position,
1490
      InferName infer = InferName::kYes);
1491 1492

  V8_INLINE PreParserExpression ExpressionFromString(int pos) {
1493
    if (scanner()->IsUseStrict()) {
1494 1495 1496 1497 1498 1499 1500 1501 1502
      return PreParserExpression::UseStrictStringLiteral();
    }
    return PreParserExpression::StringLiteral();
  }

  V8_INLINE PreParserExpressionList NewExpressionList(int size) const {
    return PreParserExpressionList();
  }

1503 1504 1505 1506 1507
  V8_INLINE PreParserExpressionList NewObjectPropertyList(int size) const {
    return PreParserExpressionList();
  }

  V8_INLINE PreParserExpressionList NewClassPropertyList(int size) const {
1508 1509 1510 1511 1512 1513 1514
    return PreParserExpressionList();
  }

  V8_INLINE PreParserStatementList NewStatementList(int size) const {
    return PreParserStatementList();
  }

1515
  V8_INLINE PreParserExpression
1516 1517
  NewV8Intrinsic(const PreParserIdentifier& name,
                 const PreParserExpressionList& arguments, int pos, bool* ok) {
1518 1519 1520
    return PreParserExpression::Default();
  }

1521 1522
  V8_INLINE PreParserStatement
  NewThrowStatement(const PreParserExpression& exception, int pos) {
1523 1524 1525
    return PreParserStatement::Jump();
  }

1526 1527
  V8_INLINE void AddParameterInitializationBlock(
      const PreParserFormalParameters& parameters, PreParserStatementList body,
1528 1529 1530 1531 1532
      bool is_async, bool* ok) {
    if (!parameters.is_simple) {
      BuildParameterInitializationBlock(parameters, ok);
    }
  }
1533 1534

  V8_INLINE void AddFormalParameter(PreParserFormalParameters* parameters,
1535 1536
                                    const PreParserExpression& pattern,
                                    const PreParserExpression& initializer,
1537 1538
                                    int initializer_end_position,
                                    bool is_rest) {
1539 1540
    if (track_unresolved_variables_) {
      DCHECK(FLAG_lazy_inner_functions);
1541
      parameters->params.Add(new (zone()) PreParserFormalParameters::Parameter(
1542
          pattern.variables_, is_rest));
1543
    }
1544
    parameters->UpdateArityAndFunctionLength(!initializer.IsNull(), is_rest);
1545 1546
  }

1547 1548
  V8_INLINE void DeclareFormalParameters(
      DeclarationScope* scope,
1549 1550
      const ThreadedList<PreParserFormalParameters::Parameter>& parameters,
      bool is_simple) {
1551
    if (!is_simple) scope->SetHasNonSimpleParameters();
1552 1553 1554
    if (track_unresolved_variables_) {
      DCHECK(FLAG_lazy_inner_functions);
      for (auto parameter : parameters) {
1555 1556 1557 1558 1559
        DCHECK_IMPLIES(is_simple, parameter->variables_ != nullptr);
        DCHECK_IMPLIES(is_simple, parameter->variables_->length() == 1);
        // Make sure each parameter is added only once even if it's a
        // destructuring parameter which contains multiple names.
        bool add_parameter = true;
1560 1561
        if (parameter->variables_ != nullptr) {
          for (auto variable : (*parameter->variables_)) {
1562 1563 1564 1565 1566 1567
            // We declare the parameter name for all names, but only create a
            // parameter entry for the first one.
            scope->DeclareParameterName(variable->raw_name(),
                                        parameter->is_rest, ast_value_factory(),
                                        true, add_parameter);
            add_parameter = false;
1568
          }
1569
        }
1570 1571 1572 1573 1574 1575 1576 1577
        if (add_parameter) {
          // No names were declared; declare a dummy one here to up the
          // parameter count.
          DCHECK(!is_simple);
          scope->DeclareParameterName(ast_value_factory()->empty_string(),
                                      parameter->is_rest, ast_value_factory(),
                                      false, add_parameter);
        }
1578 1579
      }
    }
1580 1581
  }

1582
  V8_INLINE void DeclareArrowFunctionFormalParameters(
1583
      PreParserFormalParameters* parameters, const PreParserExpression& params,
1584
      const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
1585
      bool* ok) {
1586
    // TODO(wingo): Detect duplicated identifiers in paramlists.  Detect
1587
    // parameter lists that are too long.
1588 1589 1590 1591 1592 1593 1594 1595
    if (track_unresolved_variables_) {
      DCHECK(FLAG_lazy_inner_functions);
      if (params.variables_ != nullptr) {
        for (auto variable : *params.variables_) {
          parameters->scope->DeclareVariableName(variable->raw_name(), VAR);
        }
      }
    }
1596 1597 1598
  }

  V8_INLINE PreParserExpression
1599
  ExpressionListToExpression(const PreParserExpressionList& args) {
1600
    return PreParserExpression::Default(args.variables_);
1601 1602
  }

1603
  V8_INLINE void SetFunctionNameFromPropertyName(
1604
      const PreParserExpression& property, const PreParserIdentifier& name,
1605
      const AstRawString* prefix = nullptr) {}
1606
  V8_INLINE void SetFunctionNameFromIdentifierRef(
1607 1608
      const PreParserExpression& value, const PreParserExpression& identifier) {
  }
1609

1610
  V8_INLINE ZoneList<typename ExpressionClassifier::Error>*
1611 1612 1613 1614 1615 1616 1617 1618
  GetReportedErrorList() const {
    return function_state_->GetReportedErrorList();
  }

  V8_INLINE ZoneList<PreParserExpression>* GetNonPatternList() const {
    return function_state_->non_patterns_to_rewrite();
  }

1619 1620 1621 1622
  V8_INLINE void CountUsage(v8::Isolate::UseCounterFeature feature) {
    if (use_counts_ != nullptr) ++use_counts_[feature];
  }

1623 1624
  V8_INLINE bool ParsingDynamicFunctionDeclaration() const { return false; }

1625 1626 1627 1628 1629 1630 1631
// Generate empty functions here as the preparser does not collect source
// ranges for block coverage.
#define DEFINE_RECORD_SOURCE_RANGE(Name) \
  template <typename... Ts>              \
  V8_INLINE void Record##Name##SourceRange(Ts... args) {}
  AST_SOURCE_RANGE_LIST(DEFINE_RECORD_SOURCE_RANGE)
#undef DEFINE_RECORD_SOURCE_RANGE
1632

1633 1634
  // Preparser's private field members.

1635
  int* use_counts_;
1636
  bool track_unresolved_variables_;
1637
  PreParserLogger log_;
1638
  PendingCompilationErrorHandler* pending_error_handler_;
1639 1640

  ProducedPreParsedScopeData* produced_preparsed_scope_data_;
1641
};
1642

1643 1644 1645
PreParserExpression PreParser::SpreadCall(const PreParserExpression& function,
                                          const PreParserExpressionList& args,
                                          int pos,
1646 1647
                                          Call::PossiblyEval possibly_eval) {
  return factory()->NewCall(function, args, pos, possibly_eval);
1648 1649
}

1650 1651 1652
PreParserExpression PreParser::SpreadCallNew(
    const PreParserExpression& function, const PreParserExpressionList& args,
    int pos) {
1653
  return factory()->NewCallNew(function, args, pos);
1654 1655
}

1656 1657
}  // namespace internal
}  // namespace v8
1658

1659
#endif  // V8_PARSING_PREPARSER_H