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: 52 ParserMessage(Scanner::Location loc, const char* message, 53 Vector<const char*> args) 54 : loc_(loc), 55 message_(message), 56 args_(args) { } 57 ~ParserMessage(); 58 Scanner::Location location() { return loc_; } 59 const char* message() { return message_; } 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: 70 explicit FunctionEntry(Vector<unsigned> backing) : backing_(backing) { } 71 FunctionEntry() : backing_(Vector<unsigned>::empty()) { } 72 73 int start_pos() { return backing_[kStartPosOffset]; } 74 void set_start_pos(int value) { backing_[kStartPosOffset] = value; } 75 76 int end_pos() { return backing_[kEndPosOffset]; } 77 void set_end_pos(int value) { backing_[kEndPosOffset] = value; } 78 79 int literal_count() { return backing_[kLiteralCountOffset]; } 80 void set_literal_count(int value) { backing_[kLiteralCountOffset] = value; } 81 82 int property_count() { return backing_[kPropertyCountOffset]; } 83 void set_property_count(int value) { 84 backing_[kPropertyCountOffset] = value; 85 } 86 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: 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. 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 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. 133 bool has_error() { return store_[PreparseDataConstants::kHasErrorOffset]; } 134 unsigned magic() { return store_[PreparseDataConstants::kMagicOffset]; } 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 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: 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. 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 208 T* last() { 209 ASSERT(last_ != NULL); 210 return last_; 211 } 212 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 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 238 void Clear() { 239 list_ = NULL; 240 last_ = NULL; 241 } 242 243 int length() { 244 int length = (list_ == NULL) ? 0 : list_->length(); 245 return length + ((last_ == NULL) ? 0 : 1); 246 } 247 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(); 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(); 344 bool contains_anchor() { return contains_anchor_; } 345 void set_contains_anchor() { contains_anchor_ = true; } 346 int captures_started() { return captures_ == NULL ? 0 : captures_->length(); } 347 int position() { return next_pos_ - 1; } 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: 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. 372 RegExpParserState* previous_state() { return previous_state_; } 373 bool IsSubexpression() { return previous_state_ != NULL; } 374 // RegExpBuilder building this regexp's AST. 375 RegExpBuilder* builder() { return builder_; } 376 // Type of regexp being parsed (parenthesized group or entire regexp). 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. 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 394 Isolate* isolate() { return isolate_; } 395 Zone* zone() { return isolate_->zone(); } 396 397 uc32 current() { return current_; } 398 bool has_more() { return has_more_; } 399 bool has_next() { return next_pos_ < in()->length(); } 400 uc32 Next(); 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); 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 460 Isolate* isolate() { return isolate_; } 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 474 bool inside_with() const { return with_nesting_level_ > 0; } 475 V8JavaScriptScanner& scanner() { return scanner_; } 476 Mode mode() const { return mode_; } 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 579 INLINE(Token::Value peek()) { 580 if (stack_overflow_) return Token::ILLEGAL; 581 return scanner().peek(); 582 } 583 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 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 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 663 Statement* EmptyStatement() { 664 static v8::internal::EmptyStatement empty; 665 return ∅ 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 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. 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: 785 JsonParser() 786 : isolate_(Isolate::Current()), 787 scanner_(isolate_->unicode_cache()) { } 788 ~JsonParser() { } 789 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. 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