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