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_AST_H_ 29 #define V8_AST_H_ 30 31 #include "v8.h" 32 33 #include "assembler.h" 34 #include "factory.h" 35 #include "isolate.h" 36 #include "jsregexp.h" 37 #include "list-inl.h" 38 #include "runtime.h" 39 #include "small-pointer-list.h" 40 #include "smart-pointers.h" 41 #include "token.h" 42 #include "type-info.h" // TODO(rossberg): this should eventually be removed 43 #include "types.h" 44 #include "utils.h" 45 #include "variables.h" 46 #include "interface.h" 47 #include "zone-inl.h" 48 49 namespace v8 { 50 namespace internal { 51 52 // The abstract syntax tree is an intermediate, light-weight 53 // representation of the parsed JavaScript code suitable for 54 // compilation to native code. 55 56 // Nodes are allocated in a separate zone, which allows faster 57 // allocation and constant-time deallocation of the entire syntax 58 // tree. 59 60 61 // ---------------------------------------------------------------------------- 62 // Nodes of the abstract syntax tree. Only concrete classes are 63 // enumerated here. 64 65 #define DECLARATION_NODE_LIST(V) \ 66 V(VariableDeclaration) \ 67 V(FunctionDeclaration) \ 68 V(ModuleDeclaration) \ 69 V(ImportDeclaration) \ 70 V(ExportDeclaration) \ 71 72 #define MODULE_NODE_LIST(V) \ 73 V(ModuleLiteral) \ 74 V(ModuleVariable) \ 75 V(ModulePath) \ 76 V(ModuleUrl) 77 78 #define STATEMENT_NODE_LIST(V) \ 79 V(Block) \ 80 V(ModuleStatement) \ 81 V(ExpressionStatement) \ 82 V(EmptyStatement) \ 83 V(IfStatement) \ 84 V(ContinueStatement) \ 85 V(BreakStatement) \ 86 V(ReturnStatement) \ 87 V(WithStatement) \ 88 V(SwitchStatement) \ 89 V(DoWhileStatement) \ 90 V(WhileStatement) \ 91 V(ForStatement) \ 92 V(ForInStatement) \ 93 V(ForOfStatement) \ 94 V(TryCatchStatement) \ 95 V(TryFinallyStatement) \ 96 V(DebuggerStatement) 97 98 #define EXPRESSION_NODE_LIST(V) \ 99 V(FunctionLiteral) \ 100 V(SharedFunctionInfoLiteral) \ 101 V(Conditional) \ 102 V(VariableProxy) \ 103 V(Literal) \ 104 V(RegExpLiteral) \ 105 V(ObjectLiteral) \ 106 V(ArrayLiteral) \ 107 V(Assignment) \ 108 V(Yield) \ 109 V(Throw) \ 110 V(Property) \ 111 V(Call) \ 112 V(CallNew) \ 113 V(CallRuntime) \ 114 V(UnaryOperation) \ 115 V(CountOperation) \ 116 V(BinaryOperation) \ 117 V(CompareOperation) \ 118 V(ThisFunction) 119 120 #define AST_NODE_LIST(V) \ 121 DECLARATION_NODE_LIST(V) \ 122 MODULE_NODE_LIST(V) \ 123 STATEMENT_NODE_LIST(V) \ 124 EXPRESSION_NODE_LIST(V) 125 126 #ifdef WIN32 127 #undef Yield 128 #endif 129 130 // Forward declarations 131 class AstConstructionVisitor; 132 template<class> class AstNodeFactory; 133 class AstVisitor; 134 class Declaration; 135 class Module; 136 class BreakableStatement; 137 class Expression; 138 class IterationStatement; 139 class MaterializedLiteral; 140 class Statement; 141 class TargetCollector; 142 class TypeFeedbackOracle; 143 144 class RegExpAlternative; 145 class RegExpAssertion; 146 class RegExpAtom; 147 class RegExpBackReference; 148 class RegExpCapture; 149 class RegExpCharacterClass; 150 class RegExpCompiler; 151 class RegExpDisjunction; 152 class RegExpEmpty; 153 class RegExpLookahead; 154 class RegExpQuantifier; 155 class RegExpText; 156 157 #define DEF_FORWARD_DECLARATION(type) class type; 158 AST_NODE_LIST(DEF_FORWARD_DECLARATION) 159 #undef DEF_FORWARD_DECLARATION 160 161 162 // Typedef only introduced to avoid unreadable code. 163 // Please do appreciate the required space in "> >". 164 typedef ZoneList<Handle<String> > ZoneStringList; 165 typedef ZoneList<Handle<Object> > ZoneObjectList; 166 167 168 #define DECLARE_NODE_TYPE(type) \ 169 virtual void Accept(AstVisitor* v); \ 170 virtual AstNode::NodeType node_type() const { return AstNode::k##type; } \ 171 template<class> friend class AstNodeFactory; 172 173 174 enum AstPropertiesFlag { 175 kDontInline, 176 kDontOptimize, 177 kDontSelfOptimize, 178 kDontSoftInline, 179 kDontCache 180 }; 181 182 183 class AstProperties BASE_EMBEDDED { 184 public: 185 class Flags : public EnumSet<AstPropertiesFlag, int> {}; 186 187 AstProperties() : node_count_(0) { } 188 189 Flags* flags() { return &flags_; } 190 int node_count() { return node_count_; } 191 void add_node_count(int count) { node_count_ += count; } 192 193 private: 194 Flags flags_; 195 int node_count_; 196 }; 197 198 199 class AstNode: public ZoneObject { 200 public: 201 #define DECLARE_TYPE_ENUM(type) k##type, 202 enum NodeType { 203 AST_NODE_LIST(DECLARE_TYPE_ENUM) 204 kInvalid = -1 205 }; 206 #undef DECLARE_TYPE_ENUM 207 208 void* operator new(size_t size, Zone* zone) { 209 return zone->New(static_cast<int>(size)); 210 } 211 212 AstNode() { } 213 214 virtual ~AstNode() { } 215 216 virtual void Accept(AstVisitor* v) = 0; 217 virtual NodeType node_type() const = 0; 218 219 // Type testing & conversion functions overridden by concrete subclasses. 220 #define DECLARE_NODE_FUNCTIONS(type) \ 221 bool Is##type() { return node_type() == AstNode::k##type; } \ 222 type* As##type() { return Is##type() ? reinterpret_cast<type*>(this) : NULL; } 223 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) 224 #undef DECLARE_NODE_FUNCTIONS 225 226 virtual TargetCollector* AsTargetCollector() { return NULL; } 227 virtual BreakableStatement* AsBreakableStatement() { return NULL; } 228 virtual IterationStatement* AsIterationStatement() { return NULL; } 229 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; } 230 231 protected: 232 static int GetNextId(Isolate* isolate) { 233 return ReserveIdRange(isolate, 1); 234 } 235 236 static int ReserveIdRange(Isolate* isolate, int n) { 237 int tmp = isolate->ast_node_id(); 238 isolate->set_ast_node_id(tmp + n); 239 return tmp; 240 } 241 242 // Some nodes re-use bailout IDs for type feedback. 243 static TypeFeedbackId reuse(BailoutId id) { 244 return TypeFeedbackId(id.ToInt()); 245 } 246 247 248 private: 249 // Hidden to prevent accidental usage. It would have to load the 250 // current zone from the TLS. 251 void* operator new(size_t size); 252 253 friend class CaseClause; // Generates AST IDs. 254 }; 255 256 257 class Statement: public AstNode { 258 public: 259 Statement() : statement_pos_(RelocInfo::kNoPosition) {} 260 261 bool IsEmpty() { return AsEmptyStatement() != NULL; } 262 virtual bool IsJump() const { return false; } 263 264 void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; } 265 int statement_pos() const { return statement_pos_; } 266 267 private: 268 int statement_pos_; 269 }; 270 271 272 class SmallMapList { 273 public: 274 SmallMapList() {} 275 SmallMapList(int capacity, Zone* zone) : list_(capacity, zone) {} 276 277 void Reserve(int capacity, Zone* zone) { list_.Reserve(capacity, zone); } 278 void Clear() { list_.Clear(); } 279 void Sort() { list_.Sort(); } 280 281 bool is_empty() const { return list_.is_empty(); } 282 int length() const { return list_.length(); } 283 284 void AddMapIfMissing(Handle<Map> map, Zone* zone) { 285 Map* updated = map->CurrentMapForDeprecated(); 286 if (updated == NULL) return; 287 map = Handle<Map>(updated); 288 for (int i = 0; i < length(); ++i) { 289 if (at(i).is_identical_to(map)) return; 290 } 291 Add(map, zone); 292 } 293 294 void Add(Handle<Map> handle, Zone* zone) { 295 list_.Add(handle.location(), zone); 296 } 297 298 Handle<Map> at(int i) const { 299 return Handle<Map>(list_.at(i)); 300 } 301 302 Handle<Map> first() const { return at(0); } 303 Handle<Map> last() const { return at(length() - 1); } 304 305 private: 306 // The list stores pointers to Map*, that is Map**, so it's GC safe. 307 SmallPointerList<Map*> list_; 308 309 DISALLOW_COPY_AND_ASSIGN(SmallMapList); 310 }; 311 312 313 class Expression: public AstNode { 314 public: 315 enum Context { 316 // Not assigned a context yet, or else will not be visited during 317 // code generation. 318 kUninitialized, 319 // Evaluated for its side effects. 320 kEffect, 321 // Evaluated for its value (and side effects). 322 kValue, 323 // Evaluated for control flow (and side effects). 324 kTest 325 }; 326 327 virtual int position() const { 328 UNREACHABLE(); 329 return 0; 330 } 331 332 virtual bool IsValidLeftHandSide() { return false; } 333 334 // Helpers for ToBoolean conversion. 335 virtual bool ToBooleanIsTrue() { return false; } 336 virtual bool ToBooleanIsFalse() { return false; } 337 338 // Symbols that cannot be parsed as array indices are considered property 339 // names. We do not treat symbols that can be array indexes as property 340 // names because [] for string objects is handled only by keyed ICs. 341 virtual bool IsPropertyName() { return false; } 342 343 // True iff the result can be safely overwritten (to avoid allocation). 344 // False for operations that can return one of their operands. 345 virtual bool ResultOverwriteAllowed() { return false; } 346 347 // True iff the expression is a literal represented as a smi. 348 bool IsSmiLiteral(); 349 350 // True iff the expression is a string literal. 351 bool IsStringLiteral(); 352 353 // True iff the expression is the null literal. 354 bool IsNullLiteral(); 355 356 // True if we can prove that the expression is the undefined literal. 357 bool IsUndefinedLiteral(Isolate* isolate); 358 359 // Expression type bounds 360 Bounds bounds() { return bounds_; } 361 void set_bounds(Bounds bounds) { bounds_ = bounds; } 362 363 // Type feedback information for assignments and properties. 364 virtual bool IsMonomorphic() { 365 UNREACHABLE(); 366 return false; 367 } 368 virtual SmallMapList* GetReceiverTypes() { 369 UNREACHABLE(); 370 return NULL; 371 } 372 Handle<Map> GetMonomorphicReceiverType() { 373 ASSERT(IsMonomorphic()); 374 SmallMapList* types = GetReceiverTypes(); 375 ASSERT(types != NULL && types->length() == 1); 376 return types->at(0); 377 } 378 virtual KeyedAccessStoreMode GetStoreMode() { 379 UNREACHABLE(); 380 return STANDARD_STORE; 381 } 382 383 // TODO(rossberg): this should move to its own AST node eventually. 384 virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle); 385 byte to_boolean_types() const { return to_boolean_types_; } 386 387 BailoutId id() const { return id_; } 388 TypeFeedbackId test_id() const { return test_id_; } 389 390 protected: 391 explicit Expression(Isolate* isolate) 392 : bounds_(Bounds::Unbounded(isolate)), 393 id_(GetNextId(isolate)), 394 test_id_(GetNextId(isolate)) {} 395 void set_to_boolean_types(byte types) { to_boolean_types_ = types; } 396 397 private: 398 Bounds bounds_; 399 byte to_boolean_types_; 400 401 const BailoutId id_; 402 const TypeFeedbackId test_id_; 403 }; 404 405 406 class BreakableStatement: public Statement { 407 public: 408 enum BreakableType { 409 TARGET_FOR_ANONYMOUS, 410 TARGET_FOR_NAMED_ONLY 411 }; 412 413 // The labels associated with this statement. May be NULL; 414 // if it is != NULL, guaranteed to contain at least one entry. 415 ZoneStringList* labels() const { return labels_; } 416 417 // Type testing & conversion. 418 virtual BreakableStatement* AsBreakableStatement() { return this; } 419 420 // Code generation 421 Label* break_target() { return &break_target_; } 422 423 // Testers. 424 bool is_target_for_anonymous() const { 425 return breakable_type_ == TARGET_FOR_ANONYMOUS; 426 } 427 428 BailoutId EntryId() const { return entry_id_; } 429 BailoutId ExitId() const { return exit_id_; } 430 431 protected: 432 BreakableStatement( 433 Isolate* isolate, ZoneStringList* labels, BreakableType breakable_type) 434 : labels_(labels), 435 breakable_type_(breakable_type), 436 entry_id_(GetNextId(isolate)), 437 exit_id_(GetNextId(isolate)) { 438 ASSERT(labels == NULL || labels->length() > 0); 439 } 440 441 442 private: 443 ZoneStringList* labels_; 444 BreakableType breakable_type_; 445 Label break_target_; 446 const BailoutId entry_id_; 447 const BailoutId exit_id_; 448 }; 449 450 451 class Block: public BreakableStatement { 452 public: 453 DECLARE_NODE_TYPE(Block) 454 455 void AddStatement(Statement* statement, Zone* zone) { 456 statements_.Add(statement, zone); 457 } 458 459 ZoneList<Statement*>* statements() { return &statements_; } 460 bool is_initializer_block() const { return is_initializer_block_; } 461 462 virtual bool IsJump() const { 463 return !statements_.is_empty() && statements_.last()->IsJump() 464 && labels() == NULL; // Good enough as an approximation... 465 } 466 467 Scope* scope() const { return scope_; } 468 void set_scope(Scope* scope) { scope_ = scope; } 469 470 protected: 471 Block(Isolate* isolate, 472 ZoneStringList* labels, 473 int capacity, 474 bool is_initializer_block, 475 Zone* zone) 476 : BreakableStatement(isolate, labels, TARGET_FOR_NAMED_ONLY), 477 statements_(capacity, zone), 478 is_initializer_block_(is_initializer_block), 479 scope_(NULL) { 480 } 481 482 private: 483 ZoneList<Statement*> statements_; 484 bool is_initializer_block_; 485 Scope* scope_; 486 }; 487 488 489 class Declaration: public AstNode { 490 public: 491 VariableProxy* proxy() const { return proxy_; } 492 VariableMode mode() const { return mode_; } 493 Scope* scope() const { return scope_; } 494 virtual InitializationFlag initialization() const = 0; 495 virtual bool IsInlineable() const; 496 497 protected: 498 Declaration(VariableProxy* proxy, 499 VariableMode mode, 500 Scope* scope) 501 : proxy_(proxy), 502 mode_(mode), 503 scope_(scope) { 504 ASSERT(IsDeclaredVariableMode(mode)); 505 } 506 507 private: 508 VariableProxy* proxy_; 509 VariableMode mode_; 510 511 // Nested scope from which the declaration originated. 512 Scope* scope_; 513 }; 514 515 516 class VariableDeclaration: public Declaration { 517 public: 518 DECLARE_NODE_TYPE(VariableDeclaration) 519 520 virtual InitializationFlag initialization() const { 521 return mode() == VAR ? kCreatedInitialized : kNeedsInitialization; 522 } 523 524 protected: 525 VariableDeclaration(VariableProxy* proxy, 526 VariableMode mode, 527 Scope* scope) 528 : Declaration(proxy, mode, scope) { 529 } 530 }; 531 532 533 class FunctionDeclaration: public Declaration { 534 public: 535 DECLARE_NODE_TYPE(FunctionDeclaration) 536 537 FunctionLiteral* fun() const { return fun_; } 538 virtual InitializationFlag initialization() const { 539 return kCreatedInitialized; 540 } 541 virtual bool IsInlineable() const; 542 543 protected: 544 FunctionDeclaration(VariableProxy* proxy, 545 VariableMode mode, 546 FunctionLiteral* fun, 547 Scope* scope) 548 : Declaration(proxy, mode, scope), 549 fun_(fun) { 550 // At the moment there are no "const functions" in JavaScript... 551 ASSERT(mode == VAR || mode == LET); 552 ASSERT(fun != NULL); 553 } 554 555 private: 556 FunctionLiteral* fun_; 557 }; 558 559 560 class ModuleDeclaration: public Declaration { 561 public: 562 DECLARE_NODE_TYPE(ModuleDeclaration) 563 564 Module* module() const { return module_; } 565 virtual InitializationFlag initialization() const { 566 return kCreatedInitialized; 567 } 568 569 protected: 570 ModuleDeclaration(VariableProxy* proxy, 571 Module* module, 572 Scope* scope) 573 : Declaration(proxy, MODULE, scope), 574 module_(module) { 575 } 576 577 private: 578 Module* module_; 579 }; 580 581 582 class ImportDeclaration: public Declaration { 583 public: 584 DECLARE_NODE_TYPE(ImportDeclaration) 585 586 Module* module() const { return module_; } 587 virtual InitializationFlag initialization() const { 588 return kCreatedInitialized; 589 } 590 591 protected: 592 ImportDeclaration(VariableProxy* proxy, 593 Module* module, 594 Scope* scope) 595 : Declaration(proxy, LET, scope), 596 module_(module) { 597 } 598 599 private: 600 Module* module_; 601 }; 602 603 604 class ExportDeclaration: public Declaration { 605 public: 606 DECLARE_NODE_TYPE(ExportDeclaration) 607 608 virtual InitializationFlag initialization() const { 609 return kCreatedInitialized; 610 } 611 612 protected: 613 ExportDeclaration(VariableProxy* proxy, Scope* scope) 614 : Declaration(proxy, LET, scope) {} 615 }; 616 617 618 class Module: public AstNode { 619 public: 620 Interface* interface() const { return interface_; } 621 Block* body() const { return body_; } 622 623 protected: 624 explicit Module(Zone* zone) 625 : interface_(Interface::NewModule(zone)), 626 body_(NULL) {} 627 explicit Module(Interface* interface, Block* body = NULL) 628 : interface_(interface), 629 body_(body) {} 630 631 private: 632 Interface* interface_; 633 Block* body_; 634 }; 635 636 637 class ModuleLiteral: public Module { 638 public: 639 DECLARE_NODE_TYPE(ModuleLiteral) 640 641 protected: 642 ModuleLiteral(Block* body, Interface* interface) : Module(interface, body) {} 643 }; 644 645 646 class ModuleVariable: public Module { 647 public: 648 DECLARE_NODE_TYPE(ModuleVariable) 649 650 VariableProxy* proxy() const { return proxy_; } 651 652 protected: 653 inline explicit ModuleVariable(VariableProxy* proxy); 654 655 private: 656 VariableProxy* proxy_; 657 }; 658 659 660 class ModulePath: public Module { 661 public: 662 DECLARE_NODE_TYPE(ModulePath) 663 664 Module* module() const { return module_; } 665 Handle<String> name() const { return name_; } 666 667 protected: 668 ModulePath(Module* module, Handle<String> name, Zone* zone) 669 : Module(zone), 670 module_(module), 671 name_(name) { 672 } 673 674 private: 675 Module* module_; 676 Handle<String> name_; 677 }; 678 679 680 class ModuleUrl: public Module { 681 public: 682 DECLARE_NODE_TYPE(ModuleUrl) 683 684 Handle<String> url() const { return url_; } 685 686 protected: 687 ModuleUrl(Handle<String> url, Zone* zone) 688 : Module(zone), url_(url) { 689 } 690 691 private: 692 Handle<String> url_; 693 }; 694 695 696 class ModuleStatement: public Statement { 697 public: 698 DECLARE_NODE_TYPE(ModuleStatement) 699 700 VariableProxy* proxy() const { return proxy_; } 701 Block* body() const { return body_; } 702 703 protected: 704 ModuleStatement(VariableProxy* proxy, Block* body) 705 : proxy_(proxy), 706 body_(body) { 707 } 708 709 private: 710 VariableProxy* proxy_; 711 Block* body_; 712 }; 713 714 715 class IterationStatement: public BreakableStatement { 716 public: 717 // Type testing & conversion. 718 virtual IterationStatement* AsIterationStatement() { return this; } 719 720 Statement* body() const { return body_; } 721 722 BailoutId OsrEntryId() const { return osr_entry_id_; } 723 virtual BailoutId ContinueId() const = 0; 724 virtual BailoutId StackCheckId() const = 0; 725 726 // Code generation 727 Label* continue_target() { return &continue_target_; } 728 729 protected: 730 IterationStatement(Isolate* isolate, ZoneStringList* labels) 731 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS), 732 body_(NULL), 733 osr_entry_id_(GetNextId(isolate)) { 734 } 735 736 void Initialize(Statement* body) { 737 body_ = body; 738 } 739 740 private: 741 Statement* body_; 742 Label continue_target_; 743 744 const BailoutId osr_entry_id_; 745 }; 746 747 748 class DoWhileStatement: public IterationStatement { 749 public: 750 DECLARE_NODE_TYPE(DoWhileStatement) 751 752 void Initialize(Expression* cond, Statement* body) { 753 IterationStatement::Initialize(body); 754 cond_ = cond; 755 } 756 757 Expression* cond() const { return cond_; } 758 759 // Position where condition expression starts. We need it to make 760 // the loop's condition a breakable location. 761 int condition_position() { return condition_position_; } 762 void set_condition_position(int pos) { condition_position_ = pos; } 763 764 virtual BailoutId ContinueId() const { return continue_id_; } 765 virtual BailoutId StackCheckId() const { return back_edge_id_; } 766 BailoutId BackEdgeId() const { return back_edge_id_; } 767 768 protected: 769 DoWhileStatement(Isolate* isolate, ZoneStringList* labels) 770 : IterationStatement(isolate, labels), 771 cond_(NULL), 772 condition_position_(-1), 773 continue_id_(GetNextId(isolate)), 774 back_edge_id_(GetNextId(isolate)) { 775 } 776 777 private: 778 Expression* cond_; 779 780 int condition_position_; 781 782 const BailoutId continue_id_; 783 const BailoutId back_edge_id_; 784 }; 785 786 787 class WhileStatement: public IterationStatement { 788 public: 789 DECLARE_NODE_TYPE(WhileStatement) 790 791 void Initialize(Expression* cond, Statement* body) { 792 IterationStatement::Initialize(body); 793 cond_ = cond; 794 } 795 796 Expression* cond() const { return cond_; } 797 bool may_have_function_literal() const { 798 return may_have_function_literal_; 799 } 800 void set_may_have_function_literal(bool value) { 801 may_have_function_literal_ = value; 802 } 803 804 virtual BailoutId ContinueId() const { return EntryId(); } 805 virtual BailoutId StackCheckId() const { return body_id_; } 806 BailoutId BodyId() const { return body_id_; } 807 808 protected: 809 WhileStatement(Isolate* isolate, ZoneStringList* labels) 810 : IterationStatement(isolate, labels), 811 cond_(NULL), 812 may_have_function_literal_(true), 813 body_id_(GetNextId(isolate)) { 814 } 815 816 private: 817 Expression* cond_; 818 819 // True if there is a function literal subexpression in the condition. 820 bool may_have_function_literal_; 821 822 const BailoutId body_id_; 823 }; 824 825 826 class ForStatement: public IterationStatement { 827 public: 828 DECLARE_NODE_TYPE(ForStatement) 829 830 void Initialize(Statement* init, 831 Expression* cond, 832 Statement* next, 833 Statement* body) { 834 IterationStatement::Initialize(body); 835 init_ = init; 836 cond_ = cond; 837 next_ = next; 838 } 839 840 Statement* init() const { return init_; } 841 Expression* cond() const { return cond_; } 842 Statement* next() const { return next_; } 843 844 bool may_have_function_literal() const { 845 return may_have_function_literal_; 846 } 847 void set_may_have_function_literal(bool value) { 848 may_have_function_literal_ = value; 849 } 850 851 virtual BailoutId ContinueId() const { return continue_id_; } 852 virtual BailoutId StackCheckId() const { return body_id_; } 853 BailoutId BodyId() const { return body_id_; } 854 855 bool is_fast_smi_loop() { return loop_variable_ != NULL; } 856 Variable* loop_variable() { return loop_variable_; } 857 void set_loop_variable(Variable* var) { loop_variable_ = var; } 858 859 protected: 860 ForStatement(Isolate* isolate, ZoneStringList* labels) 861 : IterationStatement(isolate, labels), 862 init_(NULL), 863 cond_(NULL), 864 next_(NULL), 865 may_have_function_literal_(true), 866 loop_variable_(NULL), 867 continue_id_(GetNextId(isolate)), 868 body_id_(GetNextId(isolate)) { 869 } 870 871 private: 872 Statement* init_; 873 Expression* cond_; 874 Statement* next_; 875 876 // True if there is a function literal subexpression in the condition. 877 bool may_have_function_literal_; 878 Variable* loop_variable_; 879 880 const BailoutId continue_id_; 881 const BailoutId body_id_; 882 }; 883 884 885 class ForEachStatement: public IterationStatement { 886 public: 887 enum VisitMode { 888 ENUMERATE, // for (each in subject) body; 889 ITERATE // for (each of subject) body; 890 }; 891 892 void Initialize(Expression* each, Expression* subject, Statement* body) { 893 IterationStatement::Initialize(body); 894 each_ = each; 895 subject_ = subject; 896 } 897 898 Expression* each() const { return each_; } 899 Expression* subject() const { return subject_; } 900 901 protected: 902 ForEachStatement(Isolate* isolate, ZoneStringList* labels) 903 : IterationStatement(isolate, labels), 904 each_(NULL), 905 subject_(NULL) { 906 } 907 908 private: 909 Expression* each_; 910 Expression* subject_; 911 }; 912 913 914 class ForInStatement: public ForEachStatement { 915 public: 916 DECLARE_NODE_TYPE(ForInStatement) 917 918 Expression* enumerable() const { 919 return subject(); 920 } 921 922 TypeFeedbackId ForInFeedbackId() const { return reuse(PrepareId()); } 923 void RecordTypeFeedback(TypeFeedbackOracle* oracle); 924 enum ForInType { FAST_FOR_IN, SLOW_FOR_IN }; 925 ForInType for_in_type() const { return for_in_type_; } 926 927 BailoutId BodyId() const { return body_id_; } 928 BailoutId PrepareId() const { return prepare_id_; } 929 virtual BailoutId ContinueId() const { return EntryId(); } 930 virtual BailoutId StackCheckId() const { return body_id_; } 931 932 protected: 933 ForInStatement(Isolate* isolate, ZoneStringList* labels) 934 : ForEachStatement(isolate, labels), 935 for_in_type_(SLOW_FOR_IN), 936 body_id_(GetNextId(isolate)), 937 prepare_id_(GetNextId(isolate)) { 938 } 939 940 ForInType for_in_type_; 941 const BailoutId body_id_; 942 const BailoutId prepare_id_; 943 }; 944 945 946 class ForOfStatement: public ForEachStatement { 947 public: 948 DECLARE_NODE_TYPE(ForOfStatement) 949 950 void Initialize(Expression* each, 951 Expression* subject, 952 Statement* body, 953 Expression* assign_iterator, 954 Expression* next_result, 955 Expression* result_done, 956 Expression* assign_each) { 957 ForEachStatement::Initialize(each, subject, body); 958 assign_iterator_ = assign_iterator; 959 next_result_ = next_result; 960 result_done_ = result_done; 961 assign_each_ = assign_each; 962 } 963 964 Expression* iterable() const { 965 return subject(); 966 } 967 968 // var iterator = iterable; 969 Expression* assign_iterator() const { 970 return assign_iterator_; 971 } 972 973 // var result = iterator.next(); 974 Expression* next_result() const { 975 return next_result_; 976 } 977 978 // result.done 979 Expression* result_done() const { 980 return result_done_; 981 } 982 983 // each = result.value 984 Expression* assign_each() const { 985 return assign_each_; 986 } 987 988 virtual BailoutId ContinueId() const { return EntryId(); } 989 virtual BailoutId StackCheckId() const { return BackEdgeId(); } 990 991 BailoutId BackEdgeId() const { return back_edge_id_; } 992 993 protected: 994 ForOfStatement(Isolate* isolate, ZoneStringList* labels) 995 : ForEachStatement(isolate, labels), 996 assign_iterator_(NULL), 997 next_result_(NULL), 998 result_done_(NULL), 999 assign_each_(NULL), 1000 back_edge_id_(GetNextId(isolate)) { 1001 } 1002 1003 Expression* assign_iterator_; 1004 Expression* next_result_; 1005 Expression* result_done_; 1006 Expression* assign_each_; 1007 const BailoutId back_edge_id_; 1008 }; 1009 1010 1011 class ExpressionStatement: public Statement { 1012 public: 1013 DECLARE_NODE_TYPE(ExpressionStatement) 1014 1015 void set_expression(Expression* e) { expression_ = e; } 1016 Expression* expression() const { return expression_; } 1017 virtual bool IsJump() const { return expression_->IsThrow(); } 1018 1019 protected: 1020 explicit ExpressionStatement(Expression* expression) 1021 : expression_(expression) { } 1022 1023 private: 1024 Expression* expression_; 1025 }; 1026 1027 1028 class JumpStatement: public Statement { 1029 public: 1030 virtual bool IsJump() const { return true; } 1031 1032 protected: 1033 JumpStatement() {} 1034 }; 1035 1036 1037 class ContinueStatement: public JumpStatement { 1038 public: 1039 DECLARE_NODE_TYPE(ContinueStatement) 1040 1041 IterationStatement* target() const { return target_; } 1042 1043 protected: 1044 explicit ContinueStatement(IterationStatement* target) 1045 : target_(target) { } 1046 1047 private: 1048 IterationStatement* target_; 1049 }; 1050 1051 1052 class BreakStatement: public JumpStatement { 1053 public: 1054 DECLARE_NODE_TYPE(BreakStatement) 1055 1056 BreakableStatement* target() const { return target_; } 1057 1058 protected: 1059 explicit BreakStatement(BreakableStatement* target) 1060 : target_(target) { } 1061 1062 private: 1063 BreakableStatement* target_; 1064 }; 1065 1066 1067 class ReturnStatement: public JumpStatement { 1068 public: 1069 DECLARE_NODE_TYPE(ReturnStatement) 1070 1071 Expression* expression() const { return expression_; } 1072 1073 protected: 1074 explicit ReturnStatement(Expression* expression) 1075 : expression_(expression) { } 1076 1077 private: 1078 Expression* expression_; 1079 }; 1080 1081 1082 class WithStatement: public Statement { 1083 public: 1084 DECLARE_NODE_TYPE(WithStatement) 1085 1086 Scope* scope() { return scope_; } 1087 Expression* expression() const { return expression_; } 1088 Statement* statement() const { return statement_; } 1089 1090 protected: 1091 WithStatement(Scope* scope, Expression* expression, Statement* statement) 1092 : scope_(scope), 1093 expression_(expression), 1094 statement_(statement) { } 1095 1096 private: 1097 Scope* scope_; 1098 Expression* expression_; 1099 Statement* statement_; 1100 }; 1101 1102 1103 class CaseClause: public ZoneObject { 1104 public: 1105 CaseClause(Isolate* isolate, 1106 Expression* label, 1107 ZoneList<Statement*>* statements, 1108 int pos); 1109 1110 bool is_default() const { return label_ == NULL; } 1111 Expression* label() const { 1112 CHECK(!is_default()); 1113 return label_; 1114 } 1115 Label* body_target() { return &body_target_; } 1116 ZoneList<Statement*>* statements() const { return statements_; } 1117 1118 int position() const { return position_; } 1119 void set_position(int pos) { position_ = pos; } 1120 1121 BailoutId EntryId() const { return entry_id_; } 1122 1123 // Type feedback information. 1124 TypeFeedbackId CompareId() { return compare_id_; } 1125 void RecordTypeFeedback(TypeFeedbackOracle* oracle); 1126 Handle<Type> compare_type() { return compare_type_; } 1127 1128 private: 1129 Expression* label_; 1130 Label body_target_; 1131 ZoneList<Statement*>* statements_; 1132 int position_; 1133 Handle<Type> compare_type_; 1134 1135 const TypeFeedbackId compare_id_; 1136 const BailoutId entry_id_; 1137 }; 1138 1139 1140 class SwitchStatement: public BreakableStatement { 1141 public: 1142 DECLARE_NODE_TYPE(SwitchStatement) 1143 1144 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) { 1145 tag_ = tag; 1146 cases_ = cases; 1147 switch_type_ = UNKNOWN_SWITCH; 1148 } 1149 1150 Expression* tag() const { return tag_; } 1151 ZoneList<CaseClause*>* cases() const { return cases_; } 1152 1153 enum SwitchType { UNKNOWN_SWITCH, SMI_SWITCH, STRING_SWITCH, GENERIC_SWITCH }; 1154 SwitchType switch_type() const { return switch_type_; } 1155 void set_switch_type(SwitchType switch_type) { switch_type_ = switch_type; } 1156 1157 protected: 1158 SwitchStatement(Isolate* isolate, ZoneStringList* labels) 1159 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS), 1160 tag_(NULL), 1161 cases_(NULL) { } 1162 1163 private: 1164 Expression* tag_; 1165 ZoneList<CaseClause*>* cases_; 1166 SwitchType switch_type_; 1167 }; 1168 1169 1170 // If-statements always have non-null references to their then- and 1171 // else-parts. When parsing if-statements with no explicit else-part, 1172 // the parser implicitly creates an empty statement. Use the 1173 // HasThenStatement() and HasElseStatement() functions to check if a 1174 // given if-statement has a then- or an else-part containing code. 1175 class IfStatement: public Statement { 1176 public: 1177 DECLARE_NODE_TYPE(IfStatement) 1178 1179 bool HasThenStatement() const { return !then_statement()->IsEmpty(); } 1180 bool HasElseStatement() const { return !else_statement()->IsEmpty(); } 1181 1182 Expression* condition() const { return condition_; } 1183 Statement* then_statement() const { return then_statement_; } 1184 Statement* else_statement() const { return else_statement_; } 1185 1186 virtual bool IsJump() const { 1187 return HasThenStatement() && then_statement()->IsJump() 1188 && HasElseStatement() && else_statement()->IsJump(); 1189 } 1190 1191 BailoutId IfId() const { return if_id_; } 1192 BailoutId ThenId() const { return then_id_; } 1193 BailoutId ElseId() const { return else_id_; } 1194 1195 protected: 1196 IfStatement(Isolate* isolate, 1197 Expression* condition, 1198 Statement* then_statement, 1199 Statement* else_statement) 1200 : condition_(condition), 1201 then_statement_(then_statement), 1202 else_statement_(else_statement), 1203 if_id_(GetNextId(isolate)), 1204 then_id_(GetNextId(isolate)), 1205 else_id_(GetNextId(isolate)) { 1206 } 1207 1208 private: 1209 Expression* condition_; 1210 Statement* then_statement_; 1211 Statement* else_statement_; 1212 const BailoutId if_id_; 1213 const BailoutId then_id_; 1214 const BailoutId else_id_; 1215 }; 1216 1217 1218 // NOTE: TargetCollectors are represented as nodes to fit in the target 1219 // stack in the compiler; this should probably be reworked. 1220 class TargetCollector: public AstNode { 1221 public: 1222 explicit TargetCollector(Zone* zone) : targets_(0, zone) { } 1223 1224 // Adds a jump target to the collector. The collector stores a pointer not 1225 // a copy of the target to make binding work, so make sure not to pass in 1226 // references to something on the stack. 1227 void AddTarget(Label* target, Zone* zone); 1228 1229 // Virtual behaviour. TargetCollectors are never part of the AST. 1230 virtual void Accept(AstVisitor* v) { UNREACHABLE(); } 1231 virtual NodeType node_type() const { return kInvalid; } 1232 virtual TargetCollector* AsTargetCollector() { return this; } 1233 1234 ZoneList<Label*>* targets() { return &targets_; } 1235 1236 private: 1237 ZoneList<Label*> targets_; 1238 }; 1239 1240 1241 class TryStatement: public Statement { 1242 public: 1243 void set_escaping_targets(ZoneList<Label*>* targets) { 1244 escaping_targets_ = targets; 1245 } 1246 1247 int index() const { return index_; } 1248 Block* try_block() const { return try_block_; } 1249 ZoneList<Label*>* escaping_targets() const { return escaping_targets_; } 1250 1251 protected: 1252 TryStatement(int index, Block* try_block) 1253 : index_(index), 1254 try_block_(try_block), 1255 escaping_targets_(NULL) { } 1256 1257 private: 1258 // Unique (per-function) index of this handler. This is not an AST ID. 1259 int index_; 1260 1261 Block* try_block_; 1262 ZoneList<Label*>* escaping_targets_; 1263 }; 1264 1265 1266 class TryCatchStatement: public TryStatement { 1267 public: 1268 DECLARE_NODE_TYPE(TryCatchStatement) 1269 1270 Scope* scope() { return scope_; } 1271 Variable* variable() { return variable_; } 1272 Block* catch_block() const { return catch_block_; } 1273 1274 protected: 1275 TryCatchStatement(int index, 1276 Block* try_block, 1277 Scope* scope, 1278 Variable* variable, 1279 Block* catch_block) 1280 : TryStatement(index, try_block), 1281 scope_(scope), 1282 variable_(variable), 1283 catch_block_(catch_block) { 1284 } 1285 1286 private: 1287 Scope* scope_; 1288 Variable* variable_; 1289 Block* catch_block_; 1290 }; 1291 1292 1293 class TryFinallyStatement: public TryStatement { 1294 public: 1295 DECLARE_NODE_TYPE(TryFinallyStatement) 1296 1297 Block* finally_block() const { return finally_block_; } 1298 1299 protected: 1300 TryFinallyStatement(int index, Block* try_block, Block* finally_block) 1301 : TryStatement(index, try_block), 1302 finally_block_(finally_block) { } 1303 1304 private: 1305 Block* finally_block_; 1306 }; 1307 1308 1309 class DebuggerStatement: public Statement { 1310 public: 1311 DECLARE_NODE_TYPE(DebuggerStatement) 1312 1313 protected: 1314 DebuggerStatement() {} 1315 }; 1316 1317 1318 class EmptyStatement: public Statement { 1319 public: 1320 DECLARE_NODE_TYPE(EmptyStatement) 1321 1322 protected: 1323 EmptyStatement() {} 1324 }; 1325 1326 1327 class Literal: public Expression { 1328 public: 1329 DECLARE_NODE_TYPE(Literal) 1330 1331 virtual bool IsPropertyName() { 1332 if (value_->IsInternalizedString()) { 1333 uint32_t ignored; 1334 return !String::cast(*value_)->AsArrayIndex(&ignored); 1335 } 1336 return false; 1337 } 1338 1339 Handle<String> AsPropertyName() { 1340 ASSERT(IsPropertyName()); 1341 return Handle<String>::cast(value_); 1342 } 1343 1344 virtual bool ToBooleanIsTrue() { return value_->BooleanValue(); } 1345 virtual bool ToBooleanIsFalse() { return !value_->BooleanValue(); } 1346 1347 // Identity testers. 1348 bool IsNull() const { 1349 ASSERT(!value_.is_null()); 1350 return value_->IsNull(); 1351 } 1352 bool IsTrue() const { 1353 ASSERT(!value_.is_null()); 1354 return value_->IsTrue(); 1355 } 1356 bool IsFalse() const { 1357 ASSERT(!value_.is_null()); 1358 return value_->IsFalse(); 1359 } 1360 1361 Handle<Object> value() const { return value_; } 1362 1363 // Support for using Literal as a HashMap key. NOTE: Currently, this works 1364 // only for string and number literals! 1365 uint32_t Hash() { return ToString()->Hash(); } 1366 1367 static bool Match(void* literal1, void* literal2) { 1368 Handle<String> s1 = static_cast<Literal*>(literal1)->ToString(); 1369 Handle<String> s2 = static_cast<Literal*>(literal2)->ToString(); 1370 return s1->Equals(*s2); 1371 } 1372 1373 TypeFeedbackId LiteralFeedbackId() const { return reuse(id()); } 1374 1375 protected: 1376 Literal(Isolate* isolate, Handle<Object> value) 1377 : Expression(isolate), 1378 value_(value) { } 1379 1380 private: 1381 Handle<String> ToString(); 1382 1383 Handle<Object> value_; 1384 }; 1385 1386 1387 // Base class for literals that needs space in the corresponding JSFunction. 1388 class MaterializedLiteral: public Expression { 1389 public: 1390 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; } 1391 1392 int literal_index() { return literal_index_; } 1393 1394 // A materialized literal is simple if the values consist of only 1395 // constants and simple object and array literals. 1396 bool is_simple() const { return is_simple_; } 1397 1398 int depth() const { return depth_; } 1399 1400 protected: 1401 MaterializedLiteral(Isolate* isolate, 1402 int literal_index, 1403 bool is_simple, 1404 int depth) 1405 : Expression(isolate), 1406 literal_index_(literal_index), 1407 is_simple_(is_simple), 1408 depth_(depth) {} 1409 1410 private: 1411 int literal_index_; 1412 bool is_simple_; 1413 int depth_; 1414 }; 1415 1416 1417 // Property is used for passing information 1418 // about an object literal's properties from the parser 1419 // to the code generator. 1420 class ObjectLiteralProperty: public ZoneObject { 1421 public: 1422 enum Kind { 1423 CONSTANT, // Property with constant value (compile time). 1424 COMPUTED, // Property with computed value (execution time). 1425 MATERIALIZED_LITERAL, // Property value is a materialized literal. 1426 GETTER, SETTER, // Property is an accessor function. 1427 PROTOTYPE // Property is __proto__. 1428 }; 1429 1430 ObjectLiteralProperty(Literal* key, Expression* value, Isolate* isolate); 1431 1432 Literal* key() { return key_; } 1433 Expression* value() { return value_; } 1434 Kind kind() { return kind_; } 1435 1436 // Type feedback information. 1437 void RecordTypeFeedback(TypeFeedbackOracle* oracle); 1438 bool IsMonomorphic() { return !receiver_type_.is_null(); } 1439 Handle<Map> GetReceiverType() { return receiver_type_; } 1440 1441 bool IsCompileTimeValue(); 1442 1443 void set_emit_store(bool emit_store); 1444 bool emit_store(); 1445 1446 protected: 1447 template<class> friend class AstNodeFactory; 1448 1449 ObjectLiteralProperty(bool is_getter, FunctionLiteral* value); 1450 void set_key(Literal* key) { key_ = key; } 1451 1452 private: 1453 Literal* key_; 1454 Expression* value_; 1455 Kind kind_; 1456 bool emit_store_; 1457 Handle<Map> receiver_type_; 1458 }; 1459 1460 1461 // An object literal has a boilerplate object that is used 1462 // for minimizing the work when constructing it at runtime. 1463 class ObjectLiteral: public MaterializedLiteral { 1464 public: 1465 typedef ObjectLiteralProperty Property; 1466 1467 DECLARE_NODE_TYPE(ObjectLiteral) 1468 1469 Handle<FixedArray> constant_properties() const { 1470 return constant_properties_; 1471 } 1472 ZoneList<Property*>* properties() const { return properties_; } 1473 bool fast_elements() const { return fast_elements_; } 1474 bool may_store_doubles() const { return may_store_doubles_; } 1475 bool has_function() const { return has_function_; } 1476 1477 // Mark all computed expressions that are bound to a key that 1478 // is shadowed by a later occurrence of the same key. For the 1479 // marked expressions, no store code is emitted. 1480 void CalculateEmitStore(Zone* zone); 1481 1482 enum Flags { 1483 kNoFlags = 0, 1484 kFastElements = 1, 1485 kHasFunction = 1 << 1 1486 }; 1487 1488 struct Accessors: public ZoneObject { 1489 Accessors() : getter(NULL), setter(NULL) { } 1490 Expression* getter; 1491 Expression* setter; 1492 }; 1493 1494 protected: 1495 ObjectLiteral(Isolate* isolate, 1496 Handle<FixedArray> constant_properties, 1497 ZoneList<Property*>* properties, 1498 int literal_index, 1499 bool is_simple, 1500 bool fast_elements, 1501 int depth, 1502 bool may_store_doubles, 1503 bool has_function) 1504 : MaterializedLiteral(isolate, literal_index, is_simple, depth), 1505 constant_properties_(constant_properties), 1506 properties_(properties), 1507 fast_elements_(fast_elements), 1508 may_store_doubles_(may_store_doubles), 1509 has_function_(has_function) {} 1510 1511 private: 1512 Handle<FixedArray> constant_properties_; 1513 ZoneList<Property*>* properties_; 1514 bool fast_elements_; 1515 bool may_store_doubles_; 1516 bool has_function_; 1517 }; 1518 1519 1520 // Node for capturing a regexp literal. 1521 class RegExpLiteral: public MaterializedLiteral { 1522 public: 1523 DECLARE_NODE_TYPE(RegExpLiteral) 1524 1525 Handle<String> pattern() const { return pattern_; } 1526 Handle<String> flags() const { return flags_; } 1527 1528 protected: 1529 RegExpLiteral(Isolate* isolate, 1530 Handle<String> pattern, 1531 Handle<String> flags, 1532 int literal_index) 1533 : MaterializedLiteral(isolate, literal_index, false, 1), 1534 pattern_(pattern), 1535 flags_(flags) {} 1536 1537 private: 1538 Handle<String> pattern_; 1539 Handle<String> flags_; 1540 }; 1541 1542 // An array literal has a literals object that is used 1543 // for minimizing the work when constructing it at runtime. 1544 class ArrayLiteral: public MaterializedLiteral { 1545 public: 1546 DECLARE_NODE_TYPE(ArrayLiteral) 1547 1548 Handle<FixedArray> constant_elements() const { return constant_elements_; } 1549 ZoneList<Expression*>* values() const { return values_; } 1550 1551 // Return an AST id for an element that is used in simulate instructions. 1552 BailoutId GetIdForElement(int i) { 1553 return BailoutId(first_element_id_.ToInt() + i); 1554 } 1555 1556 protected: 1557 ArrayLiteral(Isolate* isolate, 1558 Handle<FixedArray> constant_elements, 1559 ZoneList<Expression*>* values, 1560 int literal_index, 1561 bool is_simple, 1562 int depth) 1563 : MaterializedLiteral(isolate, literal_index, is_simple, depth), 1564 constant_elements_(constant_elements), 1565 values_(values), 1566 first_element_id_(ReserveIdRange(isolate, values->length())) {} 1567 1568 private: 1569 Handle<FixedArray> constant_elements_; 1570 ZoneList<Expression*>* values_; 1571 const BailoutId first_element_id_; 1572 }; 1573 1574 1575 class VariableProxy: public Expression { 1576 public: 1577 DECLARE_NODE_TYPE(VariableProxy) 1578 1579 virtual bool IsValidLeftHandSide() { 1580 return var_ == NULL ? true : var_->IsValidLeftHandSide(); 1581 } 1582 1583 bool IsVariable(Handle<String> n) { 1584 return !is_this() && name().is_identical_to(n); 1585 } 1586 1587 bool IsArguments() { return var_ != NULL && var_->is_arguments(); } 1588 1589 bool IsLValue() { 1590 return is_lvalue_; 1591 } 1592 1593 Handle<String> name() const { return name_; } 1594 Variable* var() const { return var_; } 1595 bool is_this() const { return is_this_; } 1596 int position() const { return position_; } 1597 Interface* interface() const { return interface_; } 1598 1599 1600 void MarkAsTrivial() { is_trivial_ = true; } 1601 void MarkAsLValue() { is_lvalue_ = true; } 1602 1603 // Bind this proxy to the variable var. Interfaces must match. 1604 void BindTo(Variable* var); 1605 1606 protected: 1607 VariableProxy(Isolate* isolate, Variable* var); 1608 1609 VariableProxy(Isolate* isolate, 1610 Handle<String> name, 1611 bool is_this, 1612 Interface* interface, 1613 int position); 1614 1615 Handle<String> name_; 1616 Variable* var_; // resolved variable, or NULL 1617 bool is_this_; 1618 bool is_trivial_; 1619 // True if this variable proxy is being used in an assignment 1620 // or with a increment/decrement operator. 1621 bool is_lvalue_; 1622 int position_; 1623 Interface* interface_; 1624 }; 1625 1626 1627 class Property: public Expression { 1628 public: 1629 DECLARE_NODE_TYPE(Property) 1630 1631 virtual bool IsValidLeftHandSide() { return true; } 1632 1633 Expression* obj() const { return obj_; } 1634 Expression* key() const { return key_; } 1635 virtual int position() const { return pos_; } 1636 1637 BailoutId LoadId() const { return load_id_; } 1638 1639 bool IsStringLength() const { return is_string_length_; } 1640 bool IsStringAccess() const { return is_string_access_; } 1641 bool IsFunctionPrototype() const { return is_function_prototype_; } 1642 1643 // Type feedback information. 1644 void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* zone); 1645 virtual bool IsMonomorphic() { return is_monomorphic_; } 1646 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; } 1647 virtual KeyedAccessStoreMode GetStoreMode() { 1648 return STANDARD_STORE; 1649 } 1650 bool IsUninitialized() { return is_uninitialized_; } 1651 TypeFeedbackId PropertyFeedbackId() { return reuse(id()); } 1652 1653 protected: 1654 Property(Isolate* isolate, 1655 Expression* obj, 1656 Expression* key, 1657 int pos) 1658 : Expression(isolate), 1659 obj_(obj), 1660 key_(key), 1661 pos_(pos), 1662 load_id_(GetNextId(isolate)), 1663 is_monomorphic_(false), 1664 is_uninitialized_(false), 1665 is_string_length_(false), 1666 is_string_access_(false), 1667 is_function_prototype_(false) { } 1668 1669 private: 1670 Expression* obj_; 1671 Expression* key_; 1672 int pos_; 1673 const BailoutId load_id_; 1674 1675 SmallMapList receiver_types_; 1676 bool is_monomorphic_ : 1; 1677 bool is_uninitialized_ : 1; 1678 bool is_string_length_ : 1; 1679 bool is_string_access_ : 1; 1680 bool is_function_prototype_ : 1; 1681 }; 1682 1683 1684 class Call: public Expression { 1685 public: 1686 DECLARE_NODE_TYPE(Call) 1687 1688 Expression* expression() const { return expression_; } 1689 ZoneList<Expression*>* arguments() const { return arguments_; } 1690 virtual int position() const { return pos_; } 1691 1692 // Type feedback information. 1693 TypeFeedbackId CallFeedbackId() const { return reuse(id()); } 1694 void RecordTypeFeedback(TypeFeedbackOracle* oracle, CallKind call_kind); 1695 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; } 1696 virtual bool IsMonomorphic() { return is_monomorphic_; } 1697 CheckType check_type() const { return check_type_; } 1698 1699 void set_string_check(Handle<JSObject> holder) { 1700 holder_ = holder; 1701 check_type_ = STRING_CHECK; 1702 } 1703 1704 void set_number_check(Handle<JSObject> holder) { 1705 holder_ = holder; 1706 check_type_ = NUMBER_CHECK; 1707 } 1708 1709 void set_map_check() { 1710 holder_ = Handle<JSObject>::null(); 1711 check_type_ = RECEIVER_MAP_CHECK; 1712 } 1713 1714 Handle<JSFunction> target() { return target_; } 1715 1716 // A cache for the holder, set as a side effect of computing the target of the 1717 // call. Note that it contains the null handle when the receiver is the same 1718 // as the holder! 1719 Handle<JSObject> holder() { return holder_; } 1720 1721 Handle<Cell> cell() { return cell_; } 1722 1723 bool ComputeTarget(Handle<Map> type, Handle<String> name); 1724 bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup); 1725 1726 BailoutId ReturnId() const { return return_id_; } 1727 1728 // TODO(rossberg): this should really move somewhere else (and be merged with 1729 // various similar methods in objets.cc), but for now... 1730 static Handle<JSObject> GetPrototypeForPrimitiveCheck( 1731 CheckType check, Isolate* isolate); 1732 1733 #ifdef DEBUG 1734 // Used to assert that the FullCodeGenerator records the return site. 1735 bool return_is_recorded_; 1736 #endif 1737 1738 protected: 1739 Call(Isolate* isolate, 1740 Expression* expression, 1741 ZoneList<Expression*>* arguments, 1742 int pos) 1743 : Expression(isolate), 1744 expression_(expression), 1745 arguments_(arguments), 1746 pos_(pos), 1747 is_monomorphic_(false), 1748 check_type_(RECEIVER_MAP_CHECK), 1749 return_id_(GetNextId(isolate)) { } 1750 1751 private: 1752 Expression* expression_; 1753 ZoneList<Expression*>* arguments_; 1754 int pos_; 1755 1756 bool is_monomorphic_; 1757 CheckType check_type_; 1758 SmallMapList receiver_types_; 1759 Handle<JSFunction> target_; 1760 Handle<JSObject> holder_; 1761 Handle<Cell> cell_; 1762 1763 const BailoutId return_id_; 1764 }; 1765 1766 1767 class CallNew: public Expression { 1768 public: 1769 DECLARE_NODE_TYPE(CallNew) 1770 1771 Expression* expression() const { return expression_; } 1772 ZoneList<Expression*>* arguments() const { return arguments_; } 1773 virtual int position() const { return pos_; } 1774 1775 // Type feedback information. 1776 TypeFeedbackId CallNewFeedbackId() const { return reuse(id()); } 1777 void RecordTypeFeedback(TypeFeedbackOracle* oracle); 1778 virtual bool IsMonomorphic() { return is_monomorphic_; } 1779 Handle<JSFunction> target() const { return target_; } 1780 ElementsKind elements_kind() const { return elements_kind_; } 1781 Handle<Cell> allocation_info_cell() const { 1782 return allocation_info_cell_; 1783 } 1784 1785 BailoutId ReturnId() const { return return_id_; } 1786 1787 protected: 1788 CallNew(Isolate* isolate, 1789 Expression* expression, 1790 ZoneList<Expression*>* arguments, 1791 int pos) 1792 : Expression(isolate), 1793 expression_(expression), 1794 arguments_(arguments), 1795 pos_(pos), 1796 is_monomorphic_(false), 1797 elements_kind_(GetInitialFastElementsKind()), 1798 return_id_(GetNextId(isolate)) { } 1799 1800 private: 1801 Expression* expression_; 1802 ZoneList<Expression*>* arguments_; 1803 int pos_; 1804 1805 bool is_monomorphic_; 1806 Handle<JSFunction> target_; 1807 ElementsKind elements_kind_; 1808 Handle<Cell> allocation_info_cell_; 1809 1810 const BailoutId return_id_; 1811 }; 1812 1813 1814 // The CallRuntime class does not represent any official JavaScript 1815 // language construct. Instead it is used to call a C or JS function 1816 // with a set of arguments. This is used from the builtins that are 1817 // implemented in JavaScript (see "v8natives.js"). 1818 class CallRuntime: public Expression { 1819 public: 1820 DECLARE_NODE_TYPE(CallRuntime) 1821 1822 Handle<String> name() const { return name_; } 1823 const Runtime::Function* function() const { return function_; } 1824 ZoneList<Expression*>* arguments() const { return arguments_; } 1825 bool is_jsruntime() const { return function_ == NULL; } 1826 1827 TypeFeedbackId CallRuntimeFeedbackId() const { return reuse(id()); } 1828 1829 protected: 1830 CallRuntime(Isolate* isolate, 1831 Handle<String> name, 1832 const Runtime::Function* function, 1833 ZoneList<Expression*>* arguments) 1834 : Expression(isolate), 1835 name_(name), 1836 function_(function), 1837 arguments_(arguments) { } 1838 1839 private: 1840 Handle<String> name_; 1841 const Runtime::Function* function_; 1842 ZoneList<Expression*>* arguments_; 1843 }; 1844 1845 1846 class UnaryOperation: public Expression { 1847 public: 1848 DECLARE_NODE_TYPE(UnaryOperation) 1849 1850 Token::Value op() const { return op_; } 1851 Expression* expression() const { return expression_; } 1852 virtual int position() const { return pos_; } 1853 1854 BailoutId MaterializeTrueId() { return materialize_true_id_; } 1855 BailoutId MaterializeFalseId() { return materialize_false_id_; } 1856 1857 virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle); 1858 1859 protected: 1860 UnaryOperation(Isolate* isolate, 1861 Token::Value op, 1862 Expression* expression, 1863 int pos) 1864 : Expression(isolate), 1865 op_(op), 1866 expression_(expression), 1867 pos_(pos), 1868 materialize_true_id_(GetNextId(isolate)), 1869 materialize_false_id_(GetNextId(isolate)) { 1870 ASSERT(Token::IsUnaryOp(op)); 1871 } 1872 1873 private: 1874 Token::Value op_; 1875 Expression* expression_; 1876 int pos_; 1877 1878 // For unary not (Token::NOT), the AST ids where true and false will 1879 // actually be materialized, respectively. 1880 const BailoutId materialize_true_id_; 1881 const BailoutId materialize_false_id_; 1882 }; 1883 1884 1885 class BinaryOperation: public Expression { 1886 public: 1887 DECLARE_NODE_TYPE(BinaryOperation) 1888 1889 virtual bool ResultOverwriteAllowed(); 1890 1891 Token::Value op() const { return op_; } 1892 Expression* left() const { return left_; } 1893 Expression* right() const { return right_; } 1894 virtual int position() const { return pos_; } 1895 1896 BailoutId RightId() const { return right_id_; } 1897 1898 TypeFeedbackId BinaryOperationFeedbackId() const { return reuse(id()); } 1899 Maybe<int> fixed_right_arg() const { return fixed_right_arg_; } 1900 void set_fixed_right_arg(Maybe<int> arg) { fixed_right_arg_ = arg; } 1901 1902 virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle); 1903 1904 protected: 1905 BinaryOperation(Isolate* isolate, 1906 Token::Value op, 1907 Expression* left, 1908 Expression* right, 1909 int pos) 1910 : Expression(isolate), 1911 op_(op), 1912 left_(left), 1913 right_(right), 1914 pos_(pos), 1915 right_id_(GetNextId(isolate)) { 1916 ASSERT(Token::IsBinaryOp(op)); 1917 } 1918 1919 private: 1920 Token::Value op_; 1921 Expression* left_; 1922 Expression* right_; 1923 int pos_; 1924 1925 // TODO(rossberg): the fixed arg should probably be represented as a Constant 1926 // type for the RHS. 1927 Maybe<int> fixed_right_arg_; 1928 1929 // The short-circuit logical operations need an AST ID for their 1930 // right-hand subexpression. 1931 const BailoutId right_id_; 1932 }; 1933 1934 1935 class CountOperation: public Expression { 1936 public: 1937 DECLARE_NODE_TYPE(CountOperation) 1938 1939 bool is_prefix() const { return is_prefix_; } 1940 bool is_postfix() const { return !is_prefix_; } 1941 1942 Token::Value op() const { return op_; } 1943 Token::Value binary_op() { 1944 return (op() == Token::INC) ? Token::ADD : Token::SUB; 1945 } 1946 1947 Expression* expression() const { return expression_; } 1948 virtual int position() const { return pos_; } 1949 1950 virtual void MarkAsStatement() { is_prefix_ = true; } 1951 1952 void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* znoe); 1953 virtual bool IsMonomorphic() { return is_monomorphic_; } 1954 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; } 1955 virtual KeyedAccessStoreMode GetStoreMode() { 1956 return store_mode_; 1957 } 1958 TypeInfo type() const { return type_; } 1959 1960 BailoutId AssignmentId() const { return assignment_id_; } 1961 1962 TypeFeedbackId CountBinOpFeedbackId() const { return count_id_; } 1963 TypeFeedbackId CountStoreFeedbackId() const { return reuse(id()); } 1964 1965 protected: 1966 CountOperation(Isolate* isolate, 1967 Token::Value op, 1968 bool is_prefix, 1969 Expression* expr, 1970 int pos) 1971 : Expression(isolate), 1972 op_(op), 1973 is_prefix_(is_prefix), 1974 is_monomorphic_(false), 1975 store_mode_(STANDARD_STORE), 1976 expression_(expr), 1977 pos_(pos), 1978 assignment_id_(GetNextId(isolate)), 1979 count_id_(GetNextId(isolate)) {} 1980 1981 private: 1982 Token::Value op_; 1983 bool is_prefix_ : 1; 1984 bool is_monomorphic_ : 1; 1985 KeyedAccessStoreMode store_mode_ : 5; // Windows treats as signed, 1986 // must have extra bit. 1987 TypeInfo type_; 1988 1989 Expression* expression_; 1990 int pos_; 1991 const BailoutId assignment_id_; 1992 const TypeFeedbackId count_id_; 1993 SmallMapList receiver_types_; 1994 }; 1995 1996 1997 class CompareOperation: public Expression { 1998 public: 1999 DECLARE_NODE_TYPE(CompareOperation) 2000 2001 Token::Value op() const { return op_; } 2002 Expression* left() const { return left_; } 2003 Expression* right() const { return right_; } 2004 virtual int position() const { return pos_; } 2005 2006 // Type feedback information. 2007 TypeFeedbackId CompareOperationFeedbackId() const { return reuse(id()); } 2008 Handle<Type> combined_type() const { return combined_type_; } 2009 void set_combined_type(Handle<Type> type) { combined_type_ = type; } 2010 2011 // Match special cases. 2012 bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check); 2013 bool IsLiteralCompareUndefined(Expression** expr, Isolate* isolate); 2014 bool IsLiteralCompareNull(Expression** expr); 2015 2016 protected: 2017 CompareOperation(Isolate* isolate, 2018 Token::Value op, 2019 Expression* left, 2020 Expression* right, 2021 int pos) 2022 : Expression(isolate), 2023 op_(op), 2024 left_(left), 2025 right_(right), 2026 pos_(pos) { 2027 ASSERT(Token::IsCompareOp(op)); 2028 } 2029 2030 private: 2031 Token::Value op_; 2032 Expression* left_; 2033 Expression* right_; 2034 int pos_; 2035 2036 Handle<Type> combined_type_; 2037 }; 2038 2039 2040 class Conditional: public Expression { 2041 public: 2042 DECLARE_NODE_TYPE(Conditional) 2043 2044 Expression* condition() const { return condition_; } 2045 Expression* then_expression() const { return then_expression_; } 2046 Expression* else_expression() const { return else_expression_; } 2047 2048 int then_expression_position() const { return then_expression_position_; } 2049 int else_expression_position() const { return else_expression_position_; } 2050 2051 BailoutId ThenId() const { return then_id_; } 2052 BailoutId ElseId() const { return else_id_; } 2053 2054 protected: 2055 Conditional(Isolate* isolate, 2056 Expression* condition, 2057 Expression* then_expression, 2058 Expression* else_expression, 2059 int then_expression_position, 2060 int else_expression_position) 2061 : Expression(isolate), 2062 condition_(condition), 2063 then_expression_(then_expression), 2064 else_expression_(else_expression), 2065 then_expression_position_(then_expression_position), 2066 else_expression_position_(else_expression_position), 2067 then_id_(GetNextId(isolate)), 2068 else_id_(GetNextId(isolate)) { } 2069 2070 private: 2071 Expression* condition_; 2072 Expression* then_expression_; 2073 Expression* else_expression_; 2074 int then_expression_position_; 2075 int else_expression_position_; 2076 const BailoutId then_id_; 2077 const BailoutId else_id_; 2078 }; 2079 2080 2081 class Assignment: public Expression { 2082 public: 2083 DECLARE_NODE_TYPE(Assignment) 2084 2085 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; } 2086 2087 Token::Value binary_op() const; 2088 2089 Token::Value op() const { return op_; } 2090 Expression* target() const { return target_; } 2091 Expression* value() const { return value_; } 2092 virtual int position() const { return pos_; } 2093 BinaryOperation* binary_operation() const { return binary_operation_; } 2094 2095 // This check relies on the definition order of token in token.h. 2096 bool is_compound() const { return op() > Token::ASSIGN; } 2097 2098 BailoutId AssignmentId() const { return assignment_id_; } 2099 2100 // Type feedback information. 2101 TypeFeedbackId AssignmentFeedbackId() { return reuse(id()); } 2102 void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* zone); 2103 virtual bool IsMonomorphic() { return is_monomorphic_; } 2104 bool IsUninitialized() { return is_uninitialized_; } 2105 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; } 2106 virtual KeyedAccessStoreMode GetStoreMode() { 2107 return store_mode_; 2108 } 2109 2110 protected: 2111 Assignment(Isolate* isolate, 2112 Token::Value op, 2113 Expression* target, 2114 Expression* value, 2115 int pos); 2116 2117 template<class Visitor> 2118 void Init(Isolate* isolate, AstNodeFactory<Visitor>* factory) { 2119 ASSERT(Token::IsAssignmentOp(op_)); 2120 if (is_compound()) { 2121 binary_operation_ = 2122 factory->NewBinaryOperation(binary_op(), target_, value_, pos_ + 1); 2123 } 2124 } 2125 2126 private: 2127 Token::Value op_; 2128 Expression* target_; 2129 Expression* value_; 2130 int pos_; 2131 BinaryOperation* binary_operation_; 2132 const BailoutId assignment_id_; 2133 2134 bool is_monomorphic_ : 1; 2135 bool is_uninitialized_ : 1; 2136 KeyedAccessStoreMode store_mode_ : 5; // Windows treats as signed, 2137 // must have extra bit. 2138 SmallMapList receiver_types_; 2139 }; 2140 2141 2142 class Yield: public Expression { 2143 public: 2144 DECLARE_NODE_TYPE(Yield) 2145 2146 enum Kind { 2147 INITIAL, // The initial yield that returns the unboxed generator object. 2148 SUSPEND, // A normal yield: { value: EXPRESSION, done: false } 2149 DELEGATING, // A yield*. 2150 FINAL // A return: { value: EXPRESSION, done: true } 2151 }; 2152 2153 Expression* generator_object() const { return generator_object_; } 2154 Expression* expression() const { return expression_; } 2155 Kind yield_kind() const { return yield_kind_; } 2156 virtual int position() const { return pos_; } 2157 2158 // Delegating yield surrounds the "yield" in a "try/catch". This index 2159 // locates the catch handler in the handler table, and is equivalent to 2160 // TryCatchStatement::index(). 2161 int index() const { 2162 ASSERT(yield_kind() == DELEGATING); 2163 return index_; 2164 } 2165 void set_index(int index) { 2166 ASSERT(yield_kind() == DELEGATING); 2167 index_ = index; 2168 } 2169 2170 protected: 2171 Yield(Isolate* isolate, 2172 Expression* generator_object, 2173 Expression* expression, 2174 Kind yield_kind, 2175 int pos) 2176 : Expression(isolate), 2177 generator_object_(generator_object), 2178 expression_(expression), 2179 yield_kind_(yield_kind), 2180 index_(-1), 2181 pos_(pos) { } 2182 2183 private: 2184 Expression* generator_object_; 2185 Expression* expression_; 2186 Kind yield_kind_; 2187 int index_; 2188 int pos_; 2189 }; 2190 2191 2192 class Throw: public Expression { 2193 public: 2194 DECLARE_NODE_TYPE(Throw) 2195 2196 Expression* exception() const { return exception_; } 2197 virtual int position() const { return pos_; } 2198 2199 protected: 2200 Throw(Isolate* isolate, Expression* exception, int pos) 2201 : Expression(isolate), exception_(exception), pos_(pos) {} 2202 2203 private: 2204 Expression* exception_; 2205 int pos_; 2206 }; 2207 2208 2209 class FunctionLiteral: public Expression { 2210 public: 2211 enum FunctionType { 2212 ANONYMOUS_EXPRESSION, 2213 NAMED_EXPRESSION, 2214 DECLARATION 2215 }; 2216 2217 enum ParameterFlag { 2218 kNoDuplicateParameters = 0, 2219 kHasDuplicateParameters = 1 2220 }; 2221 2222 enum IsFunctionFlag { 2223 kGlobalOrEval, 2224 kIsFunction 2225 }; 2226 2227 enum IsParenthesizedFlag { 2228 kIsParenthesized, 2229 kNotParenthesized 2230 }; 2231 2232 enum IsGeneratorFlag { 2233 kIsGenerator, 2234 kNotGenerator 2235 }; 2236 2237 DECLARE_NODE_TYPE(FunctionLiteral) 2238 2239 Handle<String> name() const { return name_; } 2240 Scope* scope() const { return scope_; } 2241 ZoneList<Statement*>* body() const { return body_; } 2242 void set_function_token_position(int pos) { function_token_position_ = pos; } 2243 int function_token_position() const { return function_token_position_; } 2244 int start_position() const; 2245 int end_position() const; 2246 int SourceSize() const { return end_position() - start_position(); } 2247 bool is_expression() const { return IsExpression::decode(bitfield_); } 2248 bool is_anonymous() const { return IsAnonymous::decode(bitfield_); } 2249 bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; } 2250 LanguageMode language_mode() const; 2251 2252 int materialized_literal_count() { return materialized_literal_count_; } 2253 int expected_property_count() { return expected_property_count_; } 2254 int handler_count() { return handler_count_; } 2255 int parameter_count() { return parameter_count_; } 2256 2257 bool AllowsLazyCompilation(); 2258 bool AllowsLazyCompilationWithoutContext(); 2259 2260 Handle<String> debug_name() const { 2261 if (name_->length() > 0) return name_; 2262 return inferred_name(); 2263 } 2264 2265 Handle<String> inferred_name() const { return inferred_name_; } 2266 void set_inferred_name(Handle<String> inferred_name) { 2267 inferred_name_ = inferred_name; 2268 } 2269 2270 bool pretenure() { return Pretenure::decode(bitfield_); } 2271 void set_pretenure() { bitfield_ |= Pretenure::encode(true); } 2272 2273 bool has_duplicate_parameters() { 2274 return HasDuplicateParameters::decode(bitfield_); 2275 } 2276 2277 bool is_function() { return IsFunction::decode(bitfield_) == kIsFunction; } 2278 2279 // This is used as a heuristic on when to eagerly compile a function 2280 // literal. We consider the following constructs as hints that the 2281 // function will be called immediately: 2282 // - (function() { ... })(); 2283 // - var x = function() { ... }(); 2284 bool is_parenthesized() { 2285 return IsParenthesized::decode(bitfield_) == kIsParenthesized; 2286 } 2287 void set_parenthesized() { 2288 bitfield_ = IsParenthesized::update(bitfield_, kIsParenthesized); 2289 } 2290 2291 bool is_generator() { 2292 return IsGenerator::decode(bitfield_) == kIsGenerator; 2293 } 2294 2295 int ast_node_count() { return ast_properties_.node_count(); } 2296 AstProperties::Flags* flags() { return ast_properties_.flags(); } 2297 void set_ast_properties(AstProperties* ast_properties) { 2298 ast_properties_ = *ast_properties; 2299 } 2300 2301 protected: 2302 FunctionLiteral(Isolate* isolate, 2303 Handle<String> name, 2304 Scope* scope, 2305 ZoneList<Statement*>* body, 2306 int materialized_literal_count, 2307 int expected_property_count, 2308 int handler_count, 2309 int parameter_count, 2310 FunctionType function_type, 2311 ParameterFlag has_duplicate_parameters, 2312 IsFunctionFlag is_function, 2313 IsParenthesizedFlag is_parenthesized, 2314 IsGeneratorFlag is_generator) 2315 : Expression(isolate), 2316 name_(name), 2317 scope_(scope), 2318 body_(body), 2319 inferred_name_(isolate->factory()->empty_string()), 2320 materialized_literal_count_(materialized_literal_count), 2321 expected_property_count_(expected_property_count), 2322 handler_count_(handler_count), 2323 parameter_count_(parameter_count), 2324 function_token_position_(RelocInfo::kNoPosition) { 2325 bitfield_ = 2326 IsExpression::encode(function_type != DECLARATION) | 2327 IsAnonymous::encode(function_type == ANONYMOUS_EXPRESSION) | 2328 Pretenure::encode(false) | 2329 HasDuplicateParameters::encode(has_duplicate_parameters) | 2330 IsFunction::encode(is_function) | 2331 IsParenthesized::encode(is_parenthesized) | 2332 IsGenerator::encode(is_generator); 2333 } 2334 2335 private: 2336 Handle<String> name_; 2337 Scope* scope_; 2338 ZoneList<Statement*>* body_; 2339 Handle<String> inferred_name_; 2340 AstProperties ast_properties_; 2341 2342 int materialized_literal_count_; 2343 int expected_property_count_; 2344 int handler_count_; 2345 int parameter_count_; 2346 int function_token_position_; 2347 2348 unsigned bitfield_; 2349 class IsExpression: public BitField<bool, 0, 1> {}; 2350 class IsAnonymous: public BitField<bool, 1, 1> {}; 2351 class Pretenure: public BitField<bool, 2, 1> {}; 2352 class HasDuplicateParameters: public BitField<ParameterFlag, 3, 1> {}; 2353 class IsFunction: public BitField<IsFunctionFlag, 4, 1> {}; 2354 class IsParenthesized: public BitField<IsParenthesizedFlag, 5, 1> {}; 2355 class IsGenerator: public BitField<IsGeneratorFlag, 6, 1> {}; 2356 }; 2357 2358 2359 class SharedFunctionInfoLiteral: public Expression { 2360 public: 2361 DECLARE_NODE_TYPE(SharedFunctionInfoLiteral) 2362 2363 Handle<SharedFunctionInfo> shared_function_info() const { 2364 return shared_function_info_; 2365 } 2366 2367 protected: 2368 SharedFunctionInfoLiteral( 2369 Isolate* isolate, 2370 Handle<SharedFunctionInfo> shared_function_info) 2371 : Expression(isolate), 2372 shared_function_info_(shared_function_info) { } 2373 2374 private: 2375 Handle<SharedFunctionInfo> shared_function_info_; 2376 }; 2377 2378 2379 class ThisFunction: public Expression { 2380 public: 2381 DECLARE_NODE_TYPE(ThisFunction) 2382 2383 protected: 2384 explicit ThisFunction(Isolate* isolate): Expression(isolate) {} 2385 }; 2386 2387 #undef DECLARE_NODE_TYPE 2388 2389 2390 // ---------------------------------------------------------------------------- 2391 // Regular expressions 2392 2393 2394 class RegExpVisitor BASE_EMBEDDED { 2395 public: 2396 virtual ~RegExpVisitor() { } 2397 #define MAKE_CASE(Name) \ 2398 virtual void* Visit##Name(RegExp##Name*, void* data) = 0; 2399 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE) 2400 #undef MAKE_CASE 2401 }; 2402 2403 2404 class RegExpTree: public ZoneObject { 2405 public: 2406 static const int kInfinity = kMaxInt; 2407 virtual ~RegExpTree() { } 2408 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0; 2409 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 2410 RegExpNode* on_success) = 0; 2411 virtual bool IsTextElement() { return false; } 2412 virtual bool IsAnchoredAtStart() { return false; } 2413 virtual bool IsAnchoredAtEnd() { return false; } 2414 virtual int min_match() = 0; 2415 virtual int max_match() = 0; 2416 // Returns the interval of registers used for captures within this 2417 // expression. 2418 virtual Interval CaptureRegisters() { return Interval::Empty(); } 2419 virtual void AppendToText(RegExpText* text, Zone* zone); 2420 SmartArrayPointer<const char> ToString(Zone* zone); 2421 #define MAKE_ASTYPE(Name) \ 2422 virtual RegExp##Name* As##Name(); \ 2423 virtual bool Is##Name(); 2424 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE) 2425 #undef MAKE_ASTYPE 2426 }; 2427 2428 2429 class RegExpDisjunction: public RegExpTree { 2430 public: 2431 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives); 2432 virtual void* Accept(RegExpVisitor* visitor, void* data); 2433 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 2434 RegExpNode* on_success); 2435 virtual RegExpDisjunction* AsDisjunction(); 2436 virtual Interval CaptureRegisters(); 2437 virtual bool IsDisjunction(); 2438 virtual bool IsAnchoredAtStart(); 2439 virtual bool IsAnchoredAtEnd(); 2440 virtual int min_match() { return min_match_; } 2441 virtual int max_match() { return max_match_; } 2442 ZoneList<RegExpTree*>* alternatives() { return alternatives_; } 2443 private: 2444 ZoneList<RegExpTree*>* alternatives_; 2445 int min_match_; 2446 int max_match_; 2447 }; 2448 2449 2450 class RegExpAlternative: public RegExpTree { 2451 public: 2452 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes); 2453 virtual void* Accept(RegExpVisitor* visitor, void* data); 2454 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 2455 RegExpNode* on_success); 2456 virtual RegExpAlternative* AsAlternative(); 2457 virtual Interval CaptureRegisters(); 2458 virtual bool IsAlternative(); 2459 virtual bool IsAnchoredAtStart(); 2460 virtual bool IsAnchoredAtEnd(); 2461 virtual int min_match() { return min_match_; } 2462 virtual int max_match() { return max_match_; } 2463 ZoneList<RegExpTree*>* nodes() { return nodes_; } 2464 private: 2465 ZoneList<RegExpTree*>* nodes_; 2466 int min_match_; 2467 int max_match_; 2468 }; 2469 2470 2471 class RegExpAssertion: public RegExpTree { 2472 public: 2473 enum AssertionType { 2474 START_OF_LINE, 2475 START_OF_INPUT, 2476 END_OF_LINE, 2477 END_OF_INPUT, 2478 BOUNDARY, 2479 NON_BOUNDARY 2480 }; 2481 explicit RegExpAssertion(AssertionType type) : assertion_type_(type) { } 2482 virtual void* Accept(RegExpVisitor* visitor, void* data); 2483 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 2484 RegExpNode* on_success); 2485 virtual RegExpAssertion* AsAssertion(); 2486 virtual bool IsAssertion(); 2487 virtual bool IsAnchoredAtStart(); 2488 virtual bool IsAnchoredAtEnd(); 2489 virtual int min_match() { return 0; } 2490 virtual int max_match() { return 0; } 2491 AssertionType assertion_type() { return assertion_type_; } 2492 private: 2493 AssertionType assertion_type_; 2494 }; 2495 2496 2497 class CharacterSet BASE_EMBEDDED { 2498 public: 2499 explicit CharacterSet(uc16 standard_set_type) 2500 : ranges_(NULL), 2501 standard_set_type_(standard_set_type) {} 2502 explicit CharacterSet(ZoneList<CharacterRange>* ranges) 2503 : ranges_(ranges), 2504 standard_set_type_(0) {} 2505 ZoneList<CharacterRange>* ranges(Zone* zone); 2506 uc16 standard_set_type() { return standard_set_type_; } 2507 void set_standard_set_type(uc16 special_set_type) { 2508 standard_set_type_ = special_set_type; 2509 } 2510 bool is_standard() { return standard_set_type_ != 0; } 2511 void Canonicalize(); 2512 private: 2513 ZoneList<CharacterRange>* ranges_; 2514 // If non-zero, the value represents a standard set (e.g., all whitespace 2515 // characters) without having to expand the ranges. 2516 uc16 standard_set_type_; 2517 }; 2518 2519 2520 class RegExpCharacterClass: public RegExpTree { 2521 public: 2522 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated) 2523 : set_(ranges), 2524 is_negated_(is_negated) { } 2525 explicit RegExpCharacterClass(uc16 type) 2526 : set_(type), 2527 is_negated_(false) { } 2528 virtual void* Accept(RegExpVisitor* visitor, void* data); 2529 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 2530 RegExpNode* on_success); 2531 virtual RegExpCharacterClass* AsCharacterClass(); 2532 virtual bool IsCharacterClass(); 2533 virtual bool IsTextElement() { return true; } 2534 virtual int min_match() { return 1; } 2535 virtual int max_match() { return 1; } 2536 virtual void AppendToText(RegExpText* text, Zone* zone); 2537 CharacterSet character_set() { return set_; } 2538 // TODO(lrn): Remove need for complex version if is_standard that 2539 // recognizes a mangled standard set and just do { return set_.is_special(); } 2540 bool is_standard(Zone* zone); 2541 // Returns a value representing the standard character set if is_standard() 2542 // returns true. 2543 // Currently used values are: 2544 // s : unicode whitespace 2545 // S : unicode non-whitespace 2546 // w : ASCII word character (digit, letter, underscore) 2547 // W : non-ASCII word character 2548 // d : ASCII digit 2549 // D : non-ASCII digit 2550 // . : non-unicode non-newline 2551 // * : All characters 2552 uc16 standard_type() { return set_.standard_set_type(); } 2553 ZoneList<CharacterRange>* ranges(Zone* zone) { return set_.ranges(zone); } 2554 bool is_negated() { return is_negated_; } 2555 2556 private: 2557 CharacterSet set_; 2558 bool is_negated_; 2559 }; 2560 2561 2562 class RegExpAtom: public RegExpTree { 2563 public: 2564 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { } 2565 virtual void* Accept(RegExpVisitor* visitor, void* data); 2566 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 2567 RegExpNode* on_success); 2568 virtual RegExpAtom* AsAtom(); 2569 virtual bool IsAtom(); 2570 virtual bool IsTextElement() { return true; } 2571 virtual int min_match() { return data_.length(); } 2572 virtual int max_match() { return data_.length(); } 2573 virtual void AppendToText(RegExpText* text, Zone* zone); 2574 Vector<const uc16> data() { return data_; } 2575 int length() { return data_.length(); } 2576 private: 2577 Vector<const uc16> data_; 2578 }; 2579 2580 2581 class RegExpText: public RegExpTree { 2582 public: 2583 explicit RegExpText(Zone* zone) : elements_(2, zone), length_(0) {} 2584 virtual void* Accept(RegExpVisitor* visitor, void* data); 2585 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 2586 RegExpNode* on_success); 2587 virtual RegExpText* AsText(); 2588 virtual bool IsText(); 2589 virtual bool IsTextElement() { return true; } 2590 virtual int min_match() { return length_; } 2591 virtual int max_match() { return length_; } 2592 virtual void AppendToText(RegExpText* text, Zone* zone); 2593 void AddElement(TextElement elm, Zone* zone) { 2594 elements_.Add(elm, zone); 2595 length_ += elm.length(); 2596 } 2597 ZoneList<TextElement>* elements() { return &elements_; } 2598 private: 2599 ZoneList<TextElement> elements_; 2600 int length_; 2601 }; 2602 2603 2604 class RegExpQuantifier: public RegExpTree { 2605 public: 2606 enum QuantifierType { GREEDY, NON_GREEDY, POSSESSIVE }; 2607 RegExpQuantifier(int min, int max, QuantifierType type, RegExpTree* body) 2608 : body_(body), 2609 min_(min), 2610 max_(max), 2611 min_match_(min * body->min_match()), 2612 quantifier_type_(type) { 2613 if (max > 0 && body->max_match() > kInfinity / max) { 2614 max_match_ = kInfinity; 2615 } else { 2616 max_match_ = max * body->max_match(); 2617 } 2618 } 2619 virtual void* Accept(RegExpVisitor* visitor, void* data); 2620 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 2621 RegExpNode* on_success); 2622 static RegExpNode* ToNode(int min, 2623 int max, 2624 bool is_greedy, 2625 RegExpTree* body, 2626 RegExpCompiler* compiler, 2627 RegExpNode* on_success, 2628 bool not_at_start = false); 2629 virtual RegExpQuantifier* AsQuantifier(); 2630 virtual Interval CaptureRegisters(); 2631 virtual bool IsQuantifier(); 2632 virtual int min_match() { return min_match_; } 2633 virtual int max_match() { return max_match_; } 2634 int min() { return min_; } 2635 int max() { return max_; } 2636 bool is_possessive() { return quantifier_type_ == POSSESSIVE; } 2637 bool is_non_greedy() { return quantifier_type_ == NON_GREEDY; } 2638 bool is_greedy() { return quantifier_type_ == GREEDY; } 2639 RegExpTree* body() { return body_; } 2640 2641 private: 2642 RegExpTree* body_; 2643 int min_; 2644 int max_; 2645 int min_match_; 2646 int max_match_; 2647 QuantifierType quantifier_type_; 2648 }; 2649 2650 2651 class RegExpCapture: public RegExpTree { 2652 public: 2653 explicit RegExpCapture(RegExpTree* body, int index) 2654 : body_(body), index_(index) { } 2655 virtual void* Accept(RegExpVisitor* visitor, void* data); 2656 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 2657 RegExpNode* on_success); 2658 static RegExpNode* ToNode(RegExpTree* body, 2659 int index, 2660 RegExpCompiler* compiler, 2661 RegExpNode* on_success); 2662 virtual RegExpCapture* AsCapture(); 2663 virtual bool IsAnchoredAtStart(); 2664 virtual bool IsAnchoredAtEnd(); 2665 virtual Interval CaptureRegisters(); 2666 virtual bool IsCapture(); 2667 virtual int min_match() { return body_->min_match(); } 2668 virtual int max_match() { return body_->max_match(); } 2669 RegExpTree* body() { return body_; } 2670 int index() { return index_; } 2671 static int StartRegister(int index) { return index * 2; } 2672 static int EndRegister(int index) { return index * 2 + 1; } 2673 2674 private: 2675 RegExpTree* body_; 2676 int index_; 2677 }; 2678 2679 2680 class RegExpLookahead: public RegExpTree { 2681 public: 2682 RegExpLookahead(RegExpTree* body, 2683 bool is_positive, 2684 int capture_count, 2685 int capture_from) 2686 : body_(body), 2687 is_positive_(is_positive), 2688 capture_count_(capture_count), 2689 capture_from_(capture_from) { } 2690 2691 virtual void* Accept(RegExpVisitor* visitor, void* data); 2692 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 2693 RegExpNode* on_success); 2694 virtual RegExpLookahead* AsLookahead(); 2695 virtual Interval CaptureRegisters(); 2696 virtual bool IsLookahead(); 2697 virtual bool IsAnchoredAtStart(); 2698 virtual int min_match() { return 0; } 2699 virtual int max_match() { return 0; } 2700 RegExpTree* body() { return body_; } 2701 bool is_positive() { return is_positive_; } 2702 int capture_count() { return capture_count_; } 2703 int capture_from() { return capture_from_; } 2704 2705 private: 2706 RegExpTree* body_; 2707 bool is_positive_; 2708 int capture_count_; 2709 int capture_from_; 2710 }; 2711 2712 2713 class RegExpBackReference: public RegExpTree { 2714 public: 2715 explicit RegExpBackReference(RegExpCapture* capture) 2716 : capture_(capture) { } 2717 virtual void* Accept(RegExpVisitor* visitor, void* data); 2718 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 2719 RegExpNode* on_success); 2720 virtual RegExpBackReference* AsBackReference(); 2721 virtual bool IsBackReference(); 2722 virtual int min_match() { return 0; } 2723 virtual int max_match() { return capture_->max_match(); } 2724 int index() { return capture_->index(); } 2725 RegExpCapture* capture() { return capture_; } 2726 private: 2727 RegExpCapture* capture_; 2728 }; 2729 2730 2731 class RegExpEmpty: public RegExpTree { 2732 public: 2733 RegExpEmpty() { } 2734 virtual void* Accept(RegExpVisitor* visitor, void* data); 2735 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 2736 RegExpNode* on_success); 2737 virtual RegExpEmpty* AsEmpty(); 2738 virtual bool IsEmpty(); 2739 virtual int min_match() { return 0; } 2740 virtual int max_match() { return 0; } 2741 static RegExpEmpty* GetInstance() { 2742 static RegExpEmpty* instance = ::new RegExpEmpty(); 2743 return instance; 2744 } 2745 }; 2746 2747 2748 // ---------------------------------------------------------------------------- 2749 // Out-of-line inline constructors (to side-step cyclic dependencies). 2750 2751 inline ModuleVariable::ModuleVariable(VariableProxy* proxy) 2752 : Module(proxy->interface()), 2753 proxy_(proxy) { 2754 } 2755 2756 2757 // ---------------------------------------------------------------------------- 2758 // Basic visitor 2759 // - leaf node visitors are abstract. 2760 2761 class AstVisitor BASE_EMBEDDED { 2762 public: 2763 AstVisitor() {} 2764 virtual ~AstVisitor() { } 2765 2766 // Stack overflow check and dynamic dispatch. 2767 virtual void Visit(AstNode* node) = 0; 2768 2769 // Iteration left-to-right. 2770 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations); 2771 virtual void VisitStatements(ZoneList<Statement*>* statements); 2772 virtual void VisitExpressions(ZoneList<Expression*>* expressions); 2773 2774 // Individual AST nodes. 2775 #define DEF_VISIT(type) \ 2776 virtual void Visit##type(type* node) = 0; 2777 AST_NODE_LIST(DEF_VISIT) 2778 #undef DEF_VISIT 2779 }; 2780 2781 2782 #define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS() \ 2783 public: \ 2784 virtual void Visit(AstNode* node) { \ 2785 if (!CheckStackOverflow()) node->Accept(this); \ 2786 } \ 2787 \ 2788 void SetStackOverflow() { stack_overflow_ = true; } \ 2789 void ClearStackOverflow() { stack_overflow_ = false; } \ 2790 bool HasStackOverflow() const { return stack_overflow_; } \ 2791 \ 2792 bool CheckStackOverflow() { \ 2793 if (stack_overflow_) return true; \ 2794 StackLimitCheck check(isolate_); \ 2795 if (!check.HasOverflowed()) return false; \ 2796 return (stack_overflow_ = true); \ 2797 } \ 2798 \ 2799 private: \ 2800 void InitializeAstVisitor() { \ 2801 isolate_ = Isolate::Current(); \ 2802 stack_overflow_ = false; \ 2803 } \ 2804 Isolate* isolate() { return isolate_; } \ 2805 \ 2806 Isolate* isolate_; \ 2807 bool stack_overflow_ 2808 2809 2810 // ---------------------------------------------------------------------------- 2811 // Construction time visitor. 2812 2813 class AstConstructionVisitor BASE_EMBEDDED { 2814 public: 2815 AstConstructionVisitor() { } 2816 2817 AstProperties* ast_properties() { return &properties_; } 2818 2819 private: 2820 template<class> friend class AstNodeFactory; 2821 2822 // Node visitors. 2823 #define DEF_VISIT(type) \ 2824 void Visit##type(type* node); 2825 AST_NODE_LIST(DEF_VISIT) 2826 #undef DEF_VISIT 2827 2828 void increase_node_count() { properties_.add_node_count(1); } 2829 void add_flag(AstPropertiesFlag flag) { properties_.flags()->Add(flag); } 2830 2831 AstProperties properties_; 2832 }; 2833 2834 2835 class AstNullVisitor BASE_EMBEDDED { 2836 public: 2837 // Node visitors. 2838 #define DEF_VISIT(type) \ 2839 void Visit##type(type* node) {} 2840 AST_NODE_LIST(DEF_VISIT) 2841 #undef DEF_VISIT 2842 }; 2843 2844 2845 2846 // ---------------------------------------------------------------------------- 2847 // AstNode factory 2848 2849 template<class Visitor> 2850 class AstNodeFactory BASE_EMBEDDED { 2851 public: 2852 AstNodeFactory(Isolate* isolate, Zone* zone) 2853 : isolate_(isolate), 2854 zone_(zone) { } 2855 2856 Visitor* visitor() { return &visitor_; } 2857 2858 #define VISIT_AND_RETURN(NodeType, node) \ 2859 visitor_.Visit##NodeType((node)); \ 2860 return node; 2861 2862 VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy, 2863 VariableMode mode, 2864 Scope* scope) { 2865 VariableDeclaration* decl = 2866 new(zone_) VariableDeclaration(proxy, mode, scope); 2867 VISIT_AND_RETURN(VariableDeclaration, decl) 2868 } 2869 2870 FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy, 2871 VariableMode mode, 2872 FunctionLiteral* fun, 2873 Scope* scope) { 2874 FunctionDeclaration* decl = 2875 new(zone_) FunctionDeclaration(proxy, mode, fun, scope); 2876 VISIT_AND_RETURN(FunctionDeclaration, decl) 2877 } 2878 2879 ModuleDeclaration* NewModuleDeclaration(VariableProxy* proxy, 2880 Module* module, 2881 Scope* scope) { 2882 ModuleDeclaration* decl = 2883 new(zone_) ModuleDeclaration(proxy, module, scope); 2884 VISIT_AND_RETURN(ModuleDeclaration, decl) 2885 } 2886 2887 ImportDeclaration* NewImportDeclaration(VariableProxy* proxy, 2888 Module* module, 2889 Scope* scope) { 2890 ImportDeclaration* decl = 2891 new(zone_) ImportDeclaration(proxy, module, scope); 2892 VISIT_AND_RETURN(ImportDeclaration, decl) 2893 } 2894 2895 ExportDeclaration* NewExportDeclaration(VariableProxy* proxy, 2896 Scope* scope) { 2897 ExportDeclaration* decl = 2898 new(zone_) ExportDeclaration(proxy, scope); 2899 VISIT_AND_RETURN(ExportDeclaration, decl) 2900 } 2901 2902 ModuleLiteral* NewModuleLiteral(Block* body, Interface* interface) { 2903 ModuleLiteral* module = new(zone_) ModuleLiteral(body, interface); 2904 VISIT_AND_RETURN(ModuleLiteral, module) 2905 } 2906 2907 ModuleVariable* NewModuleVariable(VariableProxy* proxy) { 2908 ModuleVariable* module = new(zone_) ModuleVariable(proxy); 2909 VISIT_AND_RETURN(ModuleVariable, module) 2910 } 2911 2912 ModulePath* NewModulePath(Module* origin, Handle<String> name) { 2913 ModulePath* module = new(zone_) ModulePath(origin, name, zone_); 2914 VISIT_AND_RETURN(ModulePath, module) 2915 } 2916 2917 ModuleUrl* NewModuleUrl(Handle<String> url) { 2918 ModuleUrl* module = new(zone_) ModuleUrl(url, zone_); 2919 VISIT_AND_RETURN(ModuleUrl, module) 2920 } 2921 2922 Block* NewBlock(ZoneStringList* labels, 2923 int capacity, 2924 bool is_initializer_block) { 2925 Block* block = new(zone_) Block( 2926 isolate_, labels, capacity, is_initializer_block, zone_); 2927 VISIT_AND_RETURN(Block, block) 2928 } 2929 2930 #define STATEMENT_WITH_LABELS(NodeType) \ 2931 NodeType* New##NodeType(ZoneStringList* labels) { \ 2932 NodeType* stmt = new(zone_) NodeType(isolate_, labels); \ 2933 VISIT_AND_RETURN(NodeType, stmt); \ 2934 } 2935 STATEMENT_WITH_LABELS(DoWhileStatement) 2936 STATEMENT_WITH_LABELS(WhileStatement) 2937 STATEMENT_WITH_LABELS(ForStatement) 2938 STATEMENT_WITH_LABELS(SwitchStatement) 2939 #undef STATEMENT_WITH_LABELS 2940 2941 ForEachStatement* NewForEachStatement(ForEachStatement::VisitMode visit_mode, 2942 ZoneStringList* labels) { 2943 switch (visit_mode) { 2944 case ForEachStatement::ENUMERATE: { 2945 ForInStatement* stmt = new(zone_) ForInStatement(isolate_, labels); 2946 VISIT_AND_RETURN(ForInStatement, stmt); 2947 } 2948 case ForEachStatement::ITERATE: { 2949 ForOfStatement* stmt = new(zone_) ForOfStatement(isolate_, labels); 2950 VISIT_AND_RETURN(ForOfStatement, stmt); 2951 } 2952 } 2953 UNREACHABLE(); 2954 return NULL; 2955 } 2956 2957 ModuleStatement* NewModuleStatement(VariableProxy* proxy, Block* body) { 2958 ModuleStatement* stmt = new(zone_) ModuleStatement(proxy, body); 2959 VISIT_AND_RETURN(ModuleStatement, stmt) 2960 } 2961 2962 ExpressionStatement* NewExpressionStatement(Expression* expression) { 2963 ExpressionStatement* stmt = new(zone_) ExpressionStatement(expression); 2964 VISIT_AND_RETURN(ExpressionStatement, stmt) 2965 } 2966 2967 ContinueStatement* NewContinueStatement(IterationStatement* target) { 2968 ContinueStatement* stmt = new(zone_) ContinueStatement(target); 2969 VISIT_AND_RETURN(ContinueStatement, stmt) 2970 } 2971 2972 BreakStatement* NewBreakStatement(BreakableStatement* target) { 2973 BreakStatement* stmt = new(zone_) BreakStatement(target); 2974 VISIT_AND_RETURN(BreakStatement, stmt) 2975 } 2976 2977 ReturnStatement* NewReturnStatement(Expression* expression) { 2978 ReturnStatement* stmt = new(zone_) ReturnStatement(expression); 2979 VISIT_AND_RETURN(ReturnStatement, stmt) 2980 } 2981 2982 WithStatement* NewWithStatement(Scope* scope, 2983 Expression* expression, 2984 Statement* statement) { 2985 WithStatement* stmt = new(zone_) WithStatement( 2986 scope, expression, statement); 2987 VISIT_AND_RETURN(WithStatement, stmt) 2988 } 2989 2990 IfStatement* NewIfStatement(Expression* condition, 2991 Statement* then_statement, 2992 Statement* else_statement) { 2993 IfStatement* stmt = new(zone_) IfStatement( 2994 isolate_, condition, then_statement, else_statement); 2995 VISIT_AND_RETURN(IfStatement, stmt) 2996 } 2997 2998 TryCatchStatement* NewTryCatchStatement(int index, 2999 Block* try_block, 3000 Scope* scope, 3001 Variable* variable, 3002 Block* catch_block) { 3003 TryCatchStatement* stmt = new(zone_) TryCatchStatement( 3004 index, try_block, scope, variable, catch_block); 3005 VISIT_AND_RETURN(TryCatchStatement, stmt) 3006 } 3007 3008 TryFinallyStatement* NewTryFinallyStatement(int index, 3009 Block* try_block, 3010 Block* finally_block) { 3011 TryFinallyStatement* stmt = 3012 new(zone_) TryFinallyStatement(index, try_block, finally_block); 3013 VISIT_AND_RETURN(TryFinallyStatement, stmt) 3014 } 3015 3016 DebuggerStatement* NewDebuggerStatement() { 3017 DebuggerStatement* stmt = new(zone_) DebuggerStatement(); 3018 VISIT_AND_RETURN(DebuggerStatement, stmt) 3019 } 3020 3021 EmptyStatement* NewEmptyStatement() { 3022 return new(zone_) EmptyStatement(); 3023 } 3024 3025 Literal* NewLiteral(Handle<Object> handle) { 3026 Literal* lit = new(zone_) Literal(isolate_, handle); 3027 VISIT_AND_RETURN(Literal, lit) 3028 } 3029 3030 Literal* NewNumberLiteral(double number) { 3031 return NewLiteral(isolate_->factory()->NewNumber(number, TENURED)); 3032 } 3033 3034 ObjectLiteral* NewObjectLiteral( 3035 Handle<FixedArray> constant_properties, 3036 ZoneList<ObjectLiteral::Property*>* properties, 3037 int literal_index, 3038 bool is_simple, 3039 bool fast_elements, 3040 int depth, 3041 bool may_store_doubles, 3042 bool has_function) { 3043 ObjectLiteral* lit = new(zone_) ObjectLiteral( 3044 isolate_, constant_properties, properties, literal_index, 3045 is_simple, fast_elements, depth, may_store_doubles, has_function); 3046 VISIT_AND_RETURN(ObjectLiteral, lit) 3047 } 3048 3049 ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter, 3050 FunctionLiteral* value) { 3051 ObjectLiteral::Property* prop = 3052 new(zone_) ObjectLiteral::Property(is_getter, value); 3053 prop->set_key(NewLiteral(value->name())); 3054 return prop; // Not an AST node, will not be visited. 3055 } 3056 3057 RegExpLiteral* NewRegExpLiteral(Handle<String> pattern, 3058 Handle<String> flags, 3059 int literal_index) { 3060 RegExpLiteral* lit = 3061 new(zone_) RegExpLiteral(isolate_, pattern, flags, literal_index); 3062 VISIT_AND_RETURN(RegExpLiteral, lit); 3063 } 3064 3065 ArrayLiteral* NewArrayLiteral(Handle<FixedArray> constant_elements, 3066 ZoneList<Expression*>* values, 3067 int literal_index, 3068 bool is_simple, 3069 int depth) { 3070 ArrayLiteral* lit = new(zone_) ArrayLiteral( 3071 isolate_, constant_elements, values, literal_index, is_simple, depth); 3072 VISIT_AND_RETURN(ArrayLiteral, lit) 3073 } 3074 3075 VariableProxy* NewVariableProxy(Variable* var) { 3076 VariableProxy* proxy = new(zone_) VariableProxy(isolate_, var); 3077 VISIT_AND_RETURN(VariableProxy, proxy) 3078 } 3079 3080 VariableProxy* NewVariableProxy(Handle<String> name, 3081 bool is_this, 3082 Interface* interface = Interface::NewValue(), 3083 int position = RelocInfo::kNoPosition) { 3084 VariableProxy* proxy = 3085 new(zone_) VariableProxy(isolate_, name, is_this, interface, position); 3086 VISIT_AND_RETURN(VariableProxy, proxy) 3087 } 3088 3089 Property* NewProperty(Expression* obj, Expression* key, int pos) { 3090 Property* prop = new(zone_) Property(isolate_, obj, key, pos); 3091 VISIT_AND_RETURN(Property, prop) 3092 } 3093 3094 Call* NewCall(Expression* expression, 3095 ZoneList<Expression*>* arguments, 3096 int pos) { 3097 Call* call = new(zone_) Call(isolate_, expression, arguments, pos); 3098 VISIT_AND_RETURN(Call, call) 3099 } 3100 3101 CallNew* NewCallNew(Expression* expression, 3102 ZoneList<Expression*>* arguments, 3103 int pos) { 3104 CallNew* call = new(zone_) CallNew(isolate_, expression, arguments, pos); 3105 VISIT_AND_RETURN(CallNew, call) 3106 } 3107 3108 CallRuntime* NewCallRuntime(Handle<String> name, 3109 const Runtime::Function* function, 3110 ZoneList<Expression*>* arguments) { 3111 CallRuntime* call = 3112 new(zone_) CallRuntime(isolate_, name, function, arguments); 3113 VISIT_AND_RETURN(CallRuntime, call) 3114 } 3115 3116 UnaryOperation* NewUnaryOperation(Token::Value op, 3117 Expression* expression, 3118 int pos) { 3119 UnaryOperation* node = 3120 new(zone_) UnaryOperation(isolate_, op, expression, pos); 3121 VISIT_AND_RETURN(UnaryOperation, node) 3122 } 3123 3124 BinaryOperation* NewBinaryOperation(Token::Value op, 3125 Expression* left, 3126 Expression* right, 3127 int pos) { 3128 BinaryOperation* node = 3129 new(zone_) BinaryOperation(isolate_, op, left, right, pos); 3130 VISIT_AND_RETURN(BinaryOperation, node) 3131 } 3132 3133 CountOperation* NewCountOperation(Token::Value op, 3134 bool is_prefix, 3135 Expression* expr, 3136 int pos) { 3137 CountOperation* node = 3138 new(zone_) CountOperation(isolate_, op, is_prefix, expr, pos); 3139 VISIT_AND_RETURN(CountOperation, node) 3140 } 3141 3142 CompareOperation* NewCompareOperation(Token::Value op, 3143 Expression* left, 3144 Expression* right, 3145 int pos) { 3146 CompareOperation* node = 3147 new(zone_) CompareOperation(isolate_, op, left, right, pos); 3148 VISIT_AND_RETURN(CompareOperation, node) 3149 } 3150 3151 Conditional* NewConditional(Expression* condition, 3152 Expression* then_expression, 3153 Expression* else_expression, 3154 int then_expression_position, 3155 int else_expression_position) { 3156 Conditional* cond = new(zone_) Conditional( 3157 isolate_, condition, then_expression, else_expression, 3158 then_expression_position, else_expression_position); 3159 VISIT_AND_RETURN(Conditional, cond) 3160 } 3161 3162 Assignment* NewAssignment(Token::Value op, 3163 Expression* target, 3164 Expression* value, 3165 int pos) { 3166 Assignment* assign = 3167 new(zone_) Assignment(isolate_, op, target, value, pos); 3168 assign->Init(isolate_, this); 3169 VISIT_AND_RETURN(Assignment, assign) 3170 } 3171 3172 Yield* NewYield(Expression *generator_object, 3173 Expression* expression, 3174 Yield::Kind yield_kind, 3175 int pos) { 3176 Yield* yield = new(zone_) Yield( 3177 isolate_, generator_object, expression, yield_kind, pos); 3178 VISIT_AND_RETURN(Yield, yield) 3179 } 3180 3181 Throw* NewThrow(Expression* exception, int pos) { 3182 Throw* t = new(zone_) Throw(isolate_, exception, pos); 3183 VISIT_AND_RETURN(Throw, t) 3184 } 3185 3186 FunctionLiteral* NewFunctionLiteral( 3187 Handle<String> name, 3188 Scope* scope, 3189 ZoneList<Statement*>* body, 3190 int materialized_literal_count, 3191 int expected_property_count, 3192 int handler_count, 3193 int parameter_count, 3194 FunctionLiteral::ParameterFlag has_duplicate_parameters, 3195 FunctionLiteral::FunctionType function_type, 3196 FunctionLiteral::IsFunctionFlag is_function, 3197 FunctionLiteral::IsParenthesizedFlag is_parenthesized, 3198 FunctionLiteral::IsGeneratorFlag is_generator) { 3199 FunctionLiteral* lit = new(zone_) FunctionLiteral( 3200 isolate_, name, scope, body, 3201 materialized_literal_count, expected_property_count, handler_count, 3202 parameter_count, function_type, has_duplicate_parameters, is_function, 3203 is_parenthesized, is_generator); 3204 // Top-level literal doesn't count for the AST's properties. 3205 if (is_function == FunctionLiteral::kIsFunction) { 3206 visitor_.VisitFunctionLiteral(lit); 3207 } 3208 return lit; 3209 } 3210 3211 SharedFunctionInfoLiteral* NewSharedFunctionInfoLiteral( 3212 Handle<SharedFunctionInfo> shared_function_info) { 3213 SharedFunctionInfoLiteral* lit = 3214 new(zone_) SharedFunctionInfoLiteral(isolate_, shared_function_info); 3215 VISIT_AND_RETURN(SharedFunctionInfoLiteral, lit) 3216 } 3217 3218 ThisFunction* NewThisFunction() { 3219 ThisFunction* fun = new(zone_) ThisFunction(isolate_); 3220 VISIT_AND_RETURN(ThisFunction, fun) 3221 } 3222 3223 #undef VISIT_AND_RETURN 3224 3225 private: 3226 Isolate* isolate_; 3227 Zone* zone_; 3228 Visitor visitor_; 3229 }; 3230 3231 3232 } } // namespace v8::internal 3233 3234 #endif // V8_AST_H_ 3235