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