Home | History | Annotate | Download | only in src
      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_PREPARSER_H
      6 #define V8_PREPARSER_H
      7 
      8 #include "src/v8.h"
      9 
     10 #include "src/bailout-reason.h"
     11 #include "src/func-name-inferrer.h"
     12 #include "src/hashmap.h"
     13 #include "src/scanner.h"
     14 #include "src/scopes.h"
     15 #include "src/token.h"
     16 
     17 namespace v8 {
     18 namespace internal {
     19 
     20 // Common base class shared between parser and pre-parser. Traits encapsulate
     21 // the differences between Parser and PreParser:
     22 
     23 // - Return types: For example, Parser functions return Expression* and
     24 // PreParser functions return PreParserExpression.
     25 
     26 // - Creating parse tree nodes: Parser generates an AST during the recursive
     27 // descent. PreParser doesn't create a tree. Instead, it passes around minimal
     28 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
     29 // just enough data for the upper layer functions. PreParserFactory is
     30 // responsible for creating these dummy objects. It provides a similar kind of
     31 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is
     32 // used.
     33 
     34 // - Miscellaneous other tasks interleaved with the recursive descent. For
     35 // example, Parser keeps track of which function literals should be marked as
     36 // pretenured, and PreParser doesn't care.
     37 
     38 // The traits are expected to contain the following typedefs:
     39 // struct Traits {
     40 //   // In particular...
     41 //   struct Type {
     42 //     // Used by FunctionState and BlockState.
     43 //     typedef Scope;
     44 //     typedef GeneratorVariable;
     45 //     typedef Zone;
     46 //     // Return types for traversing functions.
     47 //     typedef Identifier;
     48 //     typedef Expression;
     49 //     typedef FunctionLiteral;
     50 //     typedef ClassLiteral;
     51 //     typedef ObjectLiteralProperty;
     52 //     typedef Literal;
     53 //     typedef ExpressionList;
     54 //     typedef PropertyList;
     55 //     // For constructing objects returned by the traversing functions.
     56 //     typedef Factory;
     57 //   };
     58 //   // ...
     59 // };
     60 
     61 template <typename Traits>
     62 class ParserBase : public Traits {
     63  public:
     64   // Shorten type names defined by Traits.
     65   typedef typename Traits::Type::Expression ExpressionT;
     66   typedef typename Traits::Type::Identifier IdentifierT;
     67   typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
     68   typedef typename Traits::Type::Literal LiteralT;
     69   typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
     70 
     71   ParserBase(Scanner* scanner, uintptr_t stack_limit, v8::Extension* extension,
     72              ParserRecorder* log, typename Traits::Type::Zone* zone,
     73              AstNode::IdGen* ast_node_id_gen,
     74              typename Traits::Type::Parser this_object)
     75       : Traits(this_object),
     76         parenthesized_function_(false),
     77         scope_(NULL),
     78         function_state_(NULL),
     79         extension_(extension),
     80         fni_(NULL),
     81         log_(log),
     82         mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
     83         stack_limit_(stack_limit),
     84         scanner_(scanner),
     85         stack_overflow_(false),
     86         allow_lazy_(false),
     87         allow_natives_syntax_(false),
     88         allow_arrow_functions_(false),
     89         allow_harmony_object_literals_(false),
     90         zone_(zone),
     91         ast_node_id_gen_(ast_node_id_gen) {}
     92 
     93   // Getters that indicate whether certain syntactical constructs are
     94   // allowed to be parsed by this instance of the parser.
     95   bool allow_lazy() const { return allow_lazy_; }
     96   bool allow_natives_syntax() const { return allow_natives_syntax_; }
     97   bool allow_arrow_functions() const { return allow_arrow_functions_; }
     98   bool allow_modules() const { return scanner()->HarmonyModules(); }
     99   bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
    100   bool allow_harmony_numeric_literals() const {
    101     return scanner()->HarmonyNumericLiterals();
    102   }
    103   bool allow_classes() const { return scanner()->HarmonyClasses(); }
    104   bool allow_harmony_object_literals() const {
    105     return allow_harmony_object_literals_;
    106   }
    107 
    108   // Setters that determine whether certain syntactical constructs are
    109   // allowed to be parsed by this instance of the parser.
    110   void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
    111   void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
    112   void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; }
    113   void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
    114   void set_allow_harmony_scoping(bool allow) {
    115     scanner()->SetHarmonyScoping(allow);
    116   }
    117   void set_allow_harmony_numeric_literals(bool allow) {
    118     scanner()->SetHarmonyNumericLiterals(allow);
    119   }
    120   void set_allow_classes(bool allow) { scanner()->SetHarmonyClasses(allow); }
    121   void set_allow_harmony_object_literals(bool allow) {
    122     allow_harmony_object_literals_ = allow;
    123   }
    124 
    125  protected:
    126   friend class Traits::Checkpoint;
    127 
    128   enum AllowEvalOrArgumentsAsIdentifier {
    129     kAllowEvalOrArguments,
    130     kDontAllowEvalOrArguments
    131   };
    132 
    133   enum Mode {
    134     PARSE_LAZILY,
    135     PARSE_EAGERLY
    136   };
    137 
    138   class CheckpointBase;
    139   class ObjectLiteralChecker;
    140 
    141   // ---------------------------------------------------------------------------
    142   // FunctionState and BlockState together implement the parser's scope stack.
    143   // The parser's current scope is in scope_. BlockState and FunctionState
    144   // constructors push on the scope stack and the destructors pop. They are also
    145   // used to hold the parser's per-function and per-block state.
    146   class BlockState BASE_EMBEDDED {
    147    public:
    148     BlockState(typename Traits::Type::Scope** scope_stack,
    149                typename Traits::Type::Scope* scope)
    150         : scope_stack_(scope_stack),
    151           outer_scope_(*scope_stack),
    152           scope_(scope) {
    153       *scope_stack_ = scope_;
    154     }
    155     ~BlockState() { *scope_stack_ = outer_scope_; }
    156 
    157    private:
    158     typename Traits::Type::Scope** scope_stack_;
    159     typename Traits::Type::Scope* outer_scope_;
    160     typename Traits::Type::Scope* scope_;
    161   };
    162 
    163   class FunctionState BASE_EMBEDDED {
    164    public:
    165     FunctionState(FunctionState** function_state_stack,
    166                   typename Traits::Type::Scope** scope_stack,
    167                   typename Traits::Type::Scope* scope,
    168                   typename Traits::Type::Zone* zone = NULL,
    169                   AstValueFactory* ast_value_factory = NULL,
    170                   AstNode::IdGen* ast_node_id_gen = NULL);
    171     FunctionState(FunctionState** function_state_stack,
    172                   typename Traits::Type::Scope** scope_stack,
    173                   typename Traits::Type::Scope** scope,
    174                   typename Traits::Type::Zone* zone = NULL,
    175                   AstValueFactory* ast_value_factory = NULL,
    176                   AstNode::IdGen* ast_node_id_gen = NULL);
    177     ~FunctionState();
    178 
    179     int NextMaterializedLiteralIndex() {
    180       return next_materialized_literal_index_++;
    181     }
    182     int materialized_literal_count() {
    183       return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize;
    184     }
    185 
    186     int NextHandlerIndex() { return next_handler_index_++; }
    187     int handler_count() { return next_handler_index_; }
    188 
    189     void AddProperty() { expected_property_count_++; }
    190     int expected_property_count() { return expected_property_count_; }
    191 
    192     void set_is_generator(bool is_generator) { is_generator_ = is_generator; }
    193     bool is_generator() const { return is_generator_; }
    194 
    195     void set_generator_object_variable(
    196         typename Traits::Type::GeneratorVariable* variable) {
    197       DCHECK(variable != NULL);
    198       DCHECK(!is_generator());
    199       generator_object_variable_ = variable;
    200       is_generator_ = true;
    201     }
    202     typename Traits::Type::GeneratorVariable* generator_object_variable()
    203         const {
    204       return generator_object_variable_;
    205     }
    206 
    207     typename Traits::Type::Factory* factory() { return &factory_; }
    208 
    209    private:
    210     // Used to assign an index to each literal that needs materialization in
    211     // the function.  Includes regexp literals, and boilerplate for object and
    212     // array literals.
    213     int next_materialized_literal_index_;
    214 
    215     // Used to assign a per-function index to try and catch handlers.
    216     int next_handler_index_;
    217 
    218     // Properties count estimation.
    219     int expected_property_count_;
    220 
    221     // Whether the function is a generator.
    222     bool is_generator_;
    223     // For generators, this variable may hold the generator object. It variable
    224     // is used by yield expressions and return statements. It is not necessary
    225     // for generator functions to have this variable set.
    226     Variable* generator_object_variable_;
    227 
    228     FunctionState** function_state_stack_;
    229     FunctionState* outer_function_state_;
    230     typename Traits::Type::Scope** scope_stack_;
    231     typename Traits::Type::Scope* outer_scope_;
    232     AstNode::IdGen* ast_node_id_gen_;  // Only used by ParserTraits.
    233     AstNode::IdGen saved_id_gen_;      // Ditto.
    234     typename Traits::Type::Zone* extra_param_;
    235     typename Traits::Type::Factory factory_;
    236 
    237     friend class ParserTraits;
    238     friend class CheckpointBase;
    239   };
    240 
    241   // Annoyingly, arrow functions first parse as comma expressions, then when we
    242   // see the => we have to go back and reinterpret the arguments as being formal
    243   // parameters.  To do so we need to reset some of the parser state back to
    244   // what it was before the arguments were first seen.
    245   class CheckpointBase BASE_EMBEDDED {
    246    public:
    247     explicit CheckpointBase(ParserBase* parser) {
    248       function_state_ = parser->function_state_;
    249       next_materialized_literal_index_ =
    250           function_state_->next_materialized_literal_index_;
    251       next_handler_index_ = function_state_->next_handler_index_;
    252       expected_property_count_ = function_state_->expected_property_count_;
    253     }
    254 
    255     void Restore() {
    256       function_state_->next_materialized_literal_index_ =
    257           next_materialized_literal_index_;
    258       function_state_->next_handler_index_ = next_handler_index_;
    259       function_state_->expected_property_count_ = expected_property_count_;
    260     }
    261 
    262    private:
    263     FunctionState* function_state_;
    264     int next_materialized_literal_index_;
    265     int next_handler_index_;
    266     int expected_property_count_;
    267   };
    268 
    269   class ParsingModeScope BASE_EMBEDDED {
    270    public:
    271     ParsingModeScope(ParserBase* parser, Mode mode)
    272         : parser_(parser),
    273           old_mode_(parser->mode()) {
    274       parser_->mode_ = mode;
    275     }
    276     ~ParsingModeScope() {
    277       parser_->mode_ = old_mode_;
    278     }
    279 
    280    private:
    281     ParserBase* parser_;
    282     Mode old_mode_;
    283   };
    284 
    285   Scanner* scanner() const { return scanner_; }
    286   int position() { return scanner_->location().beg_pos; }
    287   int peek_position() { return scanner_->peek_location().beg_pos; }
    288   bool stack_overflow() const { return stack_overflow_; }
    289   void set_stack_overflow() { stack_overflow_ = true; }
    290   Mode mode() const { return mode_; }
    291   typename Traits::Type::Zone* zone() const { return zone_; }
    292   AstNode::IdGen* ast_node_id_gen() const { return ast_node_id_gen_; }
    293 
    294   INLINE(Token::Value peek()) {
    295     if (stack_overflow_) return Token::ILLEGAL;
    296     return scanner()->peek();
    297   }
    298 
    299   INLINE(Token::Value Next()) {
    300     if (stack_overflow_) return Token::ILLEGAL;
    301     {
    302       if (GetCurrentStackPosition() < stack_limit_) {
    303         // Any further calls to Next or peek will return the illegal token.
    304         // The current call must return the next token, which might already
    305         // have been peek'ed.
    306         stack_overflow_ = true;
    307       }
    308     }
    309     return scanner()->Next();
    310   }
    311 
    312   void Consume(Token::Value token) {
    313     Token::Value next = Next();
    314     USE(next);
    315     USE(token);
    316     DCHECK(next == token);
    317   }
    318 
    319   bool Check(Token::Value token) {
    320     Token::Value next = peek();
    321     if (next == token) {
    322       Consume(next);
    323       return true;
    324     }
    325     return false;
    326   }
    327 
    328   void Expect(Token::Value token, bool* ok) {
    329     Token::Value next = Next();
    330     if (next != token) {
    331       ReportUnexpectedToken(next);
    332       *ok = false;
    333     }
    334   }
    335 
    336   void ExpectSemicolon(bool* ok) {
    337     // Check for automatic semicolon insertion according to
    338     // the rules given in ECMA-262, section 7.9, page 21.
    339     Token::Value tok = peek();
    340     if (tok == Token::SEMICOLON) {
    341       Next();
    342       return;
    343     }
    344     if (scanner()->HasAnyLineTerminatorBeforeNext() ||
    345         tok == Token::RBRACE ||
    346         tok == Token::EOS) {
    347       return;
    348     }
    349     Expect(Token::SEMICOLON, ok);
    350   }
    351 
    352   bool peek_any_identifier() {
    353     Token::Value next = peek();
    354     return next == Token::IDENTIFIER ||
    355         next == Token::FUTURE_RESERVED_WORD ||
    356         next == Token::FUTURE_STRICT_RESERVED_WORD ||
    357         next == Token::LET ||
    358         next == Token::YIELD;
    359   }
    360 
    361   bool CheckContextualKeyword(Vector<const char> keyword) {
    362     if (peek() == Token::IDENTIFIER &&
    363         scanner()->is_next_contextual_keyword(keyword)) {
    364       Consume(Token::IDENTIFIER);
    365       return true;
    366     }
    367     return false;
    368   }
    369 
    370   void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
    371     Expect(Token::IDENTIFIER, ok);
    372     if (!*ok) return;
    373     if (!scanner()->is_literal_contextual_keyword(keyword)) {
    374       ReportUnexpectedToken(scanner()->current_token());
    375       *ok = false;
    376     }
    377   }
    378 
    379   // Checks whether an octal literal was last seen between beg_pos and end_pos.
    380   // If so, reports an error. Only called for strict mode.
    381   void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
    382     Scanner::Location octal = scanner()->octal_position();
    383     if (octal.IsValid() && beg_pos <= octal.beg_pos &&
    384         octal.end_pos <= end_pos) {
    385       ReportMessageAt(octal, "strict_octal_literal");
    386       scanner()->clear_octal_position();
    387       *ok = false;
    388     }
    389   }
    390 
    391   // Validates strict mode for function parameter lists. This has to be
    392   // done after parsing the function, since the function can declare
    393   // itself strict.
    394   void CheckStrictFunctionNameAndParameters(
    395       IdentifierT function_name,
    396       bool function_name_is_strict_reserved,
    397       const Scanner::Location& function_name_loc,
    398       const Scanner::Location& eval_args_error_loc,
    399       const Scanner::Location& dupe_error_loc,
    400       const Scanner::Location& reserved_loc,
    401       bool* ok) {
    402     if (this->IsEvalOrArguments(function_name)) {
    403       Traits::ReportMessageAt(function_name_loc, "strict_eval_arguments");
    404       *ok = false;
    405       return;
    406     }
    407     if (function_name_is_strict_reserved) {
    408       Traits::ReportMessageAt(function_name_loc, "unexpected_strict_reserved");
    409       *ok = false;
    410       return;
    411     }
    412     if (eval_args_error_loc.IsValid()) {
    413       Traits::ReportMessageAt(eval_args_error_loc, "strict_eval_arguments");
    414       *ok = false;
    415       return;
    416     }
    417     if (dupe_error_loc.IsValid()) {
    418       Traits::ReportMessageAt(dupe_error_loc, "strict_param_dupe");
    419       *ok = false;
    420       return;
    421     }
    422     if (reserved_loc.IsValid()) {
    423       Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved");
    424       *ok = false;
    425       return;
    426     }
    427   }
    428 
    429   // Determine precedence of given token.
    430   static int Precedence(Token::Value token, bool accept_IN) {
    431     if (token == Token::IN && !accept_IN)
    432       return 0;  // 0 precedence will terminate binary expression parsing
    433     return Token::Precedence(token);
    434   }
    435 
    436   typename Traits::Type::Factory* factory() {
    437     return function_state_->factory();
    438   }
    439 
    440   StrictMode strict_mode() { return scope_->strict_mode(); }
    441   bool is_generator() const { return function_state_->is_generator(); }
    442 
    443   // Report syntax errors.
    444   void ReportMessage(const char* message, const char* arg = NULL,
    445                      bool is_reference_error = false) {
    446     Scanner::Location source_location = scanner()->location();
    447     Traits::ReportMessageAt(source_location, message, arg, is_reference_error);
    448   }
    449 
    450   void ReportMessageAt(Scanner::Location location, const char* message,
    451                        bool is_reference_error = false) {
    452     Traits::ReportMessageAt(location, message,
    453                             reinterpret_cast<const char*>(NULL),
    454                             is_reference_error);
    455   }
    456 
    457   void ReportUnexpectedToken(Token::Value token);
    458 
    459   // Recursive descent functions:
    460 
    461   // Parses an identifier that is valid for the current scope, in particular it
    462   // fails on strict mode future reserved keywords in a strict scope. If
    463   // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
    464   // "arguments" as identifier even in strict mode (this is needed in cases like
    465   // "var foo = eval;").
    466   IdentifierT ParseIdentifier(
    467       AllowEvalOrArgumentsAsIdentifier,
    468       bool* ok);
    469   // Parses an identifier or a strict mode future reserved word, and indicate
    470   // whether it is strict mode future reserved.
    471   IdentifierT ParseIdentifierOrStrictReservedWord(
    472       bool* is_strict_reserved,
    473       bool* ok);
    474   IdentifierT ParseIdentifierName(bool* ok);
    475   // Parses an identifier and determines whether or not it is 'get' or 'set'.
    476   IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get,
    477                                             bool* is_set,
    478                                             bool* ok);
    479 
    480   ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok);
    481 
    482   ExpressionT ParsePrimaryExpression(bool* ok);
    483   ExpressionT ParseExpression(bool accept_IN, bool* ok);
    484   ExpressionT ParseArrayLiteral(bool* ok);
    485   IdentifierT ParsePropertyName(bool* is_get, bool* is_set, bool* is_static,
    486                                 bool* ok);
    487   ExpressionT ParseObjectLiteral(bool* ok);
    488   ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker,
    489                                                  bool in_class, bool is_static,
    490                                                  bool* ok);
    491   typename Traits::Type::ExpressionList ParseArguments(bool* ok);
    492   ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
    493   ExpressionT ParseYieldExpression(bool* ok);
    494   ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
    495   ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
    496   ExpressionT ParseUnaryExpression(bool* ok);
    497   ExpressionT ParsePostfixExpression(bool* ok);
    498   ExpressionT ParseLeftHandSideExpression(bool* ok);
    499   ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
    500   ExpressionT ParseMemberExpression(bool* ok);
    501   ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
    502                                                 bool* ok);
    503   ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
    504                                         bool* ok);
    505   ExpressionT ParseClassLiteral(IdentifierT name,
    506                                 Scanner::Location function_name_location,
    507                                 bool name_is_strict_reserved, int pos,
    508                                 bool* ok);
    509 
    510   // Checks if the expression is a valid reference expression (e.g., on the
    511   // left-hand side of assignments). Although ruled out by ECMA as early errors,
    512   // we allow calls for web compatibility and rewrite them to a runtime throw.
    513   ExpressionT CheckAndRewriteReferenceExpression(
    514       ExpressionT expression,
    515       Scanner::Location location, const char* message, bool* ok);
    516 
    517   // Used to detect duplicates in object literals. Each of the values
    518   // kGetterProperty, kSetterProperty and kValueProperty represents
    519   // a type of object literal property. When parsing a property, its
    520   // type value is stored in the DuplicateFinder for the property name.
    521   // Values are chosen so that having intersection bits means the there is
    522   // an incompatibility.
    523   // I.e., you can add a getter to a property that already has a setter, since
    524   // kGetterProperty and kSetterProperty doesn't intersect, but not if it
    525   // already has a getter or a value. Adding the getter to an existing
    526   // setter will store the value (kGetterProperty | kSetterProperty), which
    527   // is incompatible with adding any further properties.
    528   enum PropertyKind {
    529     kNone = 0,
    530     // Bit patterns representing different object literal property types.
    531     kGetterProperty = 1,
    532     kSetterProperty = 2,
    533     kValueProperty = 7,
    534     // Helper constants.
    535     kValueFlag = 4
    536   };
    537 
    538   // Validation per ECMA 262 - 11.1.5 "Object Initializer".
    539   class ObjectLiteralChecker {
    540    public:
    541     ObjectLiteralChecker(ParserBase* parser, StrictMode strict_mode)
    542         : parser_(parser),
    543           finder_(scanner()->unicode_cache()),
    544           strict_mode_(strict_mode) {}
    545 
    546     void CheckProperty(Token::Value property, PropertyKind type, bool* ok);
    547 
    548    private:
    549     ParserBase* parser() const { return parser_; }
    550     Scanner* scanner() const { return parser_->scanner(); }
    551 
    552     // Checks the type of conflict based on values coming from PropertyType.
    553     bool HasConflict(PropertyKind type1, PropertyKind type2) {
    554       return (type1 & type2) != 0;
    555     }
    556     bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) {
    557       return ((type1 & type2) & kValueFlag) != 0;
    558     }
    559     bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) {
    560       return ((type1 ^ type2) & kValueFlag) != 0;
    561     }
    562     bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) {
    563       return ((type1 | type2) & kValueFlag) == 0;
    564     }
    565 
    566     ParserBase* parser_;
    567     DuplicateFinder finder_;
    568     StrictMode strict_mode_;
    569   };
    570 
    571   // If true, the next (and immediately following) function literal is
    572   // preceded by a parenthesis.
    573   // Heuristically that means that the function will be called immediately,
    574   // so never lazily compile it.
    575   bool parenthesized_function_;
    576 
    577   typename Traits::Type::Scope* scope_;  // Scope stack.
    578   FunctionState* function_state_;  // Function state stack.
    579   v8::Extension* extension_;
    580   FuncNameInferrer* fni_;
    581   ParserRecorder* log_;
    582   Mode mode_;
    583   uintptr_t stack_limit_;
    584 
    585  private:
    586   Scanner* scanner_;
    587   bool stack_overflow_;
    588 
    589   bool allow_lazy_;
    590   bool allow_natives_syntax_;
    591   bool allow_arrow_functions_;
    592   bool allow_harmony_object_literals_;
    593 
    594   typename Traits::Type::Zone* zone_;  // Only used by Parser.
    595   AstNode::IdGen* ast_node_id_gen_;
    596 };
    597 
    598 
    599 class PreParserIdentifier {
    600  public:
    601   PreParserIdentifier() : type_(kUnknownIdentifier) {}
    602   static PreParserIdentifier Default() {
    603     return PreParserIdentifier(kUnknownIdentifier);
    604   }
    605   static PreParserIdentifier Eval() {
    606     return PreParserIdentifier(kEvalIdentifier);
    607   }
    608   static PreParserIdentifier Arguments() {
    609     return PreParserIdentifier(kArgumentsIdentifier);
    610   }
    611   static PreParserIdentifier FutureReserved() {
    612     return PreParserIdentifier(kFutureReservedIdentifier);
    613   }
    614   static PreParserIdentifier FutureStrictReserved() {
    615     return PreParserIdentifier(kFutureStrictReservedIdentifier);
    616   }
    617   static PreParserIdentifier Let() {
    618     return PreParserIdentifier(kLetIdentifier);
    619   }
    620   static PreParserIdentifier Yield() {
    621     return PreParserIdentifier(kYieldIdentifier);
    622   }
    623   static PreParserIdentifier Prototype() {
    624     return PreParserIdentifier(kPrototypeIdentifier);
    625   }
    626   static PreParserIdentifier Constructor() {
    627     return PreParserIdentifier(kConstructorIdentifier);
    628   }
    629   bool IsEval() const { return type_ == kEvalIdentifier; }
    630   bool IsArguments() const { return type_ == kArgumentsIdentifier; }
    631   bool IsYield() const { return type_ == kYieldIdentifier; }
    632   bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
    633   bool IsConstructor() const { return type_ == kConstructorIdentifier; }
    634   bool IsEvalOrArguments() const {
    635     return type_ == kEvalIdentifier || type_ == kArgumentsIdentifier;
    636   }
    637   bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
    638   bool IsFutureStrictReserved() const {
    639     return type_ == kFutureStrictReservedIdentifier;
    640   }
    641   bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; }
    642 
    643   // Allow identifier->name()[->length()] to work. The preparser
    644   // does not need the actual positions/lengths of the identifiers.
    645   const PreParserIdentifier* operator->() const { return this; }
    646   const PreParserIdentifier raw_name() const { return *this; }
    647 
    648   int position() const { return 0; }
    649   int length() const { return 0; }
    650 
    651  private:
    652   enum Type {
    653     kUnknownIdentifier,
    654     kFutureReservedIdentifier,
    655     kFutureStrictReservedIdentifier,
    656     kLetIdentifier,
    657     kYieldIdentifier,
    658     kEvalIdentifier,
    659     kArgumentsIdentifier,
    660     kPrototypeIdentifier,
    661     kConstructorIdentifier
    662   };
    663   explicit PreParserIdentifier(Type type) : type_(type) {}
    664   Type type_;
    665 
    666   friend class PreParserExpression;
    667   friend class PreParserScope;
    668 };
    669 
    670 
    671 // Bits 0 and 1 are used to identify the type of expression:
    672 // If bit 0 is set, it's an identifier.
    673 // if bit 1 is set, it's a string literal.
    674 // If neither is set, it's no particular type, and both set isn't
    675 // use yet.
    676 class PreParserExpression {
    677  public:
    678   static PreParserExpression Default() {
    679     return PreParserExpression(kUnknownExpression);
    680   }
    681 
    682   static PreParserExpression FromIdentifier(PreParserIdentifier id) {
    683     return PreParserExpression(kTypeIdentifier |
    684                                (id.type_ << kIdentifierShift));
    685   }
    686 
    687   static PreParserExpression BinaryOperation(PreParserExpression left,
    688                                              Token::Value op,
    689                                              PreParserExpression right) {
    690     int code = ((op == Token::COMMA) && !left.is_parenthesized() &&
    691                 !right.is_parenthesized())
    692                    ? left.ArrowParamListBit() & right.ArrowParamListBit()
    693                    : 0;
    694     return PreParserExpression(kTypeBinaryOperation | code);
    695   }
    696 
    697   static PreParserExpression EmptyArrowParamList() {
    698     // Any expression for which IsValidArrowParamList() returns true
    699     // will work here.
    700     return FromIdentifier(PreParserIdentifier::Default());
    701   }
    702 
    703   static PreParserExpression StringLiteral() {
    704     return PreParserExpression(kUnknownStringLiteral);
    705   }
    706 
    707   static PreParserExpression UseStrictStringLiteral() {
    708     return PreParserExpression(kUseStrictString);
    709   }
    710 
    711   static PreParserExpression This() {
    712     return PreParserExpression(kThisExpression);
    713   }
    714 
    715   static PreParserExpression Super() {
    716     return PreParserExpression(kSuperExpression);
    717   }
    718 
    719   static PreParserExpression ThisProperty() {
    720     return PreParserExpression(kThisPropertyExpression);
    721   }
    722 
    723   static PreParserExpression Property() {
    724     return PreParserExpression(kPropertyExpression);
    725   }
    726 
    727   static PreParserExpression Call() {
    728     return PreParserExpression(kCallExpression);
    729   }
    730 
    731   bool IsIdentifier() const { return (code_ & kTypeMask) == kTypeIdentifier; }
    732 
    733   PreParserIdentifier AsIdentifier() const {
    734     DCHECK(IsIdentifier());
    735     return PreParserIdentifier(
    736         static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift));
    737   }
    738 
    739   bool IsStringLiteral() const {
    740     return (code_ & kTypeMask) == kTypeStringLiteral;
    741   }
    742 
    743   bool IsUseStrictLiteral() const {
    744     return (code_ & kUseStrictString) == kUseStrictString;
    745   }
    746 
    747   bool IsThis() const { return (code_ & kThisExpression) == kThisExpression; }
    748 
    749   bool IsThisProperty() const {
    750     return (code_ & kThisPropertyExpression) == kThisPropertyExpression;
    751   }
    752 
    753   bool IsProperty() const {
    754     return (code_ & kPropertyExpression) == kPropertyExpression ||
    755            (code_ & kThisPropertyExpression) == kThisPropertyExpression;
    756   }
    757 
    758   bool IsCall() const { return (code_ & kCallExpression) == kCallExpression; }
    759 
    760   bool IsValidReferenceExpression() const {
    761     return IsIdentifier() || IsProperty();
    762   }
    763 
    764   bool IsValidArrowParamList() const {
    765     return (ArrowParamListBit() & kBinaryOperationArrowParamList) != 0 &&
    766            (code_ & kMultiParenthesizedExpression) == 0;
    767   }
    768 
    769   // At the moment PreParser doesn't track these expression types.
    770   bool IsFunctionLiteral() const { return false; }
    771   bool IsCallNew() const { return false; }
    772 
    773   PreParserExpression AsFunctionLiteral() { return *this; }
    774 
    775   bool IsBinaryOperation() const {
    776     return (code_ & kTypeMask) == kTypeBinaryOperation;
    777   }
    778 
    779   bool is_parenthesized() const {
    780     return (code_ & kParenthesizedExpression) != 0;
    781   }
    782 
    783   void increase_parenthesization_level() {
    784     code_ |= is_parenthesized() ? kMultiParenthesizedExpression
    785                                 : kParenthesizedExpression;
    786   }
    787 
    788   // Dummy implementation for making expression->somefunc() work in both Parser
    789   // and PreParser.
    790   PreParserExpression* operator->() { return this; }
    791 
    792   // More dummy implementations of things PreParser doesn't need to track:
    793   void set_index(int index) {}  // For YieldExpressions
    794   void set_parenthesized() {}
    795 
    796   int position() const { return RelocInfo::kNoPosition; }
    797   void set_function_token_position(int position) {}
    798   void set_ast_properties(int* ast_properties) {}
    799   void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {}
    800 
    801   bool operator==(const PreParserExpression& other) const {
    802     return code_ == other.code_;
    803   }
    804   bool operator!=(const PreParserExpression& other) const {
    805     return code_ != other.code_;
    806   }
    807 
    808  private:
    809   // Least significant 2 bits are used as expression type. The third least
    810   // significant bit tracks whether an expression is parenthesized. If the
    811   // expression is an identifier or a string literal, the other bits
    812   // describe the type/ (see PreParserIdentifier::Type and string literal
    813   // constants below). For binary operations, the other bits are flags
    814   // which further describe the contents of the expression.
    815   enum {
    816     kUnknownExpression = 0,
    817     kTypeMask = 1 | 2,
    818     kParenthesizedExpression = (1 << 2),
    819     kMultiParenthesizedExpression = (1 << 3),
    820 
    821     // Identifiers
    822     kTypeIdentifier = 1,  // Used to detect labels.
    823     kIdentifierShift = 5,
    824     kTypeStringLiteral = 2,  // Used to detect directive prologue.
    825     kUnknownStringLiteral = kTypeStringLiteral,
    826     kUseStrictString = kTypeStringLiteral | 32,
    827     kStringLiteralMask = kUseStrictString,
    828 
    829     // Binary operations. Those are needed to detect certain keywords and
    830     // duplicated identifier in parameter lists for arrow functions, because
    831     // they are initially parsed as comma-separated expressions.
    832     kTypeBinaryOperation = 3,
    833     kBinaryOperationArrowParamList = (1 << 4),
    834 
    835     // Below here applies if neither identifier nor string literal. Reserve the
    836     // 2 least significant bits for flags.
    837     kThisExpression = (1 << 4),
    838     kThisPropertyExpression = (2 << 4),
    839     kPropertyExpression = (3 << 4),
    840     kCallExpression = (4 << 4),
    841     kSuperExpression = (5 << 4)
    842   };
    843 
    844   explicit PreParserExpression(int expression_code) : code_(expression_code) {}
    845 
    846   V8_INLINE int ArrowParamListBit() const {
    847     if (IsBinaryOperation()) return code_ & kBinaryOperationArrowParamList;
    848     if (IsIdentifier()) {
    849       const PreParserIdentifier ident = AsIdentifier();
    850       // A valid identifier can be an arrow function parameter list
    851       // except for eval, arguments, yield, and reserved keywords.
    852       if (ident.IsEval() || ident.IsArguments() || ident.IsYield() ||
    853           ident.IsFutureStrictReserved())
    854         return 0;
    855       return kBinaryOperationArrowParamList;
    856     }
    857     return 0;
    858   }
    859 
    860   int code_;
    861 };
    862 
    863 
    864 // PreParserExpressionList doesn't actually store the expressions because
    865 // PreParser doesn't need to.
    866 class PreParserExpressionList {
    867  public:
    868   // These functions make list->Add(some_expression) work (and do nothing).
    869   PreParserExpressionList() : length_(0) {}
    870   PreParserExpressionList* operator->() { return this; }
    871   void Add(PreParserExpression, void*) { ++length_; }
    872   int length() const { return length_; }
    873  private:
    874   int length_;
    875 };
    876 
    877 
    878 class PreParserStatement {
    879  public:
    880   static PreParserStatement Default() {
    881     return PreParserStatement(kUnknownStatement);
    882   }
    883 
    884   static PreParserStatement FunctionDeclaration() {
    885     return PreParserStatement(kFunctionDeclaration);
    886   }
    887 
    888   // Creates expression statement from expression.
    889   // Preserves being an unparenthesized string literal, possibly
    890   // "use strict".
    891   static PreParserStatement ExpressionStatement(
    892       PreParserExpression expression) {
    893     if (expression.IsUseStrictLiteral()) {
    894       return PreParserStatement(kUseStrictExpressionStatement);
    895     }
    896     if (expression.IsStringLiteral()) {
    897       return PreParserStatement(kStringLiteralExpressionStatement);
    898     }
    899     return Default();
    900   }
    901 
    902   bool IsStringLiteral() {
    903     return code_ == kStringLiteralExpressionStatement;
    904   }
    905 
    906   bool IsUseStrictLiteral() {
    907     return code_ == kUseStrictExpressionStatement;
    908   }
    909 
    910   bool IsFunctionDeclaration() {
    911     return code_ == kFunctionDeclaration;
    912   }
    913 
    914  private:
    915   enum Type {
    916     kUnknownStatement,
    917     kStringLiteralExpressionStatement,
    918     kUseStrictExpressionStatement,
    919     kFunctionDeclaration
    920   };
    921 
    922   explicit PreParserStatement(Type code) : code_(code) {}
    923   Type code_;
    924 };
    925 
    926 
    927 
    928 // PreParserStatementList doesn't actually store the statements because
    929 // the PreParser does not need them.
    930 class PreParserStatementList {
    931  public:
    932   // These functions make list->Add(some_expression) work as no-ops.
    933   PreParserStatementList() {}
    934   PreParserStatementList* operator->() { return this; }
    935   void Add(PreParserStatement, void*) {}
    936 };
    937 
    938 
    939 class PreParserScope {
    940  public:
    941   explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type,
    942                           void* = NULL)
    943       : scope_type_(scope_type) {
    944     strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY;
    945   }
    946 
    947   ScopeType type() { return scope_type_; }
    948   StrictMode strict_mode() const { return strict_mode_; }
    949   void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
    950   void SetScopeName(PreParserIdentifier name) {}
    951 
    952   // When PreParser is in use, lazy compilation is already being done,
    953   // things cannot get lazier than that.
    954   bool AllowsLazyCompilation() const { return false; }
    955 
    956   void set_start_position(int position) {}
    957   void set_end_position(int position) {}
    958 
    959   bool IsDeclared(const PreParserIdentifier& identifier) const { return false; }
    960   void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) {}
    961 
    962   // Allow scope->Foo() to work.
    963   PreParserScope* operator->() { return this; }
    964 
    965  private:
    966   ScopeType scope_type_;
    967   StrictMode strict_mode_;
    968 };
    969 
    970 
    971 class PreParserFactory {
    972  public:
    973   PreParserFactory(void*, void*, void*) {}
    974   PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
    975                                        int pos) {
    976     return PreParserExpression::Default();
    977   }
    978   PreParserExpression NewNumberLiteral(double number,
    979                                        int pos) {
    980     return PreParserExpression::Default();
    981   }
    982   PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
    983                                        PreParserIdentifier js_flags,
    984                                        int literal_index,
    985                                        int pos) {
    986     return PreParserExpression::Default();
    987   }
    988   PreParserExpression NewArrayLiteral(PreParserExpressionList values,
    989                                       int literal_index,
    990                                       int pos) {
    991     return PreParserExpression::Default();
    992   }
    993   PreParserExpression NewObjectLiteralProperty(bool is_getter,
    994                                                PreParserExpression value,
    995                                                int pos, bool is_static) {
    996     return PreParserExpression::Default();
    997   }
    998   PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
    999                                                PreParserExpression value,
   1000                                                bool is_static) {
   1001     return PreParserExpression::Default();
   1002   }
   1003   PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
   1004                                        int literal_index,
   1005                                        int boilerplate_properties,
   1006                                        bool has_function,
   1007                                        int pos) {
   1008     return PreParserExpression::Default();
   1009   }
   1010   PreParserExpression NewVariableProxy(void* variable) {
   1011     return PreParserExpression::Default();
   1012   }
   1013   PreParserExpression NewProperty(PreParserExpression obj,
   1014                                   PreParserExpression key,
   1015                                   int pos) {
   1016     if (obj.IsThis()) {
   1017       return PreParserExpression::ThisProperty();
   1018     }
   1019     return PreParserExpression::Property();
   1020   }
   1021   PreParserExpression NewUnaryOperation(Token::Value op,
   1022                                         PreParserExpression expression,
   1023                                         int pos) {
   1024     return PreParserExpression::Default();
   1025   }
   1026   PreParserExpression NewBinaryOperation(Token::Value op,
   1027                                          PreParserExpression left,
   1028                                          PreParserExpression right, int pos) {
   1029     return PreParserExpression::BinaryOperation(left, op, right);
   1030   }
   1031   PreParserExpression NewCompareOperation(Token::Value op,
   1032                                           PreParserExpression left,
   1033                                           PreParserExpression right, int pos) {
   1034     return PreParserExpression::Default();
   1035   }
   1036   PreParserExpression NewAssignment(Token::Value op,
   1037                                     PreParserExpression left,
   1038                                     PreParserExpression right,
   1039                                     int pos) {
   1040     return PreParserExpression::Default();
   1041   }
   1042   PreParserExpression NewYield(PreParserExpression generator_object,
   1043                                PreParserExpression expression,
   1044                                Yield::Kind yield_kind,
   1045                                int pos) {
   1046     return PreParserExpression::Default();
   1047   }
   1048   PreParserExpression NewConditional(PreParserExpression condition,
   1049                                      PreParserExpression then_expression,
   1050                                      PreParserExpression else_expression,
   1051                                      int pos) {
   1052     return PreParserExpression::Default();
   1053   }
   1054   PreParserExpression NewCountOperation(Token::Value op,
   1055                                         bool is_prefix,
   1056                                         PreParserExpression expression,
   1057                                         int pos) {
   1058     return PreParserExpression::Default();
   1059   }
   1060   PreParserExpression NewCall(PreParserExpression expression,
   1061                               PreParserExpressionList arguments,
   1062                               int pos) {
   1063     return PreParserExpression::Call();
   1064   }
   1065   PreParserExpression NewCallNew(PreParserExpression expression,
   1066                                  PreParserExpressionList arguments,
   1067                                  int pos) {
   1068     return PreParserExpression::Default();
   1069   }
   1070   PreParserStatement NewReturnStatement(PreParserExpression expression,
   1071                                         int pos) {
   1072     return PreParserStatement::Default();
   1073   }
   1074   PreParserExpression NewFunctionLiteral(
   1075       PreParserIdentifier name, AstValueFactory* ast_value_factory,
   1076       const PreParserScope& scope, PreParserStatementList body,
   1077       int materialized_literal_count, int expected_property_count,
   1078       int handler_count, int parameter_count,
   1079       FunctionLiteral::ParameterFlag has_duplicate_parameters,
   1080       FunctionLiteral::FunctionType function_type,
   1081       FunctionLiteral::IsFunctionFlag is_function,
   1082       FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind,
   1083       int position) {
   1084     return PreParserExpression::Default();
   1085   }
   1086   PreParserExpression NewClassLiteral(PreParserIdentifier name,
   1087                                       PreParserExpression extends,
   1088                                       PreParserExpression constructor,
   1089                                       PreParserExpressionList properties,
   1090                                       int position) {
   1091     return PreParserExpression::Default();
   1092   }
   1093 
   1094   // Return the object itself as AstVisitor and implement the needed
   1095   // dummy method right in this class.
   1096   PreParserFactory* visitor() { return this; }
   1097   BailoutReason dont_optimize_reason() { return kNoReason; }
   1098   int* ast_properties() {
   1099     static int dummy = 42;
   1100     return &dummy;
   1101   }
   1102 };
   1103 
   1104 
   1105 class PreParser;
   1106 
   1107 class PreParserTraits {
   1108  public:
   1109   struct Type {
   1110     // TODO(marja): To be removed. The Traits object should contain all the data
   1111     // it needs.
   1112     typedef PreParser* Parser;
   1113 
   1114     // Used by FunctionState and BlockState.
   1115     typedef PreParserScope Scope;
   1116     typedef PreParserScope ScopePtr;
   1117 
   1118     // PreParser doesn't need to store generator variables.
   1119     typedef void GeneratorVariable;
   1120     // No interaction with Zones.
   1121     typedef void Zone;
   1122 
   1123     typedef int AstProperties;
   1124     typedef Vector<PreParserIdentifier> ParameterIdentifierVector;
   1125 
   1126     // Return types for traversing functions.
   1127     typedef PreParserIdentifier Identifier;
   1128     typedef PreParserExpression Expression;
   1129     typedef PreParserExpression YieldExpression;
   1130     typedef PreParserExpression FunctionLiteral;
   1131     typedef PreParserExpression ClassLiteral;
   1132     typedef PreParserExpression ObjectLiteralProperty;
   1133     typedef PreParserExpression Literal;
   1134     typedef PreParserExpressionList ExpressionList;
   1135     typedef PreParserExpressionList PropertyList;
   1136     typedef PreParserStatementList StatementList;
   1137 
   1138     // For constructing objects returned by the traversing functions.
   1139     typedef PreParserFactory Factory;
   1140   };
   1141 
   1142   class Checkpoint;
   1143 
   1144   explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
   1145 
   1146   // Custom operations executed when FunctionStates are created and
   1147   // destructed. (The PreParser doesn't need to do anything.)
   1148   template <typename FunctionState>
   1149   static void SetUpFunctionState(FunctionState* function_state) {}
   1150   template <typename FunctionState>
   1151   static void TearDownFunctionState(FunctionState* function_state) {}
   1152 
   1153   // Helper functions for recursive descent.
   1154   static bool IsEvalOrArguments(PreParserIdentifier identifier) {
   1155     return identifier.IsEvalOrArguments();
   1156   }
   1157 
   1158   static bool IsPrototype(PreParserIdentifier identifier) {
   1159     return identifier.IsPrototype();
   1160   }
   1161 
   1162   static bool IsConstructor(PreParserIdentifier identifier) {
   1163     return identifier.IsConstructor();
   1164   }
   1165 
   1166   // Returns true if the expression is of type "this.foo".
   1167   static bool IsThisProperty(PreParserExpression expression) {
   1168     return expression.IsThisProperty();
   1169   }
   1170 
   1171   static bool IsIdentifier(PreParserExpression expression) {
   1172     return expression.IsIdentifier();
   1173   }
   1174 
   1175   static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
   1176     return expression.AsIdentifier();
   1177   }
   1178 
   1179   static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
   1180     return identifier.IsYield() || identifier.IsFutureStrictReserved();
   1181   }
   1182 
   1183   static bool IsBoilerplateProperty(PreParserExpression property) {
   1184     // PreParser doesn't count boilerplate properties.
   1185     return false;
   1186   }
   1187 
   1188   static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
   1189     return false;
   1190   }
   1191 
   1192   // Functions for encapsulating the differences between parsing and preparsing;
   1193   // operations interleaved with the recursive descent.
   1194   static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
   1195     // PreParser should not use FuncNameInferrer.
   1196     UNREACHABLE();
   1197   }
   1198   static void PushPropertyName(FuncNameInferrer* fni,
   1199                                PreParserExpression expression) {
   1200     // PreParser should not use FuncNameInferrer.
   1201     UNREACHABLE();
   1202   }
   1203   static void InferFunctionName(FuncNameInferrer* fni,
   1204                                 PreParserExpression expression) {
   1205     // PreParser should not use FuncNameInferrer.
   1206     UNREACHABLE();
   1207   }
   1208 
   1209   static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
   1210       PreParserScope* scope, PreParserExpression property, bool* has_function) {
   1211   }
   1212 
   1213   static void CheckAssigningFunctionLiteralToProperty(
   1214       PreParserExpression left, PreParserExpression right) {}
   1215 
   1216   // PreParser doesn't need to keep track of eval calls.
   1217   static void CheckPossibleEvalCall(PreParserExpression expression,
   1218                                     PreParserScope* scope) {}
   1219 
   1220   static PreParserExpression MarkExpressionAsAssigned(
   1221       PreParserExpression expression) {
   1222     // TODO(marja): To be able to produce the same errors, the preparser needs
   1223     // to start tracking which expressions are variables and which are assigned.
   1224     return expression;
   1225   }
   1226 
   1227   bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
   1228                                               PreParserExpression y,
   1229                                               Token::Value op,
   1230                                               int pos,
   1231                                               PreParserFactory* factory) {
   1232     return false;
   1233   }
   1234 
   1235   PreParserExpression BuildUnaryExpression(PreParserExpression expression,
   1236                                            Token::Value op, int pos,
   1237                                            PreParserFactory* factory) {
   1238     return PreParserExpression::Default();
   1239   }
   1240 
   1241   PreParserExpression NewThrowReferenceError(const char* type, int pos) {
   1242     return PreParserExpression::Default();
   1243   }
   1244   PreParserExpression NewThrowSyntaxError(
   1245       const char* type, Handle<Object> arg, int pos) {
   1246     return PreParserExpression::Default();
   1247   }
   1248   PreParserExpression NewThrowTypeError(
   1249       const char* type, Handle<Object> arg, int pos) {
   1250     return PreParserExpression::Default();
   1251   }
   1252   PreParserScope NewScope(PreParserScope* outer_scope, ScopeType scope_type) {
   1253     return PreParserScope(outer_scope, scope_type);
   1254   }
   1255 
   1256   // Reporting errors.
   1257   void ReportMessageAt(Scanner::Location location,
   1258                        const char* message,
   1259                        const char* arg = NULL,
   1260                        bool is_reference_error = false);
   1261   void ReportMessageAt(int start_pos,
   1262                        int end_pos,
   1263                        const char* message,
   1264                        const char* arg = NULL,
   1265                        bool is_reference_error = false);
   1266 
   1267   // "null" return type creators.
   1268   static PreParserIdentifier EmptyIdentifier() {
   1269     return PreParserIdentifier::Default();
   1270   }
   1271   static PreParserIdentifier EmptyIdentifierString() {
   1272     return PreParserIdentifier::Default();
   1273   }
   1274   static PreParserExpression EmptyExpression() {
   1275     return PreParserExpression::Default();
   1276   }
   1277   static PreParserExpression EmptyArrowParamList() {
   1278     return PreParserExpression::EmptyArrowParamList();
   1279   }
   1280   static PreParserExpression EmptyLiteral() {
   1281     return PreParserExpression::Default();
   1282   }
   1283   static PreParserExpression EmptyObjectLiteralProperty() {
   1284     return PreParserExpression::Default();
   1285   }
   1286   static PreParserExpression EmptyFunctionLiteral() {
   1287     return PreParserExpression::Default();
   1288   }
   1289   static PreParserExpressionList NullExpressionList() {
   1290     return PreParserExpressionList();
   1291   }
   1292 
   1293   // Odd-ball literal creators.
   1294   static PreParserExpression GetLiteralTheHole(int position,
   1295                                                PreParserFactory* factory) {
   1296     return PreParserExpression::Default();
   1297   }
   1298 
   1299   // Producing data during the recursive descent.
   1300   PreParserIdentifier GetSymbol(Scanner* scanner);
   1301   PreParserIdentifier GetNumberAsSymbol(Scanner* scanner);
   1302 
   1303   static PreParserIdentifier GetNextSymbol(Scanner* scanner) {
   1304     return PreParserIdentifier::Default();
   1305   }
   1306 
   1307   static PreParserExpression ThisExpression(PreParserScope* scope,
   1308                                             PreParserFactory* factory) {
   1309     return PreParserExpression::This();
   1310   }
   1311 
   1312   static PreParserExpression SuperReference(PreParserScope* scope,
   1313                                             PreParserFactory* factory) {
   1314     return PreParserExpression::Super();
   1315   }
   1316 
   1317   static PreParserExpression ClassLiteral(PreParserIdentifier name,
   1318                                           PreParserExpression extends,
   1319                                           PreParserExpression constructor,
   1320                                           PreParserExpressionList properties,
   1321                                           int position,
   1322                                           PreParserFactory* factory) {
   1323     return PreParserExpression::Default();
   1324   }
   1325 
   1326   static PreParserExpression ExpressionFromLiteral(
   1327       Token::Value token, int pos, Scanner* scanner,
   1328       PreParserFactory* factory) {
   1329     return PreParserExpression::Default();
   1330   }
   1331 
   1332   static PreParserExpression ExpressionFromIdentifier(
   1333       PreParserIdentifier name, int pos, PreParserScope* scope,
   1334       PreParserFactory* factory) {
   1335     return PreParserExpression::FromIdentifier(name);
   1336   }
   1337 
   1338   PreParserExpression ExpressionFromString(int pos,
   1339                                            Scanner* scanner,
   1340                                            PreParserFactory* factory = NULL);
   1341 
   1342   PreParserExpression GetIterator(PreParserExpression iterable,
   1343                                   PreParserFactory* factory) {
   1344     return PreParserExpression::Default();
   1345   }
   1346 
   1347   static PreParserExpressionList NewExpressionList(int size, void* zone) {
   1348     return PreParserExpressionList();
   1349   }
   1350 
   1351   static PreParserStatementList NewStatementList(int size, void* zone) {
   1352     return PreParserStatementList();
   1353   }
   1354 
   1355   static PreParserExpressionList NewPropertyList(int size, void* zone) {
   1356     return PreParserExpressionList();
   1357   }
   1358 
   1359   V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name,
   1360                                       int* materialized_literal_count,
   1361                                       int* expected_property_count, bool* ok) {
   1362     UNREACHABLE();
   1363   }
   1364 
   1365   V8_INLINE PreParserStatementList
   1366       ParseEagerFunctionBody(PreParserIdentifier function_name, int pos,
   1367                              Variable* fvar, Token::Value fvar_init_op,
   1368                              bool is_generator, bool* ok);
   1369 
   1370   // Utility functions
   1371   int DeclareArrowParametersFromExpression(PreParserExpression expression,
   1372                                            PreParserScope* scope,
   1373                                            Scanner::Location* dupe_loc,
   1374                                            bool* ok) {
   1375     // TODO(aperez): Detect duplicated identifiers in paramlists.
   1376     *ok = expression.IsValidArrowParamList();
   1377     return 0;
   1378   }
   1379 
   1380   static AstValueFactory* ast_value_factory() { return NULL; }
   1381 
   1382   void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {}
   1383 
   1384   // Temporary glue; these functions will move to ParserBase.
   1385   PreParserExpression ParseV8Intrinsic(bool* ok);
   1386   PreParserExpression ParseFunctionLiteral(
   1387       PreParserIdentifier name, Scanner::Location function_name_location,
   1388       bool name_is_strict_reserved, FunctionKind kind,
   1389       int function_token_position, FunctionLiteral::FunctionType type,
   1390       FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
   1391 
   1392  private:
   1393   PreParser* pre_parser_;
   1394 };
   1395 
   1396 
   1397 // Preparsing checks a JavaScript program and emits preparse-data that helps
   1398 // a later parsing to be faster.
   1399 // See preparse-data-format.h for the data format.
   1400 
   1401 // The PreParser checks that the syntax follows the grammar for JavaScript,
   1402 // and collects some information about the program along the way.
   1403 // The grammar check is only performed in order to understand the program
   1404 // sufficiently to deduce some information about it, that can be used
   1405 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
   1406 // rather it is to speed up properly written and correct programs.
   1407 // That means that contextual checks (like a label being declared where
   1408 // it is used) are generally omitted.
   1409 class PreParser : public ParserBase<PreParserTraits> {
   1410  public:
   1411   typedef PreParserIdentifier Identifier;
   1412   typedef PreParserExpression Expression;
   1413   typedef PreParserStatement Statement;
   1414 
   1415   enum PreParseResult {
   1416     kPreParseStackOverflow,
   1417     kPreParseSuccess
   1418   };
   1419 
   1420   PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit)
   1421       : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, NULL,
   1422                                     this) {}
   1423 
   1424   // Pre-parse the program from the character stream; returns true on
   1425   // success (even if parsing failed, the pre-parse data successfully
   1426   // captured the syntax error), and false if a stack-overflow happened
   1427   // during parsing.
   1428   PreParseResult PreParseProgram() {
   1429     PreParserScope scope(scope_, GLOBAL_SCOPE);
   1430     FunctionState top_scope(&function_state_, &scope_, &scope);
   1431     bool ok = true;
   1432     int start_position = scanner()->peek_location().beg_pos;
   1433     ParseSourceElements(Token::EOS, &ok);
   1434     if (stack_overflow()) return kPreParseStackOverflow;
   1435     if (!ok) {
   1436       ReportUnexpectedToken(scanner()->current_token());
   1437     } else if (scope_->strict_mode() == STRICT) {
   1438       CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
   1439     }
   1440     return kPreParseSuccess;
   1441   }
   1442 
   1443   // Parses a single function literal, from the opening parentheses before
   1444   // parameters to the closing brace after the body.
   1445   // Returns a FunctionEntry describing the body of the function in enough
   1446   // detail that it can be lazily compiled.
   1447   // The scanner is expected to have matched the "function" or "function*"
   1448   // keyword and parameters, and have consumed the initial '{'.
   1449   // At return, unless an error occurred, the scanner is positioned before the
   1450   // the final '}'.
   1451   PreParseResult PreParseLazyFunction(StrictMode strict_mode,
   1452                                       bool is_generator,
   1453                                       ParserRecorder* log);
   1454 
   1455  private:
   1456   friend class PreParserTraits;
   1457 
   1458   // These types form an algebra over syntactic categories that is just
   1459   // rich enough to let us recognize and propagate the constructs that
   1460   // are either being counted in the preparser data, or is important
   1461   // to throw the correct syntax error exceptions.
   1462 
   1463   enum VariableDeclarationContext {
   1464     kSourceElement,
   1465     kStatement,
   1466     kForStatement
   1467   };
   1468 
   1469   // If a list of variable declarations includes any initializers.
   1470   enum VariableDeclarationProperties {
   1471     kHasInitializers,
   1472     kHasNoInitializers
   1473   };
   1474 
   1475 
   1476   enum SourceElements {
   1477     kUnknownSourceElements
   1478   };
   1479 
   1480   // All ParseXXX functions take as the last argument an *ok parameter
   1481   // which is set to false if parsing failed; it is unchanged otherwise.
   1482   // By making the 'exception handling' explicit, we are forced to check
   1483   // for failure at the call sites.
   1484   Statement ParseSourceElement(bool* ok);
   1485   SourceElements ParseSourceElements(int end_token, bool* ok);
   1486   Statement ParseStatement(bool* ok);
   1487   Statement ParseFunctionDeclaration(bool* ok);
   1488   Statement ParseClassDeclaration(bool* ok);
   1489   Statement ParseBlock(bool* ok);
   1490   Statement ParseVariableStatement(VariableDeclarationContext var_context,
   1491                                    bool* ok);
   1492   Statement ParseVariableDeclarations(VariableDeclarationContext var_context,
   1493                                       VariableDeclarationProperties* decl_props,
   1494                                       int* num_decl,
   1495                                       bool* ok);
   1496   Statement ParseExpressionOrLabelledStatement(bool* ok);
   1497   Statement ParseIfStatement(bool* ok);
   1498   Statement ParseContinueStatement(bool* ok);
   1499   Statement ParseBreakStatement(bool* ok);
   1500   Statement ParseReturnStatement(bool* ok);
   1501   Statement ParseWithStatement(bool* ok);
   1502   Statement ParseSwitchStatement(bool* ok);
   1503   Statement ParseDoWhileStatement(bool* ok);
   1504   Statement ParseWhileStatement(bool* ok);
   1505   Statement ParseForStatement(bool* ok);
   1506   Statement ParseThrowStatement(bool* ok);
   1507   Statement ParseTryStatement(bool* ok);
   1508   Statement ParseDebuggerStatement(bool* ok);
   1509   Expression ParseConditionalExpression(bool accept_IN, bool* ok);
   1510   Expression ParseObjectLiteral(bool* ok);
   1511   Expression ParseV8Intrinsic(bool* ok);
   1512 
   1513   V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name,
   1514                                       int* materialized_literal_count,
   1515                                       int* expected_property_count, bool* ok);
   1516   V8_INLINE PreParserStatementList
   1517       ParseEagerFunctionBody(PreParserIdentifier function_name, int pos,
   1518                              Variable* fvar, Token::Value fvar_init_op,
   1519                              bool is_generator, bool* ok);
   1520 
   1521   Expression ParseFunctionLiteral(
   1522       Identifier name, Scanner::Location function_name_location,
   1523       bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
   1524       FunctionLiteral::FunctionType function_type,
   1525       FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
   1526   void ParseLazyFunctionLiteralBody(bool* ok);
   1527 
   1528   bool CheckInOrOf(bool accept_OF);
   1529 };
   1530 
   1531 
   1532 PreParserStatementList PreParser::ParseEagerFunctionBody(
   1533     PreParserIdentifier function_name, int pos, Variable* fvar,
   1534     Token::Value fvar_init_op, bool is_generator, bool* ok) {
   1535   ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
   1536 
   1537   ParseSourceElements(Token::RBRACE, ok);
   1538   if (!*ok) return PreParserStatementList();
   1539 
   1540   Expect(Token::RBRACE, ok);
   1541   return PreParserStatementList();
   1542 }
   1543 
   1544 
   1545 PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
   1546     PreParserIdentifier function_name, int pos, Variable* fvar,
   1547     Token::Value fvar_init_op, bool is_generator, bool* ok) {
   1548   return pre_parser_->ParseEagerFunctionBody(function_name, pos, fvar,
   1549                                              fvar_init_op, is_generator, ok);
   1550 }
   1551 
   1552 
   1553 template <class Traits>
   1554 ParserBase<Traits>::FunctionState::FunctionState(
   1555     FunctionState** function_state_stack,
   1556     typename Traits::Type::Scope** scope_stack,
   1557     typename Traits::Type::Scope* scope, typename Traits::Type::Zone* zone,
   1558     AstValueFactory* ast_value_factory, AstNode::IdGen* ast_node_id_gen)
   1559     : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
   1560       next_handler_index_(0),
   1561       expected_property_count_(0),
   1562       is_generator_(false),
   1563       generator_object_variable_(NULL),
   1564       function_state_stack_(function_state_stack),
   1565       outer_function_state_(*function_state_stack),
   1566       scope_stack_(scope_stack),
   1567       outer_scope_(*scope_stack),
   1568       ast_node_id_gen_(ast_node_id_gen),
   1569       factory_(zone, ast_value_factory, ast_node_id_gen) {
   1570   *scope_stack_ = scope;
   1571   *function_state_stack = this;
   1572   Traits::SetUpFunctionState(this);
   1573 }
   1574 
   1575 
   1576 template <class Traits>
   1577 ParserBase<Traits>::FunctionState::FunctionState(
   1578     FunctionState** function_state_stack,
   1579     typename Traits::Type::Scope** scope_stack,
   1580     typename Traits::Type::Scope** scope, typename Traits::Type::Zone* zone,
   1581     AstValueFactory* ast_value_factory, AstNode::IdGen* ast_node_id_gen)
   1582     : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
   1583       next_handler_index_(0),
   1584       expected_property_count_(0),
   1585       is_generator_(false),
   1586       generator_object_variable_(NULL),
   1587       function_state_stack_(function_state_stack),
   1588       outer_function_state_(*function_state_stack),
   1589       scope_stack_(scope_stack),
   1590       outer_scope_(*scope_stack),
   1591       ast_node_id_gen_(ast_node_id_gen),
   1592       factory_(zone, ast_value_factory, ast_node_id_gen) {
   1593   *scope_stack_ = *scope;
   1594   *function_state_stack = this;
   1595   Traits::SetUpFunctionState(this);
   1596 }
   1597 
   1598 
   1599 template <class Traits>
   1600 ParserBase<Traits>::FunctionState::~FunctionState() {
   1601   *scope_stack_ = outer_scope_;
   1602   *function_state_stack_ = outer_function_state_;
   1603   Traits::TearDownFunctionState(this);
   1604 }
   1605 
   1606 
   1607 template<class Traits>
   1608 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
   1609   Scanner::Location source_location = scanner()->location();
   1610 
   1611   // Four of the tokens are treated specially
   1612   switch (token) {
   1613     case Token::EOS:
   1614       return ReportMessageAt(source_location, "unexpected_eos");
   1615     case Token::NUMBER:
   1616       return ReportMessageAt(source_location, "unexpected_token_number");
   1617     case Token::STRING:
   1618       return ReportMessageAt(source_location, "unexpected_token_string");
   1619     case Token::IDENTIFIER:
   1620       return ReportMessageAt(source_location, "unexpected_token_identifier");
   1621     case Token::FUTURE_RESERVED_WORD:
   1622       return ReportMessageAt(source_location, "unexpected_reserved");
   1623     case Token::LET:
   1624     case Token::YIELD:
   1625     case Token::FUTURE_STRICT_RESERVED_WORD:
   1626       return ReportMessageAt(source_location, strict_mode() == SLOPPY
   1627           ? "unexpected_token_identifier" : "unexpected_strict_reserved");
   1628     default:
   1629       const char* name = Token::String(token);
   1630       DCHECK(name != NULL);
   1631       Traits::ReportMessageAt(source_location, "unexpected_token", name);
   1632   }
   1633 }
   1634 
   1635 
   1636 template<class Traits>
   1637 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
   1638     AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
   1639     bool* ok) {
   1640   Token::Value next = Next();
   1641   if (next == Token::IDENTIFIER) {
   1642     IdentifierT name = this->GetSymbol(scanner());
   1643     if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
   1644         strict_mode() == STRICT && this->IsEvalOrArguments(name)) {
   1645       ReportMessage("strict_eval_arguments");
   1646       *ok = false;
   1647     }
   1648     return name;
   1649   } else if (strict_mode() == SLOPPY &&
   1650              (next == Token::FUTURE_STRICT_RESERVED_WORD ||
   1651              (next == Token::LET) ||
   1652              (next == Token::YIELD && !is_generator()))) {
   1653     return this->GetSymbol(scanner());
   1654   } else {
   1655     this->ReportUnexpectedToken(next);
   1656     *ok = false;
   1657     return Traits::EmptyIdentifier();
   1658   }
   1659 }
   1660 
   1661 
   1662 template <class Traits>
   1663 typename ParserBase<Traits>::IdentifierT ParserBase<
   1664     Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
   1665                                                  bool* ok) {
   1666   Token::Value next = Next();
   1667   if (next == Token::IDENTIFIER) {
   1668     *is_strict_reserved = false;
   1669   } else if (next == Token::FUTURE_STRICT_RESERVED_WORD ||
   1670              next == Token::LET ||
   1671              (next == Token::YIELD && !this->is_generator())) {
   1672     *is_strict_reserved = true;
   1673   } else {
   1674     ReportUnexpectedToken(next);
   1675     *ok = false;
   1676     return Traits::EmptyIdentifier();
   1677   }
   1678   return this->GetSymbol(scanner());
   1679 }
   1680 
   1681 
   1682 template <class Traits>
   1683 typename ParserBase<Traits>::IdentifierT
   1684 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
   1685   Token::Value next = Next();
   1686   if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
   1687       next != Token::LET && next != Token::YIELD &&
   1688       next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
   1689     this->ReportUnexpectedToken(next);
   1690     *ok = false;
   1691     return Traits::EmptyIdentifier();
   1692   }
   1693   return this->GetSymbol(scanner());
   1694 }
   1695 
   1696 
   1697 template <class Traits>
   1698 typename ParserBase<Traits>::IdentifierT
   1699 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
   1700                                                   bool* is_set,
   1701                                                   bool* ok) {
   1702   IdentifierT result = ParseIdentifierName(ok);
   1703   if (!*ok) return Traits::EmptyIdentifier();
   1704   scanner()->IsGetOrSet(is_get, is_set);
   1705   return result;
   1706 }
   1707 
   1708 
   1709 template <class Traits>
   1710 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
   1711     bool seen_equal, bool* ok) {
   1712   int pos = peek_position();
   1713   if (!scanner()->ScanRegExpPattern(seen_equal)) {
   1714     Next();
   1715     ReportMessage("unterminated_regexp");
   1716     *ok = false;
   1717     return Traits::EmptyExpression();
   1718   }
   1719 
   1720   int literal_index = function_state_->NextMaterializedLiteralIndex();
   1721 
   1722   IdentifierT js_pattern = this->GetNextSymbol(scanner());
   1723   if (!scanner()->ScanRegExpFlags()) {
   1724     Next();
   1725     ReportMessage("invalid_regexp_flags");
   1726     *ok = false;
   1727     return Traits::EmptyExpression();
   1728   }
   1729   IdentifierT js_flags = this->GetNextSymbol(scanner());
   1730   Next();
   1731   return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
   1732 }
   1733 
   1734 
   1735 #define CHECK_OK  ok); \
   1736   if (!*ok) return this->EmptyExpression(); \
   1737   ((void)0
   1738 #define DUMMY )  // to make indentation work
   1739 #undef DUMMY
   1740 
   1741 // Used in functions where the return type is not ExpressionT.
   1742 #define CHECK_OK_CUSTOM(x) ok); \
   1743   if (!*ok) return this->x(); \
   1744   ((void)0
   1745 #define DUMMY )  // to make indentation work
   1746 #undef DUMMY
   1747 
   1748 template <class Traits>
   1749 typename ParserBase<Traits>::ExpressionT
   1750 ParserBase<Traits>::ParsePrimaryExpression(bool* ok) {
   1751   // PrimaryExpression ::
   1752   //   'this'
   1753   //   'null'
   1754   //   'true'
   1755   //   'false'
   1756   //   Identifier
   1757   //   Number
   1758   //   String
   1759   //   ArrayLiteral
   1760   //   ObjectLiteral
   1761   //   RegExpLiteral
   1762   //   ClassLiteral
   1763   //   '(' Expression ')'
   1764 
   1765   int pos = peek_position();
   1766   ExpressionT result = this->EmptyExpression();
   1767   Token::Value token = peek();
   1768   switch (token) {
   1769     case Token::THIS: {
   1770       Consume(Token::THIS);
   1771       result = this->ThisExpression(scope_, factory());
   1772       break;
   1773     }
   1774 
   1775     case Token::NULL_LITERAL:
   1776     case Token::TRUE_LITERAL:
   1777     case Token::FALSE_LITERAL:
   1778     case Token::NUMBER:
   1779       Next();
   1780       result = this->ExpressionFromLiteral(token, pos, scanner(), factory());
   1781       break;
   1782 
   1783     case Token::IDENTIFIER:
   1784     case Token::LET:
   1785     case Token::YIELD:
   1786     case Token::FUTURE_STRICT_RESERVED_WORD: {
   1787       // Using eval or arguments in this context is OK even in strict mode.
   1788       IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
   1789       result = this->ExpressionFromIdentifier(name, pos, scope_, factory());
   1790       break;
   1791     }
   1792 
   1793     case Token::STRING: {
   1794       Consume(Token::STRING);
   1795       result = this->ExpressionFromString(pos, scanner(), factory());
   1796       break;
   1797     }
   1798 
   1799     case Token::ASSIGN_DIV:
   1800       result = this->ParseRegExpLiteral(true, CHECK_OK);
   1801       break;
   1802 
   1803     case Token::DIV:
   1804       result = this->ParseRegExpLiteral(false, CHECK_OK);
   1805       break;
   1806 
   1807     case Token::LBRACK:
   1808       result = this->ParseArrayLiteral(CHECK_OK);
   1809       break;
   1810 
   1811     case Token::LBRACE:
   1812       result = this->ParseObjectLiteral(CHECK_OK);
   1813       break;
   1814 
   1815     case Token::LPAREN:
   1816       Consume(Token::LPAREN);
   1817       if (allow_arrow_functions() && peek() == Token::RPAREN) {
   1818         // Arrow functions are the only expression type constructions
   1819         // for which an empty parameter list "()" is valid input.
   1820         Consume(Token::RPAREN);
   1821         result = this->ParseArrowFunctionLiteral(
   1822             pos, this->EmptyArrowParamList(), CHECK_OK);
   1823       } else {
   1824         // Heuristically try to detect immediately called functions before
   1825         // seeing the call parentheses.
   1826         parenthesized_function_ = (peek() == Token::FUNCTION);
   1827         result = this->ParseExpression(true, CHECK_OK);
   1828         result->increase_parenthesization_level();
   1829         Expect(Token::RPAREN, CHECK_OK);
   1830       }
   1831       break;
   1832 
   1833     case Token::CLASS: {
   1834       Consume(Token::CLASS);
   1835       int class_token_position = position();
   1836       IdentifierT name = this->EmptyIdentifier();
   1837       bool is_strict_reserved_name = false;
   1838       Scanner::Location class_name_location = Scanner::Location::invalid();
   1839       if (peek_any_identifier()) {
   1840         name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
   1841                                                    CHECK_OK);
   1842         class_name_location = scanner()->location();
   1843       }
   1844       result = this->ParseClassLiteral(name, class_name_location,
   1845                                        is_strict_reserved_name,
   1846                                        class_token_position, CHECK_OK);
   1847       break;
   1848     }
   1849 
   1850     case Token::MOD:
   1851       if (allow_natives_syntax() || extension_ != NULL) {
   1852         result = this->ParseV8Intrinsic(CHECK_OK);
   1853         break;
   1854       }
   1855       // If we're not allowing special syntax we fall-through to the
   1856       // default case.
   1857 
   1858     default: {
   1859       Next();
   1860       ReportUnexpectedToken(token);
   1861       *ok = false;
   1862     }
   1863   }
   1864 
   1865   return result;
   1866 }
   1867 
   1868 // Precedence = 1
   1869 template <class Traits>
   1870 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
   1871     bool accept_IN, bool* ok) {
   1872   // Expression ::
   1873   //   AssignmentExpression
   1874   //   Expression ',' AssignmentExpression
   1875 
   1876   ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
   1877   while (peek() == Token::COMMA) {
   1878     Expect(Token::COMMA, CHECK_OK);
   1879     int pos = position();
   1880     ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
   1881     result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
   1882   }
   1883   return result;
   1884 }
   1885 
   1886 
   1887 template <class Traits>
   1888 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
   1889     bool* ok) {
   1890   // ArrayLiteral ::
   1891   //   '[' Expression? (',' Expression?)* ']'
   1892 
   1893   int pos = peek_position();
   1894   typename Traits::Type::ExpressionList values =
   1895       this->NewExpressionList(4, zone_);
   1896   Expect(Token::LBRACK, CHECK_OK);
   1897   while (peek() != Token::RBRACK) {
   1898     ExpressionT elem = this->EmptyExpression();
   1899     if (peek() == Token::COMMA) {
   1900       elem = this->GetLiteralTheHole(peek_position(), factory());
   1901     } else {
   1902       elem = this->ParseAssignmentExpression(true, CHECK_OK);
   1903     }
   1904     values->Add(elem, zone_);
   1905     if (peek() != Token::RBRACK) {
   1906       Expect(Token::COMMA, CHECK_OK);
   1907     }
   1908   }
   1909   Expect(Token::RBRACK, CHECK_OK);
   1910 
   1911   // Update the scope information before the pre-parsing bailout.
   1912   int literal_index = function_state_->NextMaterializedLiteralIndex();
   1913 
   1914   return factory()->NewArrayLiteral(values, literal_index, pos);
   1915 }
   1916 
   1917 
   1918 template <class Traits>
   1919 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParsePropertyName(
   1920     bool* is_get, bool* is_set, bool* is_static, bool* ok) {
   1921   Token::Value next = peek();
   1922   switch (next) {
   1923     case Token::STRING:
   1924       Consume(Token::STRING);
   1925       return this->GetSymbol(scanner_);
   1926     case Token::NUMBER:
   1927       Consume(Token::NUMBER);
   1928       return this->GetNumberAsSymbol(scanner_);
   1929     case Token::STATIC:
   1930       *is_static = true;
   1931       // Fall through.
   1932     default:
   1933       return ParseIdentifierNameOrGetOrSet(is_get, is_set, ok);
   1934   }
   1935   UNREACHABLE();
   1936   return this->EmptyIdentifier();
   1937 }
   1938 
   1939 
   1940 template <class Traits>
   1941 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase<
   1942     Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker,
   1943                                      bool in_class, bool is_static, bool* ok) {
   1944   ExpressionT value = this->EmptyExpression();
   1945   bool is_get = false;
   1946   bool is_set = false;
   1947   bool name_is_static = false;
   1948   bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL);
   1949 
   1950   Token::Value name_token = peek();
   1951   int next_pos = peek_position();
   1952   IdentifierT name =
   1953       ParsePropertyName(&is_get, &is_set, &name_is_static,
   1954                         CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
   1955 
   1956   if (fni_ != NULL) this->PushLiteralName(fni_, name);
   1957 
   1958   if (!in_class && !is_generator && peek() == Token::COLON) {
   1959     // PropertyDefinition : PropertyName ':' AssignmentExpression
   1960     checker->CheckProperty(name_token, kValueProperty,
   1961                            CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
   1962     Consume(Token::COLON);
   1963     value = this->ParseAssignmentExpression(
   1964         true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
   1965 
   1966   } else if (is_generator ||
   1967              (allow_harmony_object_literals_ && peek() == Token::LPAREN)) {
   1968     // Concise Method
   1969 
   1970     if (is_static && this->IsPrototype(name)) {
   1971       ReportMessageAt(scanner()->location(), "static_prototype");
   1972       *ok = false;
   1973       return this->EmptyObjectLiteralProperty();
   1974     }
   1975     if (is_generator && in_class && !is_static && this->IsConstructor(name)) {
   1976       ReportMessageAt(scanner()->location(), "constructor_special_method");
   1977       *ok = false;
   1978       return this->EmptyObjectLiteralProperty();
   1979     }
   1980 
   1981     checker->CheckProperty(name_token, kValueProperty,
   1982                            CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
   1983     FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
   1984                                      : FunctionKind::kConciseMethod;
   1985 
   1986     value = this->ParseFunctionLiteral(
   1987         name, scanner()->location(),
   1988         false,  // reserved words are allowed here
   1989         kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
   1990         FunctionLiteral::NORMAL_ARITY,
   1991         CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
   1992 
   1993   } else if (in_class && name_is_static && !is_static) {
   1994     // static MethodDefinition
   1995     return ParsePropertyDefinition(checker, true, true, ok);
   1996 
   1997   } else if (is_get || is_set) {
   1998     // Accessor
   1999     bool dont_care = false;
   2000     name_token = peek();
   2001     name = ParsePropertyName(&dont_care, &dont_care, &dont_care,
   2002                              CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
   2003 
   2004     // Validate the property.
   2005     if (is_static && this->IsPrototype(name)) {
   2006       ReportMessageAt(scanner()->location(), "static_prototype");
   2007       *ok = false;
   2008       return this->EmptyObjectLiteralProperty();
   2009     } else if (in_class && !is_static && this->IsConstructor(name)) {
   2010       // ES6, spec draft rev 27, treats static get constructor as an error too.
   2011       // https://bugs.ecmascript.org/show_bug.cgi?id=3223
   2012       // TODO(arv): Update when bug is resolved.
   2013       ReportMessageAt(scanner()->location(), "constructor_special_method");
   2014       *ok = false;
   2015       return this->EmptyObjectLiteralProperty();
   2016     }
   2017     checker->CheckProperty(name_token,
   2018                            is_get ? kGetterProperty : kSetterProperty,
   2019                            CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
   2020 
   2021     typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
   2022         name, scanner()->location(),
   2023         false,  // reserved words are allowed here
   2024         FunctionKind::kNormalFunction, RelocInfo::kNoPosition,
   2025         FunctionLiteral::ANONYMOUS_EXPRESSION,
   2026         is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
   2027         CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
   2028     return factory()->NewObjectLiteralProperty(is_get, value, next_pos,
   2029                                                is_static);
   2030   } else {
   2031     Token::Value next = Next();
   2032     ReportUnexpectedToken(next);
   2033     *ok = false;
   2034     return this->EmptyObjectLiteralProperty();
   2035   }
   2036 
   2037   uint32_t index;
   2038   LiteralT key = this->IsArrayIndex(name, &index)
   2039                      ? factory()->NewNumberLiteral(index, next_pos)
   2040                      : factory()->NewStringLiteral(name, next_pos);
   2041 
   2042   return factory()->NewObjectLiteralProperty(key, value, is_static);
   2043 }
   2044 
   2045 
   2046 template <class Traits>
   2047 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
   2048     bool* ok) {
   2049   // ObjectLiteral ::
   2050   // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
   2051 
   2052   int pos = peek_position();
   2053   typename Traits::Type::PropertyList properties =
   2054       this->NewPropertyList(4, zone_);
   2055   int number_of_boilerplate_properties = 0;
   2056   bool has_function = false;
   2057 
   2058   ObjectLiteralChecker checker(this, strict_mode());
   2059 
   2060   Expect(Token::LBRACE, CHECK_OK);
   2061 
   2062   while (peek() != Token::RBRACE) {
   2063     if (fni_ != NULL) fni_->Enter();
   2064 
   2065     const bool in_class = false;
   2066     const bool is_static = false;
   2067     ObjectLiteralPropertyT property =
   2068         this->ParsePropertyDefinition(&checker, in_class, is_static, CHECK_OK);
   2069 
   2070     // Mark top-level object literals that contain function literals and
   2071     // pretenure the literal so it can be added as a constant function
   2072     // property. (Parser only.)
   2073     this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property,
   2074                                                           &has_function);
   2075 
   2076     // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
   2077     if (this->IsBoilerplateProperty(property)) {
   2078       number_of_boilerplate_properties++;
   2079     }
   2080     properties->Add(property, zone());
   2081 
   2082     if (peek() != Token::RBRACE) {
   2083       // Need {} because of the CHECK_OK macro.
   2084       Expect(Token::COMMA, CHECK_OK);
   2085     }
   2086 
   2087     if (fni_ != NULL) {
   2088       fni_->Infer();
   2089       fni_->Leave();
   2090     }
   2091   }
   2092   Expect(Token::RBRACE, CHECK_OK);
   2093 
   2094   // Computation of literal_index must happen before pre parse bailout.
   2095   int literal_index = function_state_->NextMaterializedLiteralIndex();
   2096 
   2097   return factory()->NewObjectLiteral(properties,
   2098                                      literal_index,
   2099                                      number_of_boilerplate_properties,
   2100                                      has_function,
   2101                                      pos);
   2102 }
   2103 
   2104 
   2105 template <class Traits>
   2106 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
   2107     bool* ok) {
   2108   // Arguments ::
   2109   //   '(' (AssignmentExpression)*[','] ')'
   2110 
   2111   typename Traits::Type::ExpressionList result =
   2112       this->NewExpressionList(4, zone_);
   2113   Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
   2114   bool done = (peek() == Token::RPAREN);
   2115   while (!done) {
   2116     ExpressionT argument = this->ParseAssignmentExpression(
   2117         true, CHECK_OK_CUSTOM(NullExpressionList));
   2118     result->Add(argument, zone_);
   2119     if (result->length() > Code::kMaxArguments) {
   2120       ReportMessage("too_many_arguments");
   2121       *ok = false;
   2122       return this->NullExpressionList();
   2123     }
   2124     done = (peek() == Token::RPAREN);
   2125     if (!done) {
   2126       // Need {} because of the CHECK_OK_CUSTOM macro.
   2127       Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList));
   2128     }
   2129   }
   2130   Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
   2131   return result;
   2132 }
   2133 
   2134 // Precedence = 2
   2135 template <class Traits>
   2136 typename ParserBase<Traits>::ExpressionT
   2137 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
   2138   // AssignmentExpression ::
   2139   //   ConditionalExpression
   2140   //   ArrowFunction
   2141   //   YieldExpression
   2142   //   LeftHandSideExpression AssignmentOperator AssignmentExpression
   2143 
   2144   Scanner::Location lhs_location = scanner()->peek_location();
   2145 
   2146   if (peek() == Token::YIELD && is_generator()) {
   2147     return this->ParseYieldExpression(ok);
   2148   }
   2149 
   2150   if (fni_ != NULL) fni_->Enter();
   2151   typename Traits::Checkpoint checkpoint(this);
   2152   ExpressionT expression =
   2153       this->ParseConditionalExpression(accept_IN, CHECK_OK);
   2154 
   2155   if (allow_arrow_functions() && peek() == Token::ARROW) {
   2156     checkpoint.Restore();
   2157     expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos,
   2158                                                  expression, CHECK_OK);
   2159     return expression;
   2160   }
   2161 
   2162   if (!Token::IsAssignmentOp(peek())) {
   2163     if (fni_ != NULL) fni_->Leave();
   2164     // Parsed conditional expression only (no assignment).
   2165     return expression;
   2166   }
   2167 
   2168   expression = this->CheckAndRewriteReferenceExpression(
   2169       expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
   2170   expression = this->MarkExpressionAsAssigned(expression);
   2171 
   2172   Token::Value op = Next();  // Get assignment operator.
   2173   int pos = position();
   2174   ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
   2175 
   2176   // TODO(1231235): We try to estimate the set of properties set by
   2177   // constructors. We define a new property whenever there is an
   2178   // assignment to a property of 'this'. We should probably only add
   2179   // properties if we haven't seen them before. Otherwise we'll
   2180   // probably overestimate the number of properties.
   2181   if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
   2182     function_state_->AddProperty();
   2183   }
   2184 
   2185   this->CheckAssigningFunctionLiteralToProperty(expression, right);
   2186 
   2187   if (fni_ != NULL) {
   2188     // Check if the right hand side is a call to avoid inferring a
   2189     // name if we're dealing with "a = function(){...}();"-like
   2190     // expression.
   2191     if ((op == Token::INIT_VAR
   2192          || op == Token::INIT_CONST_LEGACY
   2193          || op == Token::ASSIGN)
   2194         && (!right->IsCall() && !right->IsCallNew())) {
   2195       fni_->Infer();
   2196     } else {
   2197       fni_->RemoveLastFunction();
   2198     }
   2199     fni_->Leave();
   2200   }
   2201 
   2202   return factory()->NewAssignment(op, expression, right, pos);
   2203 }
   2204 
   2205 template <class Traits>
   2206 typename ParserBase<Traits>::ExpressionT
   2207 ParserBase<Traits>::ParseYieldExpression(bool* ok) {
   2208   // YieldExpression ::
   2209   //   'yield' ([no line terminator] '*'? AssignmentExpression)?
   2210   int pos = peek_position();
   2211   Expect(Token::YIELD, CHECK_OK);
   2212   ExpressionT generator_object =
   2213       factory()->NewVariableProxy(function_state_->generator_object_variable());
   2214   ExpressionT expression = Traits::EmptyExpression();
   2215   Yield::Kind kind = Yield::kSuspend;
   2216   if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
   2217     if (Check(Token::MUL)) kind = Yield::kDelegating;
   2218     switch (peek()) {
   2219       case Token::EOS:
   2220       case Token::SEMICOLON:
   2221       case Token::RBRACE:
   2222       case Token::RBRACK:
   2223       case Token::RPAREN:
   2224       case Token::COLON:
   2225       case Token::COMMA:
   2226         // The above set of tokens is the complete set of tokens that can appear
   2227         // after an AssignmentExpression, and none of them can start an
   2228         // AssignmentExpression.  This allows us to avoid looking for an RHS for
   2229         // a Yield::kSuspend operation, given only one look-ahead token.
   2230         if (kind == Yield::kSuspend)
   2231           break;
   2232         DCHECK_EQ(Yield::kDelegating, kind);
   2233         // Delegating yields require an RHS; fall through.
   2234       default:
   2235         expression = ParseAssignmentExpression(false, CHECK_OK);
   2236         break;
   2237     }
   2238   }
   2239   if (kind == Yield::kDelegating) {
   2240     // var iterator = subject[Symbol.iterator]();
   2241     expression = this->GetIterator(expression, factory());
   2242   }
   2243   typename Traits::Type::YieldExpression yield =
   2244       factory()->NewYield(generator_object, expression, kind, pos);
   2245   if (kind == Yield::kDelegating) {
   2246     yield->set_index(function_state_->NextHandlerIndex());
   2247   }
   2248   return yield;
   2249 }
   2250 
   2251 
   2252 // Precedence = 3
   2253 template <class Traits>
   2254 typename ParserBase<Traits>::ExpressionT
   2255 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, bool* ok) {
   2256   // ConditionalExpression ::
   2257   //   LogicalOrExpression
   2258   //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
   2259 
   2260   int pos = peek_position();
   2261   // We start using the binary expression parser for prec >= 4 only!
   2262   ExpressionT expression = this->ParseBinaryExpression(4, accept_IN, CHECK_OK);
   2263   if (peek() != Token::CONDITIONAL) return expression;
   2264   Consume(Token::CONDITIONAL);
   2265   // In parsing the first assignment expression in conditional
   2266   // expressions we always accept the 'in' keyword; see ECMA-262,
   2267   // section 11.12, page 58.
   2268   ExpressionT left = ParseAssignmentExpression(true, CHECK_OK);
   2269   Expect(Token::COLON, CHECK_OK);
   2270   ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK);
   2271   return factory()->NewConditional(expression, left, right, pos);
   2272 }
   2273 
   2274 
   2275 // Precedence >= 4
   2276 template <class Traits>
   2277 typename ParserBase<Traits>::ExpressionT
   2278 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
   2279   DCHECK(prec >= 4);
   2280   ExpressionT x = this->ParseUnaryExpression(CHECK_OK);
   2281   for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
   2282     // prec1 >= 4
   2283     while (Precedence(peek(), accept_IN) == prec1) {
   2284       Token::Value op = Next();
   2285       int pos = position();
   2286       ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
   2287 
   2288       if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
   2289                                                        factory())) {
   2290         continue;
   2291       }
   2292 
   2293       // For now we distinguish between comparisons and other binary
   2294       // operations.  (We could combine the two and get rid of this
   2295       // code and AST node eventually.)
   2296       if (Token::IsCompareOp(op)) {
   2297         // We have a comparison.
   2298         Token::Value cmp = op;
   2299         switch (op) {
   2300           case Token::NE: cmp = Token::EQ; break;
   2301           case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
   2302           default: break;
   2303         }
   2304         x = factory()->NewCompareOperation(cmp, x, y, pos);
   2305         if (cmp != op) {
   2306           // The comparison was negated - add a NOT.
   2307           x = factory()->NewUnaryOperation(Token::NOT, x, pos);
   2308         }
   2309 
   2310       } else {
   2311         // We have a "normal" binary operation.
   2312         x = factory()->NewBinaryOperation(op, x, y, pos);
   2313       }
   2314     }
   2315   }
   2316   return x;
   2317 }
   2318 
   2319 
   2320 template <class Traits>
   2321 typename ParserBase<Traits>::ExpressionT
   2322 ParserBase<Traits>::ParseUnaryExpression(bool* ok) {
   2323   // UnaryExpression ::
   2324   //   PostfixExpression
   2325   //   'delete' UnaryExpression
   2326   //   'void' UnaryExpression
   2327   //   'typeof' UnaryExpression
   2328   //   '++' UnaryExpression
   2329   //   '--' UnaryExpression
   2330   //   '+' UnaryExpression
   2331   //   '-' UnaryExpression
   2332   //   '~' UnaryExpression
   2333   //   '!' UnaryExpression
   2334 
   2335   Token::Value op = peek();
   2336   if (Token::IsUnaryOp(op)) {
   2337     op = Next();
   2338     int pos = position();
   2339     ExpressionT expression = ParseUnaryExpression(CHECK_OK);
   2340 
   2341     // "delete identifier" is a syntax error in strict mode.
   2342     if (op == Token::DELETE && strict_mode() == STRICT &&
   2343         this->IsIdentifier(expression)) {
   2344       ReportMessage("strict_delete");
   2345       *ok = false;
   2346       return this->EmptyExpression();
   2347     }
   2348 
   2349     // Allow Traits do rewrite the expression.
   2350     return this->BuildUnaryExpression(expression, op, pos, factory());
   2351   } else if (Token::IsCountOp(op)) {
   2352     op = Next();
   2353     Scanner::Location lhs_location = scanner()->peek_location();
   2354     ExpressionT expression = this->ParseUnaryExpression(CHECK_OK);
   2355     expression = this->CheckAndRewriteReferenceExpression(
   2356         expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK);
   2357     this->MarkExpressionAsAssigned(expression);
   2358 
   2359     return factory()->NewCountOperation(op,
   2360                                         true /* prefix */,
   2361                                         expression,
   2362                                         position());
   2363 
   2364   } else {
   2365     return this->ParsePostfixExpression(ok);
   2366   }
   2367 }
   2368 
   2369 
   2370 template <class Traits>
   2371 typename ParserBase<Traits>::ExpressionT
   2372 ParserBase<Traits>::ParsePostfixExpression(bool* ok) {
   2373   // PostfixExpression ::
   2374   //   LeftHandSideExpression ('++' | '--')?
   2375 
   2376   Scanner::Location lhs_location = scanner()->peek_location();
   2377   ExpressionT expression = this->ParseLeftHandSideExpression(CHECK_OK);
   2378   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
   2379       Token::IsCountOp(peek())) {
   2380     expression = this->CheckAndRewriteReferenceExpression(
   2381         expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK);
   2382     expression = this->MarkExpressionAsAssigned(expression);
   2383 
   2384     Token::Value next = Next();
   2385     expression =
   2386         factory()->NewCountOperation(next,
   2387                                      false /* postfix */,
   2388                                      expression,
   2389                                      position());
   2390   }
   2391   return expression;
   2392 }
   2393 
   2394 
   2395 template <class Traits>
   2396 typename ParserBase<Traits>::ExpressionT
   2397 ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) {
   2398   // LeftHandSideExpression ::
   2399   //   (NewExpression | MemberExpression) ...
   2400 
   2401   ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
   2402 
   2403   while (true) {
   2404     switch (peek()) {
   2405       case Token::LBRACK: {
   2406         Consume(Token::LBRACK);
   2407         int pos = position();
   2408         ExpressionT index = ParseExpression(true, CHECK_OK);
   2409         result = factory()->NewProperty(result, index, pos);
   2410         Expect(Token::RBRACK, CHECK_OK);
   2411         break;
   2412       }
   2413 
   2414       case Token::LPAREN: {
   2415         int pos;
   2416         if (scanner()->current_token() == Token::IDENTIFIER) {
   2417           // For call of an identifier we want to report position of
   2418           // the identifier as position of the call in the stack trace.
   2419           pos = position();
   2420         } else {
   2421           // For other kinds of calls we record position of the parenthesis as
   2422           // position of the call. Note that this is extremely important for
   2423           // expressions of the form function(){...}() for which call position
   2424           // should not point to the closing brace otherwise it will intersect
   2425           // with positions recorded for function literal and confuse debugger.
   2426           pos = peek_position();
   2427           // Also the trailing parenthesis are a hint that the function will
   2428           // be called immediately. If we happen to have parsed a preceding
   2429           // function literal eagerly, we can also compile it eagerly.
   2430           if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
   2431             result->AsFunctionLiteral()->set_parenthesized();
   2432           }
   2433         }
   2434         typename Traits::Type::ExpressionList args = ParseArguments(CHECK_OK);
   2435 
   2436         // Keep track of eval() calls since they disable all local variable
   2437         // optimizations.
   2438         // The calls that need special treatment are the
   2439         // direct eval calls. These calls are all of the form eval(...), with
   2440         // no explicit receiver.
   2441         // These calls are marked as potentially direct eval calls. Whether
   2442         // they are actually direct calls to eval is determined at run time.
   2443         this->CheckPossibleEvalCall(result, scope_);
   2444         result = factory()->NewCall(result, args, pos);
   2445         if (fni_ != NULL) fni_->RemoveLastFunction();
   2446         break;
   2447       }
   2448 
   2449       case Token::PERIOD: {
   2450         Consume(Token::PERIOD);
   2451         int pos = position();
   2452         IdentifierT name = ParseIdentifierName(CHECK_OK);
   2453         result = factory()->NewProperty(
   2454             result, factory()->NewStringLiteral(name, pos), pos);
   2455         if (fni_ != NULL) this->PushLiteralName(fni_, name);
   2456         break;
   2457       }
   2458 
   2459       default:
   2460         return result;
   2461     }
   2462   }
   2463 }
   2464 
   2465 
   2466 template <class Traits>
   2467 typename ParserBase<Traits>::ExpressionT
   2468 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) {
   2469   // NewExpression ::
   2470   //   ('new')+ MemberExpression
   2471 
   2472   // The grammar for new expressions is pretty warped. We can have several 'new'
   2473   // keywords following each other, and then a MemberExpression. When we see '('
   2474   // after the MemberExpression, it's associated with the rightmost unassociated
   2475   // 'new' to create a NewExpression with arguments. However, a NewExpression
   2476   // can also occur without arguments.
   2477 
   2478   // Examples of new expression:
   2479   // new foo.bar().baz means (new (foo.bar)()).baz
   2480   // new foo()() means (new foo())()
   2481   // new new foo()() means (new (new foo())())
   2482   // new new foo means new (new foo)
   2483   // new new foo() means new (new foo())
   2484   // new new foo().bar().baz means (new (new foo()).bar()).baz
   2485 
   2486   if (peek() == Token::NEW) {
   2487     Consume(Token::NEW);
   2488     int new_pos = position();
   2489     ExpressionT result = this->EmptyExpression();
   2490     if (Check(Token::SUPER)) {
   2491       result = this->SuperReference(scope_, factory());
   2492     } else {
   2493       result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
   2494     }
   2495     if (peek() == Token::LPAREN) {
   2496       // NewExpression with arguments.
   2497       typename Traits::Type::ExpressionList args =
   2498           this->ParseArguments(CHECK_OK);
   2499       result = factory()->NewCallNew(result, args, new_pos);
   2500       // The expression can still continue with . or [ after the arguments.
   2501       result = this->ParseMemberExpressionContinuation(result, CHECK_OK);
   2502       return result;
   2503     }
   2504     // NewExpression without arguments.
   2505     return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
   2506                                  new_pos);
   2507   }
   2508   // No 'new' or 'super' keyword.
   2509   return this->ParseMemberExpression(ok);
   2510 }
   2511 
   2512 
   2513 template <class Traits>
   2514 typename ParserBase<Traits>::ExpressionT
   2515 ParserBase<Traits>::ParseMemberExpression(bool* ok) {
   2516   // MemberExpression ::
   2517   //   (PrimaryExpression | FunctionLiteral | ClassLiteral)
   2518   //     ('[' Expression ']' | '.' Identifier | Arguments)*
   2519 
   2520   // The '[' Expression ']' and '.' Identifier parts are parsed by
   2521   // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
   2522   // caller.
   2523 
   2524   // Parse the initial primary or function expression.
   2525   ExpressionT result = this->EmptyExpression();
   2526   if (peek() == Token::FUNCTION) {
   2527     Consume(Token::FUNCTION);
   2528     int function_token_position = position();
   2529     bool is_generator = Check(Token::MUL);
   2530     IdentifierT name = this->EmptyIdentifier();
   2531     bool is_strict_reserved_name = false;
   2532     Scanner::Location function_name_location = Scanner::Location::invalid();
   2533     FunctionLiteral::FunctionType function_type =
   2534         FunctionLiteral::ANONYMOUS_EXPRESSION;
   2535     if (peek_any_identifier()) {
   2536       name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
   2537                                                  CHECK_OK);
   2538       function_name_location = scanner()->location();
   2539       function_type = FunctionLiteral::NAMED_EXPRESSION;
   2540     }
   2541     result = this->ParseFunctionLiteral(
   2542         name, function_name_location, is_strict_reserved_name,
   2543         is_generator ? FunctionKind::kGeneratorFunction
   2544                      : FunctionKind::kNormalFunction,
   2545         function_token_position, function_type, FunctionLiteral::NORMAL_ARITY,
   2546         CHECK_OK);
   2547   } else if (peek() == Token::SUPER) {
   2548     int beg_pos = position();
   2549     Consume(Token::SUPER);
   2550     Token::Value next = peek();
   2551     if (next == Token::PERIOD || next == Token::LBRACK ||
   2552         next == Token::LPAREN) {
   2553       result = this->SuperReference(scope_, factory());
   2554     } else {
   2555       ReportMessageAt(Scanner::Location(beg_pos, position()),
   2556                       "unexpected_super");
   2557       *ok = false;
   2558       return this->EmptyExpression();
   2559     }
   2560   } else {
   2561     result = ParsePrimaryExpression(CHECK_OK);
   2562   }
   2563 
   2564   result = ParseMemberExpressionContinuation(result, CHECK_OK);
   2565   return result;
   2566 }
   2567 
   2568 
   2569 template <class Traits>
   2570 typename ParserBase<Traits>::ExpressionT
   2571 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
   2572                                                       bool* ok) {
   2573   // Parses this part of MemberExpression:
   2574   // ('[' Expression ']' | '.' Identifier)*
   2575   while (true) {
   2576     switch (peek()) {
   2577       case Token::LBRACK: {
   2578         Consume(Token::LBRACK);
   2579         int pos = position();
   2580         ExpressionT index = this->ParseExpression(true, CHECK_OK);
   2581         expression = factory()->NewProperty(expression, index, pos);
   2582         if (fni_ != NULL) {
   2583           this->PushPropertyName(fni_, index);
   2584         }
   2585         Expect(Token::RBRACK, CHECK_OK);
   2586         break;
   2587       }
   2588       case Token::PERIOD: {
   2589         Consume(Token::PERIOD);
   2590         int pos = position();
   2591         IdentifierT name = ParseIdentifierName(CHECK_OK);
   2592         expression = factory()->NewProperty(
   2593             expression, factory()->NewStringLiteral(name, pos), pos);
   2594         if (fni_ != NULL) {
   2595           this->PushLiteralName(fni_, name);
   2596         }
   2597         break;
   2598       }
   2599       default:
   2600         return expression;
   2601     }
   2602   }
   2603   DCHECK(false);
   2604   return this->EmptyExpression();
   2605 }
   2606 
   2607 
   2608 template <class Traits>
   2609 typename ParserBase<Traits>::ExpressionT ParserBase<
   2610     Traits>::ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
   2611                                        bool* ok) {
   2612   // TODO(aperez): Change this to use ARROW_SCOPE
   2613   typename Traits::Type::ScopePtr scope =
   2614       this->NewScope(scope_, FUNCTION_SCOPE);
   2615   typename Traits::Type::StatementList body;
   2616   typename Traits::Type::AstProperties ast_properties;
   2617   BailoutReason dont_optimize_reason = kNoReason;
   2618   int num_parameters = -1;
   2619   int materialized_literal_count = -1;
   2620   int expected_property_count = -1;
   2621   int handler_count = 0;
   2622 
   2623   {
   2624     FunctionState function_state(&function_state_, &scope_, &scope, zone(),
   2625                                  this->ast_value_factory(), ast_node_id_gen_);
   2626     Scanner::Location dupe_error_loc = Scanner::Location::invalid();
   2627     num_parameters = Traits::DeclareArrowParametersFromExpression(
   2628         params_ast, scope_, &dupe_error_loc, ok);
   2629     if (!*ok) {
   2630       ReportMessageAt(
   2631           Scanner::Location(start_pos, scanner()->location().beg_pos),
   2632           "malformed_arrow_function_parameter_list");
   2633       return this->EmptyExpression();
   2634     }
   2635 
   2636     if (num_parameters > Code::kMaxArguments) {
   2637       ReportMessageAt(Scanner::Location(params_ast->position(), position()),
   2638                       "too_many_parameters");
   2639       *ok = false;
   2640       return this->EmptyExpression();
   2641     }
   2642 
   2643     Expect(Token::ARROW, CHECK_OK);
   2644 
   2645     if (peek() == Token::LBRACE) {
   2646       // Multiple statemente body
   2647       Consume(Token::LBRACE);
   2648       bool is_lazily_parsed =
   2649           (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation());
   2650       if (is_lazily_parsed) {
   2651         body = this->NewStatementList(0, zone());
   2652         this->SkipLazyFunctionBody(this->EmptyIdentifier(),
   2653                                    &materialized_literal_count,
   2654                                    &expected_property_count, CHECK_OK);
   2655       } else {
   2656         body = this->ParseEagerFunctionBody(
   2657             this->EmptyIdentifier(), RelocInfo::kNoPosition, NULL,
   2658             Token::INIT_VAR, false,  // Not a generator.
   2659             CHECK_OK);
   2660         materialized_literal_count =
   2661             function_state.materialized_literal_count();
   2662         expected_property_count = function_state.expected_property_count();
   2663         handler_count = function_state.handler_count();
   2664       }
   2665     } else {
   2666       // Single-expression body
   2667       int pos = position();
   2668       parenthesized_function_ = false;
   2669       ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK);
   2670       body = this->NewStatementList(1, zone());
   2671       body->Add(factory()->NewReturnStatement(expression, pos), zone());
   2672       materialized_literal_count = function_state.materialized_literal_count();
   2673       expected_property_count = function_state.expected_property_count();
   2674       handler_count = function_state.handler_count();
   2675     }
   2676 
   2677     scope->set_start_position(start_pos);
   2678     scope->set_end_position(scanner()->location().end_pos);
   2679 
   2680     // Arrow function *parameter lists* are always checked as in strict mode.
   2681     bool function_name_is_strict_reserved = false;
   2682     Scanner::Location function_name_loc = Scanner::Location::invalid();
   2683     Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
   2684     Scanner::Location reserved_loc = Scanner::Location::invalid();
   2685     this->CheckStrictFunctionNameAndParameters(
   2686         this->EmptyIdentifier(), function_name_is_strict_reserved,
   2687         function_name_loc, eval_args_error_loc, dupe_error_loc, reserved_loc,
   2688         CHECK_OK);
   2689 
   2690     // Validate strict mode.
   2691     if (strict_mode() == STRICT) {
   2692       CheckOctalLiteral(start_pos, scanner()->location().end_pos, CHECK_OK);
   2693     }
   2694 
   2695     if (allow_harmony_scoping() && strict_mode() == STRICT)
   2696       this->CheckConflictingVarDeclarations(scope, CHECK_OK);
   2697 
   2698     ast_properties = *factory()->visitor()->ast_properties();
   2699     dont_optimize_reason = factory()->visitor()->dont_optimize_reason();
   2700   }
   2701 
   2702   FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
   2703       this->EmptyIdentifierString(), this->ast_value_factory(), scope, body,
   2704       materialized_literal_count, expected_property_count, handler_count,
   2705       num_parameters, FunctionLiteral::kNoDuplicateParameters,
   2706       FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
   2707       FunctionLiteral::kNotParenthesized, FunctionKind::kArrowFunction,
   2708       start_pos);
   2709 
   2710   function_literal->set_function_token_position(start_pos);
   2711   function_literal->set_ast_properties(&ast_properties);
   2712   function_literal->set_dont_optimize_reason(dont_optimize_reason);
   2713 
   2714   if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
   2715 
   2716   return function_literal;
   2717 }
   2718 
   2719 
   2720 template <class Traits>
   2721 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseClassLiteral(
   2722     IdentifierT name, Scanner::Location class_name_location,
   2723     bool name_is_strict_reserved, int pos, bool* ok) {
   2724   // All parts of a ClassDeclaration or a ClassExpression are strict code.
   2725   if (name_is_strict_reserved) {
   2726     ReportMessageAt(class_name_location, "unexpected_strict_reserved");
   2727     *ok = false;
   2728     return this->EmptyExpression();
   2729   }
   2730   if (this->IsEvalOrArguments(name)) {
   2731     ReportMessageAt(class_name_location, "strict_eval_arguments");
   2732     *ok = false;
   2733     return this->EmptyExpression();
   2734   }
   2735 
   2736   // TODO(arv): Implement scopes and name binding in class body only.
   2737   // TODO(arv): Maybe add CLASS_SCOPE?
   2738   typename Traits::Type::ScopePtr extends_scope =
   2739       this->NewScope(scope_, BLOCK_SCOPE);
   2740   FunctionState extends_function_state(
   2741       &function_state_, &scope_, &extends_scope, zone(),
   2742       this->ast_value_factory(), ast_node_id_gen_);
   2743   scope_->SetStrictMode(STRICT);
   2744   scope_->SetScopeName(name);
   2745 
   2746   ExpressionT extends = this->EmptyExpression();
   2747   if (Check(Token::EXTENDS)) {
   2748     extends = this->ParseLeftHandSideExpression(CHECK_OK);
   2749   }
   2750 
   2751   ObjectLiteralChecker checker(this, STRICT);
   2752   typename Traits::Type::PropertyList properties =
   2753       this->NewPropertyList(4, zone_);
   2754   FunctionLiteralT constructor = this->EmptyFunctionLiteral();
   2755 
   2756   Expect(Token::LBRACE, CHECK_OK);
   2757   while (peek() != Token::RBRACE) {
   2758     if (Check(Token::SEMICOLON)) continue;
   2759     if (fni_ != NULL) fni_->Enter();
   2760 
   2761     const bool in_class = true;
   2762     const bool is_static = false;
   2763     ObjectLiteralPropertyT property =
   2764         this->ParsePropertyDefinition(&checker, in_class, is_static, CHECK_OK);
   2765 
   2766     properties->Add(property, zone());
   2767 
   2768     if (fni_ != NULL) {
   2769       fni_->Infer();
   2770       fni_->Leave();
   2771     }
   2772   }
   2773   Expect(Token::RBRACE, CHECK_OK);
   2774 
   2775   return this->ClassLiteral(name, extends, constructor, properties, pos,
   2776                             factory());
   2777 }
   2778 
   2779 
   2780 template <typename Traits>
   2781 typename ParserBase<Traits>::ExpressionT
   2782 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
   2783     ExpressionT expression,
   2784     Scanner::Location location, const char* message, bool* ok) {
   2785   if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
   2786       this->IsEvalOrArguments(this->AsIdentifier(expression))) {
   2787     this->ReportMessageAt(location, "strict_eval_arguments", false);
   2788     *ok = false;
   2789     return this->EmptyExpression();
   2790   } else if (expression->IsValidReferenceExpression()) {
   2791     return expression;
   2792   } else if (expression->IsCall()) {
   2793     // If it is a call, make it a runtime error for legacy web compatibility.
   2794     // Rewrite `expr' to `expr[throw ReferenceError]'.
   2795     int pos = location.beg_pos;
   2796     ExpressionT error = this->NewThrowReferenceError(message, pos);
   2797     return factory()->NewProperty(expression, error, pos);
   2798   } else {
   2799     this->ReportMessageAt(location, message, true);
   2800     *ok = false;
   2801     return this->EmptyExpression();
   2802   }
   2803 }
   2804 
   2805 
   2806 #undef CHECK_OK
   2807 #undef CHECK_OK_CUSTOM
   2808 
   2809 
   2810 template <typename Traits>
   2811 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
   2812     Token::Value property, PropertyKind type, bool* ok) {
   2813   int old;
   2814   if (property == Token::NUMBER) {
   2815     old = scanner()->FindNumber(&finder_, type);
   2816   } else {
   2817     old = scanner()->FindSymbol(&finder_, type);
   2818   }
   2819   PropertyKind old_type = static_cast<PropertyKind>(old);
   2820   if (HasConflict(old_type, type)) {
   2821     if (IsDataDataConflict(old_type, type)) {
   2822       // Both are data properties.
   2823       if (strict_mode_ == SLOPPY) return;
   2824       parser()->ReportMessage("strict_duplicate_property");
   2825     } else if (IsDataAccessorConflict(old_type, type)) {
   2826       // Both a data and an accessor property with the same name.
   2827       parser()->ReportMessage("accessor_data_property");
   2828     } else {
   2829       DCHECK(IsAccessorAccessorConflict(old_type, type));
   2830       // Both accessors of the same type.
   2831       parser()->ReportMessage("accessor_get_set");
   2832     }
   2833     *ok = false;
   2834   }
   2835 }
   2836 } }  // v8::internal
   2837 
   2838 #endif  // V8_PREPARSER_H
   2839