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