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