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