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
15namespace v8 {
16namespace 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
58template <typename Traits>
59class 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
492class 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.
544class 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.
654class 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
666class 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.
718class 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
727class 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
744class 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
845class PreParser;
846
847class 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.
1067class 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
1184template<class Traits>
1185ParserBase<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
1208template<class Traits>
1209ParserBase<Traits>::FunctionState::~FunctionState() {
1210  *scope_stack_ = outer_scope_;
1211  *function_state_stack_ = outer_function_state_;
1212  Traits::TearDownFunctionState(this, extra_param_);
1213}
1214
1215
1216template<class Traits>
1217void 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
1244template<class Traits>
1245typename 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
1269template <class Traits>
1270typename 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
1288template <class Traits>
1289typename ParserBase<Traits>::IdentifierT
1290ParserBase<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
1302template <class Traits>
1303typename ParserBase<Traits>::IdentifierT
1304ParserBase<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
1314template <class Traits>
1315typename 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
1353template <class Traits>
1354typename ParserBase<Traits>::ExpressionT
1355ParserBase<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
1446template <class Traits>
1447typename 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
1464template <class Traits>
1465typename 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
1495template <class Traits>
1496typename 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
1658template <class Traits>
1659typename 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
1688template <class Traits>
1689typename ParserBase<Traits>::ExpressionT
1690ParserBase<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
1749template <class Traits>
1750typename ParserBase<Traits>::ExpressionT
1751ParserBase<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
1772template <class Traits>
1773typename ParserBase<Traits>::ExpressionT
1774ParserBase<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
1795template <class Traits>
1796typename ParserBase<Traits>::ExpressionT
1797ParserBase<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
1839template <class Traits>
1840typename ParserBase<Traits>::ExpressionT
1841ParserBase<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
1889template <class Traits>
1890typename ParserBase<Traits>::ExpressionT
1891ParserBase<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
1914template <class Traits>
1915typename ParserBase<Traits>::ExpressionT
1916ParserBase<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
1985template <class Traits>
1986typename ParserBase<Traits>::ExpressionT
1987ParserBase<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
2027template <class Traits>
2028typename ParserBase<Traits>::ExpressionT
2029ParserBase<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
2072template <class Traits>
2073typename ParserBase<Traits>::ExpressionT
2074ParserBase<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
2111template <typename Traits>
2112typename ParserBase<Traits>::ExpressionT
2113ParserBase<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
2141template <typename Traits>
2142void 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