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