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