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