1 // Copyright 2010 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 "execution.h" 32 #include "factory.h" 33 #include "jsregexp.h" 34 #include "jump-target.h" 35 #include "runtime.h" 36 #include "token.h" 37 #include "variables.h" 38 39 namespace v8 { 40 namespace internal { 41 42 // The abstract syntax tree is an intermediate, light-weight 43 // representation of the parsed JavaScript code suitable for 44 // compilation to native code. 45 46 // Nodes are allocated in a separate zone, which allows faster 47 // allocation and constant-time deallocation of the entire syntax 48 // tree. 49 50 51 // ---------------------------------------------------------------------------- 52 // Nodes of the abstract syntax tree. Only concrete classes are 53 // enumerated here. 54 55 #define STATEMENT_NODE_LIST(V) \ 56 V(Block) \ 57 V(ExpressionStatement) \ 58 V(EmptyStatement) \ 59 V(IfStatement) \ 60 V(ContinueStatement) \ 61 V(BreakStatement) \ 62 V(ReturnStatement) \ 63 V(WithEnterStatement) \ 64 V(WithExitStatement) \ 65 V(SwitchStatement) \ 66 V(DoWhileStatement) \ 67 V(WhileStatement) \ 68 V(ForStatement) \ 69 V(ForInStatement) \ 70 V(TryCatchStatement) \ 71 V(TryFinallyStatement) \ 72 V(DebuggerStatement) 73 74 #define EXPRESSION_NODE_LIST(V) \ 75 V(FunctionLiteral) \ 76 V(FunctionBoilerplateLiteral) \ 77 V(Conditional) \ 78 V(Slot) \ 79 V(VariableProxy) \ 80 V(Literal) \ 81 V(RegExpLiteral) \ 82 V(ObjectLiteral) \ 83 V(ArrayLiteral) \ 84 V(CatchExtensionObject) \ 85 V(Assignment) \ 86 V(Throw) \ 87 V(Property) \ 88 V(Call) \ 89 V(CallNew) \ 90 V(CallRuntime) \ 91 V(UnaryOperation) \ 92 V(CountOperation) \ 93 V(BinaryOperation) \ 94 V(CompareOperation) \ 95 V(ThisFunction) 96 97 #define AST_NODE_LIST(V) \ 98 V(Declaration) \ 99 STATEMENT_NODE_LIST(V) \ 100 EXPRESSION_NODE_LIST(V) 101 102 // Forward declarations 103 class TargetCollector; 104 class MaterializedLiteral; 105 class DefinitionInfo; 106 107 #define DEF_FORWARD_DECLARATION(type) class type; 108 AST_NODE_LIST(DEF_FORWARD_DECLARATION) 109 #undef DEF_FORWARD_DECLARATION 110 111 112 // Typedef only introduced to avoid unreadable code. 113 // Please do appreciate the required space in "> >". 114 typedef ZoneList<Handle<String> > ZoneStringList; 115 typedef ZoneList<Handle<Object> > ZoneObjectList; 116 117 118 class AstNode: public ZoneObject { 119 public: ~AstNode()120 virtual ~AstNode() { } 121 virtual void Accept(AstVisitor* v) = 0; 122 123 // Type testing & conversion. AsStatement()124 virtual Statement* AsStatement() { return NULL; } AsExpressionStatement()125 virtual ExpressionStatement* AsExpressionStatement() { return NULL; } AsEmptyStatement()126 virtual EmptyStatement* AsEmptyStatement() { return NULL; } AsExpression()127 virtual Expression* AsExpression() { return NULL; } AsLiteral()128 virtual Literal* AsLiteral() { return NULL; } AsSlot()129 virtual Slot* AsSlot() { return NULL; } AsVariableProxy()130 virtual VariableProxy* AsVariableProxy() { return NULL; } AsProperty()131 virtual Property* AsProperty() { return NULL; } AsCall()132 virtual Call* AsCall() { return NULL; } AsTargetCollector()133 virtual TargetCollector* AsTargetCollector() { return NULL; } AsBreakableStatement()134 virtual BreakableStatement* AsBreakableStatement() { return NULL; } AsIterationStatement()135 virtual IterationStatement* AsIterationStatement() { return NULL; } AsUnaryOperation()136 virtual UnaryOperation* AsUnaryOperation() { return NULL; } AsBinaryOperation()137 virtual BinaryOperation* AsBinaryOperation() { return NULL; } AsAssignment()138 virtual Assignment* AsAssignment() { return NULL; } AsFunctionLiteral()139 virtual FunctionLiteral* AsFunctionLiteral() { return NULL; } AsMaterializedLiteral()140 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; } AsObjectLiteral()141 virtual ObjectLiteral* AsObjectLiteral() { return NULL; } AsArrayLiteral()142 virtual ArrayLiteral* AsArrayLiteral() { return NULL; } AsCompareOperation()143 virtual CompareOperation* AsCompareOperation() { return NULL; } 144 }; 145 146 147 class Statement: public AstNode { 148 public: Statement()149 Statement() : statement_pos_(RelocInfo::kNoPosition) {} 150 AsStatement()151 virtual Statement* AsStatement() { return this; } AsReturnStatement()152 virtual ReturnStatement* AsReturnStatement() { return NULL; } 153 IsEmpty()154 bool IsEmpty() { return AsEmptyStatement() != NULL; } 155 set_statement_pos(int statement_pos)156 void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; } statement_pos()157 int statement_pos() const { return statement_pos_; } 158 159 private: 160 int statement_pos_; 161 }; 162 163 164 class Expression: public AstNode { 165 public: 166 enum Context { 167 // Not assigned a context yet, or else will not be visited during 168 // code generation. 169 kUninitialized, 170 // Evaluated for its side effects. 171 kEffect, 172 // Evaluated for its value (and side effects). 173 kValue, 174 // Evaluated for control flow (and side effects). 175 kTest, 176 // Evaluated for control flow and side effects. Value is also 177 // needed if true. 178 kValueTest, 179 // Evaluated for control flow and side effects. Value is also 180 // needed if false. 181 kTestValue 182 }; 183 184 static const int kNoLabel = -1; 185 Expression()186 Expression() : num_(kNoLabel), def_(NULL), defined_vars_(NULL) {} 187 AsExpression()188 virtual Expression* AsExpression() { return this; } 189 IsValidLeftHandSide()190 virtual bool IsValidLeftHandSide() { return false; } 191 192 // Symbols that cannot be parsed as array indices are considered property 193 // names. We do not treat symbols that can be array indexes as property 194 // names because [] for string objects is handled only by keyed ICs. IsPropertyName()195 virtual bool IsPropertyName() { return false; } 196 197 // True if the expression does not have (evaluated) subexpressions. 198 // Function literals are leaves because their subexpressions are not 199 // evaluated. IsLeaf()200 virtual bool IsLeaf() { return false; } 201 202 // True if the expression has no side effects and is safe to 203 // evaluate out of order. IsTrivial()204 virtual bool IsTrivial() { return false; } 205 206 // Mark the expression as being compiled as an expression 207 // statement. This is used to transform postfix increments to 208 // (faster) prefix increments. MarkAsStatement()209 virtual void MarkAsStatement() { /* do nothing */ } 210 211 // Static type information for this expression. type()212 StaticType* type() { return &type_; } 213 num()214 int num() { return num_; } 215 216 // AST node numbering ordered by evaluation order. set_num(int n)217 void set_num(int n) { num_ = n; } 218 219 // Data flow information. var_def()220 DefinitionInfo* var_def() { return def_; } set_var_def(DefinitionInfo * def)221 void set_var_def(DefinitionInfo* def) { def_ = def; } 222 defined_vars()223 ZoneList<DefinitionInfo*>* defined_vars() { return defined_vars_; } set_defined_vars(ZoneList<DefinitionInfo * > * defined_vars)224 void set_defined_vars(ZoneList<DefinitionInfo*>* defined_vars) { 225 defined_vars_ = defined_vars; 226 } 227 228 private: 229 StaticType type_; 230 int num_; 231 DefinitionInfo* def_; 232 ZoneList<DefinitionInfo*>* defined_vars_; 233 }; 234 235 236 /** 237 * A sentinel used during pre parsing that represents some expression 238 * that is a valid left hand side without having to actually build 239 * the expression. 240 */ 241 class ValidLeftHandSideSentinel: public Expression { 242 public: IsValidLeftHandSide()243 virtual bool IsValidLeftHandSide() { return true; } Accept(AstVisitor * v)244 virtual void Accept(AstVisitor* v) { UNREACHABLE(); } instance()245 static ValidLeftHandSideSentinel* instance() { return &instance_; } 246 private: 247 static ValidLeftHandSideSentinel instance_; 248 }; 249 250 251 class BreakableStatement: public Statement { 252 public: 253 enum Type { 254 TARGET_FOR_ANONYMOUS, 255 TARGET_FOR_NAMED_ONLY 256 }; 257 258 // The labels associated with this statement. May be NULL; 259 // if it is != NULL, guaranteed to contain at least one entry. labels()260 ZoneStringList* labels() const { return labels_; } 261 262 // Type testing & conversion. AsBreakableStatement()263 virtual BreakableStatement* AsBreakableStatement() { return this; } 264 265 // Code generation break_target()266 BreakTarget* break_target() { return &break_target_; } 267 268 // Testers. is_target_for_anonymous()269 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; } 270 271 protected: BreakableStatement(ZoneStringList * labels,Type type)272 BreakableStatement(ZoneStringList* labels, Type type) 273 : labels_(labels), type_(type) { 274 ASSERT(labels == NULL || labels->length() > 0); 275 } 276 277 private: 278 ZoneStringList* labels_; 279 Type type_; 280 BreakTarget break_target_; 281 }; 282 283 284 class Block: public BreakableStatement { 285 public: Block(ZoneStringList * labels,int capacity,bool is_initializer_block)286 Block(ZoneStringList* labels, int capacity, bool is_initializer_block) 287 : BreakableStatement(labels, TARGET_FOR_NAMED_ONLY), 288 statements_(capacity), 289 is_initializer_block_(is_initializer_block) { } 290 291 virtual void Accept(AstVisitor* v); 292 AddStatement(Statement * statement)293 void AddStatement(Statement* statement) { statements_.Add(statement); } 294 statements()295 ZoneList<Statement*>* statements() { return &statements_; } is_initializer_block()296 bool is_initializer_block() const { return is_initializer_block_; } 297 298 private: 299 ZoneList<Statement*> statements_; 300 bool is_initializer_block_; 301 }; 302 303 304 class Declaration: public AstNode { 305 public: Declaration(VariableProxy * proxy,Variable::Mode mode,FunctionLiteral * fun)306 Declaration(VariableProxy* proxy, Variable::Mode mode, FunctionLiteral* fun) 307 : proxy_(proxy), 308 mode_(mode), 309 fun_(fun) { 310 ASSERT(mode == Variable::VAR || mode == Variable::CONST); 311 // At the moment there are no "const functions"'s in JavaScript... 312 ASSERT(fun == NULL || mode == Variable::VAR); 313 } 314 315 virtual void Accept(AstVisitor* v); 316 proxy()317 VariableProxy* proxy() const { return proxy_; } mode()318 Variable::Mode mode() const { return mode_; } fun()319 FunctionLiteral* fun() const { return fun_; } // may be NULL 320 321 private: 322 VariableProxy* proxy_; 323 Variable::Mode mode_; 324 FunctionLiteral* fun_; 325 }; 326 327 328 class IterationStatement: public BreakableStatement { 329 public: 330 // Type testing & conversion. AsIterationStatement()331 virtual IterationStatement* AsIterationStatement() { return this; } 332 body()333 Statement* body() const { return body_; } 334 335 // Code generation continue_target()336 BreakTarget* continue_target() { return &continue_target_; } 337 338 protected: IterationStatement(ZoneStringList * labels)339 explicit IterationStatement(ZoneStringList* labels) 340 : BreakableStatement(labels, TARGET_FOR_ANONYMOUS), body_(NULL) { } 341 Initialize(Statement * body)342 void Initialize(Statement* body) { 343 body_ = body; 344 } 345 346 private: 347 Statement* body_; 348 BreakTarget continue_target_; 349 }; 350 351 352 class DoWhileStatement: public IterationStatement { 353 public: DoWhileStatement(ZoneStringList * labels)354 explicit DoWhileStatement(ZoneStringList* labels) 355 : IterationStatement(labels), cond_(NULL), condition_position_(-1) { 356 } 357 Initialize(Expression * cond,Statement * body)358 void Initialize(Expression* cond, Statement* body) { 359 IterationStatement::Initialize(body); 360 cond_ = cond; 361 } 362 363 virtual void Accept(AstVisitor* v); 364 cond()365 Expression* cond() const { return cond_; } 366 367 // Position where condition expression starts. We need it to make 368 // the loop's condition a breakable location. condition_position()369 int condition_position() { return condition_position_; } set_condition_position(int pos)370 void set_condition_position(int pos) { condition_position_ = pos; } 371 372 private: 373 Expression* cond_; 374 int condition_position_; 375 }; 376 377 378 class WhileStatement: public IterationStatement { 379 public: WhileStatement(ZoneStringList * labels)380 explicit WhileStatement(ZoneStringList* labels) 381 : IterationStatement(labels), 382 cond_(NULL), 383 may_have_function_literal_(true) { 384 } 385 Initialize(Expression * cond,Statement * body)386 void Initialize(Expression* cond, Statement* body) { 387 IterationStatement::Initialize(body); 388 cond_ = cond; 389 } 390 391 virtual void Accept(AstVisitor* v); 392 cond()393 Expression* cond() const { return cond_; } may_have_function_literal()394 bool may_have_function_literal() const { 395 return may_have_function_literal_; 396 } 397 398 private: 399 Expression* cond_; 400 // True if there is a function literal subexpression in the condition. 401 bool may_have_function_literal_; 402 403 friend class AstOptimizer; 404 }; 405 406 407 class ForStatement: public IterationStatement { 408 public: ForStatement(ZoneStringList * labels)409 explicit ForStatement(ZoneStringList* labels) 410 : IterationStatement(labels), 411 init_(NULL), 412 cond_(NULL), 413 next_(NULL), 414 may_have_function_literal_(true) { 415 } 416 Initialize(Statement * init,Expression * cond,Statement * next,Statement * body)417 void Initialize(Statement* init, 418 Expression* cond, 419 Statement* next, 420 Statement* body) { 421 IterationStatement::Initialize(body); 422 init_ = init; 423 cond_ = cond; 424 next_ = next; 425 } 426 427 virtual void Accept(AstVisitor* v); 428 init()429 Statement* init() const { return init_; } cond()430 Expression* cond() const { return cond_; } next()431 Statement* next() const { return next_; } may_have_function_literal()432 bool may_have_function_literal() const { 433 return may_have_function_literal_; 434 } 435 436 private: 437 Statement* init_; 438 Expression* cond_; 439 Statement* next_; 440 // True if there is a function literal subexpression in the condition. 441 bool may_have_function_literal_; 442 443 friend class AstOptimizer; 444 }; 445 446 447 class ForInStatement: public IterationStatement { 448 public: ForInStatement(ZoneStringList * labels)449 explicit ForInStatement(ZoneStringList* labels) 450 : IterationStatement(labels), each_(NULL), enumerable_(NULL) { } 451 Initialize(Expression * each,Expression * enumerable,Statement * body)452 void Initialize(Expression* each, Expression* enumerable, Statement* body) { 453 IterationStatement::Initialize(body); 454 each_ = each; 455 enumerable_ = enumerable; 456 } 457 458 virtual void Accept(AstVisitor* v); 459 each()460 Expression* each() const { return each_; } enumerable()461 Expression* enumerable() const { return enumerable_; } 462 463 private: 464 Expression* each_; 465 Expression* enumerable_; 466 }; 467 468 469 class ExpressionStatement: public Statement { 470 public: ExpressionStatement(Expression * expression)471 explicit ExpressionStatement(Expression* expression) 472 : expression_(expression) { } 473 474 virtual void Accept(AstVisitor* v); 475 476 // Type testing & conversion. AsExpressionStatement()477 virtual ExpressionStatement* AsExpressionStatement() { return this; } 478 set_expression(Expression * e)479 void set_expression(Expression* e) { expression_ = e; } expression()480 Expression* expression() { return expression_; } 481 482 private: 483 Expression* expression_; 484 }; 485 486 487 class ContinueStatement: public Statement { 488 public: ContinueStatement(IterationStatement * target)489 explicit ContinueStatement(IterationStatement* target) 490 : target_(target) { } 491 492 virtual void Accept(AstVisitor* v); 493 target()494 IterationStatement* target() const { return target_; } 495 496 private: 497 IterationStatement* target_; 498 }; 499 500 501 class BreakStatement: public Statement { 502 public: BreakStatement(BreakableStatement * target)503 explicit BreakStatement(BreakableStatement* target) 504 : target_(target) { } 505 506 virtual void Accept(AstVisitor* v); 507 target()508 BreakableStatement* target() const { return target_; } 509 510 private: 511 BreakableStatement* target_; 512 }; 513 514 515 class ReturnStatement: public Statement { 516 public: ReturnStatement(Expression * expression)517 explicit ReturnStatement(Expression* expression) 518 : expression_(expression) { } 519 520 virtual void Accept(AstVisitor* v); 521 522 // Type testing & conversion. AsReturnStatement()523 virtual ReturnStatement* AsReturnStatement() { return this; } 524 expression()525 Expression* expression() { return expression_; } 526 527 private: 528 Expression* expression_; 529 }; 530 531 532 class WithEnterStatement: public Statement { 533 public: WithEnterStatement(Expression * expression,bool is_catch_block)534 explicit WithEnterStatement(Expression* expression, bool is_catch_block) 535 : expression_(expression), is_catch_block_(is_catch_block) { } 536 537 virtual void Accept(AstVisitor* v); 538 expression()539 Expression* expression() const { return expression_; } 540 is_catch_block()541 bool is_catch_block() const { return is_catch_block_; } 542 543 private: 544 Expression* expression_; 545 bool is_catch_block_; 546 }; 547 548 549 class WithExitStatement: public Statement { 550 public: WithExitStatement()551 WithExitStatement() { } 552 553 virtual void Accept(AstVisitor* v); 554 }; 555 556 557 class CaseClause: public ZoneObject { 558 public: CaseClause(Expression * label,ZoneList<Statement * > * statements)559 CaseClause(Expression* label, ZoneList<Statement*>* statements) 560 : label_(label), statements_(statements) { } 561 is_default()562 bool is_default() const { return label_ == NULL; } label()563 Expression* label() const { 564 CHECK(!is_default()); 565 return label_; 566 } body_target()567 JumpTarget* body_target() { return &body_target_; } statements()568 ZoneList<Statement*>* statements() const { return statements_; } 569 570 private: 571 Expression* label_; 572 JumpTarget body_target_; 573 ZoneList<Statement*>* statements_; 574 }; 575 576 577 class SwitchStatement: public BreakableStatement { 578 public: SwitchStatement(ZoneStringList * labels)579 explicit SwitchStatement(ZoneStringList* labels) 580 : BreakableStatement(labels, TARGET_FOR_ANONYMOUS), 581 tag_(NULL), cases_(NULL) { } 582 Initialize(Expression * tag,ZoneList<CaseClause * > * cases)583 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) { 584 tag_ = tag; 585 cases_ = cases; 586 } 587 588 virtual void Accept(AstVisitor* v); 589 tag()590 Expression* tag() const { return tag_; } cases()591 ZoneList<CaseClause*>* cases() const { return cases_; } 592 593 private: 594 Expression* tag_; 595 ZoneList<CaseClause*>* cases_; 596 }; 597 598 599 // If-statements always have non-null references to their then- and 600 // else-parts. When parsing if-statements with no explicit else-part, 601 // the parser implicitly creates an empty statement. Use the 602 // HasThenStatement() and HasElseStatement() functions to check if a 603 // given if-statement has a then- or an else-part containing code. 604 class IfStatement: public Statement { 605 public: IfStatement(Expression * condition,Statement * then_statement,Statement * else_statement)606 IfStatement(Expression* condition, 607 Statement* then_statement, 608 Statement* else_statement) 609 : condition_(condition), 610 then_statement_(then_statement), 611 else_statement_(else_statement) { } 612 613 virtual void Accept(AstVisitor* v); 614 HasThenStatement()615 bool HasThenStatement() const { return !then_statement()->IsEmpty(); } HasElseStatement()616 bool HasElseStatement() const { return !else_statement()->IsEmpty(); } 617 condition()618 Expression* condition() const { return condition_; } then_statement()619 Statement* then_statement() const { return then_statement_; } else_statement()620 Statement* else_statement() const { return else_statement_; } 621 622 private: 623 Expression* condition_; 624 Statement* then_statement_; 625 Statement* else_statement_; 626 }; 627 628 629 // NOTE: TargetCollectors are represented as nodes to fit in the target 630 // stack in the compiler; this should probably be reworked. 631 class TargetCollector: public AstNode { 632 public: TargetCollector(ZoneList<BreakTarget * > * targets)633 explicit TargetCollector(ZoneList<BreakTarget*>* targets) 634 : targets_(targets) { 635 } 636 637 // Adds a jump target to the collector. The collector stores a pointer not 638 // a copy of the target to make binding work, so make sure not to pass in 639 // references to something on the stack. 640 void AddTarget(BreakTarget* target); 641 642 // Virtual behaviour. TargetCollectors are never part of the AST. Accept(AstVisitor * v)643 virtual void Accept(AstVisitor* v) { UNREACHABLE(); } AsTargetCollector()644 virtual TargetCollector* AsTargetCollector() { return this; } 645 targets()646 ZoneList<BreakTarget*>* targets() { return targets_; } 647 648 private: 649 ZoneList<BreakTarget*>* targets_; 650 }; 651 652 653 class TryStatement: public Statement { 654 public: TryStatement(Block * try_block)655 explicit TryStatement(Block* try_block) 656 : try_block_(try_block), escaping_targets_(NULL) { } 657 set_escaping_targets(ZoneList<BreakTarget * > * targets)658 void set_escaping_targets(ZoneList<BreakTarget*>* targets) { 659 escaping_targets_ = targets; 660 } 661 try_block()662 Block* try_block() const { return try_block_; } escaping_targets()663 ZoneList<BreakTarget*>* escaping_targets() const { return escaping_targets_; } 664 665 private: 666 Block* try_block_; 667 ZoneList<BreakTarget*>* escaping_targets_; 668 }; 669 670 671 class TryCatchStatement: public TryStatement { 672 public: TryCatchStatement(Block * try_block,VariableProxy * catch_var,Block * catch_block)673 TryCatchStatement(Block* try_block, 674 VariableProxy* catch_var, 675 Block* catch_block) 676 : TryStatement(try_block), 677 catch_var_(catch_var), 678 catch_block_(catch_block) { 679 } 680 681 virtual void Accept(AstVisitor* v); 682 catch_var()683 VariableProxy* catch_var() const { return catch_var_; } catch_block()684 Block* catch_block() const { return catch_block_; } 685 686 private: 687 VariableProxy* catch_var_; 688 Block* catch_block_; 689 }; 690 691 692 class TryFinallyStatement: public TryStatement { 693 public: TryFinallyStatement(Block * try_block,Block * finally_block)694 TryFinallyStatement(Block* try_block, Block* finally_block) 695 : TryStatement(try_block), 696 finally_block_(finally_block) { } 697 698 virtual void Accept(AstVisitor* v); 699 finally_block()700 Block* finally_block() const { return finally_block_; } 701 702 private: 703 Block* finally_block_; 704 }; 705 706 707 class DebuggerStatement: public Statement { 708 public: 709 virtual void Accept(AstVisitor* v); 710 }; 711 712 713 class EmptyStatement: public Statement { 714 public: 715 virtual void Accept(AstVisitor* v); 716 717 // Type testing & conversion. AsEmptyStatement()718 virtual EmptyStatement* AsEmptyStatement() { return this; } 719 }; 720 721 722 class Literal: public Expression { 723 public: Literal(Handle<Object> handle)724 explicit Literal(Handle<Object> handle) : handle_(handle) { } 725 726 virtual void Accept(AstVisitor* v); 727 728 // Type testing & conversion. AsLiteral()729 virtual Literal* AsLiteral() { return this; } 730 731 // Check if this literal is identical to the other literal. IsIdenticalTo(const Literal * other)732 bool IsIdenticalTo(const Literal* other) const { 733 return handle_.is_identical_to(other->handle_); 734 } 735 IsPropertyName()736 virtual bool IsPropertyName() { 737 if (handle_->IsSymbol()) { 738 uint32_t ignored; 739 return !String::cast(*handle_)->AsArrayIndex(&ignored); 740 } 741 return false; 742 } 743 IsLeaf()744 virtual bool IsLeaf() { return true; } IsTrivial()745 virtual bool IsTrivial() { return true; } 746 747 // Identity testers. IsNull()748 bool IsNull() const { return handle_.is_identical_to(Factory::null_value()); } IsTrue()749 bool IsTrue() const { return handle_.is_identical_to(Factory::true_value()); } IsFalse()750 bool IsFalse() const { 751 return handle_.is_identical_to(Factory::false_value()); 752 } 753 handle()754 Handle<Object> handle() const { return handle_; } 755 756 private: 757 Handle<Object> handle_; 758 }; 759 760 761 // Base class for literals that needs space in the corresponding JSFunction. 762 class MaterializedLiteral: public Expression { 763 public: MaterializedLiteral(int literal_index,bool is_simple,int depth)764 explicit MaterializedLiteral(int literal_index, bool is_simple, int depth) 765 : literal_index_(literal_index), is_simple_(is_simple), depth_(depth) {} 766 AsMaterializedLiteral()767 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; } 768 literal_index()769 int literal_index() { return literal_index_; } 770 771 // A materialized literal is simple if the values consist of only 772 // constants and simple object and array literals. is_simple()773 bool is_simple() const { return is_simple_; } 774 depth()775 int depth() const { return depth_; } 776 777 private: 778 int literal_index_; 779 bool is_simple_; 780 int depth_; 781 }; 782 783 784 // An object literal has a boilerplate object that is used 785 // for minimizing the work when constructing it at runtime. 786 class ObjectLiteral: public MaterializedLiteral { 787 public: 788 // Property is used for passing information 789 // about an object literal's properties from the parser 790 // to the code generator. 791 class Property: public ZoneObject { 792 public: 793 794 enum Kind { 795 CONSTANT, // Property with constant value (compile time). 796 COMPUTED, // Property with computed value (execution time). 797 MATERIALIZED_LITERAL, // Property value is a materialized literal. 798 GETTER, SETTER, // Property is an accessor function. 799 PROTOTYPE // Property is __proto__. 800 }; 801 802 Property(Literal* key, Expression* value); 803 Property(bool is_getter, FunctionLiteral* value); 804 key()805 Literal* key() { return key_; } value()806 Expression* value() { return value_; } kind()807 Kind kind() { return kind_; } 808 809 bool IsCompileTimeValue(); 810 811 private: 812 Literal* key_; 813 Expression* value_; 814 Kind kind_; 815 }; 816 ObjectLiteral(Handle<FixedArray> constant_properties,ZoneList<Property * > * properties,int literal_index,bool is_simple,int depth)817 ObjectLiteral(Handle<FixedArray> constant_properties, 818 ZoneList<Property*>* properties, 819 int literal_index, 820 bool is_simple, 821 int depth) 822 : MaterializedLiteral(literal_index, is_simple, depth), 823 constant_properties_(constant_properties), 824 properties_(properties) {} 825 AsObjectLiteral()826 virtual ObjectLiteral* AsObjectLiteral() { return this; } 827 virtual void Accept(AstVisitor* v); 828 IsLeaf()829 virtual bool IsLeaf() { return properties()->is_empty(); } 830 constant_properties()831 Handle<FixedArray> constant_properties() const { 832 return constant_properties_; 833 } properties()834 ZoneList<Property*>* properties() const { return properties_; } 835 836 private: 837 Handle<FixedArray> constant_properties_; 838 ZoneList<Property*>* properties_; 839 }; 840 841 842 // Node for capturing a regexp literal. 843 class RegExpLiteral: public MaterializedLiteral { 844 public: RegExpLiteral(Handle<String> pattern,Handle<String> flags,int literal_index)845 RegExpLiteral(Handle<String> pattern, 846 Handle<String> flags, 847 int literal_index) 848 : MaterializedLiteral(literal_index, false, 1), 849 pattern_(pattern), 850 flags_(flags) {} 851 852 virtual void Accept(AstVisitor* v); 853 IsLeaf()854 virtual bool IsLeaf() { return true; } 855 pattern()856 Handle<String> pattern() const { return pattern_; } flags()857 Handle<String> flags() const { return flags_; } 858 859 private: 860 Handle<String> pattern_; 861 Handle<String> flags_; 862 }; 863 864 // An array literal has a literals object that is used 865 // for minimizing the work when constructing it at runtime. 866 class ArrayLiteral: public MaterializedLiteral { 867 public: ArrayLiteral(Handle<FixedArray> constant_elements,ZoneList<Expression * > * values,int literal_index,bool is_simple,int depth)868 ArrayLiteral(Handle<FixedArray> constant_elements, 869 ZoneList<Expression*>* values, 870 int literal_index, 871 bool is_simple, 872 int depth) 873 : MaterializedLiteral(literal_index, is_simple, depth), 874 constant_elements_(constant_elements), 875 values_(values) {} 876 877 virtual void Accept(AstVisitor* v); AsArrayLiteral()878 virtual ArrayLiteral* AsArrayLiteral() { return this; } 879 IsLeaf()880 virtual bool IsLeaf() { return values()->is_empty(); } 881 constant_elements()882 Handle<FixedArray> constant_elements() const { return constant_elements_; } values()883 ZoneList<Expression*>* values() const { return values_; } 884 885 private: 886 Handle<FixedArray> constant_elements_; 887 ZoneList<Expression*>* values_; 888 }; 889 890 891 // Node for constructing a context extension object for a catch block. 892 // The catch context extension object has one property, the catch 893 // variable, which should be DontDelete. 894 class CatchExtensionObject: public Expression { 895 public: CatchExtensionObject(Literal * key,VariableProxy * value)896 CatchExtensionObject(Literal* key, VariableProxy* value) 897 : key_(key), value_(value) { 898 } 899 900 virtual void Accept(AstVisitor* v); 901 key()902 Literal* key() const { return key_; } value()903 VariableProxy* value() const { return value_; } 904 905 private: 906 Literal* key_; 907 VariableProxy* value_; 908 }; 909 910 911 class VariableProxy: public Expression { 912 public: 913 virtual void Accept(AstVisitor* v); 914 915 // Type testing & conversion AsProperty()916 virtual Property* AsProperty() { 917 return var_ == NULL ? NULL : var_->AsProperty(); 918 } AsVariableProxy()919 virtual VariableProxy* AsVariableProxy() { return this; } 920 AsVariable()921 Variable* AsVariable() { 922 return this == NULL || var_ == NULL ? NULL : var_->AsVariable(); 923 } 924 IsValidLeftHandSide()925 virtual bool IsValidLeftHandSide() { 926 return var_ == NULL ? true : var_->IsValidLeftHandSide(); 927 } 928 IsLeaf()929 virtual bool IsLeaf() { 930 ASSERT(var_ != NULL); // Variable must be resolved. 931 return var()->is_global() || var()->rewrite()->IsLeaf(); 932 } 933 934 // Reading from a mutable variable is a side effect, but 'this' is 935 // immutable. IsTrivial()936 virtual bool IsTrivial() { return is_this(); } 937 IsVariable(Handle<String> n)938 bool IsVariable(Handle<String> n) { 939 return !is_this() && name().is_identical_to(n); 940 } 941 IsArguments()942 bool IsArguments() { 943 Variable* variable = AsVariable(); 944 return (variable == NULL) ? false : variable->is_arguments(); 945 } 946 name()947 Handle<String> name() const { return name_; } var()948 Variable* var() const { return var_; } var_uses()949 UseCount* var_uses() { return &var_uses_; } obj_uses()950 UseCount* obj_uses() { return &obj_uses_; } is_this()951 bool is_this() const { return is_this_; } inside_with()952 bool inside_with() const { return inside_with_; } 953 954 // Bind this proxy to the variable var. 955 void BindTo(Variable* var); 956 957 protected: 958 Handle<String> name_; 959 Variable* var_; // resolved variable, or NULL 960 bool is_this_; 961 bool inside_with_; 962 963 // VariableProxy usage info. 964 UseCount var_uses_; // uses of the variable value 965 UseCount obj_uses_; // uses of the object the variable points to 966 967 VariableProxy(Handle<String> name, bool is_this, bool inside_with); 968 explicit VariableProxy(bool is_this); 969 970 friend class Scope; 971 }; 972 973 974 class VariableProxySentinel: public VariableProxy { 975 public: IsValidLeftHandSide()976 virtual bool IsValidLeftHandSide() { return !is_this(); } this_proxy()977 static VariableProxySentinel* this_proxy() { return &this_proxy_; } identifier_proxy()978 static VariableProxySentinel* identifier_proxy() { 979 return &identifier_proxy_; 980 } 981 982 private: VariableProxySentinel(bool is_this)983 explicit VariableProxySentinel(bool is_this) : VariableProxy(is_this) { } 984 static VariableProxySentinel this_proxy_; 985 static VariableProxySentinel identifier_proxy_; 986 }; 987 988 989 class Slot: public Expression { 990 public: 991 enum Type { 992 // A slot in the parameter section on the stack. index() is 993 // the parameter index, counting left-to-right, starting at 0. 994 PARAMETER, 995 996 // A slot in the local section on the stack. index() is 997 // the variable index in the stack frame, starting at 0. 998 LOCAL, 999 1000 // An indexed slot in a heap context. index() is the 1001 // variable index in the context object on the heap, 1002 // starting at 0. var()->scope() is the corresponding 1003 // scope. 1004 CONTEXT, 1005 1006 // A named slot in a heap context. var()->name() is the 1007 // variable name in the context object on the heap, 1008 // with lookup starting at the current context. index() 1009 // is invalid. 1010 LOOKUP 1011 }; 1012 Slot(Variable * var,Type type,int index)1013 Slot(Variable* var, Type type, int index) 1014 : var_(var), type_(type), index_(index) { 1015 ASSERT(var != NULL); 1016 } 1017 1018 virtual void Accept(AstVisitor* v); 1019 1020 // Type testing & conversion AsSlot()1021 virtual Slot* AsSlot() { return this; } 1022 IsLeaf()1023 virtual bool IsLeaf() { return true; } 1024 1025 // Accessors var()1026 Variable* var() const { return var_; } type()1027 Type type() const { return type_; } index()1028 int index() const { return index_; } is_arguments()1029 bool is_arguments() const { return var_->is_arguments(); } 1030 1031 private: 1032 Variable* var_; 1033 Type type_; 1034 int index_; 1035 }; 1036 1037 1038 class Property: public Expression { 1039 public: 1040 // Synthetic properties are property lookups introduced by the system, 1041 // to objects that aren't visible to the user. Function calls to synthetic 1042 // properties should use the global object as receiver, not the base object 1043 // of the resolved Reference. 1044 enum Type { NORMAL, SYNTHETIC }; 1045 Property(Expression* obj, Expression* key, int pos, Type type = NORMAL) obj_(obj)1046 : obj_(obj), key_(key), pos_(pos), type_(type) { } 1047 1048 virtual void Accept(AstVisitor* v); 1049 1050 // Type testing & conversion AsProperty()1051 virtual Property* AsProperty() { return this; } 1052 IsValidLeftHandSide()1053 virtual bool IsValidLeftHandSide() { return true; } 1054 obj()1055 Expression* obj() const { return obj_; } key()1056 Expression* key() const { return key_; } position()1057 int position() const { return pos_; } is_synthetic()1058 bool is_synthetic() const { return type_ == SYNTHETIC; } 1059 1060 // Returns a property singleton property access on 'this'. Used 1061 // during preparsing. this_property()1062 static Property* this_property() { return &this_property_; } 1063 1064 private: 1065 Expression* obj_; 1066 Expression* key_; 1067 int pos_; 1068 Type type_; 1069 1070 // Dummy property used during preparsing. 1071 static Property this_property_; 1072 }; 1073 1074 1075 class Call: public Expression { 1076 public: Call(Expression * expression,ZoneList<Expression * > * arguments,int pos)1077 Call(Expression* expression, ZoneList<Expression*>* arguments, int pos) 1078 : expression_(expression), arguments_(arguments), pos_(pos) { } 1079 1080 virtual void Accept(AstVisitor* v); 1081 1082 // Type testing and conversion. AsCall()1083 virtual Call* AsCall() { return this; } 1084 expression()1085 Expression* expression() const { return expression_; } arguments()1086 ZoneList<Expression*>* arguments() const { return arguments_; } position()1087 int position() { return pos_; } 1088 sentinel()1089 static Call* sentinel() { return &sentinel_; } 1090 1091 private: 1092 Expression* expression_; 1093 ZoneList<Expression*>* arguments_; 1094 int pos_; 1095 1096 static Call sentinel_; 1097 }; 1098 1099 1100 class CallNew: public Expression { 1101 public: CallNew(Expression * expression,ZoneList<Expression * > * arguments,int pos)1102 CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos) 1103 : expression_(expression), arguments_(arguments), pos_(pos) { } 1104 1105 virtual void Accept(AstVisitor* v); 1106 expression()1107 Expression* expression() const { return expression_; } arguments()1108 ZoneList<Expression*>* arguments() const { return arguments_; } position()1109 int position() { return pos_; } 1110 1111 private: 1112 Expression* expression_; 1113 ZoneList<Expression*>* arguments_; 1114 int pos_; 1115 }; 1116 1117 1118 // The CallRuntime class does not represent any official JavaScript 1119 // language construct. Instead it is used to call a C or JS function 1120 // with a set of arguments. This is used from the builtins that are 1121 // implemented in JavaScript (see "v8natives.js"). 1122 class CallRuntime: public Expression { 1123 public: CallRuntime(Handle<String> name,Runtime::Function * function,ZoneList<Expression * > * arguments)1124 CallRuntime(Handle<String> name, 1125 Runtime::Function* function, 1126 ZoneList<Expression*>* arguments) 1127 : name_(name), function_(function), arguments_(arguments) { } 1128 1129 virtual void Accept(AstVisitor* v); 1130 name()1131 Handle<String> name() const { return name_; } function()1132 Runtime::Function* function() const { return function_; } arguments()1133 ZoneList<Expression*>* arguments() const { return arguments_; } is_jsruntime()1134 bool is_jsruntime() const { return function_ == NULL; } 1135 1136 private: 1137 Handle<String> name_; 1138 Runtime::Function* function_; 1139 ZoneList<Expression*>* arguments_; 1140 }; 1141 1142 1143 class UnaryOperation: public Expression { 1144 public: UnaryOperation(Token::Value op,Expression * expression)1145 UnaryOperation(Token::Value op, Expression* expression) 1146 : op_(op), expression_(expression) { 1147 ASSERT(Token::IsUnaryOp(op)); 1148 } 1149 1150 virtual void Accept(AstVisitor* v); 1151 1152 // Type testing & conversion AsUnaryOperation()1153 virtual UnaryOperation* AsUnaryOperation() { return this; } 1154 op()1155 Token::Value op() const { return op_; } expression()1156 Expression* expression() const { return expression_; } 1157 1158 private: 1159 Token::Value op_; 1160 Expression* expression_; 1161 }; 1162 1163 1164 class BinaryOperation: public Expression { 1165 public: BinaryOperation(Token::Value op,Expression * left,Expression * right)1166 BinaryOperation(Token::Value op, Expression* left, Expression* right) 1167 : op_(op), left_(left), right_(right) { 1168 ASSERT(Token::IsBinaryOp(op)); 1169 } 1170 1171 virtual void Accept(AstVisitor* v); 1172 1173 // Type testing & conversion AsBinaryOperation()1174 virtual BinaryOperation* AsBinaryOperation() { return this; } 1175 1176 // True iff the result can be safely overwritten (to avoid allocation). 1177 // False for operations that can return one of their operands. ResultOverwriteAllowed()1178 bool ResultOverwriteAllowed() { 1179 switch (op_) { 1180 case Token::COMMA: 1181 case Token::OR: 1182 case Token::AND: 1183 return false; 1184 case Token::BIT_OR: 1185 case Token::BIT_XOR: 1186 case Token::BIT_AND: 1187 case Token::SHL: 1188 case Token::SAR: 1189 case Token::SHR: 1190 case Token::ADD: 1191 case Token::SUB: 1192 case Token::MUL: 1193 case Token::DIV: 1194 case Token::MOD: 1195 return true; 1196 default: 1197 UNREACHABLE(); 1198 } 1199 return false; 1200 } 1201 op()1202 Token::Value op() const { return op_; } left()1203 Expression* left() const { return left_; } right()1204 Expression* right() const { return right_; } 1205 1206 private: 1207 Token::Value op_; 1208 Expression* left_; 1209 Expression* right_; 1210 }; 1211 1212 1213 class CountOperation: public Expression { 1214 public: CountOperation(bool is_prefix,Token::Value op,Expression * expression)1215 CountOperation(bool is_prefix, Token::Value op, Expression* expression) 1216 : is_prefix_(is_prefix), op_(op), expression_(expression) { 1217 ASSERT(Token::IsCountOp(op)); 1218 } 1219 1220 virtual void Accept(AstVisitor* v); 1221 is_prefix()1222 bool is_prefix() const { return is_prefix_; } is_postfix()1223 bool is_postfix() const { return !is_prefix_; } op()1224 Token::Value op() const { return op_; } binary_op()1225 Token::Value binary_op() { 1226 return op_ == Token::INC ? Token::ADD : Token::SUB; 1227 } expression()1228 Expression* expression() const { return expression_; } 1229 MarkAsStatement()1230 virtual void MarkAsStatement() { is_prefix_ = true; } 1231 1232 private: 1233 bool is_prefix_; 1234 Token::Value op_; 1235 Expression* expression_; 1236 }; 1237 1238 1239 class CompareOperation: public Expression { 1240 public: CompareOperation(Token::Value op,Expression * left,Expression * right)1241 CompareOperation(Token::Value op, Expression* left, Expression* right) 1242 : op_(op), left_(left), right_(right), is_for_loop_condition_(false) { 1243 ASSERT(Token::IsCompareOp(op)); 1244 } 1245 1246 virtual void Accept(AstVisitor* v); 1247 op()1248 Token::Value op() const { return op_; } left()1249 Expression* left() const { return left_; } right()1250 Expression* right() const { return right_; } 1251 1252 // Accessors for flag whether this compare operation is hanging of a for loop. is_for_loop_condition()1253 bool is_for_loop_condition() const { return is_for_loop_condition_; } set_is_for_loop_condition()1254 void set_is_for_loop_condition() { is_for_loop_condition_ = true; } 1255 1256 // Type testing & conversion AsCompareOperation()1257 virtual CompareOperation* AsCompareOperation() { return this; } 1258 1259 private: 1260 Token::Value op_; 1261 Expression* left_; 1262 Expression* right_; 1263 bool is_for_loop_condition_; 1264 }; 1265 1266 1267 class Conditional: public Expression { 1268 public: Conditional(Expression * condition,Expression * then_expression,Expression * else_expression)1269 Conditional(Expression* condition, 1270 Expression* then_expression, 1271 Expression* else_expression) 1272 : condition_(condition), 1273 then_expression_(then_expression), 1274 else_expression_(else_expression) { } 1275 1276 virtual void Accept(AstVisitor* v); 1277 condition()1278 Expression* condition() const { return condition_; } then_expression()1279 Expression* then_expression() const { return then_expression_; } else_expression()1280 Expression* else_expression() const { return else_expression_; } 1281 1282 private: 1283 Expression* condition_; 1284 Expression* then_expression_; 1285 Expression* else_expression_; 1286 }; 1287 1288 1289 class Assignment: public Expression { 1290 public: Assignment(Token::Value op,Expression * target,Expression * value,int pos)1291 Assignment(Token::Value op, Expression* target, Expression* value, int pos) 1292 : op_(op), target_(target), value_(value), pos_(pos), 1293 block_start_(false), block_end_(false) { 1294 ASSERT(Token::IsAssignmentOp(op)); 1295 } 1296 1297 virtual void Accept(AstVisitor* v); AsAssignment()1298 virtual Assignment* AsAssignment() { return this; } 1299 1300 Token::Value binary_op() const; 1301 op()1302 Token::Value op() const { return op_; } target()1303 Expression* target() const { return target_; } value()1304 Expression* value() const { return value_; } position()1305 int position() { return pos_; } 1306 // This check relies on the definition order of token in token.h. is_compound()1307 bool is_compound() const { return op() > Token::ASSIGN; } 1308 1309 // An initialization block is a series of statments of the form 1310 // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and 1311 // ending of these blocks to allow for optimizations of initialization 1312 // blocks. starts_initialization_block()1313 bool starts_initialization_block() { return block_start_; } ends_initialization_block()1314 bool ends_initialization_block() { return block_end_; } mark_block_start()1315 void mark_block_start() { block_start_ = true; } mark_block_end()1316 void mark_block_end() { block_end_ = true; } 1317 1318 private: 1319 Token::Value op_; 1320 Expression* target_; 1321 Expression* value_; 1322 int pos_; 1323 bool block_start_; 1324 bool block_end_; 1325 }; 1326 1327 1328 class Throw: public Expression { 1329 public: Throw(Expression * exception,int pos)1330 Throw(Expression* exception, int pos) 1331 : exception_(exception), pos_(pos) {} 1332 1333 virtual void Accept(AstVisitor* v); exception()1334 Expression* exception() const { return exception_; } position()1335 int position() const { return pos_; } 1336 1337 private: 1338 Expression* exception_; 1339 int pos_; 1340 }; 1341 1342 1343 class FunctionLiteral: public Expression { 1344 public: FunctionLiteral(Handle<String> name,Scope * scope,ZoneList<Statement * > * body,int materialized_literal_count,int expected_property_count,bool has_only_simple_this_property_assignments,Handle<FixedArray> this_property_assignments,int num_parameters,int start_position,int end_position,bool is_expression)1345 FunctionLiteral(Handle<String> name, 1346 Scope* scope, 1347 ZoneList<Statement*>* body, 1348 int materialized_literal_count, 1349 int expected_property_count, 1350 bool has_only_simple_this_property_assignments, 1351 Handle<FixedArray> this_property_assignments, 1352 int num_parameters, 1353 int start_position, 1354 int end_position, 1355 bool is_expression) 1356 : name_(name), 1357 scope_(scope), 1358 body_(body), 1359 materialized_literal_count_(materialized_literal_count), 1360 expected_property_count_(expected_property_count), 1361 has_only_simple_this_property_assignments_( 1362 has_only_simple_this_property_assignments), 1363 this_property_assignments_(this_property_assignments), 1364 num_parameters_(num_parameters), 1365 start_position_(start_position), 1366 end_position_(end_position), 1367 is_expression_(is_expression), 1368 function_token_position_(RelocInfo::kNoPosition), 1369 inferred_name_(Heap::empty_string()), 1370 try_full_codegen_(false) { 1371 #ifdef DEBUG 1372 already_compiled_ = false; 1373 #endif 1374 } 1375 1376 virtual void Accept(AstVisitor* v); 1377 1378 // Type testing & conversion AsFunctionLiteral()1379 virtual FunctionLiteral* AsFunctionLiteral() { return this; } 1380 IsLeaf()1381 virtual bool IsLeaf() { return true; } 1382 name()1383 Handle<String> name() const { return name_; } scope()1384 Scope* scope() const { return scope_; } body()1385 ZoneList<Statement*>* body() const { return body_; } set_function_token_position(int pos)1386 void set_function_token_position(int pos) { function_token_position_ = pos; } function_token_position()1387 int function_token_position() const { return function_token_position_; } start_position()1388 int start_position() const { return start_position_; } end_position()1389 int end_position() const { return end_position_; } is_expression()1390 bool is_expression() const { return is_expression_; } 1391 materialized_literal_count()1392 int materialized_literal_count() { return materialized_literal_count_; } expected_property_count()1393 int expected_property_count() { return expected_property_count_; } has_only_simple_this_property_assignments()1394 bool has_only_simple_this_property_assignments() { 1395 return has_only_simple_this_property_assignments_; 1396 } this_property_assignments()1397 Handle<FixedArray> this_property_assignments() { 1398 return this_property_assignments_; 1399 } num_parameters()1400 int num_parameters() { return num_parameters_; } 1401 1402 bool AllowsLazyCompilation(); 1403 inferred_name()1404 Handle<String> inferred_name() const { return inferred_name_; } set_inferred_name(Handle<String> inferred_name)1405 void set_inferred_name(Handle<String> inferred_name) { 1406 inferred_name_ = inferred_name; 1407 } 1408 try_full_codegen()1409 bool try_full_codegen() { return try_full_codegen_; } set_try_full_codegen(bool flag)1410 void set_try_full_codegen(bool flag) { try_full_codegen_ = flag; } 1411 1412 #ifdef DEBUG mark_as_compiled()1413 void mark_as_compiled() { 1414 ASSERT(!already_compiled_); 1415 already_compiled_ = true; 1416 } 1417 #endif 1418 1419 private: 1420 Handle<String> name_; 1421 Scope* scope_; 1422 ZoneList<Statement*>* body_; 1423 int materialized_literal_count_; 1424 int expected_property_count_; 1425 bool has_only_simple_this_property_assignments_; 1426 Handle<FixedArray> this_property_assignments_; 1427 int num_parameters_; 1428 int start_position_; 1429 int end_position_; 1430 bool is_expression_; 1431 int function_token_position_; 1432 Handle<String> inferred_name_; 1433 bool try_full_codegen_; 1434 #ifdef DEBUG 1435 bool already_compiled_; 1436 #endif 1437 }; 1438 1439 1440 class FunctionBoilerplateLiteral: public Expression { 1441 public: FunctionBoilerplateLiteral(Handle<JSFunction> boilerplate)1442 explicit FunctionBoilerplateLiteral(Handle<JSFunction> boilerplate) 1443 : boilerplate_(boilerplate) { 1444 ASSERT(boilerplate->IsBoilerplate()); 1445 } 1446 boilerplate()1447 Handle<JSFunction> boilerplate() const { return boilerplate_; } 1448 IsLeaf()1449 virtual bool IsLeaf() { return true; } 1450 1451 virtual void Accept(AstVisitor* v); 1452 1453 private: 1454 Handle<JSFunction> boilerplate_; 1455 }; 1456 1457 1458 class ThisFunction: public Expression { 1459 public: 1460 virtual void Accept(AstVisitor* v); IsLeaf()1461 virtual bool IsLeaf() { return true; } 1462 }; 1463 1464 1465 // ---------------------------------------------------------------------------- 1466 // Regular expressions 1467 1468 1469 class RegExpVisitor BASE_EMBEDDED { 1470 public: ~RegExpVisitor()1471 virtual ~RegExpVisitor() { } 1472 #define MAKE_CASE(Name) \ 1473 virtual void* Visit##Name(RegExp##Name*, void* data) = 0; 1474 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE) 1475 #undef MAKE_CASE 1476 }; 1477 1478 1479 class RegExpTree: public ZoneObject { 1480 public: 1481 static const int kInfinity = kMaxInt; ~RegExpTree()1482 virtual ~RegExpTree() { } 1483 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0; 1484 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1485 RegExpNode* on_success) = 0; IsTextElement()1486 virtual bool IsTextElement() { return false; } IsAnchored()1487 virtual bool IsAnchored() { return false; } 1488 virtual int min_match() = 0; 1489 virtual int max_match() = 0; 1490 // Returns the interval of registers used for captures within this 1491 // expression. CaptureRegisters()1492 virtual Interval CaptureRegisters() { return Interval::Empty(); } 1493 virtual void AppendToText(RegExpText* text); 1494 SmartPointer<const char> ToString(); 1495 #define MAKE_ASTYPE(Name) \ 1496 virtual RegExp##Name* As##Name(); \ 1497 virtual bool Is##Name(); 1498 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE) 1499 #undef MAKE_ASTYPE 1500 }; 1501 1502 1503 class RegExpDisjunction: public RegExpTree { 1504 public: 1505 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives); 1506 virtual void* Accept(RegExpVisitor* visitor, void* data); 1507 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1508 RegExpNode* on_success); 1509 virtual RegExpDisjunction* AsDisjunction(); 1510 virtual Interval CaptureRegisters(); 1511 virtual bool IsDisjunction(); 1512 virtual bool IsAnchored(); min_match()1513 virtual int min_match() { return min_match_; } max_match()1514 virtual int max_match() { return max_match_; } alternatives()1515 ZoneList<RegExpTree*>* alternatives() { return alternatives_; } 1516 private: 1517 ZoneList<RegExpTree*>* alternatives_; 1518 int min_match_; 1519 int max_match_; 1520 }; 1521 1522 1523 class RegExpAlternative: public RegExpTree { 1524 public: 1525 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes); 1526 virtual void* Accept(RegExpVisitor* visitor, void* data); 1527 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1528 RegExpNode* on_success); 1529 virtual RegExpAlternative* AsAlternative(); 1530 virtual Interval CaptureRegisters(); 1531 virtual bool IsAlternative(); 1532 virtual bool IsAnchored(); min_match()1533 virtual int min_match() { return min_match_; } max_match()1534 virtual int max_match() { return max_match_; } nodes()1535 ZoneList<RegExpTree*>* nodes() { return nodes_; } 1536 private: 1537 ZoneList<RegExpTree*>* nodes_; 1538 int min_match_; 1539 int max_match_; 1540 }; 1541 1542 1543 class RegExpAssertion: public RegExpTree { 1544 public: 1545 enum Type { 1546 START_OF_LINE, 1547 START_OF_INPUT, 1548 END_OF_LINE, 1549 END_OF_INPUT, 1550 BOUNDARY, 1551 NON_BOUNDARY 1552 }; RegExpAssertion(Type type)1553 explicit RegExpAssertion(Type type) : type_(type) { } 1554 virtual void* Accept(RegExpVisitor* visitor, void* data); 1555 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1556 RegExpNode* on_success); 1557 virtual RegExpAssertion* AsAssertion(); 1558 virtual bool IsAssertion(); 1559 virtual bool IsAnchored(); min_match()1560 virtual int min_match() { return 0; } max_match()1561 virtual int max_match() { return 0; } type()1562 Type type() { return type_; } 1563 private: 1564 Type type_; 1565 }; 1566 1567 1568 class CharacterSet BASE_EMBEDDED { 1569 public: CharacterSet(uc16 standard_set_type)1570 explicit CharacterSet(uc16 standard_set_type) 1571 : ranges_(NULL), 1572 standard_set_type_(standard_set_type) {} CharacterSet(ZoneList<CharacterRange> * ranges)1573 explicit CharacterSet(ZoneList<CharacterRange>* ranges) 1574 : ranges_(ranges), 1575 standard_set_type_(0) {} 1576 ZoneList<CharacterRange>* ranges(); standard_set_type()1577 uc16 standard_set_type() { return standard_set_type_; } set_standard_set_type(uc16 special_set_type)1578 void set_standard_set_type(uc16 special_set_type) { 1579 standard_set_type_ = special_set_type; 1580 } is_standard()1581 bool is_standard() { return standard_set_type_ != 0; } 1582 void Canonicalize(); 1583 private: 1584 ZoneList<CharacterRange>* ranges_; 1585 // If non-zero, the value represents a standard set (e.g., all whitespace 1586 // characters) without having to expand the ranges. 1587 uc16 standard_set_type_; 1588 }; 1589 1590 1591 class RegExpCharacterClass: public RegExpTree { 1592 public: RegExpCharacterClass(ZoneList<CharacterRange> * ranges,bool is_negated)1593 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated) 1594 : set_(ranges), 1595 is_negated_(is_negated) { } RegExpCharacterClass(uc16 type)1596 explicit RegExpCharacterClass(uc16 type) 1597 : set_(type), 1598 is_negated_(false) { } 1599 virtual void* Accept(RegExpVisitor* visitor, void* data); 1600 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1601 RegExpNode* on_success); 1602 virtual RegExpCharacterClass* AsCharacterClass(); 1603 virtual bool IsCharacterClass(); IsTextElement()1604 virtual bool IsTextElement() { return true; } min_match()1605 virtual int min_match() { return 1; } max_match()1606 virtual int max_match() { return 1; } 1607 virtual void AppendToText(RegExpText* text); character_set()1608 CharacterSet character_set() { return set_; } 1609 // TODO(lrn): Remove need for complex version if is_standard that 1610 // recognizes a mangled standard set and just do { return set_.is_special(); } 1611 bool is_standard(); 1612 // Returns a value representing the standard character set if is_standard() 1613 // returns true. 1614 // Currently used values are: 1615 // s : unicode whitespace 1616 // S : unicode non-whitespace 1617 // w : ASCII word character (digit, letter, underscore) 1618 // W : non-ASCII word character 1619 // d : ASCII digit 1620 // D : non-ASCII digit 1621 // . : non-unicode non-newline 1622 // * : All characters standard_type()1623 uc16 standard_type() { return set_.standard_set_type(); } ranges()1624 ZoneList<CharacterRange>* ranges() { return set_.ranges(); } is_negated()1625 bool is_negated() { return is_negated_; } 1626 private: 1627 CharacterSet set_; 1628 bool is_negated_; 1629 }; 1630 1631 1632 class RegExpAtom: public RegExpTree { 1633 public: RegExpAtom(Vector<const uc16> data)1634 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { } 1635 virtual void* Accept(RegExpVisitor* visitor, void* data); 1636 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1637 RegExpNode* on_success); 1638 virtual RegExpAtom* AsAtom(); 1639 virtual bool IsAtom(); IsTextElement()1640 virtual bool IsTextElement() { return true; } min_match()1641 virtual int min_match() { return data_.length(); } max_match()1642 virtual int max_match() { return data_.length(); } 1643 virtual void AppendToText(RegExpText* text); data()1644 Vector<const uc16> data() { return data_; } length()1645 int length() { return data_.length(); } 1646 private: 1647 Vector<const uc16> data_; 1648 }; 1649 1650 1651 class RegExpText: public RegExpTree { 1652 public: RegExpText()1653 RegExpText() : elements_(2), length_(0) {} 1654 virtual void* Accept(RegExpVisitor* visitor, void* data); 1655 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1656 RegExpNode* on_success); 1657 virtual RegExpText* AsText(); 1658 virtual bool IsText(); IsTextElement()1659 virtual bool IsTextElement() { return true; } min_match()1660 virtual int min_match() { return length_; } max_match()1661 virtual int max_match() { return length_; } 1662 virtual void AppendToText(RegExpText* text); AddElement(TextElement elm)1663 void AddElement(TextElement elm) { 1664 elements_.Add(elm); 1665 length_ += elm.length(); 1666 }; elements()1667 ZoneList<TextElement>* elements() { return &elements_; } 1668 private: 1669 ZoneList<TextElement> elements_; 1670 int length_; 1671 }; 1672 1673 1674 class RegExpQuantifier: public RegExpTree { 1675 public: 1676 enum Type { GREEDY, NON_GREEDY, POSSESSIVE }; RegExpQuantifier(int min,int max,Type type,RegExpTree * body)1677 RegExpQuantifier(int min, int max, Type type, RegExpTree* body) 1678 : body_(body), 1679 min_(min), 1680 max_(max), 1681 min_match_(min * body->min_match()), 1682 type_(type) { 1683 if (max > 0 && body->max_match() > kInfinity / max) { 1684 max_match_ = kInfinity; 1685 } else { 1686 max_match_ = max * body->max_match(); 1687 } 1688 } 1689 virtual void* Accept(RegExpVisitor* visitor, void* data); 1690 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1691 RegExpNode* on_success); 1692 static RegExpNode* ToNode(int min, 1693 int max, 1694 bool is_greedy, 1695 RegExpTree* body, 1696 RegExpCompiler* compiler, 1697 RegExpNode* on_success, 1698 bool not_at_start = false); 1699 virtual RegExpQuantifier* AsQuantifier(); 1700 virtual Interval CaptureRegisters(); 1701 virtual bool IsQuantifier(); min_match()1702 virtual int min_match() { return min_match_; } max_match()1703 virtual int max_match() { return max_match_; } min()1704 int min() { return min_; } max()1705 int max() { return max_; } is_possessive()1706 bool is_possessive() { return type_ == POSSESSIVE; } is_non_greedy()1707 bool is_non_greedy() { return type_ == NON_GREEDY; } is_greedy()1708 bool is_greedy() { return type_ == GREEDY; } body()1709 RegExpTree* body() { return body_; } 1710 private: 1711 RegExpTree* body_; 1712 int min_; 1713 int max_; 1714 int min_match_; 1715 int max_match_; 1716 Type type_; 1717 }; 1718 1719 1720 class RegExpCapture: public RegExpTree { 1721 public: RegExpCapture(RegExpTree * body,int index)1722 explicit RegExpCapture(RegExpTree* body, int index) 1723 : body_(body), index_(index) { } 1724 virtual void* Accept(RegExpVisitor* visitor, void* data); 1725 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1726 RegExpNode* on_success); 1727 static RegExpNode* ToNode(RegExpTree* body, 1728 int index, 1729 RegExpCompiler* compiler, 1730 RegExpNode* on_success); 1731 virtual RegExpCapture* AsCapture(); 1732 virtual bool IsAnchored(); 1733 virtual Interval CaptureRegisters(); 1734 virtual bool IsCapture(); min_match()1735 virtual int min_match() { return body_->min_match(); } max_match()1736 virtual int max_match() { return body_->max_match(); } body()1737 RegExpTree* body() { return body_; } index()1738 int index() { return index_; } StartRegister(int index)1739 static int StartRegister(int index) { return index * 2; } EndRegister(int index)1740 static int EndRegister(int index) { return index * 2 + 1; } 1741 private: 1742 RegExpTree* body_; 1743 int index_; 1744 }; 1745 1746 1747 class RegExpLookahead: public RegExpTree { 1748 public: RegExpLookahead(RegExpTree * body,bool is_positive,int capture_count,int capture_from)1749 RegExpLookahead(RegExpTree* body, 1750 bool is_positive, 1751 int capture_count, 1752 int capture_from) 1753 : body_(body), 1754 is_positive_(is_positive), 1755 capture_count_(capture_count), 1756 capture_from_(capture_from) { } 1757 1758 virtual void* Accept(RegExpVisitor* visitor, void* data); 1759 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1760 RegExpNode* on_success); 1761 virtual RegExpLookahead* AsLookahead(); 1762 virtual Interval CaptureRegisters(); 1763 virtual bool IsLookahead(); 1764 virtual bool IsAnchored(); min_match()1765 virtual int min_match() { return 0; } max_match()1766 virtual int max_match() { return 0; } body()1767 RegExpTree* body() { return body_; } is_positive()1768 bool is_positive() { return is_positive_; } capture_count()1769 int capture_count() { return capture_count_; } capture_from()1770 int capture_from() { return capture_from_; } 1771 private: 1772 RegExpTree* body_; 1773 bool is_positive_; 1774 int capture_count_; 1775 int capture_from_; 1776 }; 1777 1778 1779 class RegExpBackReference: public RegExpTree { 1780 public: RegExpBackReference(RegExpCapture * capture)1781 explicit RegExpBackReference(RegExpCapture* capture) 1782 : capture_(capture) { } 1783 virtual void* Accept(RegExpVisitor* visitor, void* data); 1784 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1785 RegExpNode* on_success); 1786 virtual RegExpBackReference* AsBackReference(); 1787 virtual bool IsBackReference(); min_match()1788 virtual int min_match() { return 0; } max_match()1789 virtual int max_match() { return capture_->max_match(); } index()1790 int index() { return capture_->index(); } capture()1791 RegExpCapture* capture() { return capture_; } 1792 private: 1793 RegExpCapture* capture_; 1794 }; 1795 1796 1797 class RegExpEmpty: public RegExpTree { 1798 public: RegExpEmpty()1799 RegExpEmpty() { } 1800 virtual void* Accept(RegExpVisitor* visitor, void* data); 1801 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1802 RegExpNode* on_success); 1803 virtual RegExpEmpty* AsEmpty(); 1804 virtual bool IsEmpty(); min_match()1805 virtual int min_match() { return 0; } max_match()1806 virtual int max_match() { return 0; } GetInstance()1807 static RegExpEmpty* GetInstance() { return &kInstance; } 1808 private: 1809 static RegExpEmpty kInstance; 1810 }; 1811 1812 1813 // ---------------------------------------------------------------------------- 1814 // Basic visitor 1815 // - leaf node visitors are abstract. 1816 1817 class AstVisitor BASE_EMBEDDED { 1818 public: AstVisitor()1819 AstVisitor() : stack_overflow_(false) { } ~AstVisitor()1820 virtual ~AstVisitor() { } 1821 1822 // Dispatch Visit(AstNode * node)1823 void Visit(AstNode* node) { node->Accept(this); } 1824 1825 // Iteration 1826 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations); 1827 virtual void VisitStatements(ZoneList<Statement*>* statements); 1828 virtual void VisitExpressions(ZoneList<Expression*>* expressions); 1829 1830 // Stack overflow tracking support. HasStackOverflow()1831 bool HasStackOverflow() const { return stack_overflow_; } CheckStackOverflow()1832 bool CheckStackOverflow() { 1833 if (stack_overflow_) return true; 1834 StackLimitCheck check; 1835 if (!check.HasOverflowed()) return false; 1836 return (stack_overflow_ = true); 1837 } 1838 1839 // If a stack-overflow exception is encountered when visiting a 1840 // node, calling SetStackOverflow will make sure that the visitor 1841 // bails out without visiting more nodes. SetStackOverflow()1842 void SetStackOverflow() { stack_overflow_ = true; } 1843 1844 1845 // Individual nodes 1846 #define DEF_VISIT(type) \ 1847 virtual void Visit##type(type* node) = 0; 1848 AST_NODE_LIST(DEF_VISIT) 1849 #undef DEF_VISIT 1850 1851 private: 1852 bool stack_overflow_; 1853 }; 1854 1855 1856 } } // namespace v8::internal 1857 1858 #endif // V8_AST_H_ 1859