f49626766eb1dab32ea2bddb5d99289aa91ecd10
[platform/framework/web/crosswalk.git] / src / v8 / src / parser.h
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #ifndef V8_PARSER_H_
29 #define V8_PARSER_H_
30
31 #include "allocation.h"
32 #include "ast.h"
33 #include "compiler.h"  // For CachedDataMode
34 #include "preparse-data-format.h"
35 #include "preparse-data.h"
36 #include "scopes.h"
37 #include "preparser.h"
38
39 namespace v8 {
40 class ScriptCompiler;
41
42 namespace internal {
43
44 class CompilationInfo;
45 class ParserLog;
46 class PositionStack;
47 class Target;
48
49 template <typename T> class ZoneListWrapper;
50
51
52 class FunctionEntry BASE_EMBEDDED {
53  public:
54   enum {
55     kStartPositionIndex,
56     kEndPositionIndex,
57     kLiteralCountIndex,
58     kPropertyCountIndex,
59     kStrictModeIndex,
60     kSize
61   };
62
63   explicit FunctionEntry(Vector<unsigned> backing)
64     : backing_(backing) { }
65
66   FunctionEntry() : backing_() { }
67
68   int start_pos() { return backing_[kStartPositionIndex]; }
69   int end_pos() { return backing_[kEndPositionIndex]; }
70   int literal_count() { return backing_[kLiteralCountIndex]; }
71   int property_count() { return backing_[kPropertyCountIndex]; }
72   StrictMode strict_mode() {
73     ASSERT(backing_[kStrictModeIndex] == SLOPPY ||
74            backing_[kStrictModeIndex] == STRICT);
75     return static_cast<StrictMode>(backing_[kStrictModeIndex]);
76   }
77
78   bool is_valid() { return !backing_.is_empty(); }
79
80  private:
81   Vector<unsigned> backing_;
82 };
83
84
85 class ScriptDataImpl : public ScriptData {
86  public:
87   explicit ScriptDataImpl(Vector<unsigned> store)
88       : store_(store),
89         owns_store_(true) { }
90
91   // Create an empty ScriptDataImpl that is guaranteed to not satisfy
92   // a SanityCheck.
93   ScriptDataImpl() : owns_store_(false) { }
94
95   virtual ~ScriptDataImpl();
96   virtual int Length();
97   virtual const char* Data();
98   virtual bool HasError();
99
100   void Initialize();
101   void ReadNextSymbolPosition();
102
103   FunctionEntry GetFunctionEntry(int start);
104   int GetSymbolIdentifier();
105   bool SanityCheck();
106
107   Scanner::Location MessageLocation();
108   const char* BuildMessage();
109   Vector<const char*> BuildArgs();
110
111   int symbol_count() {
112     return (store_.length() > PreparseDataConstants::kHeaderSize)
113         ? store_[PreparseDataConstants::kSymbolCountOffset]
114         : 0;
115   }
116   // The following functions should only be called if SanityCheck has
117   // returned true.
118   bool has_error() { return store_[PreparseDataConstants::kHasErrorOffset]; }
119   unsigned magic() { return store_[PreparseDataConstants::kMagicOffset]; }
120   unsigned version() { return store_[PreparseDataConstants::kVersionOffset]; }
121
122  private:
123   friend class v8::ScriptCompiler;
124   Vector<unsigned> store_;
125   unsigned char* symbol_data_;
126   unsigned char* symbol_data_end_;
127   int function_index_;
128   bool owns_store_;
129
130   unsigned Read(int position);
131   unsigned* ReadAddress(int position);
132   // Reads a number from the current symbols
133   int ReadNumber(byte** source);
134
135   ScriptDataImpl(const char* backing_store, int length)
136       : store_(reinterpret_cast<unsigned*>(const_cast<char*>(backing_store)),
137                length / static_cast<int>(sizeof(unsigned))),
138         owns_store_(false) {
139     ASSERT_EQ(0, static_cast<int>(
140         reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned)));
141   }
142
143   // Read strings written by ParserRecorder::WriteString.
144   static const char* ReadString(unsigned* start, int* chars);
145
146   friend class ScriptData;
147 };
148
149
150 class PreParserApi {
151  public:
152   // Pre-parse a character stream and return full preparse data.
153   //
154   // This interface is here instead of in preparser.h because it instantiates a
155   // preparser recorder object that is suited to the parser's purposes.  Also,
156   // the preparser doesn't know about ScriptDataImpl.
157   static ScriptDataImpl* PreParse(Isolate* isolate,
158                                   Utf16CharacterStream* source);
159 };
160
161
162 // ----------------------------------------------------------------------------
163 // REGEXP PARSING
164
165 // A BufferedZoneList is an automatically growing list, just like (and backed
166 // by) a ZoneList, that is optimized for the case of adding and removing
167 // a single element. The last element added is stored outside the backing list,
168 // and if no more than one element is ever added, the ZoneList isn't even
169 // allocated.
170 // Elements must not be NULL pointers.
171 template <typename T, int initial_size>
172 class BufferedZoneList {
173  public:
174   BufferedZoneList() : list_(NULL), last_(NULL) {}
175
176   // Adds element at end of list. This element is buffered and can
177   // be read using last() or removed using RemoveLast until a new Add or until
178   // RemoveLast or GetList has been called.
179   void Add(T* value, Zone* zone) {
180     if (last_ != NULL) {
181       if (list_ == NULL) {
182         list_ = new(zone) ZoneList<T*>(initial_size, zone);
183       }
184       list_->Add(last_, zone);
185     }
186     last_ = value;
187   }
188
189   T* last() {
190     ASSERT(last_ != NULL);
191     return last_;
192   }
193
194   T* RemoveLast() {
195     ASSERT(last_ != NULL);
196     T* result = last_;
197     if ((list_ != NULL) && (list_->length() > 0))
198       last_ = list_->RemoveLast();
199     else
200       last_ = NULL;
201     return result;
202   }
203
204   T* Get(int i) {
205     ASSERT((0 <= i) && (i < length()));
206     if (list_ == NULL) {
207       ASSERT_EQ(0, i);
208       return last_;
209     } else {
210       if (i == list_->length()) {
211         ASSERT(last_ != NULL);
212         return last_;
213       } else {
214         return list_->at(i);
215       }
216     }
217   }
218
219   void Clear() {
220     list_ = NULL;
221     last_ = NULL;
222   }
223
224   int length() {
225     int length = (list_ == NULL) ? 0 : list_->length();
226     return length + ((last_ == NULL) ? 0 : 1);
227   }
228
229   ZoneList<T*>* GetList(Zone* zone) {
230     if (list_ == NULL) {
231       list_ = new(zone) ZoneList<T*>(initial_size, zone);
232     }
233     if (last_ != NULL) {
234       list_->Add(last_, zone);
235       last_ = NULL;
236     }
237     return list_;
238   }
239
240  private:
241   ZoneList<T*>* list_;
242   T* last_;
243 };
244
245
246 // Accumulates RegExp atoms and assertions into lists of terms and alternatives.
247 class RegExpBuilder: public ZoneObject {
248  public:
249   explicit RegExpBuilder(Zone* zone);
250   void AddCharacter(uc16 character);
251   // "Adds" an empty expression. Does nothing except consume a
252   // following quantifier
253   void AddEmpty();
254   void AddAtom(RegExpTree* tree);
255   void AddAssertion(RegExpTree* tree);
256   void NewAlternative();  // '|'
257   void AddQuantifierToAtom(
258       int min, int max, RegExpQuantifier::QuantifierType type);
259   RegExpTree* ToRegExp();
260
261  private:
262   void FlushCharacters();
263   void FlushText();
264   void FlushTerms();
265   Zone* zone() const { return zone_; }
266
267   Zone* zone_;
268   bool pending_empty_;
269   ZoneList<uc16>* characters_;
270   BufferedZoneList<RegExpTree, 2> terms_;
271   BufferedZoneList<RegExpTree, 2> text_;
272   BufferedZoneList<RegExpTree, 2> alternatives_;
273 #ifdef DEBUG
274   enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
275 #define LAST(x) last_added_ = x;
276 #else
277 #define LAST(x)
278 #endif
279 };
280
281
282 class RegExpParser BASE_EMBEDDED {
283  public:
284   RegExpParser(FlatStringReader* in,
285                Handle<String>* error,
286                bool multiline_mode,
287                Zone* zone);
288
289   static bool ParseRegExp(FlatStringReader* input,
290                           bool multiline,
291                           RegExpCompileData* result,
292                           Zone* zone);
293
294   RegExpTree* ParsePattern();
295   RegExpTree* ParseDisjunction();
296   RegExpTree* ParseGroup();
297   RegExpTree* ParseCharacterClass();
298
299   // Parses a {...,...} quantifier and stores the range in the given
300   // out parameters.
301   bool ParseIntervalQuantifier(int* min_out, int* max_out);
302
303   // Parses and returns a single escaped character.  The character
304   // must not be 'b' or 'B' since they are usually handle specially.
305   uc32 ParseClassCharacterEscape();
306
307   // Checks whether the following is a length-digit hexadecimal number,
308   // and sets the value if it is.
309   bool ParseHexEscape(int length, uc32* value);
310
311   uc32 ParseOctalLiteral();
312
313   // Tries to parse the input as a back reference.  If successful it
314   // stores the result in the output parameter and returns true.  If
315   // it fails it will push back the characters read so the same characters
316   // can be reparsed.
317   bool ParseBackReferenceIndex(int* index_out);
318
319   CharacterRange ParseClassAtom(uc16* char_class);
320   RegExpTree* ReportError(Vector<const char> message);
321   void Advance();
322   void Advance(int dist);
323   void Reset(int pos);
324
325   // Reports whether the pattern might be used as a literal search string.
326   // Only use if the result of the parse is a single atom node.
327   bool simple();
328   bool contains_anchor() { return contains_anchor_; }
329   void set_contains_anchor() { contains_anchor_ = true; }
330   int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
331   int position() { return next_pos_ - 1; }
332   bool failed() { return failed_; }
333
334   static const int kMaxCaptures = 1 << 16;
335   static const uc32 kEndMarker = (1 << 21);
336
337  private:
338   enum SubexpressionType {
339     INITIAL,
340     CAPTURE,  // All positive values represent captures.
341     POSITIVE_LOOKAHEAD,
342     NEGATIVE_LOOKAHEAD,
343     GROUPING
344   };
345
346   class RegExpParserState : public ZoneObject {
347    public:
348     RegExpParserState(RegExpParserState* previous_state,
349                       SubexpressionType group_type,
350                       int disjunction_capture_index,
351                       Zone* zone)
352         : previous_state_(previous_state),
353           builder_(new(zone) RegExpBuilder(zone)),
354           group_type_(group_type),
355           disjunction_capture_index_(disjunction_capture_index) {}
356     // Parser state of containing expression, if any.
357     RegExpParserState* previous_state() { return previous_state_; }
358     bool IsSubexpression() { return previous_state_ != NULL; }
359     // RegExpBuilder building this regexp's AST.
360     RegExpBuilder* builder() { return builder_; }
361     // Type of regexp being parsed (parenthesized group or entire regexp).
362     SubexpressionType group_type() { return group_type_; }
363     // Index in captures array of first capture in this sub-expression, if any.
364     // Also the capture index of this sub-expression itself, if group_type
365     // is CAPTURE.
366     int capture_index() { return disjunction_capture_index_; }
367
368    private:
369     // Linked list implementation of stack of states.
370     RegExpParserState* previous_state_;
371     // Builder for the stored disjunction.
372     RegExpBuilder* builder_;
373     // Stored disjunction type (capture, look-ahead or grouping), if any.
374     SubexpressionType group_type_;
375     // Stored disjunction's capture index (if any).
376     int disjunction_capture_index_;
377   };
378
379   Isolate* isolate() { return isolate_; }
380   Zone* zone() const { return zone_; }
381
382   uc32 current() { return current_; }
383   bool has_more() { return has_more_; }
384   bool has_next() { return next_pos_ < in()->length(); }
385   uc32 Next();
386   FlatStringReader* in() { return in_; }
387   void ScanForCaptures();
388
389   Isolate* isolate_;
390   Zone* zone_;
391   Handle<String>* error_;
392   ZoneList<RegExpCapture*>* captures_;
393   FlatStringReader* in_;
394   uc32 current_;
395   int next_pos_;
396   // The capture count is only valid after we have scanned for captures.
397   int capture_count_;
398   bool has_more_;
399   bool multiline_;
400   bool simple_;
401   bool contains_anchor_;
402   bool is_scanned_for_captures_;
403   bool failed_;
404 };
405
406 // ----------------------------------------------------------------------------
407 // JAVASCRIPT PARSING
408
409 class Parser;
410 class SingletonLogger;
411
412 class ParserTraits {
413  public:
414   struct Type {
415     // TODO(marja): To be removed. The Traits object should contain all the data
416     // it needs.
417     typedef v8::internal::Parser* Parser;
418
419     // Used by FunctionState and BlockState.
420     typedef v8::internal::Scope Scope;
421     typedef Variable GeneratorVariable;
422     typedef v8::internal::Zone Zone;
423
424     // Return types for traversing functions.
425     typedef Handle<String> Identifier;
426     typedef v8::internal::Expression* Expression;
427     typedef Yield* YieldExpression;
428     typedef v8::internal::FunctionLiteral* FunctionLiteral;
429     typedef v8::internal::Literal* Literal;
430     typedef ObjectLiteral::Property* ObjectLiteralProperty;
431     typedef ZoneList<v8::internal::Expression*>* ExpressionList;
432     typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
433
434     // For constructing objects returned by the traversing functions.
435     typedef AstNodeFactory<AstConstructionVisitor> Factory;
436   };
437
438   explicit ParserTraits(Parser* parser) : parser_(parser) {}
439
440   // Custom operations executed when FunctionStates are created and destructed.
441   template<typename FunctionState>
442   static void SetUpFunctionState(FunctionState* function_state, Zone* zone) {
443     Isolate* isolate = zone->isolate();
444     function_state->isolate_ = isolate;
445     function_state->saved_ast_node_id_ = isolate->ast_node_id();
446     isolate->set_ast_node_id(BailoutId::FirstUsable().ToInt());
447   }
448
449   template<typename FunctionState>
450   static void TearDownFunctionState(FunctionState* function_state) {
451     if (function_state->outer_function_state_ != NULL) {
452       function_state->isolate_->set_ast_node_id(
453           function_state->saved_ast_node_id_);
454     }
455   }
456
457   // Helper functions for recursive descent.
458   bool IsEvalOrArguments(Handle<String> identifier) const;
459
460   // Returns true if the expression is of type "this.foo".
461   static bool IsThisProperty(Expression* expression);
462
463   static bool IsIdentifier(Expression* expression);
464
465   static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
466     return ObjectLiteral::IsBoilerplateProperty(property);
467   }
468
469   static bool IsArrayIndex(Handle<String> string, uint32_t* index) {
470     return !string.is_null() && string->AsArrayIndex(index);
471   }
472
473   // Functions for encapsulating the differences between parsing and preparsing;
474   // operations interleaved with the recursive descent.
475   static void PushLiteralName(FuncNameInferrer* fni, Handle<String> id) {
476     fni->PushLiteralName(id);
477   }
478   void PushPropertyName(FuncNameInferrer* fni, Expression* expression);
479
480   static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
481       Scope* scope, Expression* value, bool* has_function) {
482     if (scope->DeclarationScope()->is_global_scope() &&
483         value->AsFunctionLiteral() != NULL) {
484       *has_function = true;
485       value->AsFunctionLiteral()->set_pretenure();
486     }
487   }
488
489   // If we assign a function literal to a property we pretenure the
490   // literal so it can be added as a constant function property.
491   static void CheckAssigningFunctionLiteralToProperty(Expression* left,
492                                                       Expression* right);
493
494   // Keep track of eval() calls since they disable all local variable
495   // optimizations. This checks if expression is an eval call, and if yes,
496   // forwards the information to scope.
497   void CheckPossibleEvalCall(Expression* expression, Scope* scope);
498
499   // Determine if the expression is a variable proxy and mark it as being used
500   // in an assignment or with a increment/decrement operator. This is currently
501   // used on for the statically checking assignments to harmony const bindings.
502   static Expression* MarkExpressionAsLValue(Expression* expression);
503
504   // Checks LHS expression for assignment and prefix/postfix increment/decrement
505   // in strict mode.
506   void CheckStrictModeLValue(Expression* expression, bool* ok);
507
508   // Returns true if we have a binary expression between two numeric
509   // literals. In that case, *x will be changed to an expression which is the
510   // computed value.
511   bool ShortcutNumericLiteralBinaryExpression(
512       Expression** x, Expression* y, Token::Value op, int pos,
513       AstNodeFactory<AstConstructionVisitor>* factory);
514
515   // Rewrites the following types of unary expressions:
516   // not <literal> -> true / false
517   // + <numeric literal> -> <numeric literal>
518   // - <numeric literal> -> <numeric literal with value negated>
519   // ! <literal> -> true / false
520   // The following rewriting rules enable the collection of type feedback
521   // without any special stub and the multiplication is removed later in
522   // Crankshaft's canonicalization pass.
523   // + foo -> foo * 1
524   // - foo -> foo * (-1)
525   // ~ foo -> foo ^(~0)
526   Expression* BuildUnaryExpression(
527       Expression* expression, Token::Value op, int pos,
528       AstNodeFactory<AstConstructionVisitor>* factory);
529
530   // Reporting errors.
531   void ReportMessageAt(Scanner::Location source_location,
532                        const char* message,
533                        Vector<const char*> args,
534                        bool is_reference_error = false);
535   void ReportMessage(const char* message,
536                      Vector<Handle<String> > args,
537                      bool is_reference_error = false);
538   void ReportMessageAt(Scanner::Location source_location,
539                        const char* message,
540                        Vector<Handle<String> > args,
541                        bool is_reference_error = false);
542
543   // "null" return type creators.
544   static Handle<String> EmptyIdentifier() {
545     return Handle<String>();
546   }
547   static Expression* EmptyExpression() {
548     return NULL;
549   }
550   static Literal* EmptyLiteral() {
551     return NULL;
552   }
553   // Used in error return values.
554   static ZoneList<Expression*>* NullExpressionList() {
555     return NULL;
556   }
557
558   // Odd-ball literal creators.
559   Literal* GetLiteralTheHole(int position,
560                              AstNodeFactory<AstConstructionVisitor>* factory);
561
562   // Producing data during the recursive descent.
563   Handle<String> GetSymbol(Scanner* scanner = NULL);
564   Handle<String> NextLiteralString(Scanner* scanner,
565                                    PretenureFlag tenured);
566   Expression* ThisExpression(Scope* scope,
567                              AstNodeFactory<AstConstructionVisitor>* factory);
568   Literal* ExpressionFromLiteral(
569       Token::Value token, int pos, Scanner* scanner,
570       AstNodeFactory<AstConstructionVisitor>* factory);
571   Expression* ExpressionFromIdentifier(
572       Handle<String> name, int pos, Scope* scope,
573       AstNodeFactory<AstConstructionVisitor>* factory);
574   Expression* ExpressionFromString(
575       int pos, Scanner* scanner,
576       AstNodeFactory<AstConstructionVisitor>* factory);
577   ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) {
578     return new(zone) ZoneList<v8::internal::Expression*>(size, zone);
579   }
580   ZoneList<ObjectLiteral::Property*>* NewPropertyList(int size, Zone* zone) {
581     return new(zone) ZoneList<ObjectLiteral::Property*>(size, zone);
582   }
583
584   // Temporary glue; these functions will move to ParserBase.
585   Expression* ParseV8Intrinsic(bool* ok);
586   FunctionLiteral* ParseFunctionLiteral(
587       Handle<String> name,
588       Scanner::Location function_name_location,
589       bool name_is_strict_reserved,
590       bool is_generator,
591       int function_token_position,
592       FunctionLiteral::FunctionType type,
593       bool* ok);
594
595  private:
596   Parser* parser_;
597 };
598
599
600 class Parser : public ParserBase<ParserTraits> {
601  public:
602   explicit Parser(CompilationInfo* info);
603   ~Parser() {
604     delete reusable_preparser_;
605     reusable_preparser_ = NULL;
606   }
607
608   // Parses the source code represented by the compilation info and sets its
609   // function literal.  Returns false (and deallocates any allocated AST
610   // nodes) if parsing failed.
611   static bool Parse(CompilationInfo* info,
612                     bool allow_lazy = false) {
613     Parser parser(info);
614     parser.set_allow_lazy(allow_lazy);
615     return parser.Parse();
616   }
617   bool Parse();
618
619  private:
620   friend class ParserTraits;
621
622   // Limit the allowed number of local variables in a function. The hard limit
623   // is that offsets computed by FullCodeGenerator::StackOperand and similar
624   // functions are ints, and they should not overflow. In addition, accessing
625   // local variables creates user-controlled constants in the generated code,
626   // and we don't want too much user-controlled memory inside the code (this was
627   // the reason why this limit was introduced in the first place; see
628   // https://codereview.chromium.org/7003030/ ).
629   static const int kMaxNumFunctionLocals = 4194303;  // 2^22-1
630
631   enum VariableDeclarationContext {
632     kModuleElement,
633     kBlockElement,
634     kStatement,
635     kForStatement
636   };
637
638   // If a list of variable declarations includes any initializers.
639   enum VariableDeclarationProperties {
640     kHasInitializers,
641     kHasNoInitializers
642   };
643
644   // Returns NULL if parsing failed.
645   FunctionLiteral* ParseProgram();
646
647   FunctionLiteral* ParseLazy();
648   FunctionLiteral* ParseLazy(Utf16CharacterStream* source);
649
650   Isolate* isolate() { return isolate_; }
651   CompilationInfo* info() const { return info_; }
652
653   // Called by ParseProgram after setting up the scanner.
654   FunctionLiteral* DoParseProgram(CompilationInfo* info,
655                                   Handle<String> source);
656
657   // Report syntax error
658   void ReportInvalidPreparseData(Handle<String> name, bool* ok);
659
660   void SetCachedData(ScriptDataImpl** data,
661                      CachedDataMode cached_data_mode) {
662     cached_data_mode_ = cached_data_mode;
663     if (cached_data_mode == NO_CACHED_DATA) {
664       cached_data_ = NULL;
665     } else {
666       ASSERT(data != NULL);
667       cached_data_ = data;
668       symbol_cache_.Initialize(*data ? (*data)->symbol_count() : 0, zone());
669     }
670   }
671
672   bool inside_with() const { return scope_->inside_with(); }
673   ScriptDataImpl** cached_data() const { return cached_data_; }
674   CachedDataMode cached_data_mode() const { return cached_data_mode_; }
675   Scope* DeclarationScope(VariableMode mode) {
676     return IsLexicalVariableMode(mode)
677         ? scope_ : scope_->DeclarationScope();
678   }
679
680   // All ParseXXX functions take as the last argument an *ok parameter
681   // which is set to false if parsing failed; it is unchanged otherwise.
682   // By making the 'exception handling' explicit, we are forced to check
683   // for failure at the call sites.
684   void* ParseSourceElements(ZoneList<Statement*>* processor, int end_token,
685                             bool is_eval, bool is_global, bool* ok);
686   Statement* ParseModuleElement(ZoneStringList* labels, bool* ok);
687   Statement* ParseModuleDeclaration(ZoneStringList* names, bool* ok);
688   Module* ParseModule(bool* ok);
689   Module* ParseModuleLiteral(bool* ok);
690   Module* ParseModulePath(bool* ok);
691   Module* ParseModuleVariable(bool* ok);
692   Module* ParseModuleUrl(bool* ok);
693   Module* ParseModuleSpecifier(bool* ok);
694   Block* ParseImportDeclaration(bool* ok);
695   Statement* ParseExportDeclaration(bool* ok);
696   Statement* ParseBlockElement(ZoneStringList* labels, bool* ok);
697   Statement* ParseStatement(ZoneStringList* labels, bool* ok);
698   Statement* ParseFunctionDeclaration(ZoneStringList* names, bool* ok);
699   Statement* ParseNativeDeclaration(bool* ok);
700   Block* ParseBlock(ZoneStringList* labels, bool* ok);
701   Block* ParseVariableStatement(VariableDeclarationContext var_context,
702                                 ZoneStringList* names,
703                                 bool* ok);
704   Block* ParseVariableDeclarations(VariableDeclarationContext var_context,
705                                    VariableDeclarationProperties* decl_props,
706                                    ZoneStringList* names,
707                                    Handle<String>* out,
708                                    bool* ok);
709   Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels,
710                                                 bool* ok);
711   IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok);
712   Statement* ParseContinueStatement(bool* ok);
713   Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok);
714   Statement* ParseReturnStatement(bool* ok);
715   Statement* ParseWithStatement(ZoneStringList* labels, bool* ok);
716   CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
717   SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok);
718   DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok);
719   WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok);
720   Statement* ParseForStatement(ZoneStringList* labels, bool* ok);
721   Statement* ParseThrowStatement(bool* ok);
722   Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
723   TryStatement* ParseTryStatement(bool* ok);
724   DebuggerStatement* ParseDebuggerStatement(bool* ok);
725
726   // Support for hamony block scoped bindings.
727   Block* ParseScopedBlock(ZoneStringList* labels, bool* ok);
728
729   // Initialize the components of a for-in / for-of statement.
730   void InitializeForEachStatement(ForEachStatement* stmt,
731                                   Expression* each,
732                                   Expression* subject,
733                                   Statement* body);
734
735   FunctionLiteral* ParseFunctionLiteral(
736       Handle<String> name,
737       Scanner::Location function_name_location,
738       bool name_is_strict_reserved,
739       bool is_generator,
740       int function_token_position,
741       FunctionLiteral::FunctionType type,
742       bool* ok);
743
744   // Magical syntax support.
745   Expression* ParseV8Intrinsic(bool* ok);
746
747   bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode* visit_mode);
748
749   // Get odd-ball literals.
750   Literal* GetLiteralUndefined(int position);
751
752   // For harmony block scoping mode: Check if the scope has conflicting var/let
753   // declarations from different scopes. It covers for example
754   //
755   // function f() { { { var x; } let x; } }
756   // function g() { { var x; let x; } }
757   //
758   // The var declarations are hoisted to the function scope, but originate from
759   // a scope where the name has also been let bound or the var declaration is
760   // hoisted over such a scope.
761   void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
762
763   // Parser support
764   VariableProxy* NewUnresolved(Handle<String> name,
765                                VariableMode mode,
766                                Interface* interface);
767   void Declare(Declaration* declaration, bool resolve, bool* ok);
768
769   bool TargetStackContainsLabel(Handle<String> label);
770   BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
771   IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok);
772
773   void RegisterTargetUse(Label* target, Target* stop);
774
775   // Factory methods.
776
777   Scope* NewScope(Scope* parent, ScopeType type);
778
779   Handle<String> LookupCachedSymbol(int symbol_id);
780
781   // Generate AST node that throw a ReferenceError with the given type.
782   Expression* NewThrowReferenceError(Handle<String> type);
783
784   // Generate AST node that throw a SyntaxError with the given
785   // type. The first argument may be null (in the handle sense) in
786   // which case no arguments are passed to the constructor.
787   Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first);
788
789   // Generate AST node that throw a TypeError with the given
790   // type. Both arguments must be non-null (in the handle sense).
791   Expression* NewThrowTypeError(Handle<String> type,
792                                 Handle<Object> first,
793                                 Handle<Object> second);
794
795   // Generic AST generator for throwing errors from compiled code.
796   Expression* NewThrowError(Handle<String> constructor,
797                             Handle<String> type,
798                             Vector< Handle<Object> > arguments);
799
800   PreParser::PreParseResult LazyParseFunctionLiteral(
801        SingletonLogger* logger);
802
803   Isolate* isolate_;
804   ZoneList<Handle<String> > symbol_cache_;
805
806   Handle<Script> script_;
807   Scanner scanner_;
808   PreParser* reusable_preparser_;
809   Scope* original_scope_;  // for ES5 function declarations in sloppy eval
810   Target* target_stack_;  // for break, continue statements
811   ScriptDataImpl** cached_data_;
812   CachedDataMode cached_data_mode_;
813
814   CompilationInfo* info_;
815 };
816
817
818 // Support for handling complex values (array and object literals) that
819 // can be fully handled at compile time.
820 class CompileTimeValue: public AllStatic {
821  public:
822   enum LiteralType {
823     OBJECT_LITERAL_FAST_ELEMENTS,
824     OBJECT_LITERAL_SLOW_ELEMENTS,
825     ARRAY_LITERAL
826   };
827
828   static bool IsCompileTimeValue(Expression* expression);
829
830   // Get the value as a compile time value.
831   static Handle<FixedArray> GetValue(Isolate* isolate, Expression* expression);
832
833   // Get the type of a compile time value returned by GetValue().
834   static LiteralType GetLiteralType(Handle<FixedArray> value);
835
836   // Get the elements array of a compile time value returned by GetValue().
837   static Handle<FixedArray> GetElements(Handle<FixedArray> value);
838
839  private:
840   static const int kLiteralTypeSlot = 0;
841   static const int kElementsSlot = 1;
842
843   DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
844 };
845
846 } }  // namespace v8::internal
847
848 #endif  // V8_PARSER_H_