Home | History | Annotate | Download | only in parsing
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_PARSING_PREPARSER_H
      6 #define V8_PARSING_PREPARSER_H
      7 
      8 #include "src/ast/scopes.h"
      9 #include "src/bailout-reason.h"
     10 #include "src/hashmap.h"
     11 #include "src/messages.h"
     12 #include "src/parsing/expression-classifier.h"
     13 #include "src/parsing/func-name-inferrer.h"
     14 #include "src/parsing/parser-base.h"
     15 #include "src/parsing/scanner.h"
     16 #include "src/parsing/token.h"
     17 
     18 namespace v8 {
     19 namespace internal {
     20 
     21 
     22 class PreParserIdentifier {
     23  public:
     24   PreParserIdentifier() : type_(kUnknownIdentifier) {}
     25   static PreParserIdentifier Default() {
     26     return PreParserIdentifier(kUnknownIdentifier);
     27   }
     28   static PreParserIdentifier Eval() {
     29     return PreParserIdentifier(kEvalIdentifier);
     30   }
     31   static PreParserIdentifier Arguments() {
     32     return PreParserIdentifier(kArgumentsIdentifier);
     33   }
     34   static PreParserIdentifier Undefined() {
     35     return PreParserIdentifier(kUndefinedIdentifier);
     36   }
     37   static PreParserIdentifier FutureReserved() {
     38     return PreParserIdentifier(kFutureReservedIdentifier);
     39   }
     40   static PreParserIdentifier FutureStrictReserved() {
     41     return PreParserIdentifier(kFutureStrictReservedIdentifier);
     42   }
     43   static PreParserIdentifier Let() {
     44     return PreParserIdentifier(kLetIdentifier);
     45   }
     46   static PreParserIdentifier Static() {
     47     return PreParserIdentifier(kStaticIdentifier);
     48   }
     49   static PreParserIdentifier Yield() {
     50     return PreParserIdentifier(kYieldIdentifier);
     51   }
     52   static PreParserIdentifier Prototype() {
     53     return PreParserIdentifier(kPrototypeIdentifier);
     54   }
     55   static PreParserIdentifier Constructor() {
     56     return PreParserIdentifier(kConstructorIdentifier);
     57   }
     58   bool IsEval() const { return type_ == kEvalIdentifier; }
     59   bool IsArguments() const { return type_ == kArgumentsIdentifier; }
     60   bool IsEvalOrArguments() const { return IsEval() || IsArguments(); }
     61   bool IsUndefined() const { return type_ == kUndefinedIdentifier; }
     62   bool IsLet() const { return type_ == kLetIdentifier; }
     63   bool IsStatic() const { return type_ == kStaticIdentifier; }
     64   bool IsYield() const { return type_ == kYieldIdentifier; }
     65   bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
     66   bool IsConstructor() const { return type_ == kConstructorIdentifier; }
     67   bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
     68   bool IsFutureStrictReserved() const {
     69     return type_ == kFutureStrictReservedIdentifier ||
     70            type_ == kLetIdentifier || type_ == kStaticIdentifier ||
     71            type_ == kYieldIdentifier;
     72   }
     73 
     74   // Allow identifier->name()[->length()] to work. The preparser
     75   // does not need the actual positions/lengths of the identifiers.
     76   const PreParserIdentifier* operator->() const { return this; }
     77   const PreParserIdentifier raw_name() const { return *this; }
     78 
     79   int position() const { return 0; }
     80   int length() const { return 0; }
     81 
     82  private:
     83   enum Type {
     84     kUnknownIdentifier,
     85     kFutureReservedIdentifier,
     86     kFutureStrictReservedIdentifier,
     87     kLetIdentifier,
     88     kStaticIdentifier,
     89     kYieldIdentifier,
     90     kEvalIdentifier,
     91     kArgumentsIdentifier,
     92     kUndefinedIdentifier,
     93     kPrototypeIdentifier,
     94     kConstructorIdentifier
     95   };
     96 
     97   explicit PreParserIdentifier(Type type) : type_(type) {}
     98   Type type_;
     99 
    100   friend class PreParserExpression;
    101 };
    102 
    103 
    104 class PreParserExpression {
    105  public:
    106   static PreParserExpression Default() {
    107     return PreParserExpression(TypeField::encode(kExpression));
    108   }
    109 
    110   static PreParserExpression Spread(PreParserExpression expression) {
    111     return PreParserExpression(TypeField::encode(kSpreadExpression));
    112   }
    113 
    114   static PreParserExpression FromIdentifier(PreParserIdentifier id) {
    115     return PreParserExpression(TypeField::encode(kIdentifierExpression) |
    116                                IdentifierTypeField::encode(id.type_));
    117   }
    118 
    119   static PreParserExpression BinaryOperation(PreParserExpression left,
    120                                              Token::Value op,
    121                                              PreParserExpression right) {
    122     return PreParserExpression(TypeField::encode(kBinaryOperationExpression));
    123   }
    124 
    125   static PreParserExpression Assignment() {
    126     return PreParserExpression(TypeField::encode(kExpression) |
    127                                ExpressionTypeField::encode(kAssignment));
    128   }
    129 
    130   static PreParserExpression ObjectLiteral() {
    131     return PreParserExpression(TypeField::encode(kObjectLiteralExpression));
    132   }
    133 
    134   static PreParserExpression ArrayLiteral() {
    135     return PreParserExpression(TypeField::encode(kArrayLiteralExpression));
    136   }
    137 
    138   static PreParserExpression StringLiteral() {
    139     return PreParserExpression(TypeField::encode(kStringLiteralExpression));
    140   }
    141 
    142   static PreParserExpression UseStrictStringLiteral() {
    143     return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
    144                                IsUseStrictField::encode(true));
    145   }
    146 
    147   static PreParserExpression UseStrongStringLiteral() {
    148     return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
    149                                IsUseStrongField::encode(true));
    150   }
    151 
    152   static PreParserExpression This() {
    153     return PreParserExpression(TypeField::encode(kExpression) |
    154                                ExpressionTypeField::encode(kThisExpression));
    155   }
    156 
    157   static PreParserExpression ThisProperty() {
    158     return PreParserExpression(
    159         TypeField::encode(kExpression) |
    160         ExpressionTypeField::encode(kThisPropertyExpression));
    161   }
    162 
    163   static PreParserExpression Property() {
    164     return PreParserExpression(
    165         TypeField::encode(kExpression) |
    166         ExpressionTypeField::encode(kPropertyExpression));
    167   }
    168 
    169   static PreParserExpression Call() {
    170     return PreParserExpression(TypeField::encode(kExpression) |
    171                                ExpressionTypeField::encode(kCallExpression));
    172   }
    173 
    174   static PreParserExpression SuperCallReference() {
    175     return PreParserExpression(
    176         TypeField::encode(kExpression) |
    177         ExpressionTypeField::encode(kSuperCallReference));
    178   }
    179 
    180   static PreParserExpression NoTemplateTag() {
    181     return PreParserExpression(
    182         TypeField::encode(kExpression) |
    183         ExpressionTypeField::encode(kNoTemplateTagExpression));
    184   }
    185 
    186   bool IsIdentifier() const {
    187     return TypeField::decode(code_) == kIdentifierExpression;
    188   }
    189 
    190   PreParserIdentifier AsIdentifier() const {
    191     DCHECK(IsIdentifier());
    192     return PreParserIdentifier(IdentifierTypeField::decode(code_));
    193   }
    194 
    195   bool IsAssignment() const {
    196     return TypeField::decode(code_) == kExpression &&
    197            ExpressionTypeField::decode(code_) == kAssignment;
    198   }
    199 
    200   bool IsObjectLiteral() const {
    201     return TypeField::decode(code_) == kObjectLiteralExpression;
    202   }
    203 
    204   bool IsArrayLiteral() const {
    205     return TypeField::decode(code_) == kArrayLiteralExpression;
    206   }
    207 
    208   bool IsStringLiteral() const {
    209     return TypeField::decode(code_) == kStringLiteralExpression;
    210   }
    211 
    212   bool IsUseStrictLiteral() const {
    213     return TypeField::decode(code_) == kStringLiteralExpression &&
    214            IsUseStrictField::decode(code_);
    215   }
    216 
    217   bool IsUseStrongLiteral() const {
    218     return TypeField::decode(code_) == kStringLiteralExpression &&
    219            IsUseStrongField::decode(code_);
    220   }
    221 
    222   bool IsThis() const {
    223     return TypeField::decode(code_) == kExpression &&
    224            ExpressionTypeField::decode(code_) == kThisExpression;
    225   }
    226 
    227   bool IsThisProperty() const {
    228     return TypeField::decode(code_) == kExpression &&
    229            ExpressionTypeField::decode(code_) == kThisPropertyExpression;
    230   }
    231 
    232   bool IsProperty() const {
    233     return TypeField::decode(code_) == kExpression &&
    234            (ExpressionTypeField::decode(code_) == kPropertyExpression ||
    235             ExpressionTypeField::decode(code_) == kThisPropertyExpression);
    236   }
    237 
    238   bool IsCall() const {
    239     return TypeField::decode(code_) == kExpression &&
    240            ExpressionTypeField::decode(code_) == kCallExpression;
    241   }
    242 
    243   bool IsSuperCallReference() const {
    244     return TypeField::decode(code_) == kExpression &&
    245            ExpressionTypeField::decode(code_) == kSuperCallReference;
    246   }
    247 
    248   bool IsValidReferenceExpression() const {
    249     return IsIdentifier() || IsProperty();
    250   }
    251 
    252   // At the moment PreParser doesn't track these expression types.
    253   bool IsFunctionLiteral() const { return false; }
    254   bool IsCallNew() const { return false; }
    255 
    256   bool IsNoTemplateTag() const {
    257     return TypeField::decode(code_) == kExpression &&
    258            ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
    259   }
    260 
    261   bool IsSpreadExpression() const {
    262     return TypeField::decode(code_) == kSpreadExpression;
    263   }
    264 
    265   PreParserExpression AsFunctionLiteral() { return *this; }
    266 
    267   bool IsBinaryOperation() const {
    268     return TypeField::decode(code_) == kBinaryOperationExpression;
    269   }
    270 
    271   // Dummy implementation for making expression->somefunc() work in both Parser
    272   // and PreParser.
    273   PreParserExpression* operator->() { return this; }
    274 
    275   // More dummy implementations of things PreParser doesn't need to track:
    276   void set_index(int index) {}  // For YieldExpressions
    277   void set_should_eager_compile() {}
    278 
    279   int position() const { return RelocInfo::kNoPosition; }
    280   void set_function_token_position(int position) {}
    281 
    282   // Parenthesized expressions in the form `( Expression )`.
    283   void set_is_parenthesized() {
    284     code_ = ParenthesizedField::update(code_, true);
    285   }
    286   bool is_parenthesized() const { return ParenthesizedField::decode(code_); }
    287 
    288  private:
    289   enum Type {
    290     kExpression,
    291     kIdentifierExpression,
    292     kStringLiteralExpression,
    293     kBinaryOperationExpression,
    294     kSpreadExpression,
    295     kObjectLiteralExpression,
    296     kArrayLiteralExpression
    297   };
    298 
    299   enum ExpressionType {
    300     kThisExpression,
    301     kThisPropertyExpression,
    302     kPropertyExpression,
    303     kCallExpression,
    304     kSuperCallReference,
    305     kNoTemplateTagExpression,
    306     kAssignment
    307   };
    308 
    309   explicit PreParserExpression(uint32_t expression_code)
    310       : code_(expression_code) {}
    311 
    312   // The first three bits are for the Type.
    313   typedef BitField<Type, 0, 3> TypeField;
    314 
    315   // The high order bit applies only to nodes which would inherit from the
    316   // Expression ASTNode --- This is by necessity, due to the fact that
    317   // Expression nodes may be represented as multiple Types, not exclusively
    318   // through kExpression.
    319   // TODO(caitp, adamk): clean up PreParserExpression bitfields.
    320   typedef BitField<bool, 31, 1> ParenthesizedField;
    321 
    322   // The rest of the bits are interpreted depending on the value
    323   // of the Type field, so they can share the storage.
    324   typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField;
    325   typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField;
    326   typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
    327   typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10>
    328       IdentifierTypeField;
    329   typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField;
    330 
    331   uint32_t code_;
    332 };
    333 
    334 
    335 // The pre-parser doesn't need to build lists of expressions, identifiers, or
    336 // the like.
    337 template <typename T>
    338 class PreParserList {
    339  public:
    340   // These functions make list->Add(some_expression) work (and do nothing).
    341   PreParserList() : length_(0) {}
    342   PreParserList* operator->() { return this; }
    343   void Add(T, void*) { ++length_; }
    344   int length() const { return length_; }
    345  private:
    346   int length_;
    347 };
    348 
    349 
    350 typedef PreParserList<PreParserExpression> PreParserExpressionList;
    351 
    352 
    353 class PreParserStatement {
    354  public:
    355   static PreParserStatement Default() {
    356     return PreParserStatement(kUnknownStatement);
    357   }
    358 
    359   static PreParserStatement Jump() {
    360     return PreParserStatement(kJumpStatement);
    361   }
    362 
    363   static PreParserStatement FunctionDeclaration() {
    364     return PreParserStatement(kFunctionDeclaration);
    365   }
    366 
    367   // Creates expression statement from expression.
    368   // Preserves being an unparenthesized string literal, possibly
    369   // "use strict".
    370   static PreParserStatement ExpressionStatement(
    371       PreParserExpression expression) {
    372     if (expression.IsUseStrictLiteral()) {
    373       return PreParserStatement(kUseStrictExpressionStatement);
    374     }
    375     if (expression.IsUseStrongLiteral()) {
    376       return PreParserStatement(kUseStrongExpressionStatement);
    377     }
    378     if (expression.IsStringLiteral()) {
    379       return PreParserStatement(kStringLiteralExpressionStatement);
    380     }
    381     return Default();
    382   }
    383 
    384   bool IsStringLiteral() {
    385     return code_ == kStringLiteralExpressionStatement;
    386   }
    387 
    388   bool IsUseStrictLiteral() {
    389     return code_ == kUseStrictExpressionStatement;
    390   }
    391 
    392   bool IsUseStrongLiteral() { return code_ == kUseStrongExpressionStatement; }
    393 
    394   bool IsFunctionDeclaration() {
    395     return code_ == kFunctionDeclaration;
    396   }
    397 
    398   bool IsJumpStatement() {
    399     return code_ == kJumpStatement;
    400   }
    401 
    402  private:
    403   enum Type {
    404     kUnknownStatement,
    405     kJumpStatement,
    406     kStringLiteralExpressionStatement,
    407     kUseStrictExpressionStatement,
    408     kUseStrongExpressionStatement,
    409     kFunctionDeclaration
    410   };
    411 
    412   explicit PreParserStatement(Type code) : code_(code) {}
    413   Type code_;
    414 };
    415 
    416 
    417 typedef PreParserList<PreParserStatement> PreParserStatementList;
    418 
    419 
    420 class PreParserFactory {
    421  public:
    422   explicit PreParserFactory(void* unused_value_factory) {}
    423   PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
    424                                        int pos) {
    425     return PreParserExpression::Default();
    426   }
    427   PreParserExpression NewNumberLiteral(double number,
    428                                        int pos) {
    429     return PreParserExpression::Default();
    430   }
    431   PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
    432                                        int js_flags, int literal_index,
    433                                        bool is_strong, int pos) {
    434     return PreParserExpression::Default();
    435   }
    436   PreParserExpression NewArrayLiteral(PreParserExpressionList values,
    437                                       int literal_index,
    438                                       bool is_strong,
    439                                       int pos) {
    440     return PreParserExpression::ArrayLiteral();
    441   }
    442   PreParserExpression NewArrayLiteral(PreParserExpressionList values,
    443                                       int first_spread_index, int literal_index,
    444                                       bool is_strong, int pos) {
    445     return PreParserExpression::ArrayLiteral();
    446   }
    447   PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
    448                                                PreParserExpression value,
    449                                                ObjectLiteralProperty::Kind kind,
    450                                                bool is_static,
    451                                                bool is_computed_name) {
    452     return PreParserExpression::Default();
    453   }
    454   PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
    455                                                PreParserExpression value,
    456                                                bool is_static,
    457                                                bool is_computed_name) {
    458     return PreParserExpression::Default();
    459   }
    460   PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
    461                                        int literal_index,
    462                                        int boilerplate_properties,
    463                                        bool has_function,
    464                                        bool is_strong,
    465                                        int pos) {
    466     return PreParserExpression::ObjectLiteral();
    467   }
    468   PreParserExpression NewVariableProxy(void* variable) {
    469     return PreParserExpression::Default();
    470   }
    471   PreParserExpression NewProperty(PreParserExpression obj,
    472                                   PreParserExpression key,
    473                                   int pos) {
    474     if (obj.IsThis()) {
    475       return PreParserExpression::ThisProperty();
    476     }
    477     return PreParserExpression::Property();
    478   }
    479   PreParserExpression NewUnaryOperation(Token::Value op,
    480                                         PreParserExpression expression,
    481                                         int pos) {
    482     return PreParserExpression::Default();
    483   }
    484   PreParserExpression NewBinaryOperation(Token::Value op,
    485                                          PreParserExpression left,
    486                                          PreParserExpression right, int pos) {
    487     return PreParserExpression::BinaryOperation(left, op, right);
    488   }
    489   PreParserExpression NewCompareOperation(Token::Value op,
    490                                           PreParserExpression left,
    491                                           PreParserExpression right, int pos) {
    492     return PreParserExpression::Default();
    493   }
    494   PreParserExpression NewRewritableAssignmentExpression(
    495       PreParserExpression expression) {
    496     return expression;
    497   }
    498   PreParserExpression NewAssignment(Token::Value op,
    499                                     PreParserExpression left,
    500                                     PreParserExpression right,
    501                                     int pos) {
    502     return PreParserExpression::Assignment();
    503   }
    504   PreParserExpression NewYield(PreParserExpression generator_object,
    505                                PreParserExpression expression,
    506                                Yield::Kind yield_kind,
    507                                int pos) {
    508     return PreParserExpression::Default();
    509   }
    510   PreParserExpression NewConditional(PreParserExpression condition,
    511                                      PreParserExpression then_expression,
    512                                      PreParserExpression else_expression,
    513                                      int pos) {
    514     return PreParserExpression::Default();
    515   }
    516   PreParserExpression NewCountOperation(Token::Value op,
    517                                         bool is_prefix,
    518                                         PreParserExpression expression,
    519                                         int pos) {
    520     return PreParserExpression::Default();
    521   }
    522   PreParserExpression NewCall(PreParserExpression expression,
    523                               PreParserExpressionList arguments,
    524                               int pos) {
    525     return PreParserExpression::Call();
    526   }
    527   PreParserExpression NewCallNew(PreParserExpression expression,
    528                                  PreParserExpressionList arguments,
    529                                  int pos) {
    530     return PreParserExpression::Default();
    531   }
    532   PreParserExpression NewCallRuntime(const AstRawString* name,
    533                                      const Runtime::Function* function,
    534                                      PreParserExpressionList arguments,
    535                                      int pos) {
    536     return PreParserExpression::Default();
    537   }
    538   PreParserStatement NewReturnStatement(PreParserExpression expression,
    539                                         int pos) {
    540     return PreParserStatement::Default();
    541   }
    542   PreParserExpression NewFunctionLiteral(
    543       PreParserIdentifier name, Scope* scope, PreParserStatementList body,
    544       int materialized_literal_count, int expected_property_count,
    545       int parameter_count,
    546       FunctionLiteral::ParameterFlag has_duplicate_parameters,
    547       FunctionLiteral::FunctionType function_type,
    548       FunctionLiteral::EagerCompileHint eager_compile_hint, FunctionKind kind,
    549       int position) {
    550     return PreParserExpression::Default();
    551   }
    552 
    553   PreParserExpression NewSpread(PreParserExpression expression, int pos) {
    554     return PreParserExpression::Spread(expression);
    555   }
    556 
    557   PreParserExpression NewEmptyParentheses(int pos) {
    558     return PreParserExpression::Default();
    559   }
    560 
    561   // Return the object itself as AstVisitor and implement the needed
    562   // dummy method right in this class.
    563   PreParserFactory* visitor() { return this; }
    564   int* ast_properties() {
    565     static int dummy = 42;
    566     return &dummy;
    567   }
    568 };
    569 
    570 
    571 struct PreParserFormalParameters : FormalParametersBase {
    572   explicit PreParserFormalParameters(Scope* scope)
    573       : FormalParametersBase(scope) {}
    574   int arity = 0;
    575 
    576   int Arity() const { return arity; }
    577   PreParserIdentifier at(int i) { return PreParserIdentifier(); }  // Dummy
    578 };
    579 
    580 
    581 class PreParser;
    582 
    583 class PreParserTraits {
    584  public:
    585   struct Type {
    586     // TODO(marja): To be removed. The Traits object should contain all the data
    587     // it needs.
    588     typedef PreParser* Parser;
    589 
    590     // PreParser doesn't need to store generator variables.
    591     typedef void GeneratorVariable;
    592 
    593     typedef int AstProperties;
    594 
    595     // Return types for traversing functions.
    596     typedef PreParserIdentifier Identifier;
    597     typedef PreParserExpression Expression;
    598     typedef PreParserExpression YieldExpression;
    599     typedef PreParserExpression FunctionLiteral;
    600     typedef PreParserExpression ClassLiteral;
    601     typedef PreParserExpression ObjectLiteralProperty;
    602     typedef PreParserExpression Literal;
    603     typedef PreParserExpressionList ExpressionList;
    604     typedef PreParserExpressionList PropertyList;
    605     typedef PreParserIdentifier FormalParameter;
    606     typedef PreParserFormalParameters FormalParameters;
    607     typedef PreParserStatementList StatementList;
    608 
    609     // For constructing objects returned by the traversing functions.
    610     typedef PreParserFactory Factory;
    611   };
    612 
    613   explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
    614 
    615   // Helper functions for recursive descent.
    616   static bool IsEval(PreParserIdentifier identifier) {
    617     return identifier.IsEval();
    618   }
    619 
    620   static bool IsArguments(PreParserIdentifier identifier) {
    621     return identifier.IsArguments();
    622   }
    623 
    624   static bool IsEvalOrArguments(PreParserIdentifier identifier) {
    625     return identifier.IsEvalOrArguments();
    626   }
    627 
    628   static bool IsUndefined(PreParserIdentifier identifier) {
    629     return identifier.IsUndefined();
    630   }
    631 
    632   static bool IsPrototype(PreParserIdentifier identifier) {
    633     return identifier.IsPrototype();
    634   }
    635 
    636   static bool IsConstructor(PreParserIdentifier identifier) {
    637     return identifier.IsConstructor();
    638   }
    639 
    640   // Returns true if the expression is of type "this.foo".
    641   static bool IsThisProperty(PreParserExpression expression) {
    642     return expression.IsThisProperty();
    643   }
    644 
    645   static bool IsIdentifier(PreParserExpression expression) {
    646     return expression.IsIdentifier();
    647   }
    648 
    649   static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
    650     return expression.AsIdentifier();
    651   }
    652 
    653   static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
    654     return identifier.IsFutureStrictReserved();
    655   }
    656 
    657   static bool IsBoilerplateProperty(PreParserExpression property) {
    658     // PreParser doesn't count boilerplate properties.
    659     return false;
    660   }
    661 
    662   static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
    663     return false;
    664   }
    665 
    666   static PreParserExpression GetPropertyValue(PreParserExpression property) {
    667     return PreParserExpression::Default();
    668   }
    669 
    670   // Functions for encapsulating the differences between parsing and preparsing;
    671   // operations interleaved with the recursive descent.
    672   static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
    673     // PreParser should not use FuncNameInferrer.
    674     UNREACHABLE();
    675   }
    676 
    677   static void PushPropertyName(FuncNameInferrer* fni,
    678                                PreParserExpression expression) {
    679     // PreParser should not use FuncNameInferrer.
    680     UNREACHABLE();
    681   }
    682 
    683   static void InferFunctionName(FuncNameInferrer* fni,
    684                                 PreParserExpression expression) {
    685     // PreParser should not use FuncNameInferrer.
    686     UNREACHABLE();
    687   }
    688 
    689   static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
    690       Scope* scope, PreParserExpression property, bool* has_function) {}
    691 
    692   static void CheckAssigningFunctionLiteralToProperty(
    693       PreParserExpression left, PreParserExpression right) {}
    694 
    695   static PreParserExpression MarkExpressionAsAssigned(
    696       PreParserExpression expression) {
    697     // TODO(marja): To be able to produce the same errors, the preparser needs
    698     // to start tracking which expressions are variables and which are assigned.
    699     return expression;
    700   }
    701 
    702   bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
    703                                               PreParserExpression y,
    704                                               Token::Value op,
    705                                               int pos,
    706                                               PreParserFactory* factory) {
    707     return false;
    708   }
    709 
    710   PreParserExpression BuildUnaryExpression(PreParserExpression expression,
    711                                            Token::Value op, int pos,
    712                                            PreParserFactory* factory) {
    713     return PreParserExpression::Default();
    714   }
    715 
    716   PreParserExpression NewThrowReferenceError(MessageTemplate::Template message,
    717                                              int pos) {
    718     return PreParserExpression::Default();
    719   }
    720   PreParserExpression NewThrowSyntaxError(MessageTemplate::Template message,
    721                                           Handle<Object> arg, int pos) {
    722     return PreParserExpression::Default();
    723   }
    724   PreParserExpression NewThrowTypeError(MessageTemplate::Template message,
    725                                         Handle<Object> arg, int pos) {
    726     return PreParserExpression::Default();
    727   }
    728 
    729   // Reporting errors.
    730   void ReportMessageAt(Scanner::Location location,
    731                        MessageTemplate::Template message,
    732                        const char* arg = NULL,
    733                        ParseErrorType error_type = kSyntaxError);
    734   void ReportMessageAt(int start_pos, int end_pos,
    735                        MessageTemplate::Template message,
    736                        const char* arg = NULL,
    737                        ParseErrorType error_type = kSyntaxError);
    738 
    739   // "null" return type creators.
    740   static PreParserIdentifier EmptyIdentifier() {
    741     return PreParserIdentifier::Default();
    742   }
    743   static PreParserIdentifier EmptyIdentifierString() {
    744     return PreParserIdentifier::Default();
    745   }
    746   static PreParserExpression EmptyExpression() {
    747     return PreParserExpression::Default();
    748   }
    749   static PreParserExpression EmptyLiteral() {
    750     return PreParserExpression::Default();
    751   }
    752   static PreParserExpression EmptyObjectLiteralProperty() {
    753     return PreParserExpression::Default();
    754   }
    755   static PreParserExpression EmptyFunctionLiteral() {
    756     return PreParserExpression::Default();
    757   }
    758   static PreParserExpressionList NullExpressionList() {
    759     return PreParserExpressionList();
    760   }
    761 
    762   // Odd-ball literal creators.
    763   static PreParserExpression GetLiteralTheHole(int position,
    764                                                PreParserFactory* factory) {
    765     return PreParserExpression::Default();
    766   }
    767 
    768   // Producing data during the recursive descent.
    769   PreParserIdentifier GetSymbol(Scanner* scanner);
    770   PreParserIdentifier GetNumberAsSymbol(Scanner* scanner);
    771 
    772   static PreParserIdentifier GetNextSymbol(Scanner* scanner) {
    773     return PreParserIdentifier::Default();
    774   }
    775 
    776   static PreParserExpression ThisExpression(Scope* scope,
    777                                             PreParserFactory* factory,
    778                                             int pos) {
    779     return PreParserExpression::This();
    780   }
    781 
    782   static PreParserExpression SuperPropertyReference(Scope* scope,
    783                                                     PreParserFactory* factory,
    784                                                     int pos) {
    785     return PreParserExpression::Default();
    786   }
    787 
    788   static PreParserExpression SuperCallReference(Scope* scope,
    789                                                 PreParserFactory* factory,
    790                                                 int pos) {
    791     return PreParserExpression::SuperCallReference();
    792   }
    793 
    794   static PreParserExpression NewTargetExpression(Scope* scope,
    795                                                  PreParserFactory* factory,
    796                                                  int pos) {
    797     return PreParserExpression::Default();
    798   }
    799 
    800   static PreParserExpression DefaultConstructor(bool call_super, Scope* scope,
    801                                                 int pos, int end_pos) {
    802     return PreParserExpression::Default();
    803   }
    804 
    805   static PreParserExpression ExpressionFromLiteral(
    806       Token::Value token, int pos, Scanner* scanner,
    807       PreParserFactory* factory) {
    808     return PreParserExpression::Default();
    809   }
    810 
    811   static PreParserExpression ExpressionFromIdentifier(
    812       PreParserIdentifier name, int start_position, int end_position,
    813       Scope* scope, PreParserFactory* factory) {
    814     return PreParserExpression::FromIdentifier(name);
    815   }
    816 
    817   PreParserExpression ExpressionFromString(int pos,
    818                                            Scanner* scanner,
    819                                            PreParserFactory* factory = NULL);
    820 
    821   PreParserExpression GetIterator(PreParserExpression iterable,
    822                                   PreParserFactory* factory, int pos) {
    823     return PreParserExpression::Default();
    824   }
    825 
    826   static PreParserExpressionList NewExpressionList(int size, Zone* zone) {
    827     return PreParserExpressionList();
    828   }
    829 
    830   static PreParserStatementList NewStatementList(int size, Zone* zone) {
    831     return PreParserStatementList();
    832   }
    833 
    834   static PreParserExpressionList NewPropertyList(int size, Zone* zone) {
    835     return PreParserExpressionList();
    836   }
    837 
    838   static void AddParameterInitializationBlock(
    839       const PreParserFormalParameters& parameters,
    840       PreParserStatementList list, bool* ok) {}
    841 
    842   V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
    843                                       int* expected_property_count, bool* ok) {
    844     UNREACHABLE();
    845   }
    846 
    847   V8_INLINE PreParserStatementList ParseEagerFunctionBody(
    848       PreParserIdentifier function_name, int pos,
    849       const PreParserFormalParameters& parameters, FunctionKind kind,
    850       FunctionLiteral::FunctionType function_type, bool* ok);
    851 
    852   V8_INLINE void ParseArrowFunctionFormalParameterList(
    853       PreParserFormalParameters* parameters,
    854       PreParserExpression expression, const Scanner::Location& params_loc,
    855       Scanner::Location* duplicate_loc, bool* ok);
    856 
    857   void ReindexLiterals(const PreParserFormalParameters& paramaters) {}
    858 
    859   struct TemplateLiteralState {};
    860 
    861   TemplateLiteralState OpenTemplateLiteral(int pos) {
    862     return TemplateLiteralState();
    863   }
    864   void AddTemplateSpan(TemplateLiteralState*, bool) {}
    865   void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {}
    866   PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int,
    867                                            PreParserExpression tag) {
    868     if (IsTaggedTemplate(tag)) {
    869       // Emulate generation of array literals for tag callsite
    870       // 1st is array of cooked strings, second is array of raw strings
    871       MaterializeTemplateCallsiteLiterals();
    872     }
    873     return EmptyExpression();
    874   }
    875   inline void MaterializeTemplateCallsiteLiterals();
    876   PreParserExpression NoTemplateTag() {
    877     return PreParserExpression::NoTemplateTag();
    878   }
    879   static bool IsTaggedTemplate(const PreParserExpression tag) {
    880     return !tag.IsNoTemplateTag();
    881   }
    882 
    883   void AddFormalParameter(PreParserFormalParameters* parameters,
    884                           PreParserExpression pattern,
    885                           PreParserExpression initializer,
    886                           int initializer_end_position, bool is_rest) {
    887     ++parameters->arity;
    888   }
    889   void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter,
    890                               ExpressionClassifier* classifier) {
    891     if (!classifier->is_simple_parameter_list()) {
    892       scope->SetHasNonSimpleParameters();
    893     }
    894   }
    895 
    896   void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
    897 
    898   // Temporary glue; these functions will move to ParserBase.
    899   PreParserExpression ParseV8Intrinsic(bool* ok);
    900   V8_INLINE PreParserExpression ParseDoExpression(bool* ok);
    901   PreParserExpression ParseFunctionLiteral(
    902       PreParserIdentifier name, Scanner::Location function_name_location,
    903       FunctionNameValidity function_name_validity, FunctionKind kind,
    904       int function_token_position, FunctionLiteral::FunctionType type,
    905       FunctionLiteral::ArityRestriction arity_restriction,
    906       LanguageMode language_mode, bool* ok);
    907 
    908   PreParserExpression ParseClassLiteral(PreParserIdentifier name,
    909                                         Scanner::Location class_name_location,
    910                                         bool name_is_strict_reserved, int pos,
    911                                         bool* ok);
    912 
    913   PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) {
    914     return list;
    915   }
    916 
    917   inline void MaterializeUnspreadArgumentsLiterals(int count);
    918 
    919   inline PreParserExpression SpreadCall(PreParserExpression function,
    920                                         PreParserExpressionList args, int pos);
    921 
    922   inline PreParserExpression SpreadCallNew(PreParserExpression function,
    923                                            PreParserExpressionList args,
    924                                            int pos);
    925 
    926   inline void RewriteDestructuringAssignments() {}
    927 
    928   inline void QueueDestructuringAssignmentForRewriting(PreParserExpression) {}
    929 
    930   void SetFunctionNameFromPropertyName(PreParserExpression,
    931                                        PreParserIdentifier) {}
    932   void SetFunctionNameFromIdentifierRef(PreParserExpression,
    933                                         PreParserExpression) {}
    934 
    935   inline PreParserExpression RewriteNonPattern(
    936       PreParserExpression expr, const ExpressionClassifier* classifier,
    937       bool* ok);
    938   inline PreParserExpression RewriteNonPatternArguments(
    939       PreParserExpression args, const ExpressionClassifier* classifier,
    940       bool* ok);
    941   inline PreParserExpression RewriteNonPatternObjectLiteralProperty(
    942       PreParserExpression property, const ExpressionClassifier* classifier,
    943       bool* ok);
    944 
    945  private:
    946   PreParser* pre_parser_;
    947 };
    948 
    949 
    950 // Preparsing checks a JavaScript program and emits preparse-data that helps
    951 // a later parsing to be faster.
    952 // See preparse-data-format.h for the data format.
    953 
    954 // The PreParser checks that the syntax follows the grammar for JavaScript,
    955 // and collects some information about the program along the way.
    956 // The grammar check is only performed in order to understand the program
    957 // sufficiently to deduce some information about it, that can be used
    958 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
    959 // rather it is to speed up properly written and correct programs.
    960 // That means that contextual checks (like a label being declared where
    961 // it is used) are generally omitted.
    962 class PreParser : public ParserBase<PreParserTraits> {
    963  public:
    964   typedef PreParserIdentifier Identifier;
    965   typedef PreParserExpression Expression;
    966   typedef PreParserStatement Statement;
    967 
    968   enum PreParseResult {
    969     kPreParseStackOverflow,
    970     kPreParseSuccess
    971   };
    972 
    973   PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
    974             ParserRecorder* log, uintptr_t stack_limit)
    975       : ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL,
    976                                     ast_value_factory, log, this) {}
    977 
    978   // Pre-parse the program from the character stream; returns true on
    979   // success (even if parsing failed, the pre-parse data successfully
    980   // captured the syntax error), and false if a stack-overflow happened
    981   // during parsing.
    982   PreParseResult PreParseProgram(int* materialized_literals = 0) {
    983     Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
    984     PreParserFactory factory(NULL);
    985     FunctionState top_scope(&function_state_, &scope_, scope, kNormalFunction,
    986                             &factory);
    987     bool ok = true;
    988     int start_position = scanner()->peek_location().beg_pos;
    989     ParseStatementList(Token::EOS, &ok);
    990     if (stack_overflow()) return kPreParseStackOverflow;
    991     if (!ok) {
    992       ReportUnexpectedToken(scanner()->current_token());
    993     } else if (is_strict(scope_->language_mode())) {
    994       CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
    995                               &ok);
    996     }
    997     if (materialized_literals) {
    998       *materialized_literals = function_state_->materialized_literal_count();
    999     }
   1000     return kPreParseSuccess;
   1001   }
   1002 
   1003   // Parses a single function literal, from the opening parentheses before
   1004   // parameters to the closing brace after the body.
   1005   // Returns a FunctionEntry describing the body of the function in enough
   1006   // detail that it can be lazily compiled.
   1007   // The scanner is expected to have matched the "function" or "function*"
   1008   // keyword and parameters, and have consumed the initial '{'.
   1009   // At return, unless an error occurred, the scanner is positioned before the
   1010   // the final '}'.
   1011   PreParseResult PreParseLazyFunction(
   1012       LanguageMode language_mode, FunctionKind kind, bool has_simple_parameters,
   1013       ParserRecorder* log, Scanner::BookmarkScope* bookmark = nullptr);
   1014 
   1015  private:
   1016   friend class PreParserTraits;
   1017 
   1018   static const int kLazyParseTrialLimit = 200;
   1019 
   1020   // These types form an algebra over syntactic categories that is just
   1021   // rich enough to let us recognize and propagate the constructs that
   1022   // are either being counted in the preparser data, or is important
   1023   // to throw the correct syntax error exceptions.
   1024 
   1025   // All ParseXXX functions take as the last argument an *ok parameter
   1026   // which is set to false if parsing failed; it is unchanged otherwise.
   1027   // By making the 'exception handling' explicit, we are forced to check
   1028   // for failure at the call sites.
   1029   Statement ParseStatementListItem(bool* ok);
   1030   void ParseStatementList(int end_token, bool* ok,
   1031                           Scanner::BookmarkScope* bookmark = nullptr);
   1032   Statement ParseStatement(bool* ok);
   1033   Statement ParseSubStatement(bool* ok);
   1034   Statement ParseFunctionDeclaration(bool* ok);
   1035   Statement ParseClassDeclaration(bool* ok);
   1036   Statement ParseBlock(bool* ok);
   1037   Statement ParseVariableStatement(VariableDeclarationContext var_context,
   1038                                    bool* ok);
   1039   Statement ParseVariableDeclarations(VariableDeclarationContext var_context,
   1040                                       int* num_decl, bool* is_lexical,
   1041                                       bool* is_binding_pattern,
   1042                                       Scanner::Location* first_initializer_loc,
   1043                                       Scanner::Location* bindings_loc,
   1044                                       bool* ok);
   1045   Statement ParseExpressionOrLabelledStatement(bool* ok);
   1046   Statement ParseIfStatement(bool* ok);
   1047   Statement ParseContinueStatement(bool* ok);
   1048   Statement ParseBreakStatement(bool* ok);
   1049   Statement ParseReturnStatement(bool* ok);
   1050   Statement ParseWithStatement(bool* ok);
   1051   Statement ParseSwitchStatement(bool* ok);
   1052   Statement ParseDoWhileStatement(bool* ok);
   1053   Statement ParseWhileStatement(bool* ok);
   1054   Statement ParseForStatement(bool* ok);
   1055   Statement ParseThrowStatement(bool* ok);
   1056   Statement ParseTryStatement(bool* ok);
   1057   Statement ParseDebuggerStatement(bool* ok);
   1058   Expression ParseConditionalExpression(bool accept_IN, bool* ok);
   1059   Expression ParseObjectLiteral(bool* ok);
   1060   Expression ParseV8Intrinsic(bool* ok);
   1061   Expression ParseDoExpression(bool* ok);
   1062 
   1063   V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
   1064                                       int* expected_property_count, bool* ok);
   1065   V8_INLINE PreParserStatementList ParseEagerFunctionBody(
   1066       PreParserIdentifier function_name, int pos,
   1067       const PreParserFormalParameters& parameters, FunctionKind kind,
   1068       FunctionLiteral::FunctionType function_type, bool* ok);
   1069 
   1070   Expression ParseFunctionLiteral(
   1071       Identifier name, Scanner::Location function_name_location,
   1072       FunctionNameValidity function_name_validity, FunctionKind kind,
   1073       int function_token_pos, FunctionLiteral::FunctionType function_type,
   1074       FunctionLiteral::ArityRestriction arity_restriction,
   1075       LanguageMode language_mode, bool* ok);
   1076   void ParseLazyFunctionLiteralBody(bool* ok,
   1077                                     Scanner::BookmarkScope* bookmark = nullptr);
   1078 
   1079   PreParserExpression ParseClassLiteral(PreParserIdentifier name,
   1080                                         Scanner::Location class_name_location,
   1081                                         bool name_is_strict_reserved, int pos,
   1082                                         bool* ok);
   1083 };
   1084 
   1085 
   1086 void PreParserTraits::MaterializeTemplateCallsiteLiterals() {
   1087   pre_parser_->function_state_->NextMaterializedLiteralIndex();
   1088   pre_parser_->function_state_->NextMaterializedLiteralIndex();
   1089 }
   1090 
   1091 
   1092 void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) {
   1093   for (int i = 0; i < count; ++i) {
   1094     pre_parser_->function_state_->NextMaterializedLiteralIndex();
   1095   }
   1096 }
   1097 
   1098 
   1099 PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function,
   1100                                                 PreParserExpressionList args,
   1101                                                 int pos) {
   1102   return pre_parser_->factory()->NewCall(function, args, pos);
   1103 }
   1104 
   1105 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
   1106                                                    PreParserExpressionList args,
   1107                                                    int pos) {
   1108   return pre_parser_->factory()->NewCallNew(function, args, pos);
   1109 }
   1110 
   1111 
   1112 void PreParserTraits::ParseArrowFunctionFormalParameterList(
   1113     PreParserFormalParameters* parameters,
   1114     PreParserExpression params, const Scanner::Location& params_loc,
   1115     Scanner::Location* duplicate_loc, bool* ok) {
   1116   // TODO(wingo): Detect duplicated identifiers in paramlists.  Detect parameter
   1117   // lists that are too long.
   1118 }
   1119 
   1120 
   1121 PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) {
   1122   return pre_parser_->ParseDoExpression(ok);
   1123 }
   1124 
   1125 
   1126 PreParserExpression PreParserTraits::RewriteNonPattern(
   1127     PreParserExpression expr, const ExpressionClassifier* classifier,
   1128     bool* ok) {
   1129   pre_parser_->ValidateExpression(classifier, ok);
   1130   return expr;
   1131 }
   1132 
   1133 
   1134 PreParserExpression PreParserTraits::RewriteNonPatternArguments(
   1135     PreParserExpression args, const ExpressionClassifier* classifier,
   1136     bool* ok) {
   1137   pre_parser_->ValidateExpression(classifier, ok);
   1138   return args;
   1139 }
   1140 
   1141 
   1142 PreParserExpression PreParserTraits::RewriteNonPatternObjectLiteralProperty(
   1143     PreParserExpression property, const ExpressionClassifier* classifier,
   1144     bool* ok) {
   1145   pre_parser_->ValidateExpression(classifier, ok);
   1146   return property;
   1147 }
   1148 
   1149 
   1150 PreParserStatementList PreParser::ParseEagerFunctionBody(
   1151     PreParserIdentifier function_name, int pos,
   1152     const PreParserFormalParameters& parameters, FunctionKind kind,
   1153     FunctionLiteral::FunctionType function_type, bool* ok) {
   1154   ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
   1155 
   1156   ParseStatementList(Token::RBRACE, ok);
   1157   if (!*ok) return PreParserStatementList();
   1158 
   1159   Expect(Token::RBRACE, ok);
   1160   return PreParserStatementList();
   1161 }
   1162 
   1163 
   1164 PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
   1165     PreParserIdentifier function_name, int pos,
   1166     const PreParserFormalParameters& parameters, FunctionKind kind,
   1167     FunctionLiteral::FunctionType function_type, bool* ok) {
   1168   return pre_parser_->ParseEagerFunctionBody(function_name, pos, parameters,
   1169                                              kind, function_type, ok);
   1170 }
   1171 
   1172 }  // namespace internal
   1173 }  // namespace v8
   1174 
   1175 #endif  // V8_PARSING_PREPARSER_H
   1176