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/func-name-inferrer.h"
      9 #include "src/hashmap.h"
     10 #include "src/scopes.h"
     11 #include "src/token.h"
     12 #include "src/scanner.h"
     13 #include "src/v8.h"
     14 
     15 namespace v8 {
     16 namespace internal {
     17 
     18 // Common base class shared between parser and pre-parser. Traits encapsulate
     19 // the differences between Parser and PreParser:
     20 
     21 // - Return types: For example, Parser functions return Expression* and
     22 // PreParser functions return PreParserExpression.
     23 
     24 // - Creating parse tree nodes: Parser generates an AST during the recursive
     25 // descent. PreParser doesn't create a tree. Instead, it passes around minimal
     26 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
     27 // just enough data for the upper layer functions. PreParserFactory is
     28 // responsible for creating these dummy objects. It provides a similar kind of
     29 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is
     30 // used.
     31 
     32 // - Miscellanous other tasks interleaved with the recursive descent. For
     33 // example, Parser keeps track of which function literals should be marked as
     34 // pretenured, and PreParser doesn't care.
     35 
     36 // The traits are expected to contain the following typedefs:
     37 // struct Traits {
     38 //   // In particular...
     39 //   struct Type {
     40 //     // Used by FunctionState and BlockState.
     41 //     typedef Scope;
     42 //     typedef GeneratorVariable;
     43 //     typedef Zone;
     44 //     // Return types for traversing functions.
     45 //     typedef Identifier;
     46 //     typedef Expression;
     47 //     typedef FunctionLiteral;
     48 //     typedef ObjectLiteralProperty;
     49 //     typedef Literal;
     50 //     typedef ExpressionList;
     51 //     typedef PropertyList;
     52 //     // For constructing objects returned by the traversing functions.
     53 //     typedef Factory;
     54 //   };
     55 //   // ...
     56 // };
     57 
     58 template <typename Traits>
     59 class ParserBase : public Traits {
     60  public:
     61   // Shorten type names defined by Traits.
     62   typedef typename Traits::Type::Expression ExpressionT;
     63   typedef typename Traits::Type::Identifier IdentifierT;
     64 
     65   ParserBase(Scanner* scanner, uintptr_t stack_limit,
     66              v8::Extension* extension,
     67              ParserRecorder* log,
     68              typename Traits::Type::Zone* zone,
     69              typename Traits::Type::Parser this_object)
     70       : Traits(this_object),
     71         parenthesized_function_(false),
     72         scope_(NULL),
     73         function_state_(NULL),
     74         extension_(extension),
     75         fni_(NULL),
     76         log_(log),
     77         mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
     78         scanner_(scanner),
     79         stack_limit_(stack_limit),
     80         stack_overflow_(false),
     81         allow_lazy_(false),
     82         allow_natives_syntax_(false),
     83         allow_generators_(false),
     84         allow_for_of_(false),
     85         zone_(zone) { }
     86 
     87   // Getters that indicate whether certain syntactical constructs are
     88   // allowed to be parsed by this instance of the parser.
     89   bool allow_lazy() const { return allow_lazy_; }
     90   bool allow_natives_syntax() const { return allow_natives_syntax_; }
     91   bool allow_generators() const { return allow_generators_; }
     92   bool allow_for_of() const { return allow_for_of_; }
     93   bool allow_modules() const { return scanner()->HarmonyModules(); }
     94   bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
     95   bool allow_harmony_numeric_literals() const {
     96     return scanner()->HarmonyNumericLiterals();
     97   }
     98 
     99   // Setters that determine whether certain syntactical constructs are
    100   // allowed to be parsed by this instance of the parser.
    101   void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
    102   void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
    103   void set_allow_generators(bool allow) { allow_generators_ = allow; }
    104   void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
    105   void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
    106   void set_allow_harmony_scoping(bool allow) {
    107     scanner()->SetHarmonyScoping(allow);
    108   }
    109   void set_allow_harmony_numeric_literals(bool allow) {
    110     scanner()->SetHarmonyNumericLiterals(allow);
    111   }
    112 
    113  protected:
    114   enum AllowEvalOrArgumentsAsIdentifier {
    115     kAllowEvalOrArguments,
    116     kDontAllowEvalOrArguments
    117   };
    118 
    119   enum Mode {
    120     PARSE_LAZILY,
    121     PARSE_EAGERLY
    122   };
    123 
    124   // ---------------------------------------------------------------------------
    125   // FunctionState and BlockState together implement the parser's scope stack.
    126   // The parser's current scope is in scope_. BlockState and FunctionState
    127   // constructors push on the scope stack and the destructors pop. They are also
    128   // used to hold the parser's per-function and per-block state.
    129   class BlockState BASE_EMBEDDED {
    130    public:
    131     BlockState(typename Traits::Type::Scope** scope_stack,
    132                typename Traits::Type::Scope* scope)
    133         : scope_stack_(scope_stack),
    134           outer_scope_(*scope_stack),
    135           scope_(scope) {
    136       *scope_stack_ = scope_;
    137     }
    138     ~BlockState() { *scope_stack_ = outer_scope_; }
    139 
    140    private:
    141     typename Traits::Type::Scope** scope_stack_;
    142     typename Traits::Type::Scope* outer_scope_;
    143     typename Traits::Type::Scope* scope_;
    144   };
    145 
    146   class FunctionState BASE_EMBEDDED {
    147    public:
    148     FunctionState(
    149         FunctionState** function_state_stack,
    150         typename Traits::Type::Scope** scope_stack,
    151         typename Traits::Type::Scope* scope,
    152         typename Traits::Type::Zone* zone = NULL);
    153     ~FunctionState();
    154 
    155     int NextMaterializedLiteralIndex() {
    156       return next_materialized_literal_index_++;
    157     }
    158     int materialized_literal_count() {
    159       return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize;
    160     }
    161 
    162     int NextHandlerIndex() { return next_handler_index_++; }
    163     int handler_count() { return next_handler_index_; }
    164 
    165     void AddProperty() { expected_property_count_++; }
    166     int expected_property_count() { return expected_property_count_; }
    167 
    168     void set_is_generator(bool is_generator) { is_generator_ = is_generator; }
    169     bool is_generator() const { return is_generator_; }
    170 
    171     void set_generator_object_variable(
    172         typename Traits::Type::GeneratorVariable* variable) {
    173       ASSERT(variable != NULL);
    174       ASSERT(!is_generator());
    175       generator_object_variable_ = variable;
    176       is_generator_ = true;
    177     }
    178     typename Traits::Type::GeneratorVariable* generator_object_variable()
    179         const {
    180       return generator_object_variable_;
    181     }
    182 
    183     typename Traits::Type::Factory* factory() { return &factory_; }
    184 
    185    private:
    186     // Used to assign an index to each literal that needs materialization in
    187     // the function.  Includes regexp literals, and boilerplate for object and
    188     // array literals.
    189     int next_materialized_literal_index_;
    190 
    191     // Used to assign a per-function index to try and catch handlers.
    192     int next_handler_index_;
    193 
    194     // Properties count estimation.
    195     int expected_property_count_;
    196 
    197     // Whether the function is a generator.
    198     bool is_generator_;
    199     // For generators, this variable may hold the generator object. It variable
    200     // is used by yield expressions and return statements. It is not necessary
    201     // for generator functions to have this variable set.
    202     Variable* generator_object_variable_;
    203 
    204     FunctionState** function_state_stack_;
    205     FunctionState* outer_function_state_;
    206     typename Traits::Type::Scope** scope_stack_;
    207     typename Traits::Type::Scope* outer_scope_;
    208     int saved_ast_node_id_;  // Only used by ParserTraits.
    209     typename Traits::Type::Zone* extra_param_;
    210     typename Traits::Type::Factory factory_;
    211 
    212     friend class ParserTraits;
    213   };
    214 
    215   class ParsingModeScope BASE_EMBEDDED {
    216    public:
    217     ParsingModeScope(ParserBase* parser, Mode mode)
    218         : parser_(parser),
    219           old_mode_(parser->mode()) {
    220       parser_->mode_ = mode;
    221     }
    222     ~ParsingModeScope() {
    223       parser_->mode_ = old_mode_;
    224     }
    225 
    226    private:
    227     ParserBase* parser_;
    228     Mode old_mode_;
    229   };
    230 
    231   Scanner* scanner() const { return scanner_; }
    232   int position() { return scanner_->location().beg_pos; }
    233   int peek_position() { return scanner_->peek_location().beg_pos; }
    234   bool stack_overflow() const { return stack_overflow_; }
    235   void set_stack_overflow() { stack_overflow_ = true; }
    236   Mode mode() const { return mode_; }
    237   typename Traits::Type::Zone* zone() const { return zone_; }
    238 
    239   INLINE(Token::Value peek()) {
    240     if (stack_overflow_) return Token::ILLEGAL;
    241     return scanner()->peek();
    242   }
    243 
    244   INLINE(Token::Value Next()) {
    245     if (stack_overflow_) return Token::ILLEGAL;
    246     {
    247       int marker;
    248       if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) {
    249         // Any further calls to Next or peek will return the illegal token.
    250         // The current call must return the next token, which might already
    251         // have been peek'ed.
    252         stack_overflow_ = true;
    253       }
    254     }
    255     return scanner()->Next();
    256   }
    257 
    258   void Consume(Token::Value token) {
    259     Token::Value next = Next();
    260     USE(next);
    261     USE(token);
    262     ASSERT(next == token);
    263   }
    264 
    265   bool Check(Token::Value token) {
    266     Token::Value next = peek();
    267     if (next == token) {
    268       Consume(next);
    269       return true;
    270     }
    271     return false;
    272   }
    273 
    274   void Expect(Token::Value token, bool* ok) {
    275     Token::Value next = Next();
    276     if (next != token) {
    277       ReportUnexpectedToken(next);
    278       *ok = false;
    279     }
    280   }
    281 
    282   void ExpectSemicolon(bool* ok) {
    283     // Check for automatic semicolon insertion according to
    284     // the rules given in ECMA-262, section 7.9, page 21.
    285     Token::Value tok = peek();
    286     if (tok == Token::SEMICOLON) {
    287       Next();
    288       return;
    289     }
    290     if (scanner()->HasAnyLineTerminatorBeforeNext() ||
    291         tok == Token::RBRACE ||
    292         tok == Token::EOS) {
    293       return;
    294     }
    295     Expect(Token::SEMICOLON, ok);
    296   }
    297 
    298   bool peek_any_identifier() {
    299     Token::Value next = peek();
    300     return next == Token::IDENTIFIER ||
    301         next == Token::FUTURE_RESERVED_WORD ||
    302         next == Token::FUTURE_STRICT_RESERVED_WORD ||
    303         next == Token::YIELD;
    304   }
    305 
    306   bool CheckContextualKeyword(Vector<const char> keyword) {
    307     if (peek() == Token::IDENTIFIER &&
    308         scanner()->is_next_contextual_keyword(keyword)) {
    309       Consume(Token::IDENTIFIER);
    310       return true;
    311     }
    312     return false;
    313   }
    314 
    315   void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
    316     Expect(Token::IDENTIFIER, ok);
    317     if (!*ok) return;
    318     if (!scanner()->is_literal_contextual_keyword(keyword)) {
    319       ReportUnexpectedToken(scanner()->current_token());
    320       *ok = false;
    321     }
    322   }
    323 
    324   // Checks whether an octal literal was last seen between beg_pos and end_pos.
    325   // If so, reports an error. Only called for strict mode.
    326   void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
    327     Scanner::Location octal = scanner()->octal_position();
    328     if (octal.IsValid() && beg_pos <= octal.beg_pos &&
    329         octal.end_pos <= end_pos) {
    330       ReportMessageAt(octal, "strict_octal_literal");
    331       scanner()->clear_octal_position();
    332       *ok = false;
    333     }
    334   }
    335 
    336   // Determine precedence of given token.
    337   static int Precedence(Token::Value token, bool accept_IN) {
    338     if (token == Token::IN && !accept_IN)
    339       return 0;  // 0 precedence will terminate binary expression parsing
    340     return Token::Precedence(token);
    341   }
    342 
    343   typename Traits::Type::Factory* factory() {
    344     return function_state_->factory();
    345   }
    346 
    347   StrictMode strict_mode() { return scope_->strict_mode(); }
    348   bool is_generator() const { return function_state_->is_generator(); }
    349 
    350   // Report syntax errors.
    351   void ReportMessage(const char* message, const char* arg = NULL,
    352                      bool is_reference_error = false) {
    353     Scanner::Location source_location = scanner()->location();
    354     Traits::ReportMessageAt(source_location, message, arg, is_reference_error);
    355   }
    356 
    357   void ReportMessageAt(Scanner::Location location, const char* message,
    358                        bool is_reference_error = false) {
    359     Traits::ReportMessageAt(location, message, NULL, is_reference_error);
    360   }
    361 
    362   void ReportUnexpectedToken(Token::Value token);
    363 
    364   // Recursive descent functions:
    365 
    366   // Parses an identifier that is valid for the current scope, in particular it
    367   // fails on strict mode future reserved keywords in a strict scope. If
    368   // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
    369   // "arguments" as identifier even in strict mode (this is needed in cases like
    370   // "var foo = eval;").
    371   IdentifierT ParseIdentifier(
    372       AllowEvalOrArgumentsAsIdentifier,
    373       bool* ok);
    374   // Parses an identifier or a strict mode future reserved word, and indicate
    375   // whether it is strict mode future reserved.
    376   IdentifierT ParseIdentifierOrStrictReservedWord(
    377       bool* is_strict_reserved,
    378       bool* ok);
    379   IdentifierT ParseIdentifierName(bool* ok);
    380   // Parses an identifier and determines whether or not it is 'get' or 'set'.
    381   IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get,
    382                                             bool* is_set,
    383                                             bool* ok);
    384 
    385   ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok);
    386 
    387   ExpressionT ParsePrimaryExpression(bool* ok);
    388   ExpressionT ParseExpression(bool accept_IN, bool* ok);
    389   ExpressionT ParseArrayLiteral(bool* ok);
    390   ExpressionT ParseObjectLiteral(bool* ok);
    391   typename Traits::Type::ExpressionList ParseArguments(bool* ok);
    392   ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
    393   ExpressionT ParseYieldExpression(bool* ok);
    394   ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
    395   ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
    396   ExpressionT ParseUnaryExpression(bool* ok);
    397   ExpressionT ParsePostfixExpression(bool* ok);
    398   ExpressionT ParseLeftHandSideExpression(bool* ok);
    399   ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
    400   ExpressionT ParseMemberExpression(bool* ok);
    401   ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
    402                                                 bool* ok);
    403 
    404   // Checks if the expression is a valid reference expression (e.g., on the
    405   // left-hand side of assignments). Although ruled out by ECMA as early errors,
    406   // we allow calls for web compatibility and rewrite them to a runtime throw.
    407   ExpressionT CheckAndRewriteReferenceExpression(
    408       ExpressionT expression,
    409       Scanner::Location location, const char* message, bool* ok);
    410 
    411   // Used to detect duplicates in object literals. Each of the values
    412   // kGetterProperty, kSetterProperty and kValueProperty represents
    413   // a type of object literal property. When parsing a property, its
    414   // type value is stored in the DuplicateFinder for the property name.
    415   // Values are chosen so that having intersection bits means the there is
    416   // an incompatibility.
    417   // I.e., you can add a getter to a property that already has a setter, since
    418   // kGetterProperty and kSetterProperty doesn't intersect, but not if it
    419   // already has a getter or a value. Adding the getter to an existing
    420   // setter will store the value (kGetterProperty | kSetterProperty), which
    421   // is incompatible with adding any further properties.
    422   enum PropertyKind {
    423     kNone = 0,
    424     // Bit patterns representing different object literal property types.
    425     kGetterProperty = 1,
    426     kSetterProperty = 2,
    427     kValueProperty = 7,
    428     // Helper constants.
    429     kValueFlag = 4
    430   };
    431 
    432   // Validation per ECMA 262 - 11.1.5 "Object Initialiser".
    433   class ObjectLiteralChecker {
    434    public:
    435     ObjectLiteralChecker(ParserBase* parser, StrictMode strict_mode)
    436         : parser_(parser),
    437           finder_(scanner()->unicode_cache()),
    438           strict_mode_(strict_mode) { }
    439 
    440     void CheckProperty(Token::Value property, PropertyKind type, bool* ok);
    441 
    442    private:
    443     ParserBase* parser() const { return parser_; }
    444     Scanner* scanner() const { return parser_->scanner(); }
    445 
    446     // Checks the type of conflict based on values coming from PropertyType.
    447     bool HasConflict(PropertyKind type1, PropertyKind type2) {
    448       return (type1 & type2) != 0;
    449     }
    450     bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) {
    451       return ((type1 & type2) & kValueFlag) != 0;
    452     }
    453     bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) {
    454       return ((type1 ^ type2) & kValueFlag) != 0;
    455     }
    456     bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) {
    457       return ((type1 | type2) & kValueFlag) == 0;
    458     }
    459 
    460     ParserBase* parser_;
    461     DuplicateFinder finder_;
    462     StrictMode strict_mode_;
    463   };
    464 
    465   // If true, the next (and immediately following) function literal is
    466   // preceded by a parenthesis.
    467   // Heuristically that means that the function will be called immediately,
    468   // so never lazily compile it.
    469   bool parenthesized_function_;
    470 
    471   typename Traits::Type::Scope* scope_;  // Scope stack.
    472   FunctionState* function_state_;  // Function state stack.
    473   v8::Extension* extension_;
    474   FuncNameInferrer* fni_;
    475   ParserRecorder* log_;
    476   Mode mode_;
    477 
    478  private:
    479   Scanner* scanner_;
    480   uintptr_t stack_limit_;
    481   bool stack_overflow_;
    482 
    483   bool allow_lazy_;
    484   bool allow_natives_syntax_;
    485   bool allow_generators_;
    486   bool allow_for_of_;
    487 
    488   typename Traits::Type::Zone* zone_;  // Only used by Parser.
    489 };
    490 
    491 
    492 class PreParserIdentifier {
    493  public:
    494   PreParserIdentifier() : type_(kUnknownIdentifier) {}
    495   static PreParserIdentifier Default() {
    496     return PreParserIdentifier(kUnknownIdentifier);
    497   }
    498   static PreParserIdentifier Eval() {
    499     return PreParserIdentifier(kEvalIdentifier);
    500   }
    501   static PreParserIdentifier Arguments() {
    502     return PreParserIdentifier(kArgumentsIdentifier);
    503   }
    504   static PreParserIdentifier FutureReserved() {
    505     return PreParserIdentifier(kFutureReservedIdentifier);
    506   }
    507   static PreParserIdentifier FutureStrictReserved() {
    508     return PreParserIdentifier(kFutureStrictReservedIdentifier);
    509   }
    510   static PreParserIdentifier Yield() {
    511     return PreParserIdentifier(kYieldIdentifier);
    512   }
    513   bool IsEval() { return type_ == kEvalIdentifier; }
    514   bool IsArguments() { return type_ == kArgumentsIdentifier; }
    515   bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; }
    516   bool IsYield() { return type_ == kYieldIdentifier; }
    517   bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; }
    518   bool IsFutureStrictReserved() {
    519     return type_ == kFutureStrictReservedIdentifier;
    520   }
    521   bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; }
    522 
    523  private:
    524   enum Type {
    525     kUnknownIdentifier,
    526     kFutureReservedIdentifier,
    527     kFutureStrictReservedIdentifier,
    528     kYieldIdentifier,
    529     kEvalIdentifier,
    530     kArgumentsIdentifier
    531   };
    532   explicit PreParserIdentifier(Type type) : type_(type) {}
    533   Type type_;
    534 
    535   friend class PreParserExpression;
    536 };
    537 
    538 
    539 // Bits 0 and 1 are used to identify the type of expression:
    540 // If bit 0 is set, it's an identifier.
    541 // if bit 1 is set, it's a string literal.
    542 // If neither is set, it's no particular type, and both set isn't
    543 // use yet.
    544 class PreParserExpression {
    545  public:
    546   static PreParserExpression Default() {
    547     return PreParserExpression(kUnknownExpression);
    548   }
    549 
    550   static PreParserExpression FromIdentifier(PreParserIdentifier id) {
    551     return PreParserExpression(kIdentifierFlag |
    552                                (id.type_ << kIdentifierShift));
    553   }
    554 
    555   static PreParserExpression StringLiteral() {
    556     return PreParserExpression(kUnknownStringLiteral);
    557   }
    558 
    559   static PreParserExpression UseStrictStringLiteral() {
    560     return PreParserExpression(kUseStrictString);
    561   }
    562 
    563   static PreParserExpression This() {
    564     return PreParserExpression(kThisExpression);
    565   }
    566 
    567   static PreParserExpression ThisProperty() {
    568     return PreParserExpression(kThisPropertyExpression);
    569   }
    570 
    571   static PreParserExpression Property() {
    572     return PreParserExpression(kPropertyExpression);
    573   }
    574 
    575   static PreParserExpression Call() {
    576     return PreParserExpression(kCallExpression);
    577   }
    578 
    579   bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; }
    580 
    581   PreParserIdentifier AsIdentifier() {
    582     ASSERT(IsIdentifier());
    583     return PreParserIdentifier(
    584         static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift));
    585   }
    586 
    587   bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; }
    588 
    589   bool IsUseStrictLiteral() {
    590     return (code_ & kStringLiteralMask) == kUseStrictString;
    591   }
    592 
    593   bool IsThis() { return code_ == kThisExpression; }
    594 
    595   bool IsThisProperty() { return code_ == kThisPropertyExpression; }
    596 
    597   bool IsProperty() {
    598     return code_ == kPropertyExpression || code_ == kThisPropertyExpression;
    599   }
    600 
    601   bool IsCall() { return code_ == kCallExpression; }
    602 
    603   bool IsValidReferenceExpression() {
    604     return IsIdentifier() || IsProperty();
    605   }
    606 
    607   // At the moment PreParser doesn't track these expression types.
    608   bool IsFunctionLiteral() const { return false; }
    609   bool IsCallNew() const { return false; }
    610 
    611   PreParserExpression AsFunctionLiteral() { return *this; }
    612 
    613   // Dummy implementation for making expression->somefunc() work in both Parser
    614   // and PreParser.
    615   PreParserExpression* operator->() { return this; }
    616 
    617   // More dummy implementations of things PreParser doesn't need to track:
    618   void set_index(int index) {}  // For YieldExpressions
    619   void set_parenthesized() {}
    620 
    621  private:
    622   // Least significant 2 bits are used as flags. Bits 0 and 1 represent
    623   // identifiers or strings literals, and are mutually exclusive, but can both
    624   // be absent. If the expression is an identifier or a string literal, the
    625   // other bits describe the type (see PreParserIdentifier::Type and string
    626   // literal constants below).
    627   enum {
    628     kUnknownExpression = 0,
    629     // Identifiers
    630     kIdentifierFlag = 1,  // Used to detect labels.
    631     kIdentifierShift = 3,
    632 
    633     kStringLiteralFlag = 2,  // Used to detect directive prologue.
    634     kUnknownStringLiteral = kStringLiteralFlag,
    635     kUseStrictString = kStringLiteralFlag | 8,
    636     kStringLiteralMask = kUseStrictString,
    637 
    638     // Below here applies if neither identifier nor string literal. Reserve the
    639     // 2 least significant bits for flags.
    640     kThisExpression = 1 << 2,
    641     kThisPropertyExpression = 2 << 2,
    642     kPropertyExpression = 3 << 2,
    643     kCallExpression = 4 << 2
    644   };
    645 
    646   explicit PreParserExpression(int expression_code) : code_(expression_code) {}
    647 
    648   int code_;
    649 };
    650 
    651 
    652 // PreParserExpressionList doesn't actually store the expressions because
    653 // PreParser doesn't need to.
    654 class PreParserExpressionList {
    655  public:
    656   // These functions make list->Add(some_expression) work (and do nothing).
    657   PreParserExpressionList() : length_(0) {}
    658   PreParserExpressionList* operator->() { return this; }
    659   void Add(PreParserExpression, void*) { ++length_; }
    660   int length() const { return length_; }
    661  private:
    662   int length_;
    663 };
    664 
    665 
    666 class PreParserStatement {
    667  public:
    668   static PreParserStatement Default() {
    669     return PreParserStatement(kUnknownStatement);
    670   }
    671 
    672   static PreParserStatement FunctionDeclaration() {
    673     return PreParserStatement(kFunctionDeclaration);
    674   }
    675 
    676   // Creates expression statement from expression.
    677   // Preserves being an unparenthesized string literal, possibly
    678   // "use strict".
    679   static PreParserStatement ExpressionStatement(
    680       PreParserExpression expression) {
    681     if (expression.IsUseStrictLiteral()) {
    682       return PreParserStatement(kUseStrictExpressionStatement);
    683     }
    684     if (expression.IsStringLiteral()) {
    685       return PreParserStatement(kStringLiteralExpressionStatement);
    686     }
    687     return Default();
    688   }
    689 
    690   bool IsStringLiteral() {
    691     return code_ == kStringLiteralExpressionStatement;
    692   }
    693 
    694   bool IsUseStrictLiteral() {
    695     return code_ == kUseStrictExpressionStatement;
    696   }
    697 
    698   bool IsFunctionDeclaration() {
    699     return code_ == kFunctionDeclaration;
    700   }
    701 
    702  private:
    703   enum Type {
    704     kUnknownStatement,
    705     kStringLiteralExpressionStatement,
    706     kUseStrictExpressionStatement,
    707     kFunctionDeclaration
    708   };
    709 
    710   explicit PreParserStatement(Type code) : code_(code) {}
    711   Type code_;
    712 };
    713 
    714 
    715 
    716 // PreParserStatementList doesn't actually store the statements because
    717 // the PreParser does not need them.
    718 class PreParserStatementList {
    719  public:
    720   // These functions make list->Add(some_expression) work as no-ops.
    721   PreParserStatementList() {}
    722   PreParserStatementList* operator->() { return this; }
    723   void Add(PreParserStatement, void*) {}
    724 };
    725 
    726 
    727 class PreParserScope {
    728  public:
    729   explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type)
    730       : scope_type_(scope_type) {
    731     strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY;
    732   }
    733 
    734   ScopeType type() { return scope_type_; }
    735   StrictMode strict_mode() const { return strict_mode_; }
    736   void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
    737 
    738  private:
    739   ScopeType scope_type_;
    740   StrictMode strict_mode_;
    741 };
    742 
    743 
    744 class PreParserFactory {
    745  public:
    746   explicit PreParserFactory(void* extra_param) {}
    747   PreParserExpression NewLiteral(PreParserIdentifier identifier,
    748                                  int pos) {
    749     return PreParserExpression::Default();
    750   }
    751   PreParserExpression NewNumberLiteral(double number,
    752                                        int pos) {
    753     return PreParserExpression::Default();
    754   }
    755   PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
    756                                        PreParserIdentifier js_flags,
    757                                        int literal_index,
    758                                        int pos) {
    759     return PreParserExpression::Default();
    760   }
    761   PreParserExpression NewArrayLiteral(PreParserExpressionList values,
    762                                       int literal_index,
    763                                       int pos) {
    764     return PreParserExpression::Default();
    765   }
    766   PreParserExpression NewObjectLiteralProperty(bool is_getter,
    767                                                PreParserExpression value,
    768                                                int pos) {
    769     return PreParserExpression::Default();
    770   }
    771   PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
    772                                                PreParserExpression value) {
    773     return PreParserExpression::Default();
    774   }
    775   PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
    776                                        int literal_index,
    777                                        int boilerplate_properties,
    778                                        bool has_function,
    779                                        int pos) {
    780     return PreParserExpression::Default();
    781   }
    782   PreParserExpression NewVariableProxy(void* generator_variable) {
    783     return PreParserExpression::Default();
    784   }
    785   PreParserExpression NewProperty(PreParserExpression obj,
    786                                   PreParserExpression key,
    787                                   int pos) {
    788     if (obj.IsThis()) {
    789       return PreParserExpression::ThisProperty();
    790     }
    791     return PreParserExpression::Property();
    792   }
    793   PreParserExpression NewUnaryOperation(Token::Value op,
    794                                         PreParserExpression expression,
    795                                         int pos) {
    796     return PreParserExpression::Default();
    797   }
    798   PreParserExpression NewBinaryOperation(Token::Value op,
    799                                          PreParserExpression left,
    800                                          PreParserExpression right, int pos) {
    801     return PreParserExpression::Default();
    802   }
    803   PreParserExpression NewCompareOperation(Token::Value op,
    804                                           PreParserExpression left,
    805                                           PreParserExpression right, int pos) {
    806     return PreParserExpression::Default();
    807   }
    808   PreParserExpression NewAssignment(Token::Value op,
    809                                     PreParserExpression left,
    810                                     PreParserExpression right,
    811                                     int pos) {
    812     return PreParserExpression::Default();
    813   }
    814   PreParserExpression NewYield(PreParserExpression generator_object,
    815                                PreParserExpression expression,
    816                                Yield::Kind yield_kind,
    817                                int pos) {
    818     return PreParserExpression::Default();
    819   }
    820   PreParserExpression NewConditional(PreParserExpression condition,
    821                                      PreParserExpression then_expression,
    822                                      PreParserExpression else_expression,
    823                                      int pos) {
    824     return PreParserExpression::Default();
    825   }
    826   PreParserExpression NewCountOperation(Token::Value op,
    827                                         bool is_prefix,
    828                                         PreParserExpression expression,
    829                                         int pos) {
    830     return PreParserExpression::Default();
    831   }
    832   PreParserExpression NewCall(PreParserExpression expression,
    833                               PreParserExpressionList arguments,
    834                               int pos) {
    835     return PreParserExpression::Call();
    836   }
    837   PreParserExpression NewCallNew(PreParserExpression expression,
    838                                  PreParserExpressionList arguments,
    839                                  int pos) {
    840     return PreParserExpression::Default();
    841   }
    842 };
    843 
    844 
    845 class PreParser;
    846 
    847 class PreParserTraits {
    848  public:
    849   struct Type {
    850     // TODO(marja): To be removed. The Traits object should contain all the data
    851     // it needs.
    852     typedef PreParser* Parser;
    853 
    854     // Used by FunctionState and BlockState.
    855     typedef PreParserScope Scope;
    856     // PreParser doesn't need to store generator variables.
    857     typedef void GeneratorVariable;
    858     // No interaction with Zones.
    859     typedef void Zone;
    860 
    861     // Return types for traversing functions.
    862     typedef PreParserIdentifier Identifier;
    863     typedef PreParserExpression Expression;
    864     typedef PreParserExpression YieldExpression;
    865     typedef PreParserExpression FunctionLiteral;
    866     typedef PreParserExpression ObjectLiteralProperty;
    867     typedef PreParserExpression Literal;
    868     typedef PreParserExpressionList ExpressionList;
    869     typedef PreParserExpressionList PropertyList;
    870     typedef PreParserStatementList StatementList;
    871 
    872     // For constructing objects returned by the traversing functions.
    873     typedef PreParserFactory Factory;
    874   };
    875 
    876   explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
    877 
    878   // Custom operations executed when FunctionStates are created and
    879   // destructed. (The PreParser doesn't need to do anything.)
    880   template<typename FunctionState>
    881   static void SetUpFunctionState(FunctionState* function_state, void*) {}
    882   template<typename FunctionState>
    883   static void TearDownFunctionState(FunctionState* function_state, void*) {}
    884 
    885   // Helper functions for recursive descent.
    886   static bool IsEvalOrArguments(PreParserIdentifier identifier) {
    887     return identifier.IsEvalOrArguments();
    888   }
    889 
    890   // Returns true if the expression is of type "this.foo".
    891   static bool IsThisProperty(PreParserExpression expression) {
    892     return expression.IsThisProperty();
    893   }
    894 
    895   static bool IsIdentifier(PreParserExpression expression) {
    896     return expression.IsIdentifier();
    897   }
    898 
    899   static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
    900     return expression.AsIdentifier();
    901   }
    902 
    903   static bool IsBoilerplateProperty(PreParserExpression property) {
    904     // PreParser doesn't count boilerplate properties.
    905     return false;
    906   }
    907 
    908   static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
    909     return false;
    910   }
    911 
    912   // Functions for encapsulating the differences between parsing and preparsing;
    913   // operations interleaved with the recursive descent.
    914   static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
    915     // PreParser should not use FuncNameInferrer.
    916     UNREACHABLE();
    917   }
    918   static void PushPropertyName(FuncNameInferrer* fni,
    919                                PreParserExpression expression) {
    920     // PreParser should not use FuncNameInferrer.
    921     UNREACHABLE();
    922   }
    923 
    924   static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
    925       PreParserScope* scope, PreParserExpression value, bool* has_function) {}
    926 
    927   static void CheckAssigningFunctionLiteralToProperty(
    928       PreParserExpression left, PreParserExpression right) {}
    929 
    930   // PreParser doesn't need to keep track of eval calls.
    931   static void CheckPossibleEvalCall(PreParserExpression expression,
    932                                     PreParserScope* scope) {}
    933 
    934   static PreParserExpression MarkExpressionAsLValue(
    935       PreParserExpression expression) {
    936     // TODO(marja): To be able to produce the same errors, the preparser needs
    937     // to start tracking which expressions are variables and which are lvalues.
    938     return expression;
    939   }
    940 
    941   bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
    942                                               PreParserExpression y,
    943                                               Token::Value op,
    944                                               int pos,
    945                                               PreParserFactory* factory) {
    946     return false;
    947   }
    948 
    949   PreParserExpression BuildUnaryExpression(PreParserExpression expression,
    950                                            Token::Value op, int pos,
    951                                            PreParserFactory* factory) {
    952     return PreParserExpression::Default();
    953   }
    954 
    955   PreParserExpression NewThrowReferenceError(const char* type, int pos) {
    956     return PreParserExpression::Default();
    957   }
    958   PreParserExpression NewThrowSyntaxError(
    959       const char* type, Handle<Object> arg, int pos) {
    960     return PreParserExpression::Default();
    961   }
    962   PreParserExpression NewThrowTypeError(
    963       const char* type, Handle<Object> arg, int pos) {
    964     return PreParserExpression::Default();
    965   }
    966 
    967   // Reporting errors.
    968   void ReportMessageAt(Scanner::Location location,
    969                        const char* message,
    970                        const char* arg = NULL,
    971                        bool is_reference_error = false);
    972   void ReportMessageAt(int start_pos,
    973                        int end_pos,
    974                        const char* message,
    975                        const char* arg = NULL,
    976                        bool is_reference_error = false);
    977 
    978   // "null" return type creators.
    979   static PreParserIdentifier EmptyIdentifier() {
    980     return PreParserIdentifier::Default();
    981   }
    982   static PreParserExpression EmptyExpression() {
    983     return PreParserExpression::Default();
    984   }
    985   static PreParserExpression EmptyLiteral() {
    986     return PreParserExpression::Default();
    987   }
    988   static PreParserExpressionList NullExpressionList() {
    989     return PreParserExpressionList();
    990   }
    991 
    992   // Odd-ball literal creators.
    993   static PreParserExpression GetLiteralTheHole(int position,
    994                                                PreParserFactory* factory) {
    995     return PreParserExpression::Default();
    996   }
    997 
    998   // Producing data during the recursive descent.
    999   PreParserIdentifier GetSymbol(Scanner* scanner);
   1000   static PreParserIdentifier NextLiteralString(Scanner* scanner,
   1001                                                PretenureFlag tenured) {
   1002     return PreParserIdentifier::Default();
   1003   }
   1004 
   1005   static PreParserExpression ThisExpression(PreParserScope* scope,
   1006                                             PreParserFactory* factory) {
   1007     return PreParserExpression::This();
   1008   }
   1009 
   1010   static PreParserExpression ExpressionFromLiteral(
   1011       Token::Value token, int pos, Scanner* scanner,
   1012       PreParserFactory* factory) {
   1013     return PreParserExpression::Default();
   1014   }
   1015 
   1016   static PreParserExpression ExpressionFromIdentifier(
   1017       PreParserIdentifier name, int pos, PreParserScope* scope,
   1018       PreParserFactory* factory) {
   1019     return PreParserExpression::FromIdentifier(name);
   1020   }
   1021 
   1022   PreParserExpression ExpressionFromString(int pos,
   1023                                            Scanner* scanner,
   1024                                            PreParserFactory* factory = NULL);
   1025 
   1026   static PreParserExpressionList NewExpressionList(int size, void* zone) {
   1027     return PreParserExpressionList();
   1028   }
   1029 
   1030   static PreParserStatementList NewStatementList(int size, void* zone) {
   1031     return PreParserStatementList();
   1032   }
   1033 
   1034   static PreParserExpressionList NewPropertyList(int size, void* zone) {
   1035     return PreParserExpressionList();
   1036   }
   1037 
   1038   // Temporary glue; these functions will move to ParserBase.
   1039   PreParserExpression ParseV8Intrinsic(bool* ok);
   1040   PreParserExpression ParseFunctionLiteral(
   1041       PreParserIdentifier name,
   1042       Scanner::Location function_name_location,
   1043       bool name_is_strict_reserved,
   1044       bool is_generator,
   1045       int function_token_position,
   1046       FunctionLiteral::FunctionType type,
   1047       FunctionLiteral::ArityRestriction arity_restriction,
   1048       bool* ok);
   1049 
   1050  private:
   1051   PreParser* pre_parser_;
   1052 };
   1053 
   1054 
   1055 // Preparsing checks a JavaScript program and emits preparse-data that helps
   1056 // a later parsing to be faster.
   1057 // See preparse-data-format.h for the data format.
   1058 
   1059 // The PreParser checks that the syntax follows the grammar for JavaScript,
   1060 // and collects some information about the program along the way.
   1061 // The grammar check is only performed in order to understand the program
   1062 // sufficiently to deduce some information about it, that can be used
   1063 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
   1064 // rather it is to speed up properly written and correct programs.
   1065 // That means that contextual checks (like a label being declared where
   1066 // it is used) are generally omitted.
   1067 class PreParser : public ParserBase<PreParserTraits> {
   1068  public:
   1069   typedef PreParserIdentifier Identifier;
   1070   typedef PreParserExpression Expression;
   1071   typedef PreParserStatement Statement;
   1072 
   1073   enum PreParseResult {
   1074     kPreParseStackOverflow,
   1075     kPreParseSuccess
   1076   };
   1077 
   1078   PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit)
   1079       : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL,
   1080                                     this) {}
   1081 
   1082   // Pre-parse the program from the character stream; returns true on
   1083   // success (even if parsing failed, the pre-parse data successfully
   1084   // captured the syntax error), and false if a stack-overflow happened
   1085   // during parsing.
   1086   PreParseResult PreParseProgram() {
   1087     PreParserScope scope(scope_, GLOBAL_SCOPE);
   1088     FunctionState top_scope(&function_state_, &scope_, &scope, NULL);
   1089     bool ok = true;
   1090     int start_position = scanner()->peek_location().beg_pos;
   1091     ParseSourceElements(Token::EOS, &ok);
   1092     if (stack_overflow()) return kPreParseStackOverflow;
   1093     if (!ok) {
   1094       ReportUnexpectedToken(scanner()->current_token());
   1095     } else if (scope_->strict_mode() == STRICT) {
   1096       CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
   1097     }
   1098     return kPreParseSuccess;
   1099   }
   1100 
   1101   // Parses a single function literal, from the opening parentheses before
   1102   // parameters to the closing brace after the body.
   1103   // Returns a FunctionEntry describing the body of the function in enough
   1104   // detail that it can be lazily compiled.
   1105   // The scanner is expected to have matched the "function" or "function*"
   1106   // keyword and parameters, and have consumed the initial '{'.
   1107   // At return, unless an error occurred, the scanner is positioned before the
   1108   // the final '}'.
   1109   PreParseResult PreParseLazyFunction(StrictMode strict_mode,
   1110                                       bool is_generator,
   1111                                       ParserRecorder* log);
   1112 
   1113  private:
   1114   friend class PreParserTraits;
   1115 
   1116   // These types form an algebra over syntactic categories that is just
   1117   // rich enough to let us recognize and propagate the constructs that
   1118   // are either being counted in the preparser data, or is important
   1119   // to throw the correct syntax error exceptions.
   1120 
   1121   enum VariableDeclarationContext {
   1122     kSourceElement,
   1123     kStatement,
   1124     kForStatement
   1125   };
   1126 
   1127   // If a list of variable declarations includes any initializers.
   1128   enum VariableDeclarationProperties {
   1129     kHasInitializers,
   1130     kHasNoInitializers
   1131   };
   1132 
   1133 
   1134   enum SourceElements {
   1135     kUnknownSourceElements
   1136   };
   1137 
   1138   // All ParseXXX functions take as the last argument an *ok parameter
   1139   // which is set to false if parsing failed; it is unchanged otherwise.
   1140   // By making the 'exception handling' explicit, we are forced to check
   1141   // for failure at the call sites.
   1142   Statement ParseSourceElement(bool* ok);
   1143   SourceElements ParseSourceElements(int end_token, bool* ok);
   1144   Statement ParseStatement(bool* ok);
   1145   Statement ParseFunctionDeclaration(bool* ok);
   1146   Statement ParseBlock(bool* ok);
   1147   Statement ParseVariableStatement(VariableDeclarationContext var_context,
   1148                                    bool* ok);
   1149   Statement ParseVariableDeclarations(VariableDeclarationContext var_context,
   1150                                       VariableDeclarationProperties* decl_props,
   1151                                       int* num_decl,
   1152                                       bool* ok);
   1153   Statement ParseExpressionOrLabelledStatement(bool* ok);
   1154   Statement ParseIfStatement(bool* ok);
   1155   Statement ParseContinueStatement(bool* ok);
   1156   Statement ParseBreakStatement(bool* ok);
   1157   Statement ParseReturnStatement(bool* ok);
   1158   Statement ParseWithStatement(bool* ok);
   1159   Statement ParseSwitchStatement(bool* ok);
   1160   Statement ParseDoWhileStatement(bool* ok);
   1161   Statement ParseWhileStatement(bool* ok);
   1162   Statement ParseForStatement(bool* ok);
   1163   Statement ParseThrowStatement(bool* ok);
   1164   Statement ParseTryStatement(bool* ok);
   1165   Statement ParseDebuggerStatement(bool* ok);
   1166   Expression ParseConditionalExpression(bool accept_IN, bool* ok);
   1167   Expression ParseObjectLiteral(bool* ok);
   1168   Expression ParseV8Intrinsic(bool* ok);
   1169 
   1170   Expression ParseFunctionLiteral(
   1171       Identifier name,
   1172       Scanner::Location function_name_location,
   1173       bool name_is_strict_reserved,
   1174       bool is_generator,
   1175       int function_token_pos,
   1176       FunctionLiteral::FunctionType function_type,
   1177       FunctionLiteral::ArityRestriction arity_restriction,
   1178       bool* ok);
   1179   void ParseLazyFunctionLiteralBody(bool* ok);
   1180 
   1181   bool CheckInOrOf(bool accept_OF);
   1182 };
   1183 
   1184 template<class Traits>
   1185 ParserBase<Traits>::FunctionState::FunctionState(
   1186     FunctionState** function_state_stack,
   1187     typename Traits::Type::Scope** scope_stack,
   1188     typename Traits::Type::Scope* scope,
   1189     typename Traits::Type::Zone* extra_param)
   1190     : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
   1191       next_handler_index_(0),
   1192       expected_property_count_(0),
   1193       is_generator_(false),
   1194       generator_object_variable_(NULL),
   1195       function_state_stack_(function_state_stack),
   1196       outer_function_state_(*function_state_stack),
   1197       scope_stack_(scope_stack),
   1198       outer_scope_(*scope_stack),
   1199       saved_ast_node_id_(0),
   1200       extra_param_(extra_param),
   1201       factory_(extra_param) {
   1202   *scope_stack_ = scope;
   1203   *function_state_stack = this;
   1204   Traits::SetUpFunctionState(this, extra_param);
   1205 }
   1206 
   1207 
   1208 template<class Traits>
   1209 ParserBase<Traits>::FunctionState::~FunctionState() {
   1210   *scope_stack_ = outer_scope_;
   1211   *function_state_stack_ = outer_function_state_;
   1212   Traits::TearDownFunctionState(this, extra_param_);
   1213 }
   1214 
   1215 
   1216 template<class Traits>
   1217 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
   1218   Scanner::Location source_location = scanner()->location();
   1219 
   1220   // Four of the tokens are treated specially
   1221   switch (token) {
   1222     case Token::EOS:
   1223       return ReportMessageAt(source_location, "unexpected_eos");
   1224     case Token::NUMBER:
   1225       return ReportMessageAt(source_location, "unexpected_token_number");
   1226     case Token::STRING:
   1227       return ReportMessageAt(source_location, "unexpected_token_string");
   1228     case Token::IDENTIFIER:
   1229       return ReportMessageAt(source_location, "unexpected_token_identifier");
   1230     case Token::FUTURE_RESERVED_WORD:
   1231       return ReportMessageAt(source_location, "unexpected_reserved");
   1232     case Token::YIELD:
   1233     case Token::FUTURE_STRICT_RESERVED_WORD:
   1234       return ReportMessageAt(source_location, strict_mode() == SLOPPY
   1235           ? "unexpected_token_identifier" : "unexpected_strict_reserved");
   1236     default:
   1237       const char* name = Token::String(token);
   1238       ASSERT(name != NULL);
   1239       Traits::ReportMessageAt(source_location, "unexpected_token", name);
   1240   }
   1241 }
   1242 
   1243 
   1244 template<class Traits>
   1245 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
   1246     AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
   1247     bool* ok) {
   1248   Token::Value next = Next();
   1249   if (next == Token::IDENTIFIER) {
   1250     IdentifierT name = this->GetSymbol(scanner());
   1251     if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
   1252         strict_mode() == STRICT && this->IsEvalOrArguments(name)) {
   1253       ReportMessage("strict_eval_arguments");
   1254       *ok = false;
   1255     }
   1256     return name;
   1257   } else if (strict_mode() == SLOPPY &&
   1258              (next == Token::FUTURE_STRICT_RESERVED_WORD ||
   1259              (next == Token::YIELD && !is_generator()))) {
   1260     return this->GetSymbol(scanner());
   1261   } else {
   1262     this->ReportUnexpectedToken(next);
   1263     *ok = false;
   1264     return Traits::EmptyIdentifier();
   1265   }
   1266 }
   1267 
   1268 
   1269 template <class Traits>
   1270 typename ParserBase<Traits>::IdentifierT ParserBase<
   1271     Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
   1272                                                  bool* ok) {
   1273   Token::Value next = Next();
   1274   if (next == Token::IDENTIFIER) {
   1275     *is_strict_reserved = false;
   1276   } else if (next == Token::FUTURE_STRICT_RESERVED_WORD ||
   1277              (next == Token::YIELD && !this->is_generator())) {
   1278     *is_strict_reserved = true;
   1279   } else {
   1280     ReportUnexpectedToken(next);
   1281     *ok = false;
   1282     return Traits::EmptyIdentifier();
   1283   }
   1284   return this->GetSymbol(scanner());
   1285 }
   1286 
   1287 
   1288 template <class Traits>
   1289 typename ParserBase<Traits>::IdentifierT
   1290 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
   1291   Token::Value next = Next();
   1292   if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
   1293       next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
   1294     this->ReportUnexpectedToken(next);
   1295     *ok = false;
   1296     return Traits::EmptyIdentifier();
   1297   }
   1298   return this->GetSymbol(scanner());
   1299 }
   1300 
   1301 
   1302 template <class Traits>
   1303 typename ParserBase<Traits>::IdentifierT
   1304 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
   1305                                                   bool* is_set,
   1306                                                   bool* ok) {
   1307   IdentifierT result = ParseIdentifierName(ok);
   1308   if (!*ok) return Traits::EmptyIdentifier();
   1309   scanner()->IsGetOrSet(is_get, is_set);
   1310   return result;
   1311 }
   1312 
   1313 
   1314 template <class Traits>
   1315 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
   1316     bool seen_equal, bool* ok) {
   1317   int pos = peek_position();
   1318   if (!scanner()->ScanRegExpPattern(seen_equal)) {
   1319     Next();
   1320     ReportMessage("unterminated_regexp");
   1321     *ok = false;
   1322     return Traits::EmptyExpression();
   1323   }
   1324 
   1325   int literal_index = function_state_->NextMaterializedLiteralIndex();
   1326 
   1327   IdentifierT js_pattern = this->NextLiteralString(scanner(), TENURED);
   1328   if (!scanner()->ScanRegExpFlags()) {
   1329     Next();
   1330     ReportMessage("invalid_regexp_flags");
   1331     *ok = false;
   1332     return Traits::EmptyExpression();
   1333   }
   1334   IdentifierT js_flags = this->NextLiteralString(scanner(), TENURED);
   1335   Next();
   1336   return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
   1337 }
   1338 
   1339 
   1340 #define CHECK_OK  ok); \
   1341   if (!*ok) return this->EmptyExpression(); \
   1342   ((void)0
   1343 #define DUMMY )  // to make indentation work
   1344 #undef DUMMY
   1345 
   1346 // Used in functions where the return type is not ExpressionT.
   1347 #define CHECK_OK_CUSTOM(x) ok); \
   1348   if (!*ok) return this->x(); \
   1349   ((void)0
   1350 #define DUMMY )  // to make indentation work
   1351 #undef DUMMY
   1352 
   1353 template <class Traits>
   1354 typename ParserBase<Traits>::ExpressionT
   1355 ParserBase<Traits>::ParsePrimaryExpression(bool* ok) {
   1356   // PrimaryExpression ::
   1357   //   'this'
   1358   //   'null'
   1359   //   'true'
   1360   //   'false'
   1361   //   Identifier
   1362   //   Number
   1363   //   String
   1364   //   ArrayLiteral
   1365   //   ObjectLiteral
   1366   //   RegExpLiteral
   1367   //   '(' Expression ')'
   1368 
   1369   int pos = peek_position();
   1370   ExpressionT result = this->EmptyExpression();
   1371   Token::Value token = peek();
   1372   switch (token) {
   1373     case Token::THIS: {
   1374       Consume(Token::THIS);
   1375       result = this->ThisExpression(scope_, factory());
   1376       break;
   1377     }
   1378 
   1379     case Token::NULL_LITERAL:
   1380     case Token::TRUE_LITERAL:
   1381     case Token::FALSE_LITERAL:
   1382     case Token::NUMBER:
   1383       Next();
   1384       result = this->ExpressionFromLiteral(token, pos, scanner(), factory());
   1385       break;
   1386 
   1387     case Token::IDENTIFIER:
   1388     case Token::YIELD:
   1389     case Token::FUTURE_STRICT_RESERVED_WORD: {
   1390       // Using eval or arguments in this context is OK even in strict mode.
   1391       IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
   1392       result = this->ExpressionFromIdentifier(name, pos, scope_, factory());
   1393       break;
   1394     }
   1395 
   1396     case Token::STRING: {
   1397       Consume(Token::STRING);
   1398       result = this->ExpressionFromString(pos, scanner(), factory());
   1399       break;
   1400     }
   1401 
   1402     case Token::ASSIGN_DIV:
   1403       result = this->ParseRegExpLiteral(true, CHECK_OK);
   1404       break;
   1405 
   1406     case Token::DIV:
   1407       result = this->ParseRegExpLiteral(false, CHECK_OK);
   1408       break;
   1409 
   1410     case Token::LBRACK:
   1411       result = this->ParseArrayLiteral(CHECK_OK);
   1412       break;
   1413 
   1414     case Token::LBRACE:
   1415       result = this->ParseObjectLiteral(CHECK_OK);
   1416       break;
   1417 
   1418     case Token::LPAREN:
   1419       Consume(Token::LPAREN);
   1420       // Heuristically try to detect immediately called functions before
   1421       // seeing the call parentheses.
   1422       parenthesized_function_ = (peek() == Token::FUNCTION);
   1423       result = this->ParseExpression(true, CHECK_OK);
   1424       Expect(Token::RPAREN, CHECK_OK);
   1425       break;
   1426 
   1427     case Token::MOD:
   1428       if (allow_natives_syntax() || extension_ != NULL) {
   1429         result = this->ParseV8Intrinsic(CHECK_OK);
   1430         break;
   1431       }
   1432       // If we're not allowing special syntax we fall-through to the
   1433       // default case.
   1434 
   1435     default: {
   1436       Next();
   1437       ReportUnexpectedToken(token);
   1438       *ok = false;
   1439     }
   1440   }
   1441 
   1442   return result;
   1443 }
   1444 
   1445 // Precedence = 1
   1446 template <class Traits>
   1447 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
   1448     bool accept_IN, bool* ok) {
   1449   // Expression ::
   1450   //   AssignmentExpression
   1451   //   Expression ',' AssignmentExpression
   1452 
   1453   ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
   1454   while (peek() == Token::COMMA) {
   1455     Expect(Token::COMMA, CHECK_OK);
   1456     int pos = position();
   1457     ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
   1458     result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
   1459   }
   1460   return result;
   1461 }
   1462 
   1463 
   1464 template <class Traits>
   1465 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
   1466     bool* ok) {
   1467   // ArrayLiteral ::
   1468   //   '[' Expression? (',' Expression?)* ']'
   1469 
   1470   int pos = peek_position();
   1471   typename Traits::Type::ExpressionList values =
   1472       this->NewExpressionList(4, zone_);
   1473   Expect(Token::LBRACK, CHECK_OK);
   1474   while (peek() != Token::RBRACK) {
   1475     ExpressionT elem = this->EmptyExpression();
   1476     if (peek() == Token::COMMA) {
   1477       elem = this->GetLiteralTheHole(peek_position(), factory());
   1478     } else {
   1479       elem = this->ParseAssignmentExpression(true, CHECK_OK);
   1480     }
   1481     values->Add(elem, zone_);
   1482     if (peek() != Token::RBRACK) {
   1483       Expect(Token::COMMA, CHECK_OK);
   1484     }
   1485   }
   1486   Expect(Token::RBRACK, CHECK_OK);
   1487 
   1488   // Update the scope information before the pre-parsing bailout.
   1489   int literal_index = function_state_->NextMaterializedLiteralIndex();
   1490 
   1491   return factory()->NewArrayLiteral(values, literal_index, pos);
   1492 }
   1493 
   1494 
   1495 template <class Traits>
   1496 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
   1497     bool* ok) {
   1498   // ObjectLiteral ::
   1499   // '{' ((
   1500   //       ((IdentifierName | String | Number) ':' AssignmentExpression) |
   1501   //       (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
   1502   //      ) ',')* '}'
   1503   // (Except that trailing comma is not required and not allowed.)
   1504 
   1505   int pos = peek_position();
   1506   typename Traits::Type::PropertyList properties =
   1507       this->NewPropertyList(4, zone_);
   1508   int number_of_boilerplate_properties = 0;
   1509   bool has_function = false;
   1510 
   1511   ObjectLiteralChecker checker(this, strict_mode());
   1512 
   1513   Expect(Token::LBRACE, CHECK_OK);
   1514 
   1515   while (peek() != Token::RBRACE) {
   1516     if (fni_ != NULL) fni_->Enter();
   1517 
   1518     typename Traits::Type::Literal key = this->EmptyLiteral();
   1519     Token::Value next = peek();
   1520     int next_pos = peek_position();
   1521 
   1522     switch (next) {
   1523       case Token::FUTURE_RESERVED_WORD:
   1524       case Token::FUTURE_STRICT_RESERVED_WORD:
   1525       case Token::IDENTIFIER: {
   1526         bool is_getter = false;
   1527         bool is_setter = false;
   1528         IdentifierT id =
   1529             ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
   1530         if (fni_ != NULL) this->PushLiteralName(fni_, id);
   1531 
   1532         if ((is_getter || is_setter) && peek() != Token::COLON) {
   1533           // Special handling of getter and setter syntax:
   1534           // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
   1535           // We have already read the "get" or "set" keyword.
   1536           Token::Value next = Next();
   1537           if (next != i::Token::IDENTIFIER &&
   1538               next != i::Token::FUTURE_RESERVED_WORD &&
   1539               next != i::Token::FUTURE_STRICT_RESERVED_WORD &&
   1540               next != i::Token::NUMBER &&
   1541               next != i::Token::STRING &&
   1542               !Token::IsKeyword(next)) {
   1543             ReportUnexpectedToken(next);
   1544             *ok = false;
   1545             return this->EmptyLiteral();
   1546           }
   1547           // Validate the property.
   1548           PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
   1549           checker.CheckProperty(next, type, CHECK_OK);
   1550           IdentifierT name = this->GetSymbol(scanner_);
   1551           typename Traits::Type::FunctionLiteral value =
   1552               this->ParseFunctionLiteral(
   1553                   name, scanner()->location(),
   1554                   false,  // reserved words are allowed here
   1555                   false,  // not a generator
   1556                   RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
   1557                   is_getter ? FunctionLiteral::GETTER_ARITY
   1558                             : FunctionLiteral::SETTER_ARITY,
   1559                   CHECK_OK);
   1560           typename Traits::Type::ObjectLiteralProperty property =
   1561               factory()->NewObjectLiteralProperty(is_getter, value, next_pos);
   1562           if (this->IsBoilerplateProperty(property)) {
   1563             number_of_boilerplate_properties++;
   1564           }
   1565           properties->Add(property, zone());
   1566           if (peek() != Token::RBRACE) {
   1567             // Need {} because of the CHECK_OK macro.
   1568             Expect(Token::COMMA, CHECK_OK);
   1569           }
   1570 
   1571           if (fni_ != NULL) {
   1572             fni_->Infer();
   1573             fni_->Leave();
   1574           }
   1575           continue;  // restart the while
   1576         }
   1577         // Failed to parse as get/set property, so it's just a normal property
   1578         // (which might be called "get" or "set" or something else).
   1579         key = factory()->NewLiteral(id, next_pos);
   1580         break;
   1581       }
   1582       case Token::STRING: {
   1583         Consume(Token::STRING);
   1584         IdentifierT string = this->GetSymbol(scanner_);
   1585         if (fni_ != NULL) this->PushLiteralName(fni_, string);
   1586         uint32_t index;
   1587         if (this->IsArrayIndex(string, &index)) {
   1588           key = factory()->NewNumberLiteral(index, next_pos);
   1589           break;
   1590         }
   1591         key = factory()->NewLiteral(string, next_pos);
   1592         break;
   1593       }
   1594       case Token::NUMBER: {
   1595         Consume(Token::NUMBER);
   1596         key = this->ExpressionFromLiteral(Token::NUMBER, next_pos, scanner_,
   1597                                           factory());
   1598         break;
   1599       }
   1600       default:
   1601         if (Token::IsKeyword(next)) {
   1602           Consume(next);
   1603           IdentifierT string = this->GetSymbol(scanner_);
   1604           key = factory()->NewLiteral(string, next_pos);
   1605         } else {
   1606           Token::Value next = Next();
   1607           ReportUnexpectedToken(next);
   1608           *ok = false;
   1609           return this->EmptyLiteral();
   1610         }
   1611     }
   1612 
   1613     // Validate the property
   1614     checker.CheckProperty(next, kValueProperty, CHECK_OK);
   1615 
   1616     Expect(Token::COLON, CHECK_OK);
   1617     ExpressionT value = this->ParseAssignmentExpression(true, CHECK_OK);
   1618 
   1619     typename Traits::Type::ObjectLiteralProperty property =
   1620         factory()->NewObjectLiteralProperty(key, value);
   1621 
   1622     // Mark top-level object literals that contain function literals and
   1623     // pretenure the literal so it can be added as a constant function
   1624     // property. (Parser only.)
   1625     this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value,
   1626                                                           &has_function);
   1627 
   1628     // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
   1629     if (this->IsBoilerplateProperty(property)) {
   1630       number_of_boilerplate_properties++;
   1631     }
   1632     properties->Add(property, zone());
   1633 
   1634     // TODO(1240767): Consider allowing trailing comma.
   1635     if (peek() != Token::RBRACE) {
   1636       // Need {} because of the CHECK_OK macro.
   1637       Expect(Token::COMMA, CHECK_OK);
   1638     }
   1639 
   1640     if (fni_ != NULL) {
   1641       fni_->Infer();
   1642       fni_->Leave();
   1643     }
   1644   }
   1645   Expect(Token::RBRACE, CHECK_OK);
   1646 
   1647   // Computation of literal_index must happen before pre parse bailout.
   1648   int literal_index = function_state_->NextMaterializedLiteralIndex();
   1649 
   1650   return factory()->NewObjectLiteral(properties,
   1651                                      literal_index,
   1652                                      number_of_boilerplate_properties,
   1653                                      has_function,
   1654                                      pos);
   1655 }
   1656 
   1657 
   1658 template <class Traits>
   1659 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
   1660     bool* ok) {
   1661   // Arguments ::
   1662   //   '(' (AssignmentExpression)*[','] ')'
   1663 
   1664   typename Traits::Type::ExpressionList result =
   1665       this->NewExpressionList(4, zone_);
   1666   Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
   1667   bool done = (peek() == Token::RPAREN);
   1668   while (!done) {
   1669     ExpressionT argument = this->ParseAssignmentExpression(
   1670         true, CHECK_OK_CUSTOM(NullExpressionList));
   1671     result->Add(argument, zone_);
   1672     if (result->length() > Code::kMaxArguments) {
   1673       ReportMessage("too_many_arguments");
   1674       *ok = false;
   1675       return this->NullExpressionList();
   1676     }
   1677     done = (peek() == Token::RPAREN);
   1678     if (!done) {
   1679       // Need {} because of the CHECK_OK_CUSTOM macro.
   1680       Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList));
   1681     }
   1682   }
   1683   Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
   1684   return result;
   1685 }
   1686 
   1687 // Precedence = 2
   1688 template <class Traits>
   1689 typename ParserBase<Traits>::ExpressionT
   1690 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
   1691   // AssignmentExpression ::
   1692   //   ConditionalExpression
   1693   //   YieldExpression
   1694   //   LeftHandSideExpression AssignmentOperator AssignmentExpression
   1695 
   1696   Scanner::Location lhs_location = scanner()->peek_location();
   1697 
   1698   if (peek() == Token::YIELD && is_generator()) {
   1699     return this->ParseYieldExpression(ok);
   1700   }
   1701 
   1702   if (fni_ != NULL) fni_->Enter();
   1703   ExpressionT expression =
   1704       this->ParseConditionalExpression(accept_IN, CHECK_OK);
   1705 
   1706   if (!Token::IsAssignmentOp(peek())) {
   1707     if (fni_ != NULL) fni_->Leave();
   1708     // Parsed conditional expression only (no assignment).
   1709     return expression;
   1710   }
   1711 
   1712   expression = this->CheckAndRewriteReferenceExpression(
   1713       expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
   1714   expression = this->MarkExpressionAsLValue(expression);
   1715 
   1716   Token::Value op = Next();  // Get assignment operator.
   1717   int pos = position();
   1718   ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
   1719 
   1720   // TODO(1231235): We try to estimate the set of properties set by
   1721   // constructors. We define a new property whenever there is an
   1722   // assignment to a property of 'this'. We should probably only add
   1723   // properties if we haven't seen them before. Otherwise we'll
   1724   // probably overestimate the number of properties.
   1725   if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
   1726     function_state_->AddProperty();
   1727   }
   1728 
   1729   this->CheckAssigningFunctionLiteralToProperty(expression, right);
   1730 
   1731   if (fni_ != NULL) {
   1732     // Check if the right hand side is a call to avoid inferring a
   1733     // name if we're dealing with "a = function(){...}();"-like
   1734     // expression.
   1735     if ((op == Token::INIT_VAR
   1736          || op == Token::INIT_CONST_LEGACY
   1737          || op == Token::ASSIGN)
   1738         && (!right->IsCall() && !right->IsCallNew())) {
   1739       fni_->Infer();
   1740     } else {
   1741       fni_->RemoveLastFunction();
   1742     }
   1743     fni_->Leave();
   1744   }
   1745 
   1746   return factory()->NewAssignment(op, expression, right, pos);
   1747 }
   1748 
   1749 template <class Traits>
   1750 typename ParserBase<Traits>::ExpressionT
   1751 ParserBase<Traits>::ParseYieldExpression(bool* ok) {
   1752   // YieldExpression ::
   1753   //   'yield' '*'? AssignmentExpression
   1754   int pos = peek_position();
   1755   Expect(Token::YIELD, CHECK_OK);
   1756   Yield::Kind kind =
   1757       Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND;
   1758   ExpressionT generator_object =
   1759       factory()->NewVariableProxy(function_state_->generator_object_variable());
   1760   ExpressionT expression =
   1761       ParseAssignmentExpression(false, CHECK_OK);
   1762   typename Traits::Type::YieldExpression yield =
   1763       factory()->NewYield(generator_object, expression, kind, pos);
   1764   if (kind == Yield::DELEGATING) {
   1765     yield->set_index(function_state_->NextHandlerIndex());
   1766   }
   1767   return yield;
   1768 }
   1769 
   1770 
   1771 // Precedence = 3
   1772 template <class Traits>
   1773 typename ParserBase<Traits>::ExpressionT
   1774 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, bool* ok) {
   1775   // ConditionalExpression ::
   1776   //   LogicalOrExpression
   1777   //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
   1778 
   1779   int pos = peek_position();
   1780   // We start using the binary expression parser for prec >= 4 only!
   1781   ExpressionT expression = this->ParseBinaryExpression(4, accept_IN, CHECK_OK);
   1782   if (peek() != Token::CONDITIONAL) return expression;
   1783   Consume(Token::CONDITIONAL);
   1784   // In parsing the first assignment expression in conditional
   1785   // expressions we always accept the 'in' keyword; see ECMA-262,
   1786   // section 11.12, page 58.
   1787   ExpressionT left = ParseAssignmentExpression(true, CHECK_OK);
   1788   Expect(Token::COLON, CHECK_OK);
   1789   ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK);
   1790   return factory()->NewConditional(expression, left, right, pos);
   1791 }
   1792 
   1793 
   1794 // Precedence >= 4
   1795 template <class Traits>
   1796 typename ParserBase<Traits>::ExpressionT
   1797 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
   1798   ASSERT(prec >= 4);
   1799   ExpressionT x = this->ParseUnaryExpression(CHECK_OK);
   1800   for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
   1801     // prec1 >= 4
   1802     while (Precedence(peek(), accept_IN) == prec1) {
   1803       Token::Value op = Next();
   1804       int pos = position();
   1805       ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
   1806 
   1807       if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
   1808                                                        factory())) {
   1809         continue;
   1810       }
   1811 
   1812       // For now we distinguish between comparisons and other binary
   1813       // operations.  (We could combine the two and get rid of this
   1814       // code and AST node eventually.)
   1815       if (Token::IsCompareOp(op)) {
   1816         // We have a comparison.
   1817         Token::Value cmp = op;
   1818         switch (op) {
   1819           case Token::NE: cmp = Token::EQ; break;
   1820           case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
   1821           default: break;
   1822         }
   1823         x = factory()->NewCompareOperation(cmp, x, y, pos);
   1824         if (cmp != op) {
   1825           // The comparison was negated - add a NOT.
   1826           x = factory()->NewUnaryOperation(Token::NOT, x, pos);
   1827         }
   1828 
   1829       } else {
   1830         // We have a "normal" binary operation.
   1831         x = factory()->NewBinaryOperation(op, x, y, pos);
   1832       }
   1833     }
   1834   }
   1835   return x;
   1836 }
   1837 
   1838 
   1839 template <class Traits>
   1840 typename ParserBase<Traits>::ExpressionT
   1841 ParserBase<Traits>::ParseUnaryExpression(bool* ok) {
   1842   // UnaryExpression ::
   1843   //   PostfixExpression
   1844   //   'delete' UnaryExpression
   1845   //   'void' UnaryExpression
   1846   //   'typeof' UnaryExpression
   1847   //   '++' UnaryExpression
   1848   //   '--' UnaryExpression
   1849   //   '+' UnaryExpression
   1850   //   '-' UnaryExpression
   1851   //   '~' UnaryExpression
   1852   //   '!' UnaryExpression
   1853 
   1854   Token::Value op = peek();
   1855   if (Token::IsUnaryOp(op)) {
   1856     op = Next();
   1857     int pos = position();
   1858     ExpressionT expression = ParseUnaryExpression(CHECK_OK);
   1859 
   1860     // "delete identifier" is a syntax error in strict mode.
   1861     if (op == Token::DELETE && strict_mode() == STRICT &&
   1862         this->IsIdentifier(expression)) {
   1863       ReportMessage("strict_delete");
   1864       *ok = false;
   1865       return this->EmptyExpression();
   1866     }
   1867 
   1868     // Allow Traits do rewrite the expression.
   1869     return this->BuildUnaryExpression(expression, op, pos, factory());
   1870   } else if (Token::IsCountOp(op)) {
   1871     op = Next();
   1872     Scanner::Location lhs_location = scanner()->peek_location();
   1873     ExpressionT expression = this->ParseUnaryExpression(CHECK_OK);
   1874     expression = this->CheckAndRewriteReferenceExpression(
   1875         expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK);
   1876     this->MarkExpressionAsLValue(expression);
   1877 
   1878     return factory()->NewCountOperation(op,
   1879                                         true /* prefix */,
   1880                                         expression,
   1881                                         position());
   1882 
   1883   } else {
   1884     return this->ParsePostfixExpression(ok);
   1885   }
   1886 }
   1887 
   1888 
   1889 template <class Traits>
   1890 typename ParserBase<Traits>::ExpressionT
   1891 ParserBase<Traits>::ParsePostfixExpression(bool* ok) {
   1892   // PostfixExpression ::
   1893   //   LeftHandSideExpression ('++' | '--')?
   1894 
   1895   Scanner::Location lhs_location = scanner()->peek_location();
   1896   ExpressionT expression = this->ParseLeftHandSideExpression(CHECK_OK);
   1897   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
   1898       Token::IsCountOp(peek())) {
   1899     expression = this->CheckAndRewriteReferenceExpression(
   1900         expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK);
   1901     expression = this->MarkExpressionAsLValue(expression);
   1902 
   1903     Token::Value next = Next();
   1904     expression =
   1905         factory()->NewCountOperation(next,
   1906                                      false /* postfix */,
   1907                                      expression,
   1908                                      position());
   1909   }
   1910   return expression;
   1911 }
   1912 
   1913 
   1914 template <class Traits>
   1915 typename ParserBase<Traits>::ExpressionT
   1916 ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) {
   1917   // LeftHandSideExpression ::
   1918   //   (NewExpression | MemberExpression) ...
   1919 
   1920   ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
   1921 
   1922   while (true) {
   1923     switch (peek()) {
   1924       case Token::LBRACK: {
   1925         Consume(Token::LBRACK);
   1926         int pos = position();
   1927         ExpressionT index = ParseExpression(true, CHECK_OK);
   1928         result = factory()->NewProperty(result, index, pos);
   1929         Expect(Token::RBRACK, CHECK_OK);
   1930         break;
   1931       }
   1932 
   1933       case Token::LPAREN: {
   1934         int pos;
   1935         if (scanner()->current_token() == Token::IDENTIFIER) {
   1936           // For call of an identifier we want to report position of
   1937           // the identifier as position of the call in the stack trace.
   1938           pos = position();
   1939         } else {
   1940           // For other kinds of calls we record position of the parenthesis as
   1941           // position of the call. Note that this is extremely important for
   1942           // expressions of the form function(){...}() for which call position
   1943           // should not point to the closing brace otherwise it will intersect
   1944           // with positions recorded for function literal and confuse debugger.
   1945           pos = peek_position();
   1946           // Also the trailing parenthesis are a hint that the function will
   1947           // be called immediately. If we happen to have parsed a preceding
   1948           // function literal eagerly, we can also compile it eagerly.
   1949           if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
   1950             result->AsFunctionLiteral()->set_parenthesized();
   1951           }
   1952         }
   1953         typename Traits::Type::ExpressionList args = ParseArguments(CHECK_OK);
   1954 
   1955         // Keep track of eval() calls since they disable all local variable
   1956         // optimizations.
   1957         // The calls that need special treatment are the
   1958         // direct eval calls. These calls are all of the form eval(...), with
   1959         // no explicit receiver.
   1960         // These calls are marked as potentially direct eval calls. Whether
   1961         // they are actually direct calls to eval is determined at run time.
   1962         this->CheckPossibleEvalCall(result, scope_);
   1963         result = factory()->NewCall(result, args, pos);
   1964         if (fni_ != NULL) fni_->RemoveLastFunction();
   1965         break;
   1966       }
   1967 
   1968       case Token::PERIOD: {
   1969         Consume(Token::PERIOD);
   1970         int pos = position();
   1971         IdentifierT name = ParseIdentifierName(CHECK_OK);
   1972         result = factory()->NewProperty(
   1973             result, factory()->NewLiteral(name, pos), pos);
   1974         if (fni_ != NULL) this->PushLiteralName(fni_, name);
   1975         break;
   1976       }
   1977 
   1978       default:
   1979         return result;
   1980     }
   1981   }
   1982 }
   1983 
   1984 
   1985 template <class Traits>
   1986 typename ParserBase<Traits>::ExpressionT
   1987 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) {
   1988   // NewExpression ::
   1989   //   ('new')+ MemberExpression
   1990 
   1991   // The grammar for new expressions is pretty warped. We can have several 'new'
   1992   // keywords following each other, and then a MemberExpression. When we see '('
   1993   // after the MemberExpression, it's associated with the rightmost unassociated
   1994   // 'new' to create a NewExpression with arguments. However, a NewExpression
   1995   // can also occur without arguments.
   1996 
   1997   // Examples of new expression:
   1998   // new foo.bar().baz means (new (foo.bar)()).baz
   1999   // new foo()() means (new foo())()
   2000   // new new foo()() means (new (new foo())())
   2001   // new new foo means new (new foo)
   2002   // new new foo() means new (new foo())
   2003   // new new foo().bar().baz means (new (new foo()).bar()).baz
   2004 
   2005   if (peek() == Token::NEW) {
   2006     Consume(Token::NEW);
   2007     int new_pos = position();
   2008     ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
   2009     if (peek() == Token::LPAREN) {
   2010       // NewExpression with arguments.
   2011       typename Traits::Type::ExpressionList args =
   2012           this->ParseArguments(CHECK_OK);
   2013       result = factory()->NewCallNew(result, args, new_pos);
   2014       // The expression can still continue with . or [ after the arguments.
   2015       result = this->ParseMemberExpressionContinuation(result, CHECK_OK);
   2016       return result;
   2017     }
   2018     // NewExpression without arguments.
   2019     return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
   2020                                  new_pos);
   2021   }
   2022   // No 'new' keyword.
   2023   return this->ParseMemberExpression(ok);
   2024 }
   2025 
   2026 
   2027 template <class Traits>
   2028 typename ParserBase<Traits>::ExpressionT
   2029 ParserBase<Traits>::ParseMemberExpression(bool* ok) {
   2030   // MemberExpression ::
   2031   //   (PrimaryExpression | FunctionLiteral)
   2032   //     ('[' Expression ']' | '.' Identifier | Arguments)*
   2033 
   2034   // The '[' Expression ']' and '.' Identifier parts are parsed by
   2035   // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
   2036   // caller.
   2037 
   2038   // Parse the initial primary or function expression.
   2039   ExpressionT result = this->EmptyExpression();
   2040   if (peek() == Token::FUNCTION) {
   2041     Consume(Token::FUNCTION);
   2042     int function_token_position = position();
   2043     bool is_generator = allow_generators() && Check(Token::MUL);
   2044     IdentifierT name = this->EmptyIdentifier();
   2045     bool is_strict_reserved_name = false;
   2046     Scanner::Location function_name_location = Scanner::Location::invalid();
   2047     FunctionLiteral::FunctionType function_type =
   2048         FunctionLiteral::ANONYMOUS_EXPRESSION;
   2049     if (peek_any_identifier()) {
   2050       name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
   2051                                                  CHECK_OK);
   2052       function_name_location = scanner()->location();
   2053       function_type = FunctionLiteral::NAMED_EXPRESSION;
   2054     }
   2055     result = this->ParseFunctionLiteral(name,
   2056                                         function_name_location,
   2057                                         is_strict_reserved_name,
   2058                                         is_generator,
   2059                                         function_token_position,
   2060                                         function_type,
   2061                                         FunctionLiteral::NORMAL_ARITY,
   2062                                         CHECK_OK);
   2063   } else {
   2064     result = ParsePrimaryExpression(CHECK_OK);
   2065   }
   2066 
   2067   result = ParseMemberExpressionContinuation(result, CHECK_OK);
   2068   return result;
   2069 }
   2070 
   2071 
   2072 template <class Traits>
   2073 typename ParserBase<Traits>::ExpressionT
   2074 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
   2075                                                       bool* ok) {
   2076   // Parses this part of MemberExpression:
   2077   // ('[' Expression ']' | '.' Identifier)*
   2078   while (true) {
   2079     switch (peek()) {
   2080       case Token::LBRACK: {
   2081         Consume(Token::LBRACK);
   2082         int pos = position();
   2083         ExpressionT index = this->ParseExpression(true, CHECK_OK);
   2084         expression = factory()->NewProperty(expression, index, pos);
   2085         if (fni_ != NULL) {
   2086           this->PushPropertyName(fni_, index);
   2087         }
   2088         Expect(Token::RBRACK, CHECK_OK);
   2089         break;
   2090       }
   2091       case Token::PERIOD: {
   2092         Consume(Token::PERIOD);
   2093         int pos = position();
   2094         IdentifierT name = ParseIdentifierName(CHECK_OK);
   2095         expression = factory()->NewProperty(
   2096             expression, factory()->NewLiteral(name, pos), pos);
   2097         if (fni_ != NULL) {
   2098           this->PushLiteralName(fni_, name);
   2099         }
   2100         break;
   2101       }
   2102       default:
   2103         return expression;
   2104     }
   2105   }
   2106   ASSERT(false);
   2107   return this->EmptyExpression();
   2108 }
   2109 
   2110 
   2111 template <typename Traits>
   2112 typename ParserBase<Traits>::ExpressionT
   2113 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
   2114     ExpressionT expression,
   2115     Scanner::Location location, const char* message, bool* ok) {
   2116   if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
   2117       this->IsEvalOrArguments(this->AsIdentifier(expression))) {
   2118     this->ReportMessageAt(location, "strict_eval_arguments", false);
   2119     *ok = false;
   2120     return this->EmptyExpression();
   2121   } else if (expression->IsValidReferenceExpression()) {
   2122     return expression;
   2123   } else if (expression->IsCall()) {
   2124     // If it is a call, make it a runtime error for legacy web compatibility.
   2125     // Rewrite `expr' to `expr[throw ReferenceError]'.
   2126     int pos = location.beg_pos;
   2127     ExpressionT error = this->NewThrowReferenceError(message, pos);
   2128     return factory()->NewProperty(expression, error, pos);
   2129   } else {
   2130     this->ReportMessageAt(location, message, true);
   2131     *ok = false;
   2132     return this->EmptyExpression();
   2133   }
   2134 }
   2135 
   2136 
   2137 #undef CHECK_OK
   2138 #undef CHECK_OK_CUSTOM
   2139 
   2140 
   2141 template <typename Traits>
   2142 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
   2143     Token::Value property,
   2144     PropertyKind type,
   2145     bool* ok) {
   2146   int old;
   2147   if (property == Token::NUMBER) {
   2148     old = scanner()->FindNumber(&finder_, type);
   2149   } else {
   2150     old = scanner()->FindSymbol(&finder_, type);
   2151   }
   2152   PropertyKind old_type = static_cast<PropertyKind>(old);
   2153   if (HasConflict(old_type, type)) {
   2154     if (IsDataDataConflict(old_type, type)) {
   2155       // Both are data properties.
   2156       if (strict_mode_ == SLOPPY) return;
   2157       parser()->ReportMessage("strict_duplicate_property");
   2158     } else if (IsDataAccessorConflict(old_type, type)) {
   2159       // Both a data and an accessor property with the same name.
   2160       parser()->ReportMessage("accessor_data_property");
   2161     } else {
   2162       ASSERT(IsAccessorAccessorConflict(old_type, type));
   2163       // Both accessors of the same type.
   2164       parser()->ReportMessage("accessor_get_set");
   2165     }
   2166     *ok = false;
   2167   }
   2168 }
   2169 
   2170 
   2171 } }  // v8::internal
   2172 
   2173 #endif  // V8_PREPARSER_H
   2174