• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 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 "scanner.h"
34 #include "scopes.h"
35 #include "preparse-data.h"
36 
37 namespace v8 {
38 namespace internal {
39 
40 class CompilationInfo;
41 class FuncNameInferrer;
42 class ParserLog;
43 class PositionStack;
44 class Target;
45 class LexicalScope;
46 
47 template <typename T> class ZoneListWrapper;
48 
49 
50 class ParserMessage : public Malloced {
51  public:
ParserMessage(Scanner::Location loc,const char * message,Vector<const char * > args)52   ParserMessage(Scanner::Location loc, const char* message,
53                 Vector<const char*> args)
54       : loc_(loc),
55         message_(message),
56         args_(args) { }
57   ~ParserMessage();
location()58   Scanner::Location location() { return loc_; }
message()59   const char* message() { return message_; }
args()60   Vector<const char*> args() { return args_; }
61  private:
62   Scanner::Location loc_;
63   const char* message_;
64   Vector<const char*> args_;
65 };
66 
67 
68 class FunctionEntry BASE_EMBEDDED {
69  public:
FunctionEntry(Vector<unsigned> backing)70   explicit FunctionEntry(Vector<unsigned> backing) : backing_(backing) { }
FunctionEntry()71   FunctionEntry() : backing_(Vector<unsigned>::empty()) { }
72 
start_pos()73   int start_pos() { return backing_[kStartPosOffset]; }
set_start_pos(int value)74   void set_start_pos(int value) { backing_[kStartPosOffset] = value; }
75 
end_pos()76   int end_pos() { return backing_[kEndPosOffset]; }
set_end_pos(int value)77   void set_end_pos(int value) { backing_[kEndPosOffset] = value; }
78 
literal_count()79   int literal_count() { return backing_[kLiteralCountOffset]; }
set_literal_count(int value)80   void set_literal_count(int value) { backing_[kLiteralCountOffset] = value; }
81 
property_count()82   int property_count() { return backing_[kPropertyCountOffset]; }
set_property_count(int value)83   void set_property_count(int value) {
84     backing_[kPropertyCountOffset] = value;
85   }
86 
is_valid()87   bool is_valid() { return backing_.length() > 0; }
88 
89   static const int kSize = 4;
90 
91  private:
92   Vector<unsigned> backing_;
93   static const int kStartPosOffset = 0;
94   static const int kEndPosOffset = 1;
95   static const int kLiteralCountOffset = 2;
96   static const int kPropertyCountOffset = 3;
97 };
98 
99 
100 class ScriptDataImpl : public ScriptData {
101  public:
ScriptDataImpl(Vector<unsigned> store)102   explicit ScriptDataImpl(Vector<unsigned> store)
103       : store_(store),
104         owns_store_(true) { }
105 
106   // Create an empty ScriptDataImpl that is guaranteed to not satisfy
107   // a SanityCheck.
ScriptDataImpl()108   ScriptDataImpl() : store_(Vector<unsigned>()), owns_store_(false) { }
109 
110   virtual ~ScriptDataImpl();
111   virtual int Length();
112   virtual const char* Data();
113   virtual bool HasError();
114 
115   void Initialize();
116   void ReadNextSymbolPosition();
117 
118   FunctionEntry GetFunctionEntry(int start);
119   int GetSymbolIdentifier();
120   bool SanityCheck();
121 
122   Scanner::Location MessageLocation();
123   const char* BuildMessage();
124   Vector<const char*> BuildArgs();
125 
symbol_count()126   int symbol_count() {
127     return (store_.length() > PreparseDataConstants::kHeaderSize)
128         ? store_[PreparseDataConstants::kSymbolCountOffset]
129         : 0;
130   }
131   // The following functions should only be called if SanityCheck has
132   // returned true.
has_error()133   bool has_error() { return store_[PreparseDataConstants::kHasErrorOffset]; }
magic()134   unsigned magic() { return store_[PreparseDataConstants::kMagicOffset]; }
version()135   unsigned version() { return store_[PreparseDataConstants::kVersionOffset]; }
136 
137  private:
138   Vector<unsigned> store_;
139   unsigned char* symbol_data_;
140   unsigned char* symbol_data_end_;
141   int function_index_;
142   bool owns_store_;
143 
144   unsigned Read(int position);
145   unsigned* ReadAddress(int position);
146   // Reads a number from the current symbols
147   int ReadNumber(byte** source);
148 
ScriptDataImpl(const char * backing_store,int length)149   ScriptDataImpl(const char* backing_store, int length)
150       : store_(reinterpret_cast<unsigned*>(const_cast<char*>(backing_store)),
151                length / static_cast<int>(sizeof(unsigned))),
152         owns_store_(false) {
153     ASSERT_EQ(0, static_cast<int>(
154         reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned)));
155   }
156 
157   // Read strings written by ParserRecorder::WriteString.
158   static const char* ReadString(unsigned* start, int* chars);
159 
160   friend class ScriptData;
161 };
162 
163 
164 class ParserApi {
165  public:
166   // Parses the source code represented by the compilation info and sets its
167   // function literal.  Returns false (and deallocates any allocated AST
168   // nodes) if parsing failed.
169   static bool Parse(CompilationInfo* info);
170 
171   // Generic preparser generating full preparse data.
172   static ScriptDataImpl* PreParse(UC16CharacterStream* source,
173                                   v8::Extension* extension);
174 
175   // Preparser that only does preprocessing that makes sense if only used
176   // immediately after.
177   static ScriptDataImpl* PartialPreParse(UC16CharacterStream* source,
178                                          v8::Extension* extension);
179 };
180 
181 // ----------------------------------------------------------------------------
182 // REGEXP PARSING
183 
184 // A BuffferedZoneList is an automatically growing list, just like (and backed
185 // by) a ZoneList, that is optimized for the case of adding and removing
186 // a single element. The last element added is stored outside the backing list,
187 // and if no more than one element is ever added, the ZoneList isn't even
188 // allocated.
189 // Elements must not be NULL pointers.
190 template <typename T, int initial_size>
191 class BufferedZoneList {
192  public:
BufferedZoneList()193   BufferedZoneList() : list_(NULL), last_(NULL) {}
194 
195   // Adds element at end of list. This element is buffered and can
196   // be read using last() or removed using RemoveLast until a new Add or until
197   // RemoveLast or GetList has been called.
Add(T * value)198   void Add(T* value) {
199     if (last_ != NULL) {
200       if (list_ == NULL) {
201         list_ = new ZoneList<T*>(initial_size);
202       }
203       list_->Add(last_);
204     }
205     last_ = value;
206   }
207 
last()208   T* last() {
209     ASSERT(last_ != NULL);
210     return last_;
211   }
212 
RemoveLast()213   T* RemoveLast() {
214     ASSERT(last_ != NULL);
215     T* result = last_;
216     if ((list_ != NULL) && (list_->length() > 0))
217       last_ = list_->RemoveLast();
218     else
219       last_ = NULL;
220     return result;
221   }
222 
Get(int i)223   T* Get(int i) {
224     ASSERT((0 <= i) && (i < length()));
225     if (list_ == NULL) {
226       ASSERT_EQ(0, i);
227       return last_;
228     } else {
229       if (i == list_->length()) {
230         ASSERT(last_ != NULL);
231         return last_;
232       } else {
233         return list_->at(i);
234       }
235     }
236   }
237 
Clear()238   void Clear() {
239     list_ = NULL;
240     last_ = NULL;
241   }
242 
length()243   int length() {
244     int length = (list_ == NULL) ? 0 : list_->length();
245     return length + ((last_ == NULL) ? 0 : 1);
246   }
247 
GetList()248   ZoneList<T*>* GetList() {
249     if (list_ == NULL) {
250       list_ = new ZoneList<T*>(initial_size);
251     }
252     if (last_ != NULL) {
253       list_->Add(last_);
254       last_ = NULL;
255     }
256     return list_;
257   }
258 
259  private:
260   ZoneList<T*>* list_;
261   T* last_;
262 };
263 
264 
265 // Accumulates RegExp atoms and assertions into lists of terms and alternatives.
266 class RegExpBuilder: public ZoneObject {
267  public:
268   RegExpBuilder();
269   void AddCharacter(uc16 character);
270   // "Adds" an empty expression. Does nothing except consume a
271   // following quantifier
272   void AddEmpty();
273   void AddAtom(RegExpTree* tree);
274   void AddAssertion(RegExpTree* tree);
275   void NewAlternative();  // '|'
276   void AddQuantifierToAtom(int min, int max, RegExpQuantifier::Type type);
277   RegExpTree* ToRegExp();
278 
279  private:
280   void FlushCharacters();
281   void FlushText();
282   void FlushTerms();
zone()283   Zone* zone() { return zone_; }
284 
285   Zone* zone_;
286   bool pending_empty_;
287   ZoneList<uc16>* characters_;
288   BufferedZoneList<RegExpTree, 2> terms_;
289   BufferedZoneList<RegExpTree, 2> text_;
290   BufferedZoneList<RegExpTree, 2> alternatives_;
291 #ifdef DEBUG
292   enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
293 #define LAST(x) last_added_ = x;
294 #else
295 #define LAST(x)
296 #endif
297 };
298 
299 
300 class RegExpParser {
301  public:
302   RegExpParser(FlatStringReader* in,
303                Handle<String>* error,
304                bool multiline_mode);
305 
306   static bool ParseRegExp(FlatStringReader* input,
307                           bool multiline,
308                           RegExpCompileData* result);
309 
310   RegExpTree* ParsePattern();
311   RegExpTree* ParseDisjunction();
312   RegExpTree* ParseGroup();
313   RegExpTree* ParseCharacterClass();
314 
315   // Parses a {...,...} quantifier and stores the range in the given
316   // out parameters.
317   bool ParseIntervalQuantifier(int* min_out, int* max_out);
318 
319   // Parses and returns a single escaped character.  The character
320   // must not be 'b' or 'B' since they are usually handle specially.
321   uc32 ParseClassCharacterEscape();
322 
323   // Checks whether the following is a length-digit hexadecimal number,
324   // and sets the value if it is.
325   bool ParseHexEscape(int length, uc32* value);
326 
327   uc32 ParseOctalLiteral();
328 
329   // Tries to parse the input as a back reference.  If successful it
330   // stores the result in the output parameter and returns true.  If
331   // it fails it will push back the characters read so the same characters
332   // can be reparsed.
333   bool ParseBackReferenceIndex(int* index_out);
334 
335   CharacterRange ParseClassAtom(uc16* char_class);
336   RegExpTree* ReportError(Vector<const char> message);
337   void Advance();
338   void Advance(int dist);
339   void Reset(int pos);
340 
341   // Reports whether the pattern might be used as a literal search string.
342   // Only use if the result of the parse is a single atom node.
343   bool simple();
contains_anchor()344   bool contains_anchor() { return contains_anchor_; }
set_contains_anchor()345   void set_contains_anchor() { contains_anchor_ = true; }
captures_started()346   int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
position()347   int position() { return next_pos_ - 1; }
failed()348   bool failed() { return failed_; }
349 
350   static const int kMaxCaptures = 1 << 16;
351   static const uc32 kEndMarker = (1 << 21);
352 
353  private:
354   enum SubexpressionType {
355     INITIAL,
356     CAPTURE,  // All positive values represent captures.
357     POSITIVE_LOOKAHEAD,
358     NEGATIVE_LOOKAHEAD,
359     GROUPING
360   };
361 
362   class RegExpParserState : public ZoneObject {
363    public:
RegExpParserState(RegExpParserState * previous_state,SubexpressionType group_type,int disjunction_capture_index)364     RegExpParserState(RegExpParserState* previous_state,
365                       SubexpressionType group_type,
366                       int disjunction_capture_index)
367         : previous_state_(previous_state),
368           builder_(new RegExpBuilder()),
369           group_type_(group_type),
370           disjunction_capture_index_(disjunction_capture_index) {}
371     // Parser state of containing expression, if any.
previous_state()372     RegExpParserState* previous_state() { return previous_state_; }
IsSubexpression()373     bool IsSubexpression() { return previous_state_ != NULL; }
374     // RegExpBuilder building this regexp's AST.
builder()375     RegExpBuilder* builder() { return builder_; }
376     // Type of regexp being parsed (parenthesized group or entire regexp).
group_type()377     SubexpressionType group_type() { return group_type_; }
378     // Index in captures array of first capture in this sub-expression, if any.
379     // Also the capture index of this sub-expression itself, if group_type
380     // is CAPTURE.
capture_index()381     int capture_index() { return disjunction_capture_index_; }
382 
383    private:
384     // Linked list implementation of stack of states.
385     RegExpParserState* previous_state_;
386     // Builder for the stored disjunction.
387     RegExpBuilder* builder_;
388     // Stored disjunction type (capture, look-ahead or grouping), if any.
389     SubexpressionType group_type_;
390     // Stored disjunction's capture index (if any).
391     int disjunction_capture_index_;
392   };
393 
isolate()394   Isolate* isolate() { return isolate_; }
zone()395   Zone* zone() { return isolate_->zone(); }
396 
current()397   uc32 current() { return current_; }
has_more()398   bool has_more() { return has_more_; }
has_next()399   bool has_next() { return next_pos_ < in()->length(); }
400   uc32 Next();
in()401   FlatStringReader* in() { return in_; }
402   void ScanForCaptures();
403 
404   Isolate* isolate_;
405   Handle<String>* error_;
406   ZoneList<RegExpCapture*>* captures_;
407   FlatStringReader* in_;
408   uc32 current_;
409   int next_pos_;
410   // The capture count is only valid after we have scanned for captures.
411   int capture_count_;
412   bool has_more_;
413   bool multiline_;
414   bool simple_;
415   bool contains_anchor_;
416   bool is_scanned_for_captures_;
417   bool failed_;
418 };
419 
420 // ----------------------------------------------------------------------------
421 // JAVASCRIPT PARSING
422 
423 class Parser {
424  public:
425   Parser(Handle<Script> script,
426          bool allow_natives_syntax,
427          v8::Extension* extension,
428          ScriptDataImpl* pre_data);
~Parser()429   virtual ~Parser() { }
430 
431   // Returns NULL if parsing failed.
432   FunctionLiteral* ParseProgram(Handle<String> source,
433                                 bool in_global_context,
434                                 StrictModeFlag strict_mode);
435 
436   FunctionLiteral* ParseLazy(CompilationInfo* info);
437 
438   void ReportMessageAt(Scanner::Location loc,
439                        const char* message,
440                        Vector<const char*> args);
441   void ReportMessageAt(Scanner::Location loc,
442                        const char* message,
443                        Vector<Handle<String> > args);
444 
445  protected:
446   // Limit on number of function parameters is chosen arbitrarily.
447   // Code::Flags uses only the low 17 bits of num-parameters to
448   // construct a hashable id, so if more than 2^17 are allowed, this
449   // should be checked.
450   static const int kMaxNumFunctionParameters = 32766;
451   static const int kMaxNumFunctionLocals = 32767;
452   FunctionLiteral* ParseLazy(CompilationInfo* info,
453                              UC16CharacterStream* source,
454                              ZoneScope* zone_scope);
455   enum Mode {
456     PARSE_LAZILY,
457     PARSE_EAGERLY
458   };
459 
isolate()460   Isolate* isolate() { return isolate_; }
zone()461   Zone* zone() { return isolate_->zone(); }
462 
463   // Called by ParseProgram after setting up the scanner.
464   FunctionLiteral* DoParseProgram(Handle<String> source,
465                                   bool in_global_context,
466                                   StrictModeFlag strict_mode,
467                                   ZoneScope* zone_scope);
468 
469   // Report syntax error
470   void ReportUnexpectedToken(Token::Value token);
471   void ReportInvalidPreparseData(Handle<String> name, bool* ok);
472   void ReportMessage(const char* message, Vector<const char*> args);
473 
inside_with()474   bool inside_with() const { return with_nesting_level_ > 0; }
scanner()475   V8JavaScriptScanner& scanner()  { return scanner_; }
mode()476   Mode mode() const { return mode_; }
pre_data()477   ScriptDataImpl* pre_data() const { return pre_data_; }
478 
479   // Check if the given string is 'eval' or 'arguments'.
480   bool IsEvalOrArguments(Handle<String> string);
481 
482   // All ParseXXX functions take as the last argument an *ok parameter
483   // which is set to false if parsing failed; it is unchanged otherwise.
484   // By making the 'exception handling' explicit, we are forced to check
485   // for failure at the call sites.
486   void* ParseSourceElements(ZoneList<Statement*>* processor,
487                             int end_token, bool* ok);
488   Statement* ParseStatement(ZoneStringList* labels, bool* ok);
489   Statement* ParseFunctionDeclaration(bool* ok);
490   Statement* ParseNativeDeclaration(bool* ok);
491   Block* ParseBlock(ZoneStringList* labels, bool* ok);
492   Block* ParseVariableStatement(bool* ok);
493   Block* ParseVariableDeclarations(bool accept_IN, Expression** var, bool* ok);
494   Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels,
495                                                 bool* ok);
496   IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok);
497   Statement* ParseContinueStatement(bool* ok);
498   Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok);
499   Statement* ParseReturnStatement(bool* ok);
500   Block* WithHelper(Expression* obj,
501                     ZoneStringList* labels,
502                     bool is_catch_block,
503                     bool* ok);
504   Statement* ParseWithStatement(ZoneStringList* labels, bool* ok);
505   CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
506   SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok);
507   DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok);
508   WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok);
509   Statement* ParseForStatement(ZoneStringList* labels, bool* ok);
510   Statement* ParseThrowStatement(bool* ok);
511   Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
512   TryStatement* ParseTryStatement(bool* ok);
513   DebuggerStatement* ParseDebuggerStatement(bool* ok);
514 
515   Expression* ParseExpression(bool accept_IN, bool* ok);
516   Expression* ParseAssignmentExpression(bool accept_IN, bool* ok);
517   Expression* ParseConditionalExpression(bool accept_IN, bool* ok);
518   Expression* ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
519   Expression* ParseUnaryExpression(bool* ok);
520   Expression* ParsePostfixExpression(bool* ok);
521   Expression* ParseLeftHandSideExpression(bool* ok);
522   Expression* ParseNewExpression(bool* ok);
523   Expression* ParseMemberExpression(bool* ok);
524   Expression* ParseNewPrefix(PositionStack* stack, bool* ok);
525   Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack,
526                                                    bool* ok);
527   Expression* ParsePrimaryExpression(bool* ok);
528   Expression* ParseArrayLiteral(bool* ok);
529   Expression* ParseObjectLiteral(bool* ok);
530   ObjectLiteral::Property* ParseObjectLiteralGetSet(bool is_getter, bool* ok);
531   Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
532 
533   Expression* NewCompareNode(Token::Value op,
534                              Expression* x,
535                              Expression* y,
536                              int position);
537 
538   // Populate the constant properties fixed array for a materialized object
539   // literal.
540   void BuildObjectLiteralConstantProperties(
541       ZoneList<ObjectLiteral::Property*>* properties,
542       Handle<FixedArray> constants,
543       bool* is_simple,
544       bool* fast_elements,
545       int* depth);
546 
547   // Populate the literals fixed array for a materialized array literal.
548   void BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* properties,
549                                             Handle<FixedArray> constants,
550                                             bool* is_simple,
551                                             int* depth);
552 
553   // Decide if a property should be in the object boilerplate.
554   bool IsBoilerplateProperty(ObjectLiteral::Property* property);
555   // If the expression is a literal, return the literal value;
556   // if the expression is a materialized literal and is simple return a
557   // compile time value as encoded by CompileTimeValue::GetValue().
558   // Otherwise, return undefined literal as the placeholder
559   // in the object literal boilerplate.
560   Handle<Object> GetBoilerplateValue(Expression* expression);
561 
562   enum FunctionLiteralType {
563     EXPRESSION,
564     DECLARATION,
565     NESTED
566   };
567 
568   ZoneList<Expression*>* ParseArguments(bool* ok);
569   FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name,
570                                         bool name_is_reserved,
571                                         int function_token_position,
572                                         FunctionLiteralType type,
573                                         bool* ok);
574 
575 
576   // Magical syntax support.
577   Expression* ParseV8Intrinsic(bool* ok);
578 
INLINE(Token::Value peek ())579   INLINE(Token::Value peek()) {
580     if (stack_overflow_) return Token::ILLEGAL;
581     return scanner().peek();
582   }
583 
INLINE(Token::Value Next ())584   INLINE(Token::Value Next()) {
585     // BUG 1215673: Find a thread safe way to set a stack limit in
586     // pre-parse mode. Otherwise, we cannot safely pre-parse from other
587     // threads.
588     if (stack_overflow_) {
589       return Token::ILLEGAL;
590     }
591     if (StackLimitCheck(isolate()).HasOverflowed()) {
592       // Any further calls to Next or peek will return the illegal token.
593       // The current call must return the next token, which might already
594       // have been peek'ed.
595       stack_overflow_ = true;
596     }
597     return scanner().Next();
598   }
599 
600   bool peek_any_identifier();
601 
602   INLINE(void Consume(Token::Value token));
603   void Expect(Token::Value token, bool* ok);
604   bool Check(Token::Value token);
605   void ExpectSemicolon(bool* ok);
606 
LiteralString(PretenureFlag tenured)607   Handle<String> LiteralString(PretenureFlag tenured) {
608     if (scanner().is_literal_ascii()) {
609       return isolate_->factory()->NewStringFromAscii(
610           scanner().literal_ascii_string(), tenured);
611     } else {
612       return isolate_->factory()->NewStringFromTwoByte(
613             scanner().literal_uc16_string(), tenured);
614     }
615   }
616 
NextLiteralString(PretenureFlag tenured)617   Handle<String> NextLiteralString(PretenureFlag tenured) {
618     if (scanner().is_next_literal_ascii()) {
619       return isolate_->factory()->NewStringFromAscii(
620           scanner().next_literal_ascii_string(), tenured);
621     } else {
622       return isolate_->factory()->NewStringFromTwoByte(
623           scanner().next_literal_uc16_string(), tenured);
624     }
625   }
626 
627   Handle<String> GetSymbol(bool* ok);
628 
629   // Get odd-ball literals.
630   Literal* GetLiteralUndefined();
631   Literal* GetLiteralTheHole();
632   Literal* GetLiteralNumber(double value);
633 
634   Handle<String> ParseIdentifier(bool* ok);
635   Handle<String> ParseIdentifierOrReservedWord(bool* is_reserved, bool* ok);
636   Handle<String> ParseIdentifierName(bool* ok);
637   Handle<String> ParseIdentifierOrGetOrSet(bool* is_get,
638                                            bool* is_set,
639                                            bool* ok);
640 
641   // Strict mode validation of LValue expressions
642   void CheckStrictModeLValue(Expression* expression,
643                              const char* error,
644                              bool* ok);
645 
646   // Strict mode octal literal validation.
647   void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok);
648 
649   // Parser support
650   VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
651                          FunctionLiteral* fun,
652                          bool resolve,
653                          bool* ok);
654 
655   bool TargetStackContainsLabel(Handle<String> label);
656   BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
657   IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok);
658 
659   void RegisterTargetUse(Label* target, Target* stop);
660 
661   // Factory methods.
662 
EmptyStatement()663   Statement* EmptyStatement() {
664     static v8::internal::EmptyStatement empty;
665     return &empty;
666   }
667 
668   Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with);
669 
670   Handle<String> LookupSymbol(int symbol_id);
671 
672   Handle<String> LookupCachedSymbol(int symbol_id);
673 
NewCall(Expression * expression,ZoneList<Expression * > * arguments,int pos)674   Expression* NewCall(Expression* expression,
675                       ZoneList<Expression*>* arguments,
676                       int pos) {
677     return new Call(expression, arguments, pos);
678   }
679 
680 
681   // Create a number literal.
682   Literal* NewNumberLiteral(double value);
683 
684   // Generate AST node that throw a ReferenceError with the given type.
685   Expression* NewThrowReferenceError(Handle<String> type);
686 
687   // Generate AST node that throw a SyntaxError with the given
688   // type. The first argument may be null (in the handle sense) in
689   // which case no arguments are passed to the constructor.
690   Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first);
691 
692   // Generate AST node that throw a TypeError with the given
693   // type. Both arguments must be non-null (in the handle sense).
694   Expression* NewThrowTypeError(Handle<String> type,
695                                 Handle<Object> first,
696                                 Handle<Object> second);
697 
698   // Generic AST generator for throwing errors from compiled code.
699   Expression* NewThrowError(Handle<String> constructor,
700                             Handle<String> type,
701                             Vector< Handle<Object> > arguments);
702 
703   Isolate* isolate_;
704   ZoneList<Handle<String> > symbol_cache_;
705 
706   Handle<Script> script_;
707   V8JavaScriptScanner scanner_;
708 
709   Scope* top_scope_;
710   int with_nesting_level_;
711 
712   LexicalScope* lexical_scope_;
713   Mode mode_;
714 
715   Target* target_stack_;  // for break, continue statements
716   bool allow_natives_syntax_;
717   v8::Extension* extension_;
718   bool is_pre_parsing_;
719   ScriptDataImpl* pre_data_;
720   FuncNameInferrer* fni_;
721   bool stack_overflow_;
722   // If true, the next (and immediately following) function literal is
723   // preceded by a parenthesis.
724   // Heuristically that means that the function will be called immediately,
725   // so never lazily compile it.
726   bool parenthesized_function_;
727 
728   friend class LexicalScope;
729 };
730 
731 
732 // Support for handling complex values (array and object literals) that
733 // can be fully handled at compile time.
734 class CompileTimeValue: public AllStatic {
735  public:
736   enum Type {
737     OBJECT_LITERAL_FAST_ELEMENTS,
738     OBJECT_LITERAL_SLOW_ELEMENTS,
739     ARRAY_LITERAL
740   };
741 
742   static bool IsCompileTimeValue(Expression* expression);
743 
744   static bool ArrayLiteralElementNeedsInitialization(Expression* value);
745 
746   // Get the value as a compile time value.
747   static Handle<FixedArray> GetValue(Expression* expression);
748 
749   // Get the type of a compile time value returned by GetValue().
750   static Type GetType(Handle<FixedArray> value);
751 
752   // Get the elements array of a compile time value returned by GetValue().
753   static Handle<FixedArray> GetElements(Handle<FixedArray> value);
754 
755  private:
756   static const int kTypeSlot = 0;
757   static const int kElementsSlot = 1;
758 
759   DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
760 };
761 
762 
763 // ----------------------------------------------------------------------------
764 // JSON PARSING
765 
766 // JSON is a subset of JavaScript, as specified in, e.g., the ECMAScript 5
767 // specification section 15.12.1 (and appendix A.8).
768 // The grammar is given section 15.12.1.2 (and appendix A.8.2).
769 class JsonParser BASE_EMBEDDED {
770  public:
771   // Parse JSON input as a single JSON value.
772   // Returns null handle and sets exception if parsing failed.
Parse(Handle<String> source)773   static Handle<Object> Parse(Handle<String> source) {
774     if (source->IsExternalTwoByteString()) {
775       ExternalTwoByteStringUC16CharacterStream stream(
776           Handle<ExternalTwoByteString>::cast(source), 0, source->length());
777       return JsonParser().ParseJson(source, &stream);
778     } else {
779       GenericStringUC16CharacterStream stream(source, 0, source->length());
780       return JsonParser().ParseJson(source, &stream);
781     }
782   }
783 
784  private:
JsonParser()785   JsonParser()
786       : isolate_(Isolate::Current()),
787         scanner_(isolate_->unicode_cache()) { }
~JsonParser()788   ~JsonParser() { }
789 
isolate()790   Isolate* isolate() { return isolate_; }
791 
792   // Parse a string containing a single JSON value.
793   Handle<Object> ParseJson(Handle<String> script, UC16CharacterStream* source);
794   // Parse a single JSON value from input (grammar production JSONValue).
795   // A JSON value is either a (double-quoted) string literal, a number literal,
796   // one of "true", "false", or "null", or an object or array literal.
797   Handle<Object> ParseJsonValue();
798   // Parse a JSON object literal (grammar production JSONObject).
799   // An object literal is a squiggly-braced and comma separated sequence
800   // (possibly empty) of key/value pairs, where the key is a JSON string
801   // literal, the value is a JSON value, and the two are separated by a colon.
802   // A JSON array dosn't allow numbers and identifiers as keys, like a
803   // JavaScript array.
804   Handle<Object> ParseJsonObject();
805   // Parses a JSON array literal (grammar production JSONArray). An array
806   // literal is a square-bracketed and comma separated sequence (possibly empty)
807   // of JSON values.
808   // A JSON array doesn't allow leaving out values from the sequence, nor does
809   // it allow a terminal comma, like a JavaScript array does.
810   Handle<Object> ParseJsonArray();
811 
812   // Mark that a parsing error has happened at the current token, and
813   // return a null handle. Primarily for readability.
ReportUnexpectedToken()814   Handle<Object> ReportUnexpectedToken() { return Handle<Object>::null(); }
815   // Converts the currently parsed literal to a JavaScript String.
816   Handle<String> GetString();
817 
818   Isolate* isolate_;
819   JsonScanner scanner_;
820   bool stack_overflow_;
821 };
822 } }  // namespace v8::internal
823 
824 #endif  // V8_PARSER_H_
825