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