Upstream version 9.38.198.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     class Checkpoint BASE_EMBEDDED {
359      public:
360       template <typename Parser>
361       explicit Checkpoint(Parser* parser) {
362         isolate_ = parser->zone()->isolate();
363         saved_ast_node_id_ = isolate_->ast_node_id();
364       }
365
366       void Restore() { isolate_->set_ast_node_id(saved_ast_node_id_); }
367
368      private:
369       Isolate* isolate_;
370       int saved_ast_node_id_;
371     };
372
373     typedef v8::internal::AstProperties AstProperties;
374     typedef Vector<VariableProxy*> ParameterIdentifierVector;
375
376     // Return types for traversing functions.
377     typedef const AstRawString* Identifier;
378     typedef v8::internal::Expression* Expression;
379     typedef Yield* YieldExpression;
380     typedef v8::internal::FunctionLiteral* FunctionLiteral;
381     typedef v8::internal::Literal* Literal;
382     typedef ObjectLiteral::Property* ObjectLiteralProperty;
383     typedef ZoneList<v8::internal::Expression*>* ExpressionList;
384     typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
385     typedef ZoneList<v8::internal::Statement*>* StatementList;
386
387     // For constructing objects returned by the traversing functions.
388     typedef AstNodeFactory<AstConstructionVisitor> Factory;
389   };
390
391   explicit ParserTraits(Parser* parser) : parser_(parser) {}
392
393   // Custom operations executed when FunctionStates are created and destructed.
394   template<typename FunctionState>
395   static void SetUpFunctionState(FunctionState* function_state, Zone* zone) {
396     Isolate* isolate = zone->isolate();
397     function_state->saved_ast_node_id_ = isolate->ast_node_id();
398     isolate->set_ast_node_id(BailoutId::FirstUsable().ToInt());
399   }
400
401   template<typename FunctionState>
402   static void TearDownFunctionState(FunctionState* function_state, Zone* zone) {
403     if (function_state->outer_function_state_ != NULL) {
404       zone->isolate()->set_ast_node_id(function_state->saved_ast_node_id_);
405     }
406   }
407
408   // Helper functions for recursive descent.
409   bool IsEvalOrArguments(const AstRawString* identifier) const;
410   V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const;
411
412   // Returns true if the expression is of type "this.foo".
413   static bool IsThisProperty(Expression* expression);
414
415   static bool IsIdentifier(Expression* expression);
416
417   static const AstRawString* AsIdentifier(Expression* expression) {
418     DCHECK(IsIdentifier(expression));
419     return expression->AsVariableProxy()->raw_name();
420   }
421
422   static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
423     return ObjectLiteral::IsBoilerplateProperty(property);
424   }
425
426   static bool IsArrayIndex(const AstRawString* string, uint32_t* index) {
427     return string->AsArrayIndex(index);
428   }
429
430   // Functions for encapsulating the differences between parsing and preparsing;
431   // operations interleaved with the recursive descent.
432   static void PushLiteralName(FuncNameInferrer* fni, const AstRawString* id) {
433     fni->PushLiteralName(id);
434   }
435   void PushPropertyName(FuncNameInferrer* fni, Expression* expression);
436   static void InferFunctionName(FuncNameInferrer* fni,
437                                 FunctionLiteral* func_to_infer) {
438     fni->AddFunction(func_to_infer);
439   }
440
441   static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
442       Scope* scope, Expression* value, bool* has_function) {
443     if (scope->DeclarationScope()->is_global_scope() &&
444         value->AsFunctionLiteral() != NULL) {
445       *has_function = true;
446       value->AsFunctionLiteral()->set_pretenure();
447     }
448   }
449
450   // If we assign a function literal to a property we pretenure the
451   // literal so it can be added as a constant function property.
452   static void CheckAssigningFunctionLiteralToProperty(Expression* left,
453                                                       Expression* right);
454
455   // Keep track of eval() calls since they disable all local variable
456   // optimizations. This checks if expression is an eval call, and if yes,
457   // forwards the information to scope.
458   void CheckPossibleEvalCall(Expression* expression, Scope* scope);
459
460   // Determine if the expression is a variable proxy and mark it as being used
461   // in an assignment or with a increment/decrement operator.
462   static Expression* MarkExpressionAsAssigned(Expression* expression);
463
464   // Returns true if we have a binary expression between two numeric
465   // literals. In that case, *x will be changed to an expression which is the
466   // computed value.
467   bool ShortcutNumericLiteralBinaryExpression(
468       Expression** x, Expression* y, Token::Value op, int pos,
469       AstNodeFactory<AstConstructionVisitor>* factory);
470
471   // Rewrites the following types of unary expressions:
472   // not <literal> -> true / false
473   // + <numeric literal> -> <numeric literal>
474   // - <numeric literal> -> <numeric literal with value negated>
475   // ! <literal> -> true / false
476   // The following rewriting rules enable the collection of type feedback
477   // without any special stub and the multiplication is removed later in
478   // Crankshaft's canonicalization pass.
479   // + foo -> foo * 1
480   // - foo -> foo * (-1)
481   // ~ foo -> foo ^(~0)
482   Expression* BuildUnaryExpression(
483       Expression* expression, Token::Value op, int pos,
484       AstNodeFactory<AstConstructionVisitor>* factory);
485
486   // Generate AST node that throws a ReferenceError with the given type.
487   Expression* NewThrowReferenceError(const char* type, int pos);
488
489   // Generate AST node that throws a SyntaxError with the given
490   // type. The first argument may be null (in the handle sense) in
491   // which case no arguments are passed to the constructor.
492   Expression* NewThrowSyntaxError(
493       const char* type, const AstRawString* arg, int pos);
494
495   // Generate AST node that throws a TypeError with the given
496   // type. Both arguments must be non-null (in the handle sense).
497   Expression* NewThrowTypeError(const char* type, const AstRawString* arg,
498                                 int pos);
499
500   // Generic AST generator for throwing errors from compiled code.
501   Expression* NewThrowError(
502       const AstRawString* constructor, const char* type,
503       const AstRawString* arg, int pos);
504
505   // Reporting errors.
506   void ReportMessageAt(Scanner::Location source_location,
507                        const char* message,
508                        const char* arg = NULL,
509                        bool is_reference_error = false);
510   void ReportMessage(const char* message,
511                      const char* arg = NULL,
512                      bool is_reference_error = false);
513   void ReportMessage(const char* message,
514                      const AstRawString* arg,
515                      bool is_reference_error = false);
516   void ReportMessageAt(Scanner::Location source_location,
517                        const char* message,
518                        const AstRawString* arg,
519                        bool is_reference_error = false);
520
521   // "null" return type creators.
522   static const AstRawString* EmptyIdentifier() {
523     return NULL;
524   }
525   static Expression* EmptyExpression() {
526     return NULL;
527   }
528   static Expression* EmptyArrowParamList() { return NULL; }
529   static Literal* EmptyLiteral() {
530     return NULL;
531   }
532
533   // Used in error return values.
534   static ZoneList<Expression*>* NullExpressionList() {
535     return NULL;
536   }
537
538   // Non-NULL empty string.
539   V8_INLINE const AstRawString* EmptyIdentifierString();
540
541   // Odd-ball literal creators.
542   Literal* GetLiteralTheHole(int position,
543                              AstNodeFactory<AstConstructionVisitor>* factory);
544
545   // Producing data during the recursive descent.
546   const AstRawString* GetSymbol(Scanner* scanner);
547   const AstRawString* GetNextSymbol(Scanner* scanner);
548
549   Expression* ThisExpression(Scope* scope,
550                              AstNodeFactory<AstConstructionVisitor>* factory,
551                              int pos = RelocInfo::kNoPosition);
552   Literal* ExpressionFromLiteral(
553       Token::Value token, int pos, Scanner* scanner,
554       AstNodeFactory<AstConstructionVisitor>* factory);
555   Expression* ExpressionFromIdentifier(
556       const AstRawString* name, int pos, Scope* scope,
557       AstNodeFactory<AstConstructionVisitor>* factory);
558   Expression* ExpressionFromString(
559       int pos, Scanner* scanner,
560       AstNodeFactory<AstConstructionVisitor>* factory);
561   Expression* GetIterator(Expression* iterable,
562                           AstNodeFactory<AstConstructionVisitor>* factory);
563   ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) {
564     return new(zone) ZoneList<v8::internal::Expression*>(size, zone);
565   }
566   ZoneList<ObjectLiteral::Property*>* NewPropertyList(int size, Zone* zone) {
567     return new(zone) ZoneList<ObjectLiteral::Property*>(size, zone);
568   }
569   ZoneList<v8::internal::Statement*>* NewStatementList(int size, Zone* zone) {
570     return new(zone) ZoneList<v8::internal::Statement*>(size, zone);
571   }
572   V8_INLINE Scope* NewScope(Scope* parent_scope, ScopeType scope_type);
573
574   // Utility functions
575   int DeclareArrowParametersFromExpression(Expression* expression, Scope* scope,
576                                            Scanner::Location* dupe_loc,
577                                            bool* ok);
578   V8_INLINE AstValueFactory* ast_value_factory();
579
580   // Temporary glue; these functions will move to ParserBase.
581   Expression* ParseV8Intrinsic(bool* ok);
582   FunctionLiteral* ParseFunctionLiteral(
583       const AstRawString* name,
584       Scanner::Location function_name_location,
585       bool name_is_strict_reserved,
586       bool is_generator,
587       int function_token_position,
588       FunctionLiteral::FunctionType type,
589       FunctionLiteral::ArityRestriction arity_restriction,
590       bool* ok);
591   V8_INLINE void SkipLazyFunctionBody(const AstRawString* name,
592                                       int* materialized_literal_count,
593                                       int* expected_property_count, bool* ok);
594   V8_INLINE ZoneList<Statement*>* ParseEagerFunctionBody(
595       const AstRawString* name, int pos, Variable* fvar,
596       Token::Value fvar_init_op, bool is_generator, bool* ok);
597   V8_INLINE void CheckConflictingVarDeclarations(v8::internal::Scope* scope,
598                                                  bool* ok);
599
600  private:
601   Parser* parser_;
602 };
603
604
605 class Parser : public ParserBase<ParserTraits> {
606  public:
607   explicit Parser(CompilationInfo* info);
608   ~Parser() {
609     delete reusable_preparser_;
610     reusable_preparser_ = NULL;
611     delete cached_parse_data_;
612     cached_parse_data_ = NULL;
613   }
614
615   // Parses the source code represented by the compilation info and sets its
616   // function literal.  Returns false (and deallocates any allocated AST
617   // nodes) if parsing failed.
618   static bool Parse(CompilationInfo* info,
619                     bool allow_lazy = false) {
620     Parser parser(info);
621     parser.set_allow_lazy(allow_lazy);
622     return parser.Parse();
623   }
624   bool Parse();
625
626  private:
627   friend class ParserTraits;
628
629   // Limit the allowed number of local variables in a function. The hard limit
630   // is that offsets computed by FullCodeGenerator::StackOperand and similar
631   // functions are ints, and they should not overflow. In addition, accessing
632   // local variables creates user-controlled constants in the generated code,
633   // and we don't want too much user-controlled memory inside the code (this was
634   // the reason why this limit was introduced in the first place; see
635   // https://codereview.chromium.org/7003030/ ).
636   static const int kMaxNumFunctionLocals = 4194303;  // 2^22-1
637
638   enum VariableDeclarationContext {
639     kModuleElement,
640     kBlockElement,
641     kStatement,
642     kForStatement
643   };
644
645   // If a list of variable declarations includes any initializers.
646   enum VariableDeclarationProperties {
647     kHasInitializers,
648     kHasNoInitializers
649   };
650
651   // Returns NULL if parsing failed.
652   FunctionLiteral* ParseProgram();
653
654   FunctionLiteral* ParseLazy();
655   FunctionLiteral* ParseLazy(Utf16CharacterStream* source);
656
657   Isolate* isolate() { return isolate_; }
658   CompilationInfo* info() const { return info_; }
659
660   // Called by ParseProgram after setting up the scanner.
661   FunctionLiteral* DoParseProgram(CompilationInfo* info,
662                                   Handle<String> source);
663
664   void SetCachedData();
665
666   bool inside_with() const { return scope_->inside_with(); }
667   ScriptCompiler::CompileOptions compile_options() const {
668     return info_->compile_options();
669   }
670   Scope* DeclarationScope(VariableMode mode) {
671     return IsLexicalVariableMode(mode)
672         ? scope_ : scope_->DeclarationScope();
673   }
674
675   // All ParseXXX functions take as the last argument an *ok parameter
676   // which is set to false if parsing failed; it is unchanged otherwise.
677   // By making the 'exception handling' explicit, we are forced to check
678   // for failure at the call sites.
679   void* ParseSourceElements(ZoneList<Statement*>* processor, int end_token,
680                             bool is_eval, bool is_global, bool* ok);
681   Statement* ParseModuleElement(ZoneList<const AstRawString*>* labels,
682                                 bool* ok);
683   Statement* ParseModuleDeclaration(ZoneList<const AstRawString*>* names,
684                                     bool* ok);
685   Module* ParseModule(bool* ok);
686   Module* ParseModuleLiteral(bool* ok);
687   Module* ParseModulePath(bool* ok);
688   Module* ParseModuleVariable(bool* ok);
689   Module* ParseModuleUrl(bool* ok);
690   Module* ParseModuleSpecifier(bool* ok);
691   Block* ParseImportDeclaration(bool* ok);
692   Statement* ParseExportDeclaration(bool* ok);
693   Statement* ParseBlockElement(ZoneList<const AstRawString*>* labels, bool* ok);
694   Statement* ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok);
695   Statement* ParseFunctionDeclaration(ZoneList<const AstRawString*>* names,
696                                       bool* ok);
697   Statement* ParseNativeDeclaration(bool* ok);
698   Block* ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok);
699   Block* ParseVariableStatement(VariableDeclarationContext var_context,
700                                 ZoneList<const AstRawString*>* names,
701                                 bool* ok);
702   Block* ParseVariableDeclarations(VariableDeclarationContext var_context,
703                                    VariableDeclarationProperties* decl_props,
704                                    ZoneList<const AstRawString*>* names,
705                                    const AstRawString** out,
706                                    bool* ok);
707   Statement* ParseExpressionOrLabelledStatement(
708       ZoneList<const AstRawString*>* labels, bool* ok);
709   IfStatement* ParseIfStatement(ZoneList<const AstRawString*>* labels,
710                                 bool* ok);
711   Statement* ParseContinueStatement(bool* ok);
712   Statement* ParseBreakStatement(ZoneList<const AstRawString*>* labels,
713                                  bool* ok);
714   Statement* ParseReturnStatement(bool* ok);
715   Statement* ParseWithStatement(ZoneList<const AstRawString*>* labels,
716                                 bool* ok);
717   CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
718   SwitchStatement* ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
719                                         bool* ok);
720   DoWhileStatement* ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
721                                           bool* ok);
722   WhileStatement* ParseWhileStatement(ZoneList<const AstRawString*>* labels,
723                                       bool* ok);
724   Statement* ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
725   Statement* ParseThrowStatement(bool* ok);
726   Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
727   TryStatement* ParseTryStatement(bool* ok);
728   DebuggerStatement* ParseDebuggerStatement(bool* ok);
729
730   // Support for hamony block scoped bindings.
731   Block* ParseScopedBlock(ZoneList<const AstRawString*>* labels, bool* ok);
732
733   // Initialize the components of a for-in / for-of statement.
734   void InitializeForEachStatement(ForEachStatement* stmt,
735                                   Expression* each,
736                                   Expression* subject,
737                                   Statement* body);
738   Statement* DesugarLetBindingsInForStatement(
739       Scope* inner_scope, ZoneList<const AstRawString*>* names,
740       ForStatement* loop, Statement* init, Expression* cond, Statement* next,
741       Statement* body, bool* ok);
742
743   FunctionLiteral* ParseFunctionLiteral(
744       const AstRawString* name,
745       Scanner::Location function_name_location,
746       bool name_is_strict_reserved,
747       bool is_generator,
748       int function_token_position,
749       FunctionLiteral::FunctionType type,
750       FunctionLiteral::ArityRestriction arity_restriction,
751       bool* ok);
752
753   // Magical syntax support.
754   Expression* ParseV8Intrinsic(bool* ok);
755
756   bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode* visit_mode);
757
758   // Get odd-ball literals.
759   Literal* GetLiteralUndefined(int position);
760
761   // For harmony block scoping mode: Check if the scope has conflicting var/let
762   // declarations from different scopes. It covers for example
763   //
764   // function f() { { { var x; } let x; } }
765   // function g() { { var x; let x; } }
766   //
767   // The var declarations are hoisted to the function scope, but originate from
768   // a scope where the name has also been let bound or the var declaration is
769   // hoisted over such a scope.
770   void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
771
772   // Parser support
773   VariableProxy* NewUnresolved(const AstRawString* name,
774                                VariableMode mode,
775                                Interface* interface);
776   void Declare(Declaration* declaration, bool resolve, bool* ok);
777
778   bool TargetStackContainsLabel(const AstRawString* label);
779   BreakableStatement* LookupBreakTarget(const AstRawString* label, bool* ok);
780   IterationStatement* LookupContinueTarget(const AstRawString* label, bool* ok);
781
782   void RegisterTargetUse(Label* target, Target* stop);
783
784   // Factory methods.
785
786   Scope* NewScope(Scope* parent, ScopeType type);
787
788   // Skip over a lazy function, either using cached data if we have it, or
789   // by parsing the function with PreParser. Consumes the ending }.
790   void SkipLazyFunctionBody(const AstRawString* function_name,
791                             int* materialized_literal_count,
792                             int* expected_property_count,
793                             bool* ok);
794
795   PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser(
796       SingletonLogger* logger);
797
798   // Consumes the ending }.
799   ZoneList<Statement*>* ParseEagerFunctionBody(
800       const AstRawString* function_name, int pos, Variable* fvar,
801       Token::Value fvar_init_op, bool is_generator, bool* ok);
802
803   void HandleSourceURLComments();
804
805   void ThrowPendingError();
806
807   void InternalizeUseCounts();
808
809   Isolate* isolate_;
810
811   Handle<Script> script_;
812   Scanner scanner_;
813   PreParser* reusable_preparser_;
814   Scope* original_scope_;  // for ES5 function declarations in sloppy eval
815   Target* target_stack_;  // for break, continue statements
816   ParseData* cached_parse_data_;
817   AstValueFactory* ast_value_factory_;
818
819   CompilationInfo* info_;
820
821   // Pending errors.
822   bool has_pending_error_;
823   Scanner::Location pending_error_location_;
824   const char* pending_error_message_;
825   const AstRawString* pending_error_arg_;
826   const char* pending_error_char_arg_;
827   bool pending_error_is_reference_error_;
828
829   int use_counts_[v8::Isolate::kUseCounterFeatureCount];
830 };
831
832
833 bool ParserTraits::IsFutureStrictReserved(
834     const AstRawString* identifier) const {
835   return identifier->IsOneByteEqualTo("yield") ||
836          parser_->scanner()->IdentifierIsFutureStrictReserved(identifier);
837 }
838
839
840 Scope* ParserTraits::NewScope(Scope* parent_scope, ScopeType scope_type) {
841   return parser_->NewScope(parent_scope, scope_type);
842 }
843
844
845 const AstRawString* ParserTraits::EmptyIdentifierString() {
846   return parser_->ast_value_factory_->empty_string();
847 }
848
849
850 void ParserTraits::SkipLazyFunctionBody(const AstRawString* function_name,
851                                         int* materialized_literal_count,
852                                         int* expected_property_count,
853                                         bool* ok) {
854   return parser_->SkipLazyFunctionBody(
855       function_name, materialized_literal_count, expected_property_count, ok);
856 }
857
858
859 ZoneList<Statement*>* ParserTraits::ParseEagerFunctionBody(
860     const AstRawString* name, int pos, Variable* fvar,
861     Token::Value fvar_init_op, bool is_generator, bool* ok) {
862   return parser_->ParseEagerFunctionBody(name, pos, fvar, fvar_init_op,
863                                          is_generator, ok);
864 }
865
866 void ParserTraits::CheckConflictingVarDeclarations(v8::internal::Scope* scope,
867                                                    bool* ok) {
868   parser_->CheckConflictingVarDeclarations(scope, ok);
869 }
870
871
872 AstValueFactory* ParserTraits::ast_value_factory() {
873   return parser_->ast_value_factory_;
874 }
875
876
877 // Support for handling complex values (array and object literals) that
878 // can be fully handled at compile time.
879 class CompileTimeValue: public AllStatic {
880  public:
881   enum LiteralType {
882     OBJECT_LITERAL_FAST_ELEMENTS,
883     OBJECT_LITERAL_SLOW_ELEMENTS,
884     ARRAY_LITERAL
885   };
886
887   static bool IsCompileTimeValue(Expression* expression);
888
889   // Get the value as a compile time value.
890   static Handle<FixedArray> GetValue(Isolate* isolate, Expression* expression);
891
892   // Get the type of a compile time value returned by GetValue().
893   static LiteralType GetLiteralType(Handle<FixedArray> value);
894
895   // Get the elements array of a compile time value returned by GetValue().
896   static Handle<FixedArray> GetElements(Handle<FixedArray> value);
897
898  private:
899   static const int kLiteralTypeSlot = 0;
900   static const int kElementsSlot = 1;
901
902   DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
903 };
904
905 } }  // namespace v8::internal
906
907 #endif  // V8_PARSER_H_