preparser.h revision 014dc512cdd3e367bee49a713fdc5ed92584a3e5
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_PARSING_PREPARSER_H
6#define V8_PARSING_PREPARSER_H
7
8#include "src/ast/scopes.h"
9#include "src/bailout-reason.h"
10#include "src/hashmap.h"
11#include "src/messages.h"
12#include "src/parsing/expression-classifier.h"
13#include "src/parsing/func-name-inferrer.h"
14#include "src/parsing/parser-base.h"
15#include "src/parsing/scanner.h"
16#include "src/parsing/token.h"
17
18namespace v8 {
19namespace internal {
20
21
22class PreParserIdentifier {
23 public:
24  PreParserIdentifier() : type_(kUnknownIdentifier) {}
25  static PreParserIdentifier Default() {
26    return PreParserIdentifier(kUnknownIdentifier);
27  }
28  static PreParserIdentifier Eval() {
29    return PreParserIdentifier(kEvalIdentifier);
30  }
31  static PreParserIdentifier Arguments() {
32    return PreParserIdentifier(kArgumentsIdentifier);
33  }
34  static PreParserIdentifier Undefined() {
35    return PreParserIdentifier(kUndefinedIdentifier);
36  }
37  static PreParserIdentifier FutureReserved() {
38    return PreParserIdentifier(kFutureReservedIdentifier);
39  }
40  static PreParserIdentifier FutureStrictReserved() {
41    return PreParserIdentifier(kFutureStrictReservedIdentifier);
42  }
43  static PreParserIdentifier Let() {
44    return PreParserIdentifier(kLetIdentifier);
45  }
46  static PreParserIdentifier Static() {
47    return PreParserIdentifier(kStaticIdentifier);
48  }
49  static PreParserIdentifier Yield() {
50    return PreParserIdentifier(kYieldIdentifier);
51  }
52  static PreParserIdentifier Prototype() {
53    return PreParserIdentifier(kPrototypeIdentifier);
54  }
55  static PreParserIdentifier Constructor() {
56    return PreParserIdentifier(kConstructorIdentifier);
57  }
58  bool IsEval() const { return type_ == kEvalIdentifier; }
59  bool IsArguments() const { return type_ == kArgumentsIdentifier; }
60  bool IsEvalOrArguments() const { return IsEval() || IsArguments(); }
61  bool IsUndefined() const { return type_ == kUndefinedIdentifier; }
62  bool IsLet() const { return type_ == kLetIdentifier; }
63  bool IsStatic() const { return type_ == kStaticIdentifier; }
64  bool IsYield() const { return type_ == kYieldIdentifier; }
65  bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
66  bool IsConstructor() const { return type_ == kConstructorIdentifier; }
67  bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
68  bool IsFutureStrictReserved() const {
69    return type_ == kFutureStrictReservedIdentifier ||
70           type_ == kLetIdentifier || type_ == kStaticIdentifier ||
71           type_ == kYieldIdentifier;
72  }
73
74  // Allow identifier->name()[->length()] to work. The preparser
75  // does not need the actual positions/lengths of the identifiers.
76  const PreParserIdentifier* operator->() const { return this; }
77  const PreParserIdentifier raw_name() const { return *this; }
78
79  int position() const { return 0; }
80  int length() const { return 0; }
81
82 private:
83  enum Type {
84    kUnknownIdentifier,
85    kFutureReservedIdentifier,
86    kFutureStrictReservedIdentifier,
87    kLetIdentifier,
88    kStaticIdentifier,
89    kYieldIdentifier,
90    kEvalIdentifier,
91    kArgumentsIdentifier,
92    kUndefinedIdentifier,
93    kPrototypeIdentifier,
94    kConstructorIdentifier
95  };
96
97  explicit PreParserIdentifier(Type type) : type_(type) {}
98  Type type_;
99
100  friend class PreParserExpression;
101};
102
103
104class PreParserExpression {
105 public:
106  static PreParserExpression Default() {
107    return PreParserExpression(TypeField::encode(kExpression));
108  }
109
110  static PreParserExpression Spread(PreParserExpression expression) {
111    return PreParserExpression(TypeField::encode(kSpreadExpression));
112  }
113
114  static PreParserExpression FromIdentifier(PreParserIdentifier id) {
115    return PreParserExpression(TypeField::encode(kIdentifierExpression) |
116                               IdentifierTypeField::encode(id.type_));
117  }
118
119  static PreParserExpression BinaryOperation(PreParserExpression left,
120                                             Token::Value op,
121                                             PreParserExpression right) {
122    return PreParserExpression(TypeField::encode(kBinaryOperationExpression));
123  }
124
125  static PreParserExpression Assignment() {
126    return PreParserExpression(TypeField::encode(kExpression) |
127                               ExpressionTypeField::encode(kAssignment));
128  }
129
130  static PreParserExpression ObjectLiteral() {
131    return PreParserExpression(TypeField::encode(kObjectLiteralExpression));
132  }
133
134  static PreParserExpression ArrayLiteral() {
135    return PreParserExpression(TypeField::encode(kArrayLiteralExpression));
136  }
137
138  static PreParserExpression StringLiteral() {
139    return PreParserExpression(TypeField::encode(kStringLiteralExpression));
140  }
141
142  static PreParserExpression UseStrictStringLiteral() {
143    return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
144                               IsUseStrictField::encode(true));
145  }
146
147  static PreParserExpression UseStrongStringLiteral() {
148    return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
149                               IsUseStrongField::encode(true));
150  }
151
152  static PreParserExpression This() {
153    return PreParserExpression(TypeField::encode(kExpression) |
154                               ExpressionTypeField::encode(kThisExpression));
155  }
156
157  static PreParserExpression ThisProperty() {
158    return PreParserExpression(
159        TypeField::encode(kExpression) |
160        ExpressionTypeField::encode(kThisPropertyExpression));
161  }
162
163  static PreParserExpression Property() {
164    return PreParserExpression(
165        TypeField::encode(kExpression) |
166        ExpressionTypeField::encode(kPropertyExpression));
167  }
168
169  static PreParserExpression Call() {
170    return PreParserExpression(TypeField::encode(kExpression) |
171                               ExpressionTypeField::encode(kCallExpression));
172  }
173
174  static PreParserExpression SuperCallReference() {
175    return PreParserExpression(
176        TypeField::encode(kExpression) |
177        ExpressionTypeField::encode(kSuperCallReference));
178  }
179
180  static PreParserExpression NoTemplateTag() {
181    return PreParserExpression(
182        TypeField::encode(kExpression) |
183        ExpressionTypeField::encode(kNoTemplateTagExpression));
184  }
185
186  bool IsIdentifier() const {
187    return TypeField::decode(code_) == kIdentifierExpression;
188  }
189
190  PreParserIdentifier AsIdentifier() const {
191    DCHECK(IsIdentifier());
192    return PreParserIdentifier(IdentifierTypeField::decode(code_));
193  }
194
195  bool IsAssignment() const {
196    return TypeField::decode(code_) == kExpression &&
197           ExpressionTypeField::decode(code_) == kAssignment;
198  }
199
200  bool IsObjectLiteral() const {
201    return TypeField::decode(code_) == kObjectLiteralExpression;
202  }
203
204  bool IsArrayLiteral() const {
205    return TypeField::decode(code_) == kArrayLiteralExpression;
206  }
207
208  bool IsStringLiteral() const {
209    return TypeField::decode(code_) == kStringLiteralExpression;
210  }
211
212  bool IsUseStrictLiteral() const {
213    return TypeField::decode(code_) == kStringLiteralExpression &&
214           IsUseStrictField::decode(code_);
215  }
216
217  bool IsUseStrongLiteral() const {
218    return TypeField::decode(code_) == kStringLiteralExpression &&
219           IsUseStrongField::decode(code_);
220  }
221
222  bool IsThis() const {
223    return TypeField::decode(code_) == kExpression &&
224           ExpressionTypeField::decode(code_) == kThisExpression;
225  }
226
227  bool IsThisProperty() const {
228    return TypeField::decode(code_) == kExpression &&
229           ExpressionTypeField::decode(code_) == kThisPropertyExpression;
230  }
231
232  bool IsProperty() const {
233    return TypeField::decode(code_) == kExpression &&
234           (ExpressionTypeField::decode(code_) == kPropertyExpression ||
235            ExpressionTypeField::decode(code_) == kThisPropertyExpression);
236  }
237
238  bool IsCall() const {
239    return TypeField::decode(code_) == kExpression &&
240           ExpressionTypeField::decode(code_) == kCallExpression;
241  }
242
243  bool IsSuperCallReference() const {
244    return TypeField::decode(code_) == kExpression &&
245           ExpressionTypeField::decode(code_) == kSuperCallReference;
246  }
247
248  bool IsValidReferenceExpression() const {
249    return IsIdentifier() || IsProperty();
250  }
251
252  // At the moment PreParser doesn't track these expression types.
253  bool IsFunctionLiteral() const { return false; }
254  bool IsCallNew() const { return false; }
255
256  bool IsNoTemplateTag() const {
257    return TypeField::decode(code_) == kExpression &&
258           ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
259  }
260
261  bool IsSpreadExpression() const {
262    return TypeField::decode(code_) == kSpreadExpression;
263  }
264
265  PreParserExpression AsFunctionLiteral() { return *this; }
266
267  bool IsBinaryOperation() const {
268    return TypeField::decode(code_) == kBinaryOperationExpression;
269  }
270
271  // Dummy implementation for making expression->somefunc() work in both Parser
272  // and PreParser.
273  PreParserExpression* operator->() { return this; }
274
275  // More dummy implementations of things PreParser doesn't need to track:
276  void set_index(int index) {}  // For YieldExpressions
277  void set_should_eager_compile() {}
278
279  int position() const { return RelocInfo::kNoPosition; }
280  void set_function_token_position(int position) {}
281
282  // Parenthesized expressions in the form `( Expression )`.
283  void set_is_parenthesized() {
284    code_ = ParenthesizedField::update(code_, true);
285  }
286  bool is_parenthesized() const { return ParenthesizedField::decode(code_); }
287
288 private:
289  enum Type {
290    kExpression,
291    kIdentifierExpression,
292    kStringLiteralExpression,
293    kBinaryOperationExpression,
294    kSpreadExpression,
295    kObjectLiteralExpression,
296    kArrayLiteralExpression
297  };
298
299  enum ExpressionType {
300    kThisExpression,
301    kThisPropertyExpression,
302    kPropertyExpression,
303    kCallExpression,
304    kSuperCallReference,
305    kNoTemplateTagExpression,
306    kAssignment
307  };
308
309  explicit PreParserExpression(uint32_t expression_code)
310      : code_(expression_code) {}
311
312  // The first three bits are for the Type.
313  typedef BitField<Type, 0, 3> TypeField;
314
315  // The high order bit applies only to nodes which would inherit from the
316  // Expression ASTNode --- This is by necessity, due to the fact that
317  // Expression nodes may be represented as multiple Types, not exclusively
318  // through kExpression.
319  // TODO(caitp, adamk): clean up PreParserExpression bitfields.
320  typedef BitField<bool, 31, 1> ParenthesizedField;
321
322  // The rest of the bits are interpreted depending on the value
323  // of the Type field, so they can share the storage.
324  typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField;
325  typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField;
326  typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
327  typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10>
328      IdentifierTypeField;
329  typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField;
330
331  uint32_t code_;
332};
333
334
335// The pre-parser doesn't need to build lists of expressions, identifiers, or
336// the like.
337template <typename T>
338class PreParserList {
339 public:
340  // These functions make list->Add(some_expression) work (and do nothing).
341  PreParserList() : length_(0) {}
342  PreParserList* operator->() { return this; }
343  void Add(T, void*) { ++length_; }
344  int length() const { return length_; }
345 private:
346  int length_;
347};
348
349
350typedef PreParserList<PreParserExpression> PreParserExpressionList;
351
352
353class PreParserStatement {
354 public:
355  static PreParserStatement Default() {
356    return PreParserStatement(kUnknownStatement);
357  }
358
359  static PreParserStatement Jump() {
360    return PreParserStatement(kJumpStatement);
361  }
362
363  static PreParserStatement FunctionDeclaration() {
364    return PreParserStatement(kFunctionDeclaration);
365  }
366
367  // Creates expression statement from expression.
368  // Preserves being an unparenthesized string literal, possibly
369  // "use strict".
370  static PreParserStatement ExpressionStatement(
371      PreParserExpression expression) {
372    if (expression.IsUseStrictLiteral()) {
373      return PreParserStatement(kUseStrictExpressionStatement);
374    }
375    if (expression.IsUseStrongLiteral()) {
376      return PreParserStatement(kUseStrongExpressionStatement);
377    }
378    if (expression.IsStringLiteral()) {
379      return PreParserStatement(kStringLiteralExpressionStatement);
380    }
381    return Default();
382  }
383
384  bool IsStringLiteral() {
385    return code_ == kStringLiteralExpressionStatement;
386  }
387
388  bool IsUseStrictLiteral() {
389    return code_ == kUseStrictExpressionStatement;
390  }
391
392  bool IsUseStrongLiteral() { return code_ == kUseStrongExpressionStatement; }
393
394  bool IsFunctionDeclaration() {
395    return code_ == kFunctionDeclaration;
396  }
397
398  bool IsJumpStatement() {
399    return code_ == kJumpStatement;
400  }
401
402 private:
403  enum Type {
404    kUnknownStatement,
405    kJumpStatement,
406    kStringLiteralExpressionStatement,
407    kUseStrictExpressionStatement,
408    kUseStrongExpressionStatement,
409    kFunctionDeclaration
410  };
411
412  explicit PreParserStatement(Type code) : code_(code) {}
413  Type code_;
414};
415
416
417typedef PreParserList<PreParserStatement> PreParserStatementList;
418
419
420class PreParserFactory {
421 public:
422  explicit PreParserFactory(void* unused_value_factory) {}
423  PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
424                                       int pos) {
425    return PreParserExpression::Default();
426  }
427  PreParserExpression NewNumberLiteral(double number,
428                                       int pos) {
429    return PreParserExpression::Default();
430  }
431  PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
432                                       int js_flags, int literal_index,
433                                       bool is_strong, int pos) {
434    return PreParserExpression::Default();
435  }
436  PreParserExpression NewArrayLiteral(PreParserExpressionList values,
437                                      int literal_index,
438                                      bool is_strong,
439                                      int pos) {
440    return PreParserExpression::ArrayLiteral();
441  }
442  PreParserExpression NewArrayLiteral(PreParserExpressionList values,
443                                      int first_spread_index, int literal_index,
444                                      bool is_strong, int pos) {
445    return PreParserExpression::ArrayLiteral();
446  }
447  PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
448                                               PreParserExpression value,
449                                               ObjectLiteralProperty::Kind kind,
450                                               bool is_static,
451                                               bool is_computed_name) {
452    return PreParserExpression::Default();
453  }
454  PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
455                                               PreParserExpression value,
456                                               bool is_static,
457                                               bool is_computed_name) {
458    return PreParserExpression::Default();
459  }
460  PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
461                                       int literal_index,
462                                       int boilerplate_properties,
463                                       bool has_function,
464                                       bool is_strong,
465                                       int pos) {
466    return PreParserExpression::ObjectLiteral();
467  }
468  PreParserExpression NewVariableProxy(void* variable) {
469    return PreParserExpression::Default();
470  }
471  PreParserExpression NewProperty(PreParserExpression obj,
472                                  PreParserExpression key,
473                                  int pos) {
474    if (obj.IsThis()) {
475      return PreParserExpression::ThisProperty();
476    }
477    return PreParserExpression::Property();
478  }
479  PreParserExpression NewUnaryOperation(Token::Value op,
480                                        PreParserExpression expression,
481                                        int pos) {
482    return PreParserExpression::Default();
483  }
484  PreParserExpression NewBinaryOperation(Token::Value op,
485                                         PreParserExpression left,
486                                         PreParserExpression right, int pos) {
487    return PreParserExpression::BinaryOperation(left, op, right);
488  }
489  PreParserExpression NewCompareOperation(Token::Value op,
490                                          PreParserExpression left,
491                                          PreParserExpression right, int pos) {
492    return PreParserExpression::Default();
493  }
494  PreParserExpression NewRewritableAssignmentExpression(
495      PreParserExpression expression) {
496    return expression;
497  }
498  PreParserExpression NewAssignment(Token::Value op,
499                                    PreParserExpression left,
500                                    PreParserExpression right,
501                                    int pos) {
502    return PreParserExpression::Assignment();
503  }
504  PreParserExpression NewYield(PreParserExpression generator_object,
505                               PreParserExpression expression,
506                               Yield::Kind yield_kind,
507                               int pos) {
508    return PreParserExpression::Default();
509  }
510  PreParserExpression NewConditional(PreParserExpression condition,
511                                     PreParserExpression then_expression,
512                                     PreParserExpression else_expression,
513                                     int pos) {
514    return PreParserExpression::Default();
515  }
516  PreParserExpression NewCountOperation(Token::Value op,
517                                        bool is_prefix,
518                                        PreParserExpression expression,
519                                        int pos) {
520    return PreParserExpression::Default();
521  }
522  PreParserExpression NewCall(PreParserExpression expression,
523                              PreParserExpressionList arguments,
524                              int pos) {
525    return PreParserExpression::Call();
526  }
527  PreParserExpression NewCallNew(PreParserExpression expression,
528                                 PreParserExpressionList arguments,
529                                 int pos) {
530    return PreParserExpression::Default();
531  }
532  PreParserExpression NewCallRuntime(const AstRawString* name,
533                                     const Runtime::Function* function,
534                                     PreParserExpressionList arguments,
535                                     int pos) {
536    return PreParserExpression::Default();
537  }
538  PreParserStatement NewReturnStatement(PreParserExpression expression,
539                                        int pos) {
540    return PreParserStatement::Default();
541  }
542  PreParserExpression NewFunctionLiteral(
543      PreParserIdentifier name, Scope* scope, PreParserStatementList body,
544      int materialized_literal_count, int expected_property_count,
545      int parameter_count,
546      FunctionLiteral::ParameterFlag has_duplicate_parameters,
547      FunctionLiteral::FunctionType function_type,
548      FunctionLiteral::EagerCompileHint eager_compile_hint, FunctionKind kind,
549      int position) {
550    return PreParserExpression::Default();
551  }
552
553  PreParserExpression NewSpread(PreParserExpression expression, int pos) {
554    return PreParserExpression::Spread(expression);
555  }
556
557  PreParserExpression NewEmptyParentheses(int pos) {
558    return PreParserExpression::Default();
559  }
560
561  // Return the object itself as AstVisitor and implement the needed
562  // dummy method right in this class.
563  PreParserFactory* visitor() { return this; }
564  int* ast_properties() {
565    static int dummy = 42;
566    return &dummy;
567  }
568};
569
570
571struct PreParserFormalParameters : FormalParametersBase {
572  explicit PreParserFormalParameters(Scope* scope)
573      : FormalParametersBase(scope) {}
574  int arity = 0;
575
576  int Arity() const { return arity; }
577  PreParserIdentifier at(int i) { return PreParserIdentifier(); }  // Dummy
578};
579
580
581class PreParser;
582
583class PreParserTraits {
584 public:
585  struct Type {
586    // TODO(marja): To be removed. The Traits object should contain all the data
587    // it needs.
588    typedef PreParser* Parser;
589
590    // PreParser doesn't need to store generator variables.
591    typedef void GeneratorVariable;
592
593    typedef int AstProperties;
594
595    // Return types for traversing functions.
596    typedef PreParserIdentifier Identifier;
597    typedef PreParserExpression Expression;
598    typedef PreParserExpression YieldExpression;
599    typedef PreParserExpression FunctionLiteral;
600    typedef PreParserExpression ClassLiteral;
601    typedef PreParserExpression ObjectLiteralProperty;
602    typedef PreParserExpression Literal;
603    typedef PreParserExpressionList ExpressionList;
604    typedef PreParserExpressionList PropertyList;
605    typedef PreParserIdentifier FormalParameter;
606    typedef PreParserFormalParameters FormalParameters;
607    typedef PreParserStatementList StatementList;
608
609    // For constructing objects returned by the traversing functions.
610    typedef PreParserFactory Factory;
611  };
612
613  explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
614
615  // Helper functions for recursive descent.
616  static bool IsEval(PreParserIdentifier identifier) {
617    return identifier.IsEval();
618  }
619
620  static bool IsArguments(PreParserIdentifier identifier) {
621    return identifier.IsArguments();
622  }
623
624  static bool IsEvalOrArguments(PreParserIdentifier identifier) {
625    return identifier.IsEvalOrArguments();
626  }
627
628  static bool IsUndefined(PreParserIdentifier identifier) {
629    return identifier.IsUndefined();
630  }
631
632  static bool IsPrototype(PreParserIdentifier identifier) {
633    return identifier.IsPrototype();
634  }
635
636  static bool IsConstructor(PreParserIdentifier identifier) {
637    return identifier.IsConstructor();
638  }
639
640  // Returns true if the expression is of type "this.foo".
641  static bool IsThisProperty(PreParserExpression expression) {
642    return expression.IsThisProperty();
643  }
644
645  static bool IsIdentifier(PreParserExpression expression) {
646    return expression.IsIdentifier();
647  }
648
649  static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
650    return expression.AsIdentifier();
651  }
652
653  static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
654    return identifier.IsFutureStrictReserved();
655  }
656
657  static bool IsBoilerplateProperty(PreParserExpression property) {
658    // PreParser doesn't count boilerplate properties.
659    return false;
660  }
661
662  static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
663    return false;
664  }
665
666  static PreParserExpression GetPropertyValue(PreParserExpression property) {
667    return PreParserExpression::Default();
668  }
669
670  // Functions for encapsulating the differences between parsing and preparsing;
671  // operations interleaved with the recursive descent.
672  static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
673    // PreParser should not use FuncNameInferrer.
674    UNREACHABLE();
675  }
676
677  static void PushPropertyName(FuncNameInferrer* fni,
678                               PreParserExpression expression) {
679    // PreParser should not use FuncNameInferrer.
680    UNREACHABLE();
681  }
682
683  static void InferFunctionName(FuncNameInferrer* fni,
684                                PreParserExpression expression) {
685    // PreParser should not use FuncNameInferrer.
686    UNREACHABLE();
687  }
688
689  static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
690      Scope* scope, PreParserExpression property, bool* has_function) {}
691
692  static void CheckAssigningFunctionLiteralToProperty(
693      PreParserExpression left, PreParserExpression right) {}
694
695  static PreParserExpression MarkExpressionAsAssigned(
696      PreParserExpression expression) {
697    // TODO(marja): To be able to produce the same errors, the preparser needs
698    // to start tracking which expressions are variables and which are assigned.
699    return expression;
700  }
701
702  bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
703                                              PreParserExpression y,
704                                              Token::Value op,
705                                              int pos,
706                                              PreParserFactory* factory) {
707    return false;
708  }
709
710  PreParserExpression BuildUnaryExpression(PreParserExpression expression,
711                                           Token::Value op, int pos,
712                                           PreParserFactory* factory) {
713    return PreParserExpression::Default();
714  }
715
716  PreParserExpression NewThrowReferenceError(MessageTemplate::Template message,
717                                             int pos) {
718    return PreParserExpression::Default();
719  }
720  PreParserExpression NewThrowSyntaxError(MessageTemplate::Template message,
721                                          Handle<Object> arg, int pos) {
722    return PreParserExpression::Default();
723  }
724  PreParserExpression NewThrowTypeError(MessageTemplate::Template message,
725                                        Handle<Object> arg, int pos) {
726    return PreParserExpression::Default();
727  }
728
729  // Reporting errors.
730  void ReportMessageAt(Scanner::Location location,
731                       MessageTemplate::Template message,
732                       const char* arg = NULL,
733                       ParseErrorType error_type = kSyntaxError);
734  void ReportMessageAt(int start_pos, int end_pos,
735                       MessageTemplate::Template message,
736                       const char* arg = NULL,
737                       ParseErrorType error_type = kSyntaxError);
738
739  // "null" return type creators.
740  static PreParserIdentifier EmptyIdentifier() {
741    return PreParserIdentifier::Default();
742  }
743  static PreParserIdentifier EmptyIdentifierString() {
744    return PreParserIdentifier::Default();
745  }
746  static PreParserExpression EmptyExpression() {
747    return PreParserExpression::Default();
748  }
749  static PreParserExpression EmptyLiteral() {
750    return PreParserExpression::Default();
751  }
752  static PreParserExpression EmptyObjectLiteralProperty() {
753    return PreParserExpression::Default();
754  }
755  static PreParserExpression EmptyFunctionLiteral() {
756    return PreParserExpression::Default();
757  }
758  static PreParserExpressionList NullExpressionList() {
759    return PreParserExpressionList();
760  }
761
762  // Odd-ball literal creators.
763  static PreParserExpression GetLiteralTheHole(int position,
764                                               PreParserFactory* factory) {
765    return PreParserExpression::Default();
766  }
767
768  // Producing data during the recursive descent.
769  PreParserIdentifier GetSymbol(Scanner* scanner);
770  PreParserIdentifier GetNumberAsSymbol(Scanner* scanner);
771
772  static PreParserIdentifier GetNextSymbol(Scanner* scanner) {
773    return PreParserIdentifier::Default();
774  }
775
776  static PreParserExpression ThisExpression(Scope* scope,
777                                            PreParserFactory* factory,
778                                            int pos) {
779    return PreParserExpression::This();
780  }
781
782  static PreParserExpression SuperPropertyReference(Scope* scope,
783                                                    PreParserFactory* factory,
784                                                    int pos) {
785    return PreParserExpression::Default();
786  }
787
788  static PreParserExpression SuperCallReference(Scope* scope,
789                                                PreParserFactory* factory,
790                                                int pos) {
791    return PreParserExpression::SuperCallReference();
792  }
793
794  static PreParserExpression NewTargetExpression(Scope* scope,
795                                                 PreParserFactory* factory,
796                                                 int pos) {
797    return PreParserExpression::Default();
798  }
799
800  static PreParserExpression DefaultConstructor(bool call_super, Scope* scope,
801                                                int pos, int end_pos) {
802    return PreParserExpression::Default();
803  }
804
805  static PreParserExpression ExpressionFromLiteral(
806      Token::Value token, int pos, Scanner* scanner,
807      PreParserFactory* factory) {
808    return PreParserExpression::Default();
809  }
810
811  static PreParserExpression ExpressionFromIdentifier(
812      PreParserIdentifier name, int start_position, int end_position,
813      Scope* scope, PreParserFactory* factory) {
814    return PreParserExpression::FromIdentifier(name);
815  }
816
817  PreParserExpression ExpressionFromString(int pos,
818                                           Scanner* scanner,
819                                           PreParserFactory* factory = NULL);
820
821  PreParserExpression GetIterator(PreParserExpression iterable,
822                                  PreParserFactory* factory, int pos) {
823    return PreParserExpression::Default();
824  }
825
826  static PreParserExpressionList NewExpressionList(int size, Zone* zone) {
827    return PreParserExpressionList();
828  }
829
830  static PreParserStatementList NewStatementList(int size, Zone* zone) {
831    return PreParserStatementList();
832  }
833
834  static PreParserExpressionList NewPropertyList(int size, Zone* zone) {
835    return PreParserExpressionList();
836  }
837
838  static void AddParameterInitializationBlock(
839      const PreParserFormalParameters& parameters,
840      PreParserStatementList list, bool* ok) {}
841
842  V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
843                                      int* expected_property_count, bool* ok) {
844    UNREACHABLE();
845  }
846
847  V8_INLINE PreParserStatementList ParseEagerFunctionBody(
848      PreParserIdentifier function_name, int pos,
849      const PreParserFormalParameters& parameters, FunctionKind kind,
850      FunctionLiteral::FunctionType function_type, bool* ok);
851
852  V8_INLINE void ParseArrowFunctionFormalParameterList(
853      PreParserFormalParameters* parameters,
854      PreParserExpression expression, const Scanner::Location& params_loc,
855      Scanner::Location* duplicate_loc, bool* ok);
856
857  void ReindexLiterals(const PreParserFormalParameters& paramaters) {}
858
859  struct TemplateLiteralState {};
860
861  TemplateLiteralState OpenTemplateLiteral(int pos) {
862    return TemplateLiteralState();
863  }
864  void AddTemplateSpan(TemplateLiteralState*, bool) {}
865  void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {}
866  PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int,
867                                           PreParserExpression tag) {
868    if (IsTaggedTemplate(tag)) {
869      // Emulate generation of array literals for tag callsite
870      // 1st is array of cooked strings, second is array of raw strings
871      MaterializeTemplateCallsiteLiterals();
872    }
873    return EmptyExpression();
874  }
875  inline void MaterializeTemplateCallsiteLiterals();
876  PreParserExpression NoTemplateTag() {
877    return PreParserExpression::NoTemplateTag();
878  }
879  static bool IsTaggedTemplate(const PreParserExpression tag) {
880    return !tag.IsNoTemplateTag();
881  }
882
883  void AddFormalParameter(PreParserFormalParameters* parameters,
884                          PreParserExpression pattern,
885                          PreParserExpression initializer,
886                          int initializer_end_position, bool is_rest) {
887    ++parameters->arity;
888  }
889  void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter,
890                              ExpressionClassifier* classifier) {
891    if (!classifier->is_simple_parameter_list()) {
892      scope->SetHasNonSimpleParameters();
893    }
894  }
895
896  void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
897
898  // Temporary glue; these functions will move to ParserBase.
899  PreParserExpression ParseV8Intrinsic(bool* ok);
900  V8_INLINE PreParserExpression ParseDoExpression(bool* ok);
901  PreParserExpression ParseFunctionLiteral(
902      PreParserIdentifier name, Scanner::Location function_name_location,
903      FunctionNameValidity function_name_validity, FunctionKind kind,
904      int function_token_position, FunctionLiteral::FunctionType type,
905      FunctionLiteral::ArityRestriction arity_restriction,
906      LanguageMode language_mode, bool* ok);
907
908  PreParserExpression ParseClassLiteral(PreParserIdentifier name,
909                                        Scanner::Location class_name_location,
910                                        bool name_is_strict_reserved, int pos,
911                                        bool* ok);
912
913  PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) {
914    return list;
915  }
916
917  inline void MaterializeUnspreadArgumentsLiterals(int count);
918
919  inline PreParserExpression SpreadCall(PreParserExpression function,
920                                        PreParserExpressionList args, int pos);
921
922  inline PreParserExpression SpreadCallNew(PreParserExpression function,
923                                           PreParserExpressionList args,
924                                           int pos);
925
926  inline void RewriteDestructuringAssignments() {}
927
928  inline void QueueDestructuringAssignmentForRewriting(PreParserExpression) {}
929
930  void SetFunctionNameFromPropertyName(PreParserExpression,
931                                       PreParserIdentifier) {}
932  void SetFunctionNameFromIdentifierRef(PreParserExpression,
933                                        PreParserExpression) {}
934
935  inline PreParserExpression RewriteNonPattern(
936      PreParserExpression expr, const ExpressionClassifier* classifier,
937      bool* ok);
938  inline PreParserExpression RewriteNonPatternArguments(
939      PreParserExpression args, const ExpressionClassifier* classifier,
940      bool* ok);
941  inline PreParserExpression RewriteNonPatternObjectLiteralProperty(
942      PreParserExpression property, const ExpressionClassifier* classifier,
943      bool* ok);
944
945 private:
946  PreParser* pre_parser_;
947};
948
949
950// Preparsing checks a JavaScript program and emits preparse-data that helps
951// a later parsing to be faster.
952// See preparse-data-format.h for the data format.
953
954// The PreParser checks that the syntax follows the grammar for JavaScript,
955// and collects some information about the program along the way.
956// The grammar check is only performed in order to understand the program
957// sufficiently to deduce some information about it, that can be used
958// to speed up later parsing. Finding errors is not the goal of pre-parsing,
959// rather it is to speed up properly written and correct programs.
960// That means that contextual checks (like a label being declared where
961// it is used) are generally omitted.
962class PreParser : public ParserBase<PreParserTraits> {
963 public:
964  typedef PreParserIdentifier Identifier;
965  typedef PreParserExpression Expression;
966  typedef PreParserStatement Statement;
967
968  enum PreParseResult {
969    kPreParseStackOverflow,
970    kPreParseSuccess
971  };
972
973  PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
974            ParserRecorder* log, uintptr_t stack_limit)
975      : ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL,
976                                    ast_value_factory, log, this) {}
977
978  // Pre-parse the program from the character stream; returns true on
979  // success (even if parsing failed, the pre-parse data successfully
980  // captured the syntax error), and false if a stack-overflow happened
981  // during parsing.
982  PreParseResult PreParseProgram(int* materialized_literals = 0) {
983    Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
984    PreParserFactory factory(NULL);
985    FunctionState top_scope(&function_state_, &scope_, scope, kNormalFunction,
986                            &factory);
987    bool ok = true;
988    int start_position = scanner()->peek_location().beg_pos;
989    ParseStatementList(Token::EOS, &ok);
990    if (stack_overflow()) return kPreParseStackOverflow;
991    if (!ok) {
992      ReportUnexpectedToken(scanner()->current_token());
993    } else if (is_strict(scope_->language_mode())) {
994      CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
995                              &ok);
996    }
997    if (materialized_literals) {
998      *materialized_literals = function_state_->materialized_literal_count();
999    }
1000    return kPreParseSuccess;
1001  }
1002
1003  // Parses a single function literal, from the opening parentheses before
1004  // parameters to the closing brace after the body.
1005  // Returns a FunctionEntry describing the body of the function in enough
1006  // detail that it can be lazily compiled.
1007  // The scanner is expected to have matched the "function" or "function*"
1008  // keyword and parameters, and have consumed the initial '{'.
1009  // At return, unless an error occurred, the scanner is positioned before the
1010  // the final '}'.
1011  PreParseResult PreParseLazyFunction(
1012      LanguageMode language_mode, FunctionKind kind, bool has_simple_parameters,
1013      ParserRecorder* log, Scanner::BookmarkScope* bookmark = nullptr);
1014
1015 private:
1016  friend class PreParserTraits;
1017
1018  static const int kLazyParseTrialLimit = 200;
1019
1020  // These types form an algebra over syntactic categories that is just
1021  // rich enough to let us recognize and propagate the constructs that
1022  // are either being counted in the preparser data, or is important
1023  // to throw the correct syntax error exceptions.
1024
1025  // All ParseXXX functions take as the last argument an *ok parameter
1026  // which is set to false if parsing failed; it is unchanged otherwise.
1027  // By making the 'exception handling' explicit, we are forced to check
1028  // for failure at the call sites.
1029  Statement ParseStatementListItem(bool* ok);
1030  void ParseStatementList(int end_token, bool* ok,
1031                          Scanner::BookmarkScope* bookmark = nullptr);
1032  Statement ParseStatement(bool* ok);
1033  Statement ParseSubStatement(bool* ok);
1034  Statement ParseFunctionDeclaration(bool* ok);
1035  Statement ParseClassDeclaration(bool* ok);
1036  Statement ParseBlock(bool* ok);
1037  Statement ParseVariableStatement(VariableDeclarationContext var_context,
1038                                   bool* ok);
1039  Statement ParseVariableDeclarations(VariableDeclarationContext var_context,
1040                                      int* num_decl, bool* is_lexical,
1041                                      bool* is_binding_pattern,
1042                                      Scanner::Location* first_initializer_loc,
1043                                      Scanner::Location* bindings_loc,
1044                                      bool* ok);
1045  Statement ParseExpressionOrLabelledStatement(bool* ok);
1046  Statement ParseIfStatement(bool* ok);
1047  Statement ParseContinueStatement(bool* ok);
1048  Statement ParseBreakStatement(bool* ok);
1049  Statement ParseReturnStatement(bool* ok);
1050  Statement ParseWithStatement(bool* ok);
1051  Statement ParseSwitchStatement(bool* ok);
1052  Statement ParseDoWhileStatement(bool* ok);
1053  Statement ParseWhileStatement(bool* ok);
1054  Statement ParseForStatement(bool* ok);
1055  Statement ParseThrowStatement(bool* ok);
1056  Statement ParseTryStatement(bool* ok);
1057  Statement ParseDebuggerStatement(bool* ok);
1058  Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1059  Expression ParseObjectLiteral(bool* ok);
1060  Expression ParseV8Intrinsic(bool* ok);
1061  Expression ParseDoExpression(bool* ok);
1062
1063  V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
1064                                      int* expected_property_count, bool* ok);
1065  V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1066      PreParserIdentifier function_name, int pos,
1067      const PreParserFormalParameters& parameters, FunctionKind kind,
1068      FunctionLiteral::FunctionType function_type, bool* ok);
1069
1070  Expression ParseFunctionLiteral(
1071      Identifier name, Scanner::Location function_name_location,
1072      FunctionNameValidity function_name_validity, FunctionKind kind,
1073      int function_token_pos, FunctionLiteral::FunctionType function_type,
1074      FunctionLiteral::ArityRestriction arity_restriction,
1075      LanguageMode language_mode, bool* ok);
1076  void ParseLazyFunctionLiteralBody(bool* ok,
1077                                    Scanner::BookmarkScope* bookmark = nullptr);
1078
1079  PreParserExpression ParseClassLiteral(PreParserIdentifier name,
1080                                        Scanner::Location class_name_location,
1081                                        bool name_is_strict_reserved, int pos,
1082                                        bool* ok);
1083};
1084
1085
1086void PreParserTraits::MaterializeTemplateCallsiteLiterals() {
1087  pre_parser_->function_state_->NextMaterializedLiteralIndex();
1088  pre_parser_->function_state_->NextMaterializedLiteralIndex();
1089}
1090
1091
1092void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) {
1093  for (int i = 0; i < count; ++i) {
1094    pre_parser_->function_state_->NextMaterializedLiteralIndex();
1095  }
1096}
1097
1098
1099PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function,
1100                                                PreParserExpressionList args,
1101                                                int pos) {
1102  return pre_parser_->factory()->NewCall(function, args, pos);
1103}
1104
1105PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
1106                                                   PreParserExpressionList args,
1107                                                   int pos) {
1108  return pre_parser_->factory()->NewCallNew(function, args, pos);
1109}
1110
1111
1112void PreParserTraits::ParseArrowFunctionFormalParameterList(
1113    PreParserFormalParameters* parameters,
1114    PreParserExpression params, const Scanner::Location& params_loc,
1115    Scanner::Location* duplicate_loc, bool* ok) {
1116  // TODO(wingo): Detect duplicated identifiers in paramlists.  Detect parameter
1117  // lists that are too long.
1118}
1119
1120
1121PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) {
1122  return pre_parser_->ParseDoExpression(ok);
1123}
1124
1125
1126PreParserExpression PreParserTraits::RewriteNonPattern(
1127    PreParserExpression expr, const ExpressionClassifier* classifier,
1128    bool* ok) {
1129  pre_parser_->ValidateExpression(classifier, ok);
1130  return expr;
1131}
1132
1133
1134PreParserExpression PreParserTraits::RewriteNonPatternArguments(
1135    PreParserExpression args, const ExpressionClassifier* classifier,
1136    bool* ok) {
1137  pre_parser_->ValidateExpression(classifier, ok);
1138  return args;
1139}
1140
1141
1142PreParserExpression PreParserTraits::RewriteNonPatternObjectLiteralProperty(
1143    PreParserExpression property, const ExpressionClassifier* classifier,
1144    bool* ok) {
1145  pre_parser_->ValidateExpression(classifier, ok);
1146  return property;
1147}
1148
1149
1150PreParserStatementList PreParser::ParseEagerFunctionBody(
1151    PreParserIdentifier function_name, int pos,
1152    const PreParserFormalParameters& parameters, FunctionKind kind,
1153    FunctionLiteral::FunctionType function_type, bool* ok) {
1154  ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1155
1156  ParseStatementList(Token::RBRACE, ok);
1157  if (!*ok) return PreParserStatementList();
1158
1159  Expect(Token::RBRACE, ok);
1160  return PreParserStatementList();
1161}
1162
1163
1164PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1165    PreParserIdentifier function_name, int pos,
1166    const PreParserFormalParameters& parameters, FunctionKind kind,
1167    FunctionLiteral::FunctionType function_type, bool* ok) {
1168  return pre_parser_->ParseEagerFunctionBody(function_name, pos, parameters,
1169                                             kind, function_type, ok);
1170}
1171
1172}  // namespace internal
1173}  // namespace v8
1174
1175#endif  // V8_PARSING_PREPARSER_H
1176