713133a67924da7006c93fa2361e4ae5ac491f3d
[platform/upstream/nodejs.git] / deps / v8 / src / parser.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_PARSER_H_
6 #define V8_PARSER_H_
7
8 #include "src/allocation.h"
9 #include "src/ast.h"
10 #include "src/compiler.h"  // For CachedDataMode
11 #include "src/preparse-data.h"
12 #include "src/preparse-data-format.h"
13 #include "src/preparser.h"
14 #include "src/scopes.h"
15
16 namespace v8 {
17 class ScriptCompiler;
18
19 namespace internal {
20
21 class CompilationInfo;
22 class ParserLog;
23 class PositionStack;
24 class Target;
25
26
27 class FunctionEntry BASE_EMBEDDED {
28  public:
29   enum {
30     kStartPositionIndex,
31     kEndPositionIndex,
32     kLiteralCountIndex,
33     kPropertyCountIndex,
34     kLanguageModeIndex,
35     kUsesSuperPropertyIndex,
36     kSize
37   };
38
39   explicit FunctionEntry(Vector<unsigned> backing)
40     : backing_(backing) { }
41
42   FunctionEntry() : backing_() { }
43
44   int start_pos() { return backing_[kStartPositionIndex]; }
45   int end_pos() { return backing_[kEndPositionIndex]; }
46   int literal_count() { return backing_[kLiteralCountIndex]; }
47   int property_count() { return backing_[kPropertyCountIndex]; }
48   LanguageMode language_mode() {
49     DCHECK(is_valid_language_mode(backing_[kLanguageModeIndex]));
50     return static_cast<LanguageMode>(backing_[kLanguageModeIndex]);
51   }
52   bool uses_super_property() { return backing_[kUsesSuperPropertyIndex]; }
53
54   bool is_valid() { return !backing_.is_empty(); }
55
56  private:
57   Vector<unsigned> backing_;
58 };
59
60
61 // Wrapper around ScriptData to provide parser-specific functionality.
62 class ParseData {
63  public:
64   static ParseData* FromCachedData(ScriptData* cached_data) {
65     ParseData* pd = new ParseData(cached_data);
66     if (pd->IsSane()) return pd;
67     cached_data->Reject();
68     delete pd;
69     return NULL;
70   }
71
72   void Initialize();
73   FunctionEntry GetFunctionEntry(int start);
74   int FunctionCount();
75
76   bool HasError();
77
78   unsigned* Data() {  // Writable data as unsigned int array.
79     return reinterpret_cast<unsigned*>(const_cast<byte*>(script_data_->data()));
80   }
81
82   void Reject() { script_data_->Reject(); }
83
84   bool rejected() const { return script_data_->rejected(); }
85
86  private:
87   explicit ParseData(ScriptData* script_data) : script_data_(script_data) {}
88
89   bool IsSane();
90   unsigned Magic();
91   unsigned Version();
92   int FunctionsSize();
93   int Length() const {
94     // Script data length is already checked to be a multiple of unsigned size.
95     return script_data_->length() / sizeof(unsigned);
96   }
97
98   ScriptData* script_data_;
99   int function_index_;
100
101   DISALLOW_COPY_AND_ASSIGN(ParseData);
102 };
103
104 // ----------------------------------------------------------------------------
105 // REGEXP PARSING
106
107 // A BufferedZoneList is an automatically growing list, just like (and backed
108 // by) a ZoneList, that is optimized for the case of adding and removing
109 // a single element. The last element added is stored outside the backing list,
110 // and if no more than one element is ever added, the ZoneList isn't even
111 // allocated.
112 // Elements must not be NULL pointers.
113 template <typename T, int initial_size>
114 class BufferedZoneList {
115  public:
116   BufferedZoneList() : list_(NULL), last_(NULL) {}
117
118   // Adds element at end of list. This element is buffered and can
119   // be read using last() or removed using RemoveLast until a new Add or until
120   // RemoveLast or GetList has been called.
121   void Add(T* value, Zone* zone) {
122     if (last_ != NULL) {
123       if (list_ == NULL) {
124         list_ = new(zone) ZoneList<T*>(initial_size, zone);
125       }
126       list_->Add(last_, zone);
127     }
128     last_ = value;
129   }
130
131   T* last() {
132     DCHECK(last_ != NULL);
133     return last_;
134   }
135
136   T* RemoveLast() {
137     DCHECK(last_ != NULL);
138     T* result = last_;
139     if ((list_ != NULL) && (list_->length() > 0))
140       last_ = list_->RemoveLast();
141     else
142       last_ = NULL;
143     return result;
144   }
145
146   T* Get(int i) {
147     DCHECK((0 <= i) && (i < length()));
148     if (list_ == NULL) {
149       DCHECK_EQ(0, i);
150       return last_;
151     } else {
152       if (i == list_->length()) {
153         DCHECK(last_ != NULL);
154         return last_;
155       } else {
156         return list_->at(i);
157       }
158     }
159   }
160
161   void Clear() {
162     list_ = NULL;
163     last_ = NULL;
164   }
165
166   int length() {
167     int length = (list_ == NULL) ? 0 : list_->length();
168     return length + ((last_ == NULL) ? 0 : 1);
169   }
170
171   ZoneList<T*>* GetList(Zone* zone) {
172     if (list_ == NULL) {
173       list_ = new(zone) ZoneList<T*>(initial_size, zone);
174     }
175     if (last_ != NULL) {
176       list_->Add(last_, zone);
177       last_ = NULL;
178     }
179     return list_;
180   }
181
182  private:
183   ZoneList<T*>* list_;
184   T* last_;
185 };
186
187
188 // Accumulates RegExp atoms and assertions into lists of terms and alternatives.
189 class RegExpBuilder: public ZoneObject {
190  public:
191   explicit RegExpBuilder(Zone* zone);
192   void AddCharacter(uc16 character);
193   // "Adds" an empty expression. Does nothing except consume a
194   // following quantifier
195   void AddEmpty();
196   void AddAtom(RegExpTree* tree);
197   void AddAssertion(RegExpTree* tree);
198   void NewAlternative();  // '|'
199   void AddQuantifierToAtom(
200       int min, int max, RegExpQuantifier::QuantifierType type);
201   RegExpTree* ToRegExp();
202
203  private:
204   void FlushCharacters();
205   void FlushText();
206   void FlushTerms();
207   Zone* zone() const { return zone_; }
208
209   Zone* zone_;
210   bool pending_empty_;
211   ZoneList<uc16>* characters_;
212   BufferedZoneList<RegExpTree, 2> terms_;
213   BufferedZoneList<RegExpTree, 2> text_;
214   BufferedZoneList<RegExpTree, 2> alternatives_;
215 #ifdef DEBUG
216   enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
217 #define LAST(x) last_added_ = x;
218 #else
219 #define LAST(x)
220 #endif
221 };
222
223
224 class RegExpParser BASE_EMBEDDED {
225  public:
226   RegExpParser(FlatStringReader* in, Handle<String>* error, bool multiline_mode,
227                bool unicode, Isolate* isolate, Zone* zone);
228
229   static bool ParseRegExp(Isolate* isolate, Zone* zone, FlatStringReader* input,
230                           bool multiline, bool unicode,
231                           RegExpCompileData* result);
232
233   RegExpTree* ParsePattern();
234   RegExpTree* ParseDisjunction();
235   RegExpTree* ParseGroup();
236   RegExpTree* ParseCharacterClass();
237
238   // Parses a {...,...} quantifier and stores the range in the given
239   // out parameters.
240   bool ParseIntervalQuantifier(int* min_out, int* max_out);
241
242   // Parses and returns a single escaped character.  The character
243   // must not be 'b' or 'B' since they are usually handle specially.
244   uc32 ParseClassCharacterEscape();
245
246   // Checks whether the following is a length-digit hexadecimal number,
247   // and sets the value if it is.
248   bool ParseHexEscape(int length, uc32* value);
249   bool ParseUnicodeEscape(uc32* value);
250   bool ParseUnlimitedLengthHexNumber(int max_value, uc32* value);
251
252   uc32 ParseOctalLiteral();
253
254   // Tries to parse the input as a back reference.  If successful it
255   // stores the result in the output parameter and returns true.  If
256   // it fails it will push back the characters read so the same characters
257   // can be reparsed.
258   bool ParseBackReferenceIndex(int* index_out);
259
260   CharacterRange ParseClassAtom(uc16* char_class);
261   RegExpTree* ReportError(Vector<const char> message);
262   void Advance();
263   void Advance(int dist);
264   void Reset(int pos);
265
266   // Reports whether the pattern might be used as a literal search string.
267   // Only use if the result of the parse is a single atom node.
268   bool simple();
269   bool contains_anchor() { return contains_anchor_; }
270   void set_contains_anchor() { contains_anchor_ = true; }
271   int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
272   int position() { return next_pos_ - 1; }
273   bool failed() { return failed_; }
274
275   static bool IsSyntaxCharacter(uc32 c);
276
277   static const int kMaxCaptures = 1 << 16;
278   static const uc32 kEndMarker = (1 << 21);
279
280  private:
281   enum SubexpressionType {
282     INITIAL,
283     CAPTURE,  // All positive values represent captures.
284     POSITIVE_LOOKAHEAD,
285     NEGATIVE_LOOKAHEAD,
286     GROUPING
287   };
288
289   class RegExpParserState : public ZoneObject {
290    public:
291     RegExpParserState(RegExpParserState* previous_state,
292                       SubexpressionType group_type,
293                       int disjunction_capture_index,
294                       Zone* zone)
295         : previous_state_(previous_state),
296           builder_(new(zone) RegExpBuilder(zone)),
297           group_type_(group_type),
298           disjunction_capture_index_(disjunction_capture_index) {}
299     // Parser state of containing expression, if any.
300     RegExpParserState* previous_state() { return previous_state_; }
301     bool IsSubexpression() { return previous_state_ != NULL; }
302     // RegExpBuilder building this regexp's AST.
303     RegExpBuilder* builder() { return builder_; }
304     // Type of regexp being parsed (parenthesized group or entire regexp).
305     SubexpressionType group_type() { return group_type_; }
306     // Index in captures array of first capture in this sub-expression, if any.
307     // Also the capture index of this sub-expression itself, if group_type
308     // is CAPTURE.
309     int capture_index() { return disjunction_capture_index_; }
310
311    private:
312     // Linked list implementation of stack of states.
313     RegExpParserState* previous_state_;
314     // Builder for the stored disjunction.
315     RegExpBuilder* builder_;
316     // Stored disjunction type (capture, look-ahead or grouping), if any.
317     SubexpressionType group_type_;
318     // Stored disjunction's capture index (if any).
319     int disjunction_capture_index_;
320   };
321
322   Isolate* isolate() { return isolate_; }
323   Zone* zone() const { return zone_; }
324
325   uc32 current() { return current_; }
326   bool has_more() { return has_more_; }
327   bool has_next() { return next_pos_ < in()->length(); }
328   uc32 Next();
329   FlatStringReader* in() { return in_; }
330   void ScanForCaptures();
331
332   Isolate* isolate_;
333   Zone* zone_;
334   Handle<String>* error_;
335   ZoneList<RegExpCapture*>* captures_;
336   FlatStringReader* in_;
337   uc32 current_;
338   int next_pos_;
339   // The capture count is only valid after we have scanned for captures.
340   int capture_count_;
341   bool has_more_;
342   bool multiline_;
343   bool unicode_;
344   bool simple_;
345   bool contains_anchor_;
346   bool is_scanned_for_captures_;
347   bool failed_;
348 };
349
350 // ----------------------------------------------------------------------------
351 // JAVASCRIPT PARSING
352
353 class Parser;
354 class SingletonLogger;
355
356 class ParserTraits {
357  public:
358   struct Type {
359     // TODO(marja): To be removed. The Traits object should contain all the data
360     // it needs.
361     typedef v8::internal::Parser* Parser;
362
363     typedef Variable GeneratorVariable;
364
365     typedef v8::internal::AstProperties AstProperties;
366
367     // Return types for traversing functions.
368     typedef const AstRawString* Identifier;
369     typedef v8::internal::Expression* Expression;
370     typedef Yield* YieldExpression;
371     typedef v8::internal::FunctionLiteral* FunctionLiteral;
372     typedef v8::internal::ClassLiteral* ClassLiteral;
373     typedef v8::internal::Literal* Literal;
374     typedef ObjectLiteral::Property* ObjectLiteralProperty;
375     typedef ZoneList<v8::internal::Expression*>* ExpressionList;
376     typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
377     typedef ZoneList<v8::internal::Statement*>* StatementList;
378
379     // For constructing objects returned by the traversing functions.
380     typedef AstNodeFactory Factory;
381   };
382
383   explicit ParserTraits(Parser* parser) : parser_(parser) {}
384
385   // Helper functions for recursive descent.
386   bool IsEval(const AstRawString* identifier) const;
387   bool IsArguments(const AstRawString* identifier) const;
388   bool IsEvalOrArguments(const AstRawString* identifier) const;
389   V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const;
390
391   // Returns true if the expression is of type "this.foo".
392   static bool IsThisProperty(Expression* expression);
393
394   static bool IsIdentifier(Expression* expression);
395
396   bool IsPrototype(const AstRawString* identifier) const;
397
398   bool IsConstructor(const AstRawString* identifier) const;
399
400   static const AstRawString* AsIdentifier(Expression* expression) {
401     DCHECK(IsIdentifier(expression));
402     return expression->AsVariableProxy()->raw_name();
403   }
404
405   static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
406     return ObjectLiteral::IsBoilerplateProperty(property);
407   }
408
409   static bool IsArrayIndex(const AstRawString* string, uint32_t* index) {
410     return string->AsArrayIndex(index);
411   }
412
413   static Expression* GetPropertyValue(ObjectLiteral::Property* property) {
414     return property->value();
415   }
416
417   // Functions for encapsulating the differences between parsing and preparsing;
418   // operations interleaved with the recursive descent.
419   static void PushLiteralName(FuncNameInferrer* fni, const AstRawString* id) {
420     fni->PushLiteralName(id);
421   }
422
423   void PushPropertyName(FuncNameInferrer* fni, Expression* expression);
424
425   static void InferFunctionName(FuncNameInferrer* fni,
426                                 FunctionLiteral* func_to_infer) {
427     fni->AddFunction(func_to_infer);
428   }
429
430   static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
431       Scope* scope, ObjectLiteralProperty* property, bool* has_function) {
432     Expression* value = property->value();
433     if (scope->DeclarationScope()->is_script_scope() &&
434         value->AsFunctionLiteral() != NULL) {
435       *has_function = true;
436       value->AsFunctionLiteral()->set_pretenure();
437     }
438   }
439
440   // If we assign a function literal to a property we pretenure the
441   // literal so it can be added as a constant function property.
442   static void CheckAssigningFunctionLiteralToProperty(Expression* left,
443                                                       Expression* right);
444
445   // Keep track of eval() calls since they disable all local variable
446   // optimizations. This checks if expression is an eval call, and if yes,
447   // forwards the information to scope.
448   void CheckPossibleEvalCall(Expression* expression, Scope* scope);
449
450   // Determine if the expression is a variable proxy and mark it as being used
451   // in an assignment or with a increment/decrement operator.
452   static Expression* MarkExpressionAsAssigned(Expression* expression);
453
454   // Returns true if we have a binary expression between two numeric
455   // literals. In that case, *x will be changed to an expression which is the
456   // computed value.
457   bool ShortcutNumericLiteralBinaryExpression(Expression** x, Expression* y,
458                                               Token::Value op, int pos,
459                                               AstNodeFactory* factory);
460
461   // Rewrites the following types of unary expressions:
462   // not <literal> -> true / false
463   // + <numeric literal> -> <numeric literal>
464   // - <numeric literal> -> <numeric literal with value negated>
465   // ! <literal> -> true / false
466   // The following rewriting rules enable the collection of type feedback
467   // without any special stub and the multiplication is removed later in
468   // Crankshaft's canonicalization pass.
469   // + foo -> foo * 1
470   // - foo -> foo * (-1)
471   // ~ foo -> foo ^(~0)
472   Expression* BuildUnaryExpression(Expression* expression, Token::Value op,
473                                    int pos, AstNodeFactory* factory);
474
475   // Generate AST node that throws a ReferenceError with the given type.
476   Expression* NewThrowReferenceError(const char* type, int pos);
477
478   // Generate AST node that throws a SyntaxError with the given
479   // type. The first argument may be null (in the handle sense) in
480   // which case no arguments are passed to the constructor.
481   Expression* NewThrowSyntaxError(
482       const char* type, const AstRawString* arg, int pos);
483
484   // Generate AST node that throws a TypeError with the given
485   // type. Both arguments must be non-null (in the handle sense).
486   Expression* NewThrowTypeError(const char* type, const AstRawString* arg,
487                                 int pos);
488
489   // Generic AST generator for throwing errors from compiled code.
490   Expression* NewThrowError(
491       const AstRawString* constructor, const char* type,
492       const AstRawString* arg, int pos);
493
494   // Reporting errors.
495   void ReportMessageAt(Scanner::Location source_location,
496                        const char* message,
497                        const char* arg = NULL,
498                        bool is_reference_error = false);
499   void ReportMessage(const char* message,
500                      const char* arg = NULL,
501                      bool is_reference_error = false);
502   void ReportMessage(const char* message,
503                      const AstRawString* arg,
504                      bool is_reference_error = false);
505   void ReportMessageAt(Scanner::Location source_location,
506                        const char* message,
507                        const AstRawString* arg,
508                        bool is_reference_error = false);
509
510   // "null" return type creators.
511   static const AstRawString* EmptyIdentifier() {
512     return NULL;
513   }
514   static Expression* EmptyExpression() {
515     return NULL;
516   }
517   static Expression* EmptyArrowParamList() { return NULL; }
518   static Literal* EmptyLiteral() {
519     return NULL;
520   }
521   static ObjectLiteralProperty* EmptyObjectLiteralProperty() { return NULL; }
522   static FunctionLiteral* EmptyFunctionLiteral() { return NULL; }
523
524   // Used in error return values.
525   static ZoneList<Expression*>* NullExpressionList() {
526     return NULL;
527   }
528
529   // Non-NULL empty string.
530   V8_INLINE const AstRawString* EmptyIdentifierString();
531
532   // Odd-ball literal creators.
533   Literal* GetLiteralTheHole(int position, AstNodeFactory* factory);
534
535   // Producing data during the recursive descent.
536   const AstRawString* GetSymbol(Scanner* scanner);
537   const AstRawString* GetNextSymbol(Scanner* scanner);
538   const AstRawString* GetNumberAsSymbol(Scanner* scanner);
539
540   Expression* ThisExpression(Scope* scope, AstNodeFactory* factory,
541                              int pos = RelocInfo::kNoPosition);
542   Expression* SuperReference(Scope* scope, AstNodeFactory* factory,
543                              int pos = RelocInfo::kNoPosition);
544   Expression* DefaultConstructor(bool call_super, Scope* scope, int pos,
545                                  int end_pos);
546   Literal* ExpressionFromLiteral(Token::Value token, int pos, Scanner* scanner,
547                                  AstNodeFactory* factory);
548   Expression* ExpressionFromIdentifier(const AstRawString* name, int pos,
549                                        Scope* scope, AstNodeFactory* factory);
550   Expression* ExpressionFromString(int pos, Scanner* scanner,
551                                    AstNodeFactory* factory);
552   Expression* GetIterator(Expression* iterable, AstNodeFactory* factory);
553   ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) {
554     return new(zone) ZoneList<v8::internal::Expression*>(size, zone);
555   }
556   ZoneList<ObjectLiteral::Property*>* NewPropertyList(int size, Zone* zone) {
557     return new(zone) ZoneList<ObjectLiteral::Property*>(size, zone);
558   }
559   ZoneList<v8::internal::Statement*>* NewStatementList(int size, Zone* zone) {
560     return new(zone) ZoneList<v8::internal::Statement*>(size, zone);
561   }
562   V8_INLINE Scope* NewScope(Scope* parent_scope, ScopeType scope_type,
563                             FunctionKind kind = kNormalFunction);
564
565   // Utility functions
566   int DeclareArrowParametersFromExpression(Expression* expression, Scope* scope,
567                                            Scanner::Location* dupe_loc,
568                                            bool* ok);
569
570   // Temporary glue; these functions will move to ParserBase.
571   Expression* ParseV8Intrinsic(bool* ok);
572   FunctionLiteral* ParseFunctionLiteral(
573       const AstRawString* name, Scanner::Location function_name_location,
574       bool name_is_strict_reserved, FunctionKind kind,
575       int function_token_position, FunctionLiteral::FunctionType type,
576       FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
577   V8_INLINE void SkipLazyFunctionBody(const AstRawString* name,
578                                       int* materialized_literal_count,
579                                       int* expected_property_count, bool* ok);
580   V8_INLINE ZoneList<Statement*>* ParseEagerFunctionBody(
581       const AstRawString* name, int pos, Variable* fvar,
582       Token::Value fvar_init_op, FunctionKind kind, bool* ok);
583
584   ClassLiteral* ParseClassLiteral(const AstRawString* name,
585                                   Scanner::Location class_name_location,
586                                   bool name_is_strict_reserved, int pos,
587                                   bool* ok);
588
589   V8_INLINE void CheckConflictingVarDeclarations(v8::internal::Scope* scope,
590                                                  bool* ok);
591
592   class TemplateLiteral : public ZoneObject {
593    public:
594     TemplateLiteral(Zone* zone, int pos)
595         : cooked_(8, zone), raw_(8, zone), expressions_(8, zone), pos_(pos) {}
596
597     const ZoneList<Expression*>* cooked() const { return &cooked_; }
598     const ZoneList<Expression*>* raw() const { return &raw_; }
599     const ZoneList<Expression*>* expressions() const { return &expressions_; }
600     int position() const { return pos_; }
601
602     void AddTemplateSpan(Literal* cooked, Literal* raw, int end, Zone* zone) {
603       DCHECK_NOT_NULL(cooked);
604       DCHECK_NOT_NULL(raw);
605       cooked_.Add(cooked, zone);
606       raw_.Add(raw, zone);
607     }
608
609     void AddExpression(Expression* expression, Zone* zone) {
610       DCHECK_NOT_NULL(expression);
611       expressions_.Add(expression, zone);
612     }
613
614    private:
615     ZoneList<Expression*> cooked_;
616     ZoneList<Expression*> raw_;
617     ZoneList<Expression*> expressions_;
618     int pos_;
619   };
620
621   typedef TemplateLiteral* TemplateLiteralState;
622
623   V8_INLINE TemplateLiteralState OpenTemplateLiteral(int pos);
624   V8_INLINE void AddTemplateSpan(TemplateLiteralState* state, bool tail);
625   V8_INLINE void AddTemplateExpression(TemplateLiteralState* state,
626                                        Expression* expression);
627   V8_INLINE Expression* CloseTemplateLiteral(TemplateLiteralState* state,
628                                              int start, Expression* tag);
629   V8_INLINE Expression* NoTemplateTag() { return NULL; }
630   V8_INLINE static bool IsTaggedTemplate(const Expression* tag) {
631     return tag != NULL;
632   }
633
634  private:
635   Parser* parser_;
636 };
637
638
639 class Parser : public ParserBase<ParserTraits> {
640  public:
641   Parser(CompilationInfo* info, uintptr_t stack_limit, uint32_t hash_seed,
642          UnicodeCache* unicode_cache);
643   ~Parser() {
644     delete reusable_preparser_;
645     reusable_preparser_ = NULL;
646     delete cached_parse_data_;
647     cached_parse_data_ = NULL;
648   }
649
650   // Parses the source code represented by the compilation info and sets its
651   // function literal.  Returns false (and deallocates any allocated AST
652   // nodes) if parsing failed.
653   static bool ParseStatic(CompilationInfo* info, bool allow_lazy = false);
654   bool Parse(CompilationInfo* info);
655   void ParseOnBackground(CompilationInfo* info);
656
657   // Handle errors detected during parsing, move statistics to Isolate,
658   // internalize strings (move them to the heap).
659   void Internalize(CompilationInfo* info);
660   void HandleSourceURLComments(CompilationInfo* info);
661
662  private:
663   friend class ParserTraits;
664
665   // Limit the allowed number of local variables in a function. The hard limit
666   // is that offsets computed by FullCodeGenerator::StackOperand and similar
667   // functions are ints, and they should not overflow. In addition, accessing
668   // local variables creates user-controlled constants in the generated code,
669   // and we don't want too much user-controlled memory inside the code (this was
670   // the reason why this limit was introduced in the first place; see
671   // https://codereview.chromium.org/7003030/ ).
672   static const int kMaxNumFunctionLocals = 4194303;  // 2^22-1
673
674   // Returns NULL if parsing failed.
675   FunctionLiteral* ParseProgram(CompilationInfo* info);
676
677   FunctionLiteral* ParseLazy(CompilationInfo* info);
678   FunctionLiteral* ParseLazy(CompilationInfo* info,
679                              Utf16CharacterStream* source);
680
681   // Called by ParseProgram after setting up the scanner.
682   FunctionLiteral* DoParseProgram(CompilationInfo* info, Scope** scope,
683                                   Scope** ad_hoc_eval_scope);
684
685   void SetCachedData(CompilationInfo* info);
686
687   bool inside_with() const { return scope_->inside_with(); }
688   ScriptCompiler::CompileOptions compile_options() const {
689     return compile_options_;
690   }
691   bool consume_cached_parse_data() const {
692     return compile_options_ == ScriptCompiler::kConsumeParserCache &&
693            cached_parse_data_ != NULL;
694   }
695   bool produce_cached_parse_data() const {
696     return compile_options_ == ScriptCompiler::kProduceParserCache;
697   }
698   Scope* DeclarationScope(VariableMode mode) {
699     return IsLexicalVariableMode(mode)
700         ? scope_ : scope_->DeclarationScope();
701   }
702
703   // All ParseXXX functions take as the last argument an *ok parameter
704   // which is set to false if parsing failed; it is unchanged otherwise.
705   // By making the 'exception handling' explicit, we are forced to check
706   // for failure at the call sites.
707   void* ParseStatementList(ZoneList<Statement*>* body, int end_token,
708                            bool is_eval, Scope** ad_hoc_eval_scope, bool* ok);
709   Statement* ParseStatementListItem(bool* ok);
710   Statement* ParseModule(bool* ok);
711   Statement* ParseModuleItem(bool* ok);
712   Literal* ParseModuleSpecifier(bool* ok);
713   Statement* ParseImportDeclaration(bool* ok);
714   Statement* ParseExportDeclaration(bool* ok);
715   Statement* ParseExportDefault(bool* ok);
716   void* ParseExportClause(ZoneList<const AstRawString*>* names,
717                           Scanner::Location* reserved_loc, bool* ok);
718   void* ParseNamedImports(ZoneList<const AstRawString*>* names, bool* ok);
719   Statement* ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok);
720   Statement* ParseSubStatement(ZoneList<const AstRawString*>* labels, bool* ok);
721   Statement* ParseFunctionDeclaration(ZoneList<const AstRawString*>* names,
722                                       bool* ok);
723   Statement* ParseClassDeclaration(ZoneList<const AstRawString*>* names,
724                                    bool* ok);
725   Statement* ParseNativeDeclaration(bool* ok);
726   Block* ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok);
727   Block* ParseVariableStatement(VariableDeclarationContext var_context,
728                                 ZoneList<const AstRawString*>* names,
729                                 bool* ok);
730   Block* ParseVariableDeclarations(VariableDeclarationContext var_context,
731                                    VariableDeclarationProperties* decl_props,
732                                    ZoneList<const AstRawString*>* names,
733                                    const AstRawString** out,
734                                    bool* ok);
735   Statement* ParseExpressionOrLabelledStatement(
736       ZoneList<const AstRawString*>* labels, bool* ok);
737   IfStatement* ParseIfStatement(ZoneList<const AstRawString*>* labels,
738                                 bool* ok);
739   Statement* ParseContinueStatement(bool* ok);
740   Statement* ParseBreakStatement(ZoneList<const AstRawString*>* labels,
741                                  bool* ok);
742   Statement* ParseReturnStatement(bool* ok);
743   Statement* ParseWithStatement(ZoneList<const AstRawString*>* labels,
744                                 bool* ok);
745   CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
746   SwitchStatement* ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
747                                         bool* ok);
748   DoWhileStatement* ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
749                                           bool* ok);
750   WhileStatement* ParseWhileStatement(ZoneList<const AstRawString*>* labels,
751                                       bool* ok);
752   Statement* ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
753   Statement* ParseThrowStatement(bool* ok);
754   Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
755   TryStatement* ParseTryStatement(bool* ok);
756   DebuggerStatement* ParseDebuggerStatement(bool* ok);
757
758   // Support for hamony block scoped bindings.
759   Block* ParseScopedBlock(ZoneList<const AstRawString*>* labels, bool* ok);
760
761   // Initialize the components of a for-in / for-of statement.
762   void InitializeForEachStatement(ForEachStatement* stmt,
763                                   Expression* each,
764                                   Expression* subject,
765                                   Statement* body);
766   Statement* DesugarLetBindingsInForStatement(
767       Scope* inner_scope, ZoneList<const AstRawString*>* names,
768       ForStatement* loop, Statement* init, Expression* cond, Statement* next,
769       Statement* body, bool* ok);
770
771   FunctionLiteral* ParseFunctionLiteral(
772       const AstRawString* name, Scanner::Location function_name_location,
773       bool name_is_strict_reserved, FunctionKind kind,
774       int function_token_position, FunctionLiteral::FunctionType type,
775       FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
776
777
778   ClassLiteral* ParseClassLiteral(const AstRawString* name,
779                                   Scanner::Location class_name_location,
780                                   bool name_is_strict_reserved, int pos,
781                                   bool* ok);
782
783   // Magical syntax support.
784   Expression* ParseV8Intrinsic(bool* ok);
785
786   // Get odd-ball literals.
787   Literal* GetLiteralUndefined(int position);
788
789   // For harmony block scoping mode: Check if the scope has conflicting var/let
790   // declarations from different scopes. It covers for example
791   //
792   // function f() { { { var x; } let x; } }
793   // function g() { { var x; let x; } }
794   //
795   // The var declarations are hoisted to the function scope, but originate from
796   // a scope where the name has also been let bound or the var declaration is
797   // hoisted over such a scope.
798   void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
799
800   // Parser support
801   VariableProxy* NewUnresolved(const AstRawString* name, VariableMode mode);
802   void Declare(Declaration* declaration, bool resolve, bool* ok);
803
804   bool TargetStackContainsLabel(const AstRawString* label);
805   BreakableStatement* LookupBreakTarget(const AstRawString* label, bool* ok);
806   IterationStatement* LookupContinueTarget(const AstRawString* label, bool* ok);
807
808   void AddAssertIsConstruct(ZoneList<Statement*>* body, int pos);
809
810   // Factory methods.
811   FunctionLiteral* DefaultConstructor(bool call_super, Scope* scope, int pos,
812                                       int end_pos);
813
814   // Skip over a lazy function, either using cached data if we have it, or
815   // by parsing the function with PreParser. Consumes the ending }.
816   void SkipLazyFunctionBody(const AstRawString* function_name,
817                             int* materialized_literal_count,
818                             int* expected_property_count,
819                             bool* ok);
820
821   PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser(
822       SingletonLogger* logger);
823
824   // Consumes the ending }.
825   ZoneList<Statement*>* ParseEagerFunctionBody(
826       const AstRawString* function_name, int pos, Variable* fvar,
827       Token::Value fvar_init_op, FunctionKind kind, bool* ok);
828
829   void ThrowPendingError(Isolate* isolate, Handle<Script> script);
830
831   TemplateLiteralState OpenTemplateLiteral(int pos);
832   void AddTemplateSpan(TemplateLiteralState* state, bool tail);
833   void AddTemplateExpression(TemplateLiteralState* state,
834                              Expression* expression);
835   Expression* CloseTemplateLiteral(TemplateLiteralState* state, int start,
836                                    Expression* tag);
837   uint32_t ComputeTemplateLiteralHash(const TemplateLiteral* lit);
838
839   Scanner scanner_;
840   PreParser* reusable_preparser_;
841   Scope* original_scope_;  // for ES5 function declarations in sloppy eval
842   Target* target_stack_;  // for break, continue statements
843   ScriptCompiler::CompileOptions compile_options_;
844   ParseData* cached_parse_data_;
845
846   bool parsing_lazy_arrow_parameters_;  // for lazily parsed arrow functions.
847
848   // Pending errors.
849   bool has_pending_error_;
850   Scanner::Location pending_error_location_;
851   const char* pending_error_message_;
852   const AstRawString* pending_error_arg_;
853   const char* pending_error_char_arg_;
854   bool pending_error_is_reference_error_;
855
856   // Other information which will be stored in Parser and moved to Isolate after
857   // parsing.
858   int use_counts_[v8::Isolate::kUseCounterFeatureCount];
859   int total_preparse_skipped_;
860   HistogramTimer* pre_parse_timer_;
861
862   bool parsing_on_main_thread_;
863 };
864
865
866 bool ParserTraits::IsFutureStrictReserved(
867     const AstRawString* identifier) const {
868   return parser_->scanner()->IdentifierIsFutureStrictReserved(identifier);
869 }
870
871
872 Scope* ParserTraits::NewScope(Scope* parent_scope, ScopeType scope_type,
873                               FunctionKind kind) {
874   return parser_->NewScope(parent_scope, scope_type, kind);
875 }
876
877
878 const AstRawString* ParserTraits::EmptyIdentifierString() {
879   return parser_->ast_value_factory()->empty_string();
880 }
881
882
883 void ParserTraits::SkipLazyFunctionBody(const AstRawString* function_name,
884                                         int* materialized_literal_count,
885                                         int* expected_property_count,
886                                         bool* ok) {
887   return parser_->SkipLazyFunctionBody(
888       function_name, materialized_literal_count, expected_property_count, ok);
889 }
890
891
892 ZoneList<Statement*>* ParserTraits::ParseEagerFunctionBody(
893     const AstRawString* name, int pos, Variable* fvar,
894     Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
895   return parser_->ParseEagerFunctionBody(name, pos, fvar, fvar_init_op, kind,
896                                          ok);
897 }
898
899 void ParserTraits::CheckConflictingVarDeclarations(v8::internal::Scope* scope,
900                                                    bool* ok) {
901   parser_->CheckConflictingVarDeclarations(scope, ok);
902 }
903
904
905 // Support for handling complex values (array and object literals) that
906 // can be fully handled at compile time.
907 class CompileTimeValue: public AllStatic {
908  public:
909   enum LiteralType {
910     OBJECT_LITERAL_FAST_ELEMENTS,
911     OBJECT_LITERAL_SLOW_ELEMENTS,
912     ARRAY_LITERAL
913   };
914
915   static bool IsCompileTimeValue(Expression* expression);
916
917   // Get the value as a compile time value.
918   static Handle<FixedArray> GetValue(Isolate* isolate, Expression* expression);
919
920   // Get the type of a compile time value returned by GetValue().
921   static LiteralType GetLiteralType(Handle<FixedArray> value);
922
923   // Get the elements array of a compile time value returned by GetValue().
924   static Handle<FixedArray> GetElements(Handle<FixedArray> value);
925
926  private:
927   static const int kLiteralTypeSlot = 0;
928   static const int kElementsSlot = 1;
929
930   DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
931 };
932
933
934 ParserTraits::TemplateLiteralState ParserTraits::OpenTemplateLiteral(int pos) {
935   return parser_->OpenTemplateLiteral(pos);
936 }
937
938
939 void ParserTraits::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
940   parser_->AddTemplateSpan(state, tail);
941 }
942
943
944 void ParserTraits::AddTemplateExpression(TemplateLiteralState* state,
945                                          Expression* expression) {
946   parser_->AddTemplateExpression(state, expression);
947 }
948
949
950 Expression* ParserTraits::CloseTemplateLiteral(TemplateLiteralState* state,
951                                                int start, Expression* tag) {
952   return parser_->CloseTemplateLiteral(state, start, tag);
953 }
954 } }  // namespace v8::internal
955
956 #endif  // V8_PARSER_H_