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