1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_AST_AST_H_ 6 #define V8_AST_AST_H_ 7 8 #include <memory> 9 10 #include "src/ast/ast-value-factory.h" 11 #include "src/ast/modules.h" 12 #include "src/ast/variables.h" 13 #include "src/bailout-reason.h" 14 #include "src/globals.h" 15 #include "src/heap/factory.h" 16 #include "src/isolate.h" 17 #include "src/label.h" 18 #include "src/objects/literal-objects.h" 19 #include "src/parsing/token.h" 20 #include "src/runtime/runtime.h" 21 22 namespace v8 { 23 namespace internal { 24 25 // The abstract syntax tree is an intermediate, light-weight 26 // representation of the parsed JavaScript code suitable for 27 // compilation to native code. 28 29 // Nodes are allocated in a separate zone, which allows faster 30 // allocation and constant-time deallocation of the entire syntax 31 // tree. 32 33 34 // ---------------------------------------------------------------------------- 35 // Nodes of the abstract syntax tree. Only concrete classes are 36 // enumerated here. 37 38 #define DECLARATION_NODE_LIST(V) \ 39 V(VariableDeclaration) \ 40 V(FunctionDeclaration) 41 42 #define ITERATION_NODE_LIST(V) \ 43 V(DoWhileStatement) \ 44 V(WhileStatement) \ 45 V(ForStatement) \ 46 V(ForInStatement) \ 47 V(ForOfStatement) 48 49 #define BREAKABLE_NODE_LIST(V) \ 50 V(Block) \ 51 V(SwitchStatement) 52 53 #define STATEMENT_NODE_LIST(V) \ 54 ITERATION_NODE_LIST(V) \ 55 BREAKABLE_NODE_LIST(V) \ 56 V(ExpressionStatement) \ 57 V(EmptyStatement) \ 58 V(SloppyBlockFunctionStatement) \ 59 V(IfStatement) \ 60 V(ContinueStatement) \ 61 V(BreakStatement) \ 62 V(ReturnStatement) \ 63 V(WithStatement) \ 64 V(TryCatchStatement) \ 65 V(TryFinallyStatement) \ 66 V(DebuggerStatement) \ 67 V(InitializeClassFieldsStatement) 68 69 #define LITERAL_NODE_LIST(V) \ 70 V(RegExpLiteral) \ 71 V(ObjectLiteral) \ 72 V(ArrayLiteral) 73 74 #define EXPRESSION_NODE_LIST(V) \ 75 LITERAL_NODE_LIST(V) \ 76 V(Assignment) \ 77 V(Await) \ 78 V(BinaryOperation) \ 79 V(NaryOperation) \ 80 V(Call) \ 81 V(CallNew) \ 82 V(CallRuntime) \ 83 V(ClassLiteral) \ 84 V(CompareOperation) \ 85 V(CompoundAssignment) \ 86 V(Conditional) \ 87 V(CountOperation) \ 88 V(DoExpression) \ 89 V(EmptyParentheses) \ 90 V(FunctionLiteral) \ 91 V(GetIterator) \ 92 V(GetTemplateObject) \ 93 V(ImportCallExpression) \ 94 V(Literal) \ 95 V(NativeFunctionLiteral) \ 96 V(Property) \ 97 V(ResolvedProperty) \ 98 V(RewritableExpression) \ 99 V(Spread) \ 100 V(StoreInArrayLiteral) \ 101 V(SuperCallReference) \ 102 V(SuperPropertyReference) \ 103 V(TemplateLiteral) \ 104 V(ThisFunction) \ 105 V(Throw) \ 106 V(UnaryOperation) \ 107 V(VariableProxy) \ 108 V(Yield) \ 109 V(YieldStar) 110 111 #define AST_NODE_LIST(V) \ 112 DECLARATION_NODE_LIST(V) \ 113 STATEMENT_NODE_LIST(V) \ 114 EXPRESSION_NODE_LIST(V) 115 116 // Forward declarations 117 class AstNode; 118 class AstNodeFactory; 119 class Declaration; 120 class BreakableStatement; 121 class Expression; 122 class IterationStatement; 123 class MaterializedLiteral; 124 class NestedVariableDeclaration; 125 class ProducedPreParsedScopeData; 126 class Statement; 127 128 #define DEF_FORWARD_DECLARATION(type) class type; 129 AST_NODE_LIST(DEF_FORWARD_DECLARATION) 130 #undef DEF_FORWARD_DECLARATION 131 132 class AstNode: public ZoneObject { 133 public: 134 #define DECLARE_TYPE_ENUM(type) k##type, 135 enum NodeType : uint8_t { AST_NODE_LIST(DECLARE_TYPE_ENUM) }; 136 #undef DECLARE_TYPE_ENUM 137 138 void* operator new(size_t size, Zone* zone) { return zone->New(size); } 139 140 NodeType node_type() const { return NodeTypeField::decode(bit_field_); } 141 int position() const { return position_; } 142 143 #ifdef DEBUG 144 void Print(); 145 void Print(Isolate* isolate); 146 #endif // DEBUG 147 148 // Type testing & conversion functions overridden by concrete subclasses. 149 #define DECLARE_NODE_FUNCTIONS(type) \ 150 V8_INLINE bool Is##type() const; \ 151 V8_INLINE type* As##type(); \ 152 V8_INLINE const type* As##type() const; 153 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) 154 #undef DECLARE_NODE_FUNCTIONS 155 156 BreakableStatement* AsBreakableStatement(); 157 IterationStatement* AsIterationStatement(); 158 MaterializedLiteral* AsMaterializedLiteral(); 159 160 private: 161 // Hidden to prevent accidental usage. It would have to load the 162 // current zone from the TLS. 163 void* operator new(size_t size); 164 165 int position_; 166 class NodeTypeField : public BitField<NodeType, 0, 6> {}; 167 168 protected: 169 uint32_t bit_field_; 170 static const uint8_t kNextBitFieldIndex = NodeTypeField::kNext; 171 172 AstNode(int position, NodeType type) 173 : position_(position), bit_field_(NodeTypeField::encode(type)) {} 174 }; 175 176 177 class Statement : public AstNode { 178 public: 179 bool IsEmpty() { return AsEmptyStatement() != nullptr; } 180 bool IsJump() const; 181 182 protected: 183 Statement(int position, NodeType type) : AstNode(position, type) {} 184 185 static const uint8_t kNextBitFieldIndex = AstNode::kNextBitFieldIndex; 186 }; 187 188 189 class Expression : public AstNode { 190 public: 191 enum Context { 192 // Not assigned a context yet, or else will not be visited during 193 // code generation. 194 kUninitialized, 195 // Evaluated for its side effects. 196 kEffect, 197 // Evaluated for its value (and side effects). 198 kValue, 199 // Evaluated for control flow (and side effects). 200 kTest 201 }; 202 203 // True iff the expression is a valid reference expression. 204 bool IsValidReferenceExpression() const; 205 206 // Helpers for ToBoolean conversion. 207 bool ToBooleanIsTrue() const; 208 bool ToBooleanIsFalse() const; 209 210 // Symbols that cannot be parsed as array indices are considered property 211 // names. We do not treat symbols that can be array indexes as property 212 // names because [] for string objects is handled only by keyed ICs. 213 bool IsPropertyName() const; 214 215 // True iff the expression is a class or function expression without 216 // a syntactic name. 217 bool IsAnonymousFunctionDefinition() const; 218 219 // True iff the expression is a concise method definition. 220 bool IsConciseMethodDefinition() const; 221 222 // True iff the expression is an accessor function definition. 223 bool IsAccessorFunctionDefinition() const; 224 225 // True iff the expression is a literal represented as a smi. 226 bool IsSmiLiteral() const; 227 228 // True iff the expression is a literal represented as a number. 229 bool IsNumberLiteral() const; 230 231 // True iff the expression is a string literal. 232 bool IsStringLiteral() const; 233 234 // True iff the expression is the null literal. 235 bool IsNullLiteral() const; 236 237 // True iff the expression is the hole literal. 238 bool IsTheHoleLiteral() const; 239 240 // True if we can prove that the expression is the undefined literal. Note 241 // that this also checks for loads of the global "undefined" variable. 242 bool IsUndefinedLiteral() const; 243 244 bool IsCompileTimeValue(); 245 246 protected: 247 Expression(int pos, NodeType type) : AstNode(pos, type) {} 248 249 static const uint8_t kNextBitFieldIndex = AstNode::kNextBitFieldIndex; 250 }; 251 252 // V8's notion of BreakableStatement does not correspond to the notion of 253 // BreakableStatement in ECMAScript. In V8, the idea is that a 254 // BreakableStatement is a statement that can be the target of a break 255 // statement. The BreakableStatement AST node carries a list of labels, any of 256 // which can be used as an argument to the break statement in order to target 257 // it. 258 // 259 // Since we don't want to attach a list of labels to all kinds of statements, we 260 // only declare switchs, loops, and blocks as BreakableStatements. This means 261 // that we implement breaks targeting other statement forms as breaks targeting 262 // a substatement thereof. For instance, in "foo: if (b) { f(); break foo; }" we 263 // pretend that foo is the label of the inner block. That's okay because one 264 // can't observe the difference. 265 // 266 // This optimization makes it harder to detect invalid continue labels, see the 267 // need for own_labels in IterationStatement. 268 // 269 class BreakableStatement : public Statement { 270 public: 271 enum BreakableType { 272 TARGET_FOR_ANONYMOUS, 273 TARGET_FOR_NAMED_ONLY 274 }; 275 276 // A list of all labels declared on the path up to the previous 277 // BreakableStatement (if any). 278 // 279 // Example: "l1: for (;;) l2: l3: { l4: if (b) l5: { s } }" 280 // labels() of the ForStatement will be l1. 281 // labels() of the Block { l4: ... } will be l2, l3. 282 // labels() of the Block { s } will be l4, l5. 283 ZonePtrList<const AstRawString>* labels() const; 284 285 // Testers. 286 bool is_target_for_anonymous() const { 287 return BreakableTypeField::decode(bit_field_) == TARGET_FOR_ANONYMOUS; 288 } 289 290 private: 291 class BreakableTypeField 292 : public BitField<BreakableType, Statement::kNextBitFieldIndex, 1> {}; 293 294 protected: 295 BreakableStatement(BreakableType breakable_type, int position, NodeType type) 296 : Statement(position, type) { 297 bit_field_ |= BreakableTypeField::encode(breakable_type); 298 } 299 300 static const uint8_t kNextBitFieldIndex = BreakableTypeField::kNext; 301 }; 302 303 class Block : public BreakableStatement { 304 public: 305 ZonePtrList<Statement>* statements() { return &statements_; } 306 bool ignore_completion_value() const { 307 return IgnoreCompletionField::decode(bit_field_); 308 } 309 310 inline ZonePtrList<const AstRawString>* labels() const; 311 312 bool IsJump() const { 313 return !statements_.is_empty() && statements_.last()->IsJump() && 314 labels() == nullptr; // Good enough as an approximation... 315 } 316 317 Scope* scope() const { return scope_; } 318 void set_scope(Scope* scope) { scope_ = scope; } 319 320 private: 321 friend class AstNodeFactory; 322 323 ZonePtrList<Statement> statements_; 324 Scope* scope_; 325 326 class IgnoreCompletionField 327 : public BitField<bool, BreakableStatement::kNextBitFieldIndex, 1> {}; 328 class IsLabeledField 329 : public BitField<bool, IgnoreCompletionField::kNext, 1> {}; 330 331 protected: 332 Block(Zone* zone, ZonePtrList<const AstRawString>* labels, int capacity, 333 bool ignore_completion_value) 334 : BreakableStatement(TARGET_FOR_NAMED_ONLY, kNoSourcePosition, kBlock), 335 statements_(capacity, zone), 336 scope_(nullptr) { 337 bit_field_ |= IgnoreCompletionField::encode(ignore_completion_value) | 338 IsLabeledField::encode(labels != nullptr); 339 } 340 }; 341 342 class LabeledBlock final : public Block { 343 private: 344 friend class AstNodeFactory; 345 friend class Block; 346 347 LabeledBlock(Zone* zone, ZonePtrList<const AstRawString>* labels, 348 int capacity, bool ignore_completion_value) 349 : Block(zone, labels, capacity, ignore_completion_value), 350 labels_(labels) { 351 DCHECK_NOT_NULL(labels); 352 DCHECK_GT(labels->length(), 0); 353 } 354 355 ZonePtrList<const AstRawString>* labels_; 356 }; 357 358 inline ZonePtrList<const AstRawString>* Block::labels() const { 359 if (IsLabeledField::decode(bit_field_)) { 360 return static_cast<const LabeledBlock*>(this)->labels_; 361 } 362 return nullptr; 363 } 364 365 class DoExpression final : public Expression { 366 public: 367 Block* block() { return block_; } 368 VariableProxy* result() { return result_; } 369 370 private: 371 friend class AstNodeFactory; 372 373 DoExpression(Block* block, VariableProxy* result, int pos) 374 : Expression(pos, kDoExpression), block_(block), result_(result) { 375 DCHECK_NOT_NULL(block_); 376 DCHECK_NOT_NULL(result_); 377 } 378 379 Block* block_; 380 VariableProxy* result_; 381 }; 382 383 384 class Declaration : public AstNode { 385 public: 386 typedef ThreadedList<Declaration> List; 387 388 VariableProxy* proxy() const { return proxy_; } 389 390 protected: 391 Declaration(VariableProxy* proxy, int pos, NodeType type) 392 : AstNode(pos, type), proxy_(proxy), next_(nullptr) {} 393 394 private: 395 VariableProxy* proxy_; 396 // Declarations list threaded through the declarations. 397 Declaration** next() { return &next_; } 398 Declaration* next_; 399 friend List; 400 }; 401 402 class VariableDeclaration : public Declaration { 403 public: 404 inline NestedVariableDeclaration* AsNested(); 405 406 private: 407 friend class AstNodeFactory; 408 409 class IsNestedField 410 : public BitField<bool, Declaration::kNextBitFieldIndex, 1> {}; 411 412 protected: 413 VariableDeclaration(VariableProxy* proxy, int pos, bool is_nested = false) 414 : Declaration(proxy, pos, kVariableDeclaration) { 415 bit_field_ = IsNestedField::update(bit_field_, is_nested); 416 } 417 418 static const uint8_t kNextBitFieldIndex = IsNestedField::kNext; 419 }; 420 421 // For var declarations that appear in a block scope. 422 // Only distinguished from VariableDeclaration during Scope analysis, 423 // so it doesn't get its own NodeType. 424 class NestedVariableDeclaration final : public VariableDeclaration { 425 public: 426 Scope* scope() const { return scope_; } 427 428 private: 429 friend class AstNodeFactory; 430 431 NestedVariableDeclaration(VariableProxy* proxy, Scope* scope, int pos) 432 : VariableDeclaration(proxy, pos, true), scope_(scope) {} 433 434 // Nested scope from which the declaration originated. 435 Scope* scope_; 436 }; 437 438 inline NestedVariableDeclaration* VariableDeclaration::AsNested() { 439 return IsNestedField::decode(bit_field_) 440 ? static_cast<NestedVariableDeclaration*>(this) 441 : nullptr; 442 } 443 444 class FunctionDeclaration final : public Declaration { 445 public: 446 FunctionLiteral* fun() const { return fun_; } 447 448 private: 449 friend class AstNodeFactory; 450 451 FunctionDeclaration(VariableProxy* proxy, FunctionLiteral* fun, int pos) 452 : Declaration(proxy, pos, kFunctionDeclaration), fun_(fun) { 453 DCHECK_NOT_NULL(fun); 454 } 455 456 FunctionLiteral* fun_; 457 }; 458 459 460 class IterationStatement : public BreakableStatement { 461 public: 462 Statement* body() const { return body_; } 463 void set_body(Statement* s) { body_ = s; } 464 465 ZonePtrList<const AstRawString>* labels() const { return labels_; } 466 467 // A list of all labels that the iteration statement is directly prefixed 468 // with, i.e. all the labels that a continue statement in the body can use to 469 // continue this iteration statement. This is always a subset of {labels}. 470 // 471 // Example: "l1: { l2: if (b) l3: l4: for (;;) s }" 472 // labels() of the Block will be l1. 473 // labels() of the ForStatement will be l2, l3, l4. 474 // own_labels() of the ForStatement will be l3, l4. 475 ZonePtrList<const AstRawString>* own_labels() const { return own_labels_; } 476 477 protected: 478 IterationStatement(ZonePtrList<const AstRawString>* labels, 479 ZonePtrList<const AstRawString>* own_labels, int pos, 480 NodeType type) 481 : BreakableStatement(TARGET_FOR_ANONYMOUS, pos, type), 482 labels_(labels), 483 own_labels_(own_labels), 484 body_(nullptr) {} 485 void Initialize(Statement* body) { body_ = body; } 486 487 static const uint8_t kNextBitFieldIndex = 488 BreakableStatement::kNextBitFieldIndex; 489 490 private: 491 ZonePtrList<const AstRawString>* labels_; 492 ZonePtrList<const AstRawString>* own_labels_; 493 Statement* body_; 494 }; 495 496 497 class DoWhileStatement final : public IterationStatement { 498 public: 499 void Initialize(Expression* cond, Statement* body) { 500 IterationStatement::Initialize(body); 501 cond_ = cond; 502 } 503 504 Expression* cond() const { return cond_; } 505 506 private: 507 friend class AstNodeFactory; 508 509 DoWhileStatement(ZonePtrList<const AstRawString>* labels, 510 ZonePtrList<const AstRawString>* own_labels, int pos) 511 : IterationStatement(labels, own_labels, pos, kDoWhileStatement), 512 cond_(nullptr) {} 513 514 Expression* cond_; 515 }; 516 517 518 class WhileStatement final : public IterationStatement { 519 public: 520 void Initialize(Expression* cond, Statement* body) { 521 IterationStatement::Initialize(body); 522 cond_ = cond; 523 } 524 525 Expression* cond() const { return cond_; } 526 527 private: 528 friend class AstNodeFactory; 529 530 WhileStatement(ZonePtrList<const AstRawString>* labels, 531 ZonePtrList<const AstRawString>* own_labels, int pos) 532 : IterationStatement(labels, own_labels, pos, kWhileStatement), 533 cond_(nullptr) {} 534 535 Expression* cond_; 536 }; 537 538 539 class ForStatement final : public IterationStatement { 540 public: 541 void Initialize(Statement* init, Expression* cond, Statement* next, 542 Statement* body) { 543 IterationStatement::Initialize(body); 544 init_ = init; 545 cond_ = cond; 546 next_ = next; 547 } 548 549 Statement* init() const { return init_; } 550 Expression* cond() const { return cond_; } 551 Statement* next() const { return next_; } 552 553 private: 554 friend class AstNodeFactory; 555 556 ForStatement(ZonePtrList<const AstRawString>* labels, 557 ZonePtrList<const AstRawString>* own_labels, int pos) 558 : IterationStatement(labels, own_labels, pos, kForStatement), 559 init_(nullptr), 560 cond_(nullptr), 561 next_(nullptr) {} 562 563 Statement* init_; 564 Expression* cond_; 565 Statement* next_; 566 }; 567 568 569 class ForEachStatement : public IterationStatement { 570 public: 571 enum VisitMode { 572 ENUMERATE, // for (each in subject) body; 573 ITERATE // for (each of subject) body; 574 }; 575 576 using IterationStatement::Initialize; 577 578 static const char* VisitModeString(VisitMode mode) { 579 return mode == ITERATE ? "for-of" : "for-in"; 580 } 581 582 protected: 583 ForEachStatement(ZonePtrList<const AstRawString>* labels, 584 ZonePtrList<const AstRawString>* own_labels, int pos, 585 NodeType type) 586 : IterationStatement(labels, own_labels, pos, type) {} 587 }; 588 589 590 class ForInStatement final : public ForEachStatement { 591 public: 592 void Initialize(Expression* each, Expression* subject, Statement* body) { 593 ForEachStatement::Initialize(body); 594 each_ = each; 595 subject_ = subject; 596 } 597 598 Expression* enumerable() const { 599 return subject(); 600 } 601 602 Expression* each() const { return each_; } 603 Expression* subject() const { return subject_; } 604 605 enum ForInType { FAST_FOR_IN, SLOW_FOR_IN }; 606 ForInType for_in_type() const { return ForInTypeField::decode(bit_field_); } 607 608 private: 609 friend class AstNodeFactory; 610 611 ForInStatement(ZonePtrList<const AstRawString>* labels, 612 ZonePtrList<const AstRawString>* own_labels, int pos) 613 : ForEachStatement(labels, own_labels, pos, kForInStatement), 614 each_(nullptr), 615 subject_(nullptr) { 616 bit_field_ = ForInTypeField::update(bit_field_, SLOW_FOR_IN); 617 } 618 619 Expression* each_; 620 Expression* subject_; 621 622 class ForInTypeField 623 : public BitField<ForInType, ForEachStatement::kNextBitFieldIndex, 1> {}; 624 }; 625 626 627 class ForOfStatement final : public ForEachStatement { 628 public: 629 void Initialize(Statement* body, Variable* iterator, 630 Expression* assign_iterator, Expression* assign_next, 631 Expression* next_result, Expression* result_done, 632 Expression* assign_each) { 633 ForEachStatement::Initialize(body); 634 iterator_ = iterator; 635 assign_iterator_ = assign_iterator; 636 assign_next_ = assign_next; 637 next_result_ = next_result; 638 result_done_ = result_done; 639 assign_each_ = assign_each; 640 } 641 642 Variable* iterator() const { 643 return iterator_; 644 } 645 646 // iterator = subject[Symbol.iterator]() 647 Expression* assign_iterator() const { 648 return assign_iterator_; 649 } 650 651 // iteratorRecord.next = iterator.next 652 Expression* assign_next() const { return assign_next_; } 653 654 // result = iterator.next() // with type check 655 Expression* next_result() const { 656 return next_result_; 657 } 658 659 // result.done 660 Expression* result_done() const { 661 return result_done_; 662 } 663 664 // each = result.value 665 Expression* assign_each() const { 666 return assign_each_; 667 } 668 669 void set_assign_iterator(Expression* e) { assign_iterator_ = e; } 670 void set_assign_next(Expression* e) { assign_next_ = e; } 671 void set_next_result(Expression* e) { next_result_ = e; } 672 void set_result_done(Expression* e) { result_done_ = e; } 673 void set_assign_each(Expression* e) { assign_each_ = e; } 674 675 private: 676 friend class AstNodeFactory; 677 678 ForOfStatement(ZonePtrList<const AstRawString>* labels, 679 ZonePtrList<const AstRawString>* own_labels, int pos) 680 : ForEachStatement(labels, own_labels, pos, kForOfStatement), 681 iterator_(nullptr), 682 assign_iterator_(nullptr), 683 next_result_(nullptr), 684 result_done_(nullptr), 685 assign_each_(nullptr) {} 686 687 Variable* iterator_; 688 Expression* assign_iterator_; 689 Expression* assign_next_; 690 Expression* next_result_; 691 Expression* result_done_; 692 Expression* assign_each_; 693 }; 694 695 696 class ExpressionStatement final : public Statement { 697 public: 698 void set_expression(Expression* e) { expression_ = e; } 699 Expression* expression() const { return expression_; } 700 bool IsJump() const { return expression_->IsThrow(); } 701 702 private: 703 friend class AstNodeFactory; 704 705 ExpressionStatement(Expression* expression, int pos) 706 : Statement(pos, kExpressionStatement), expression_(expression) {} 707 708 Expression* expression_; 709 }; 710 711 712 class JumpStatement : public Statement { 713 public: 714 bool IsJump() const { return true; } 715 716 protected: 717 JumpStatement(int pos, NodeType type) : Statement(pos, type) {} 718 }; 719 720 721 class ContinueStatement final : public JumpStatement { 722 public: 723 IterationStatement* target() const { return target_; } 724 725 private: 726 friend class AstNodeFactory; 727 728 ContinueStatement(IterationStatement* target, int pos) 729 : JumpStatement(pos, kContinueStatement), target_(target) {} 730 731 IterationStatement* target_; 732 }; 733 734 735 class BreakStatement final : public JumpStatement { 736 public: 737 BreakableStatement* target() const { return target_; } 738 739 private: 740 friend class AstNodeFactory; 741 742 BreakStatement(BreakableStatement* target, int pos) 743 : JumpStatement(pos, kBreakStatement), target_(target) {} 744 745 BreakableStatement* target_; 746 }; 747 748 749 class ReturnStatement final : public JumpStatement { 750 public: 751 enum Type { kNormal, kAsyncReturn }; 752 Expression* expression() const { return expression_; } 753 754 Type type() const { return TypeField::decode(bit_field_); } 755 bool is_async_return() const { return type() == kAsyncReturn; } 756 757 int end_position() const { return end_position_; } 758 759 private: 760 friend class AstNodeFactory; 761 762 ReturnStatement(Expression* expression, Type type, int pos, int end_position) 763 : JumpStatement(pos, kReturnStatement), 764 expression_(expression), 765 end_position_(end_position) { 766 bit_field_ |= TypeField::encode(type); 767 } 768 769 Expression* expression_; 770 int end_position_; 771 772 class TypeField 773 : public BitField<Type, JumpStatement::kNextBitFieldIndex, 1> {}; 774 }; 775 776 777 class WithStatement final : public Statement { 778 public: 779 Scope* scope() { return scope_; } 780 Expression* expression() const { return expression_; } 781 Statement* statement() const { return statement_; } 782 void set_statement(Statement* s) { statement_ = s; } 783 784 private: 785 friend class AstNodeFactory; 786 787 WithStatement(Scope* scope, Expression* expression, Statement* statement, 788 int pos) 789 : Statement(pos, kWithStatement), 790 scope_(scope), 791 expression_(expression), 792 statement_(statement) {} 793 794 Scope* scope_; 795 Expression* expression_; 796 Statement* statement_; 797 }; 798 799 class CaseClause final : public ZoneObject { 800 public: 801 bool is_default() const { return label_ == nullptr; } 802 Expression* label() const { 803 DCHECK(!is_default()); 804 return label_; 805 } 806 ZonePtrList<Statement>* statements() const { return statements_; } 807 808 private: 809 friend class AstNodeFactory; 810 811 CaseClause(Expression* label, ZonePtrList<Statement>* statements); 812 813 Expression* label_; 814 ZonePtrList<Statement>* statements_; 815 }; 816 817 818 class SwitchStatement final : public BreakableStatement { 819 public: 820 ZonePtrList<const AstRawString>* labels() const { return labels_; } 821 822 Expression* tag() const { return tag_; } 823 void set_tag(Expression* t) { tag_ = t; } 824 825 ZonePtrList<CaseClause>* cases() { return &cases_; } 826 827 private: 828 friend class AstNodeFactory; 829 830 SwitchStatement(Zone* zone, ZonePtrList<const AstRawString>* labels, 831 Expression* tag, int pos) 832 : BreakableStatement(TARGET_FOR_ANONYMOUS, pos, kSwitchStatement), 833 labels_(labels), 834 tag_(tag), 835 cases_(4, zone) {} 836 837 ZonePtrList<const AstRawString>* labels_; 838 Expression* tag_; 839 ZonePtrList<CaseClause> cases_; 840 }; 841 842 843 // If-statements always have non-null references to their then- and 844 // else-parts. When parsing if-statements with no explicit else-part, 845 // the parser implicitly creates an empty statement. Use the 846 // HasThenStatement() and HasElseStatement() functions to check if a 847 // given if-statement has a then- or an else-part containing code. 848 class IfStatement final : public Statement { 849 public: 850 bool HasThenStatement() const { return !then_statement()->IsEmpty(); } 851 bool HasElseStatement() const { return !else_statement()->IsEmpty(); } 852 853 Expression* condition() const { return condition_; } 854 Statement* then_statement() const { return then_statement_; } 855 Statement* else_statement() const { return else_statement_; } 856 857 void set_then_statement(Statement* s) { then_statement_ = s; } 858 void set_else_statement(Statement* s) { else_statement_ = s; } 859 860 bool IsJump() const { 861 return HasThenStatement() && then_statement()->IsJump() 862 && HasElseStatement() && else_statement()->IsJump(); 863 } 864 865 private: 866 friend class AstNodeFactory; 867 868 IfStatement(Expression* condition, Statement* then_statement, 869 Statement* else_statement, int pos) 870 : Statement(pos, kIfStatement), 871 condition_(condition), 872 then_statement_(then_statement), 873 else_statement_(else_statement) {} 874 875 Expression* condition_; 876 Statement* then_statement_; 877 Statement* else_statement_; 878 }; 879 880 881 class TryStatement : public Statement { 882 public: 883 Block* try_block() const { return try_block_; } 884 void set_try_block(Block* b) { try_block_ = b; } 885 886 protected: 887 TryStatement(Block* try_block, int pos, NodeType type) 888 : Statement(pos, type), try_block_(try_block) {} 889 890 private: 891 Block* try_block_; 892 }; 893 894 895 class TryCatchStatement final : public TryStatement { 896 public: 897 Scope* scope() { return scope_; } 898 Block* catch_block() const { return catch_block_; } 899 void set_catch_block(Block* b) { catch_block_ = b; } 900 901 // Prediction of whether exceptions thrown into the handler for this try block 902 // will be caught. 903 // 904 // BytecodeGenerator tracks the state of catch prediction, which can change 905 // with each TryCatchStatement encountered. The tracked catch prediction is 906 // later compiled into the code's handler table. The runtime uses this 907 // information to implement a feature that notifies the debugger when an 908 // uncaught exception is thrown, _before_ the exception propagates to the top. 909 // 910 // If this try/catch statement is meant to rethrow (HandlerTable::UNCAUGHT), 911 // the catch prediction value is set to the same value as the surrounding 912 // catch prediction. 913 // 914 // Since it's generally undecidable whether an exception will be caught, our 915 // prediction is only an approximation. 916 // --------------------------------------------------------------------------- 917 inline HandlerTable::CatchPrediction GetCatchPrediction( 918 HandlerTable::CatchPrediction outer_catch_prediction) const { 919 if (catch_prediction_ == HandlerTable::UNCAUGHT) { 920 return outer_catch_prediction; 921 } 922 return catch_prediction_; 923 } 924 925 // Indicates whether or not code should be generated to clear the pending 926 // exception. The pending exception is cleared for cases where the exception 927 // is not guaranteed to be rethrown, indicated by the value 928 // HandlerTable::UNCAUGHT. If both the current and surrounding catch handler's 929 // are predicted uncaught, the exception is not cleared. 930 // 931 // If this handler is not going to simply rethrow the exception, this method 932 // indicates that the isolate's pending exception message should be cleared 933 // before executing the catch_block. 934 // In the normal use case, this flag is always on because the message object 935 // is not needed anymore when entering the catch block and should not be 936 // kept alive. 937 // The use case where the flag is off is when the catch block is guaranteed 938 // to rethrow the caught exception (using %ReThrow), which reuses the 939 // pending message instead of generating a new one. 940 // (When the catch block doesn't rethrow but is guaranteed to perform an 941 // ordinary throw, not clearing the old message is safe but not very 942 // useful.) 943 inline bool ShouldClearPendingException( 944 HandlerTable::CatchPrediction outer_catch_prediction) const { 945 return catch_prediction_ != HandlerTable::UNCAUGHT || 946 outer_catch_prediction != HandlerTable::UNCAUGHT; 947 } 948 949 private: 950 friend class AstNodeFactory; 951 952 TryCatchStatement(Block* try_block, Scope* scope, Block* catch_block, 953 HandlerTable::CatchPrediction catch_prediction, int pos) 954 : TryStatement(try_block, pos, kTryCatchStatement), 955 scope_(scope), 956 catch_block_(catch_block), 957 catch_prediction_(catch_prediction) {} 958 959 Scope* scope_; 960 Block* catch_block_; 961 HandlerTable::CatchPrediction catch_prediction_; 962 }; 963 964 965 class TryFinallyStatement final : public TryStatement { 966 public: 967 Block* finally_block() const { return finally_block_; } 968 void set_finally_block(Block* b) { finally_block_ = b; } 969 970 private: 971 friend class AstNodeFactory; 972 973 TryFinallyStatement(Block* try_block, Block* finally_block, int pos) 974 : TryStatement(try_block, pos, kTryFinallyStatement), 975 finally_block_(finally_block) {} 976 977 Block* finally_block_; 978 }; 979 980 981 class DebuggerStatement final : public Statement { 982 private: 983 friend class AstNodeFactory; 984 985 explicit DebuggerStatement(int pos) : Statement(pos, kDebuggerStatement) {} 986 }; 987 988 989 class EmptyStatement final : public Statement { 990 private: 991 friend class AstNodeFactory; 992 explicit EmptyStatement(int pos) : Statement(pos, kEmptyStatement) {} 993 }; 994 995 996 // Delegates to another statement, which may be overwritten. 997 // This was introduced to implement ES2015 Annex B3.3 for conditionally making 998 // sloppy-mode block-scoped functions have a var binding, which is changed 999 // from one statement to another during parsing. 1000 class SloppyBlockFunctionStatement final : public Statement { 1001 public: 1002 Statement* statement() const { return statement_; } 1003 void set_statement(Statement* statement) { statement_ = statement; } 1004 1005 private: 1006 friend class AstNodeFactory; 1007 1008 explicit SloppyBlockFunctionStatement(Statement* statement) 1009 : Statement(kNoSourcePosition, kSloppyBlockFunctionStatement), 1010 statement_(statement) {} 1011 1012 Statement* statement_; 1013 }; 1014 1015 1016 class Literal final : public Expression { 1017 public: 1018 enum Type { 1019 kSmi, 1020 kHeapNumber, 1021 kBigInt, 1022 kString, 1023 kSymbol, 1024 kBoolean, 1025 kUndefined, 1026 kNull, 1027 kTheHole, 1028 }; 1029 1030 Type type() const { return TypeField::decode(bit_field_); } 1031 1032 // Returns true if literal represents a property name (i.e. cannot be parsed 1033 // as array indices). 1034 bool IsPropertyName() const; 1035 1036 // Returns true if literal represents an array index. 1037 // Note, that in general the following statement is not true: 1038 // key->IsPropertyName() != key->AsArrayIndex(...) 1039 // but for non-computed LiteralProperty properties the following is true: 1040 // property->key()->IsPropertyName() != property->key()->AsArrayIndex(...) 1041 bool AsArrayIndex(uint32_t* index) const; 1042 1043 const AstRawString* AsRawPropertyName() { 1044 DCHECK(IsPropertyName()); 1045 return string_; 1046 } 1047 1048 Smi* AsSmiLiteral() const { 1049 DCHECK_EQ(kSmi, type()); 1050 return Smi::FromInt(smi_); 1051 } 1052 1053 // Returns true if literal represents a Number. 1054 bool IsNumber() const { return type() == kHeapNumber || type() == kSmi; } 1055 double AsNumber() const { 1056 DCHECK(IsNumber()); 1057 switch (type()) { 1058 case kSmi: 1059 return smi_; 1060 case kHeapNumber: 1061 return number_; 1062 default: 1063 UNREACHABLE(); 1064 } 1065 } 1066 1067 AstBigInt AsBigInt() const { 1068 DCHECK_EQ(type(), kBigInt); 1069 return bigint_; 1070 } 1071 1072 bool IsString() const { return type() == kString; } 1073 const AstRawString* AsRawString() { 1074 DCHECK_EQ(type(), kString); 1075 return string_; 1076 } 1077 1078 AstSymbol AsSymbol() { 1079 DCHECK_EQ(type(), kSymbol); 1080 return symbol_; 1081 } 1082 1083 V8_EXPORT_PRIVATE bool ToBooleanIsTrue() const; 1084 bool ToBooleanIsFalse() const { return !ToBooleanIsTrue(); } 1085 1086 bool ToUint32(uint32_t* value) const; 1087 1088 // Returns an appropriate Object representing this Literal, allocating 1089 // a heap object if needed. 1090 Handle<Object> BuildValue(Isolate* isolate) const; 1091 1092 // Support for using Literal as a HashMap key. NOTE: Currently, this works 1093 // only for string and number literals! 1094 uint32_t Hash(); 1095 static bool Match(void* literal1, void* literal2); 1096 1097 private: 1098 friend class AstNodeFactory; 1099 1100 class TypeField : public BitField<Type, Expression::kNextBitFieldIndex, 4> {}; 1101 1102 Literal(int smi, int position) : Expression(position, kLiteral), smi_(smi) { 1103 bit_field_ = TypeField::update(bit_field_, kSmi); 1104 } 1105 1106 Literal(double number, int position) 1107 : Expression(position, kLiteral), number_(number) { 1108 bit_field_ = TypeField::update(bit_field_, kHeapNumber); 1109 } 1110 1111 Literal(AstBigInt bigint, int position) 1112 : Expression(position, kLiteral), bigint_(bigint) { 1113 bit_field_ = TypeField::update(bit_field_, kBigInt); 1114 } 1115 1116 Literal(const AstRawString* string, int position) 1117 : Expression(position, kLiteral), string_(string) { 1118 bit_field_ = TypeField::update(bit_field_, kString); 1119 } 1120 1121 Literal(AstSymbol symbol, int position) 1122 : Expression(position, kLiteral), symbol_(symbol) { 1123 bit_field_ = TypeField::update(bit_field_, kSymbol); 1124 } 1125 1126 Literal(bool boolean, int position) 1127 : Expression(position, kLiteral), boolean_(boolean) { 1128 bit_field_ = TypeField::update(bit_field_, kBoolean); 1129 } 1130 1131 Literal(Type type, int position) : Expression(position, kLiteral) { 1132 DCHECK(type == kNull || type == kUndefined || type == kTheHole); 1133 bit_field_ = TypeField::update(bit_field_, type); 1134 } 1135 1136 union { 1137 const AstRawString* string_; 1138 int smi_; 1139 double number_; 1140 AstSymbol symbol_; 1141 AstBigInt bigint_; 1142 bool boolean_; 1143 }; 1144 }; 1145 1146 // Base class for literals that need space in the type feedback vector. 1147 class MaterializedLiteral : public Expression { 1148 public: 1149 // A Materializedliteral is simple if the values consist of only 1150 // constants and simple object and array literals. 1151 bool IsSimple() const; 1152 1153 protected: 1154 MaterializedLiteral(int pos, NodeType type) : Expression(pos, type) {} 1155 1156 friend class CompileTimeValue; 1157 friend class ArrayLiteral; 1158 friend class ObjectLiteral; 1159 1160 // Populate the depth field and any flags the literal has, returns the depth. 1161 int InitDepthAndFlags(); 1162 1163 bool NeedsInitialAllocationSite(); 1164 1165 // Populate the constant properties/elements fixed array. 1166 void BuildConstants(Isolate* isolate); 1167 1168 // If the expression is a literal, return the literal value; 1169 // if the expression is a materialized literal and is_simple 1170 // then return an Array or Object Boilerplate Description 1171 // Otherwise, return undefined literal as the placeholder 1172 // in the object literal boilerplate. 1173 Handle<Object> GetBoilerplateValue(Expression* expression, Isolate* isolate); 1174 }; 1175 1176 // Node for capturing a regexp literal. 1177 class RegExpLiteral final : public MaterializedLiteral { 1178 public: 1179 Handle<String> pattern() const { return pattern_->string(); } 1180 const AstRawString* raw_pattern() const { return pattern_; } 1181 int flags() const { return flags_; } 1182 1183 private: 1184 friend class AstNodeFactory; 1185 1186 RegExpLiteral(const AstRawString* pattern, int flags, int pos) 1187 : MaterializedLiteral(pos, kRegExpLiteral), 1188 flags_(flags), 1189 pattern_(pattern) {} 1190 1191 int const flags_; 1192 const AstRawString* const pattern_; 1193 }; 1194 1195 // Base class for Array and Object literals, providing common code for handling 1196 // nested subliterals. 1197 class AggregateLiteral : public MaterializedLiteral { 1198 public: 1199 enum Flags { 1200 kNoFlags = 0, 1201 kIsShallow = 1, 1202 kDisableMementos = 1 << 1, 1203 kNeedsInitialAllocationSite = 1 << 2, 1204 }; 1205 1206 bool is_initialized() const { return 0 < depth_; } 1207 int depth() const { 1208 DCHECK(is_initialized()); 1209 return depth_; 1210 } 1211 1212 bool is_shallow() const { return depth() == 1; } 1213 bool needs_initial_allocation_site() const { 1214 return NeedsInitialAllocationSiteField::decode(bit_field_); 1215 } 1216 1217 int ComputeFlags(bool disable_mementos = false) const { 1218 int flags = kNoFlags; 1219 if (is_shallow()) flags |= kIsShallow; 1220 if (disable_mementos) flags |= kDisableMementos; 1221 if (needs_initial_allocation_site()) flags |= kNeedsInitialAllocationSite; 1222 return flags; 1223 } 1224 1225 // An AggregateLiteral is simple if the values consist of only 1226 // constants and simple object and array literals. 1227 bool is_simple() const { return IsSimpleField::decode(bit_field_); } 1228 1229 private: 1230 int depth_ : 31; 1231 class NeedsInitialAllocationSiteField 1232 : public BitField<bool, MaterializedLiteral::kNextBitFieldIndex, 1> {}; 1233 class IsSimpleField 1234 : public BitField<bool, NeedsInitialAllocationSiteField::kNext, 1> {}; 1235 1236 protected: 1237 friend class AstNodeFactory; 1238 AggregateLiteral(int pos, NodeType type) 1239 : MaterializedLiteral(pos, type), depth_(0) { 1240 bit_field_ |= NeedsInitialAllocationSiteField::encode(false) | 1241 IsSimpleField::encode(false); 1242 } 1243 1244 void set_is_simple(bool is_simple) { 1245 bit_field_ = IsSimpleField::update(bit_field_, is_simple); 1246 } 1247 1248 void set_depth(int depth) { 1249 DCHECK(!is_initialized()); 1250 depth_ = depth; 1251 } 1252 1253 void set_needs_initial_allocation_site(bool required) { 1254 bit_field_ = NeedsInitialAllocationSiteField::update(bit_field_, required); 1255 } 1256 1257 static const uint8_t kNextBitFieldIndex = IsSimpleField::kNext; 1258 }; 1259 1260 // Common supertype for ObjectLiteralProperty and ClassLiteralProperty 1261 class LiteralProperty : public ZoneObject { 1262 public: 1263 Expression* key() const { return key_; } 1264 Expression* value() const { return value_; } 1265 1266 bool is_computed_name() const { return is_computed_name_; } 1267 bool NeedsSetFunctionName() const; 1268 1269 protected: 1270 LiteralProperty(Expression* key, Expression* value, bool is_computed_name) 1271 : key_(key), value_(value), is_computed_name_(is_computed_name) {} 1272 1273 Expression* key_; 1274 Expression* value_; 1275 bool is_computed_name_; 1276 }; 1277 1278 // Property is used for passing information 1279 // about an object literal's properties from the parser 1280 // to the code generator. 1281 class ObjectLiteralProperty final : public LiteralProperty { 1282 public: 1283 enum Kind : uint8_t { 1284 CONSTANT, // Property with constant value (compile time). 1285 COMPUTED, // Property with computed value (execution time). 1286 MATERIALIZED_LITERAL, // Property value is a materialized literal. 1287 GETTER, 1288 SETTER, // Property is an accessor function. 1289 PROTOTYPE, // Property is __proto__. 1290 SPREAD 1291 }; 1292 1293 Kind kind() const { return kind_; } 1294 1295 bool IsCompileTimeValue() const; 1296 1297 void set_emit_store(bool emit_store); 1298 bool emit_store() const; 1299 1300 bool IsNullPrototype() const { 1301 return IsPrototype() && value()->IsNullLiteral(); 1302 } 1303 bool IsPrototype() const { return kind() == PROTOTYPE; } 1304 1305 private: 1306 friend class AstNodeFactory; 1307 1308 ObjectLiteralProperty(Expression* key, Expression* value, Kind kind, 1309 bool is_computed_name); 1310 ObjectLiteralProperty(AstValueFactory* ast_value_factory, Expression* key, 1311 Expression* value, bool is_computed_name); 1312 1313 Kind kind_; 1314 bool emit_store_; 1315 }; 1316 1317 1318 // An object literal has a boilerplate object that is used 1319 // for minimizing the work when constructing it at runtime. 1320 class ObjectLiteral final : public AggregateLiteral { 1321 public: 1322 typedef ObjectLiteralProperty Property; 1323 1324 Handle<ObjectBoilerplateDescription> boilerplate_description() const { 1325 DCHECK(!boilerplate_description_.is_null()); 1326 return boilerplate_description_; 1327 } 1328 int properties_count() const { return boilerplate_properties_; } 1329 ZonePtrList<Property>* properties() const { return properties_; } 1330 bool has_elements() const { return HasElementsField::decode(bit_field_); } 1331 bool has_rest_property() const { 1332 return HasRestPropertyField::decode(bit_field_); 1333 } 1334 bool fast_elements() const { return FastElementsField::decode(bit_field_); } 1335 bool has_null_prototype() const { 1336 return HasNullPrototypeField::decode(bit_field_); 1337 } 1338 1339 bool is_empty() const { 1340 DCHECK(is_initialized()); 1341 return !has_elements() && properties_count() == 0 && 1342 properties()->length() == 0; 1343 } 1344 1345 bool IsEmptyObjectLiteral() const { 1346 return is_empty() && !has_null_prototype(); 1347 } 1348 1349 // Populate the depth field and flags, returns the depth. 1350 int InitDepthAndFlags(); 1351 1352 // Get the boilerplate description, populating it if necessary. 1353 Handle<ObjectBoilerplateDescription> GetOrBuildBoilerplateDescription( 1354 Isolate* isolate) { 1355 if (boilerplate_description_.is_null()) { 1356 BuildBoilerplateDescription(isolate); 1357 } 1358 return boilerplate_description(); 1359 } 1360 1361 // Populate the boilerplate description. 1362 void BuildBoilerplateDescription(Isolate* isolate); 1363 1364 // Mark all computed expressions that are bound to a key that 1365 // is shadowed by a later occurrence of the same key. For the 1366 // marked expressions, no store code is emitted. 1367 void CalculateEmitStore(Zone* zone); 1368 1369 // Determines whether the {CreateShallowObjectLiteratal} builtin can be used. 1370 bool IsFastCloningSupported() const; 1371 1372 // Assemble bitfield of flags for the CreateObjectLiteral helper. 1373 int ComputeFlags(bool disable_mementos = false) const { 1374 int flags = AggregateLiteral::ComputeFlags(disable_mementos); 1375 if (fast_elements()) flags |= kFastElements; 1376 if (has_null_prototype()) flags |= kHasNullPrototype; 1377 return flags; 1378 } 1379 1380 int EncodeLiteralType() { 1381 int flags = kNoFlags; 1382 if (fast_elements()) flags |= kFastElements; 1383 if (has_null_prototype()) flags |= kHasNullPrototype; 1384 return flags; 1385 } 1386 1387 enum Flags { 1388 kFastElements = 1 << 3, 1389 kHasNullPrototype = 1 << 4, 1390 }; 1391 STATIC_ASSERT( 1392 static_cast<int>(AggregateLiteral::kNeedsInitialAllocationSite) < 1393 static_cast<int>(kFastElements)); 1394 1395 struct Accessors: public ZoneObject { 1396 Accessors() : getter(nullptr), setter(nullptr) {} 1397 ObjectLiteralProperty* getter; 1398 ObjectLiteralProperty* setter; 1399 }; 1400 1401 private: 1402 friend class AstNodeFactory; 1403 1404 ObjectLiteral(ZonePtrList<Property>* properties, 1405 uint32_t boilerplate_properties, int pos, 1406 bool has_rest_property) 1407 : AggregateLiteral(pos, kObjectLiteral), 1408 boilerplate_properties_(boilerplate_properties), 1409 properties_(properties) { 1410 bit_field_ |= HasElementsField::encode(false) | 1411 HasRestPropertyField::encode(has_rest_property) | 1412 FastElementsField::encode(false) | 1413 HasNullPrototypeField::encode(false); 1414 } 1415 1416 void InitFlagsForPendingNullPrototype(int i); 1417 1418 void set_has_elements(bool has_elements) { 1419 bit_field_ = HasElementsField::update(bit_field_, has_elements); 1420 } 1421 void set_fast_elements(bool fast_elements) { 1422 bit_field_ = FastElementsField::update(bit_field_, fast_elements); 1423 } 1424 void set_has_null_protoype(bool has_null_prototype) { 1425 bit_field_ = HasNullPrototypeField::update(bit_field_, has_null_prototype); 1426 } 1427 1428 uint32_t boilerplate_properties_; 1429 Handle<ObjectBoilerplateDescription> boilerplate_description_; 1430 ZoneList<Property*>* properties_; 1431 1432 class HasElementsField 1433 : public BitField<bool, AggregateLiteral::kNextBitFieldIndex, 1> {}; 1434 class HasRestPropertyField 1435 : public BitField<bool, HasElementsField::kNext, 1> {}; 1436 class FastElementsField 1437 : public BitField<bool, HasRestPropertyField::kNext, 1> {}; 1438 class HasNullPrototypeField 1439 : public BitField<bool, FastElementsField::kNext, 1> {}; 1440 }; 1441 1442 1443 // A map from property names to getter/setter pairs allocated in the zone. 1444 class AccessorTable 1445 : public base::TemplateHashMap<Literal, ObjectLiteral::Accessors, 1446 bool (*)(void*, void*), 1447 ZoneAllocationPolicy> { 1448 public: 1449 explicit AccessorTable(Zone* zone) 1450 : base::TemplateHashMap<Literal, ObjectLiteral::Accessors, 1451 bool (*)(void*, void*), ZoneAllocationPolicy>( 1452 Literal::Match, ZoneAllocationPolicy(zone)), 1453 zone_(zone) {} 1454 1455 Iterator lookup(Literal* literal) { 1456 Iterator it = find(literal, true, ZoneAllocationPolicy(zone_)); 1457 if (it->second == nullptr) { 1458 it->second = new (zone_) ObjectLiteral::Accessors(); 1459 } 1460 return it; 1461 } 1462 1463 private: 1464 Zone* zone_; 1465 }; 1466 1467 1468 // An array literal has a literals object that is used 1469 // for minimizing the work when constructing it at runtime. 1470 class ArrayLiteral final : public AggregateLiteral { 1471 public: 1472 Handle<ArrayBoilerplateDescription> boilerplate_description() const { 1473 return boilerplate_description_; 1474 } 1475 1476 ZonePtrList<Expression>* values() const { return values_; } 1477 1478 int first_spread_index() const { return first_spread_index_; } 1479 1480 bool is_empty() const; 1481 1482 // Populate the depth field and flags, returns the depth. 1483 int InitDepthAndFlags(); 1484 1485 // Get the boilerplate description, populating it if necessary. 1486 Handle<ArrayBoilerplateDescription> GetOrBuildBoilerplateDescription( 1487 Isolate* isolate) { 1488 if (boilerplate_description_.is_null()) { 1489 BuildBoilerplateDescription(isolate); 1490 } 1491 return boilerplate_description(); 1492 } 1493 1494 // Populate the boilerplate description. 1495 void BuildBoilerplateDescription(Isolate* isolate); 1496 1497 // Determines whether the {CreateShallowArrayLiteral} builtin can be used. 1498 bool IsFastCloningSupported() const; 1499 1500 // Assemble bitfield of flags for the CreateArrayLiteral helper. 1501 int ComputeFlags(bool disable_mementos = false) const { 1502 return AggregateLiteral::ComputeFlags(disable_mementos); 1503 } 1504 1505 private: 1506 friend class AstNodeFactory; 1507 1508 ArrayLiteral(ZonePtrList<Expression>* values, int first_spread_index, int pos) 1509 : AggregateLiteral(pos, kArrayLiteral), 1510 first_spread_index_(first_spread_index), 1511 values_(values) {} 1512 1513 int first_spread_index_; 1514 Handle<ArrayBoilerplateDescription> boilerplate_description_; 1515 ZonePtrList<Expression>* values_; 1516 }; 1517 1518 enum class HoleCheckMode { kRequired, kElided }; 1519 1520 class VariableProxy final : public Expression { 1521 public: 1522 bool IsValidReferenceExpression() const { 1523 return !is_this() && !is_new_target(); 1524 } 1525 1526 Handle<String> name() const { return raw_name()->string(); } 1527 const AstRawString* raw_name() const { 1528 return is_resolved() ? var_->raw_name() : raw_name_; 1529 } 1530 1531 Variable* var() const { 1532 DCHECK(is_resolved()); 1533 return var_; 1534 } 1535 void set_var(Variable* v) { 1536 DCHECK(!is_resolved()); 1537 DCHECK_NOT_NULL(v); 1538 var_ = v; 1539 } 1540 1541 bool is_this() const { return IsThisField::decode(bit_field_); } 1542 1543 bool is_assigned() const { return IsAssignedField::decode(bit_field_); } 1544 void set_is_assigned() { 1545 bit_field_ = IsAssignedField::update(bit_field_, true); 1546 if (is_resolved()) { 1547 var()->set_maybe_assigned(); 1548 } 1549 } 1550 1551 bool is_resolved() const { return IsResolvedField::decode(bit_field_); } 1552 void set_is_resolved() { 1553 bit_field_ = IsResolvedField::update(bit_field_, true); 1554 } 1555 1556 bool is_new_target() const { return IsNewTargetField::decode(bit_field_); } 1557 void set_is_new_target() { 1558 bit_field_ = IsNewTargetField::update(bit_field_, true); 1559 } 1560 1561 HoleCheckMode hole_check_mode() const { 1562 HoleCheckMode mode = HoleCheckModeField::decode(bit_field_); 1563 DCHECK_IMPLIES(mode == HoleCheckMode::kRequired, 1564 var()->binding_needs_init() || 1565 var()->local_if_not_shadowed()->binding_needs_init()); 1566 return mode; 1567 } 1568 void set_needs_hole_check() { 1569 bit_field_ = 1570 HoleCheckModeField::update(bit_field_, HoleCheckMode::kRequired); 1571 } 1572 1573 bool is_private_field() const { return IsPrivateField::decode(bit_field_); } 1574 void set_is_private_field() { 1575 bit_field_ = IsPrivateField::update(bit_field_, true); 1576 } 1577 1578 // Bind this proxy to the variable var. 1579 void BindTo(Variable* var); 1580 1581 void set_next_unresolved(VariableProxy* next) { next_unresolved_ = next; } 1582 VariableProxy* next_unresolved() { return next_unresolved_; } 1583 1584 private: 1585 friend class AstNodeFactory; 1586 1587 VariableProxy(Variable* var, int start_position); 1588 1589 VariableProxy(const AstRawString* name, VariableKind variable_kind, 1590 int start_position) 1591 : Expression(start_position, kVariableProxy), 1592 raw_name_(name), 1593 next_unresolved_(nullptr) { 1594 bit_field_ |= IsThisField::encode(variable_kind == THIS_VARIABLE) | 1595 IsAssignedField::encode(false) | 1596 IsResolvedField::encode(false) | 1597 HoleCheckModeField::encode(HoleCheckMode::kElided) | 1598 IsPrivateField::encode(false); 1599 } 1600 1601 explicit VariableProxy(const VariableProxy* copy_from); 1602 1603 class IsThisField : public BitField<bool, Expression::kNextBitFieldIndex, 1> { 1604 }; 1605 class IsAssignedField : public BitField<bool, IsThisField::kNext, 1> {}; 1606 class IsResolvedField : public BitField<bool, IsAssignedField::kNext, 1> {}; 1607 class IsNewTargetField : public BitField<bool, IsResolvedField::kNext, 1> {}; 1608 class HoleCheckModeField 1609 : public BitField<HoleCheckMode, IsNewTargetField::kNext, 1> {}; 1610 class IsPrivateField : public BitField<bool, HoleCheckModeField::kNext, 1> {}; 1611 1612 union { 1613 const AstRawString* raw_name_; // if !is_resolved_ 1614 Variable* var_; // if is_resolved_ 1615 }; 1616 VariableProxy* next_unresolved_; 1617 }; 1618 1619 1620 // Left-hand side can only be a property, a global or a (parameter or local) 1621 // slot. 1622 enum LhsKind { 1623 VARIABLE, 1624 NAMED_PROPERTY, 1625 KEYED_PROPERTY, 1626 NAMED_SUPER_PROPERTY, 1627 KEYED_SUPER_PROPERTY 1628 }; 1629 1630 class Property final : public Expression { 1631 public: 1632 bool IsValidReferenceExpression() const { return true; } 1633 1634 Expression* obj() const { return obj_; } 1635 Expression* key() const { return key_; } 1636 1637 bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); } 1638 1639 // Returns the properties assign type. 1640 static LhsKind GetAssignType(Property* property) { 1641 if (property == nullptr) return VARIABLE; 1642 bool super_access = property->IsSuperAccess(); 1643 return (property->key()->IsPropertyName()) 1644 ? (super_access ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY) 1645 : (super_access ? KEYED_SUPER_PROPERTY : KEYED_PROPERTY); 1646 } 1647 1648 private: 1649 friend class AstNodeFactory; 1650 1651 Property(Expression* obj, Expression* key, int pos) 1652 : Expression(pos, kProperty), obj_(obj), key_(key) { 1653 } 1654 1655 Expression* obj_; 1656 Expression* key_; 1657 }; 1658 1659 // ResolvedProperty pairs a receiver field with a value field. It allows Call 1660 // to support arbitrary receivers while still taking advantage of TypeFeedback. 1661 class ResolvedProperty final : public Expression { 1662 public: 1663 VariableProxy* object() const { return object_; } 1664 VariableProxy* property() const { return property_; } 1665 1666 void set_object(VariableProxy* e) { object_ = e; } 1667 void set_property(VariableProxy* e) { property_ = e; } 1668 1669 private: 1670 friend class AstNodeFactory; 1671 1672 ResolvedProperty(VariableProxy* obj, VariableProxy* property, int pos) 1673 : Expression(pos, kResolvedProperty), object_(obj), property_(property) {} 1674 1675 VariableProxy* object_; 1676 VariableProxy* property_; 1677 }; 1678 1679 class Call final : public Expression { 1680 public: 1681 Expression* expression() const { return expression_; } 1682 ZonePtrList<Expression>* arguments() const { return arguments_; } 1683 1684 bool is_possibly_eval() const { 1685 return IsPossiblyEvalField::decode(bit_field_); 1686 } 1687 1688 bool is_tagged_template() const { 1689 return IsTaggedTemplateField::decode(bit_field_); 1690 } 1691 1692 bool only_last_arg_is_spread() { 1693 return !arguments_->is_empty() && arguments_->last()->IsSpread(); 1694 } 1695 1696 enum CallType { 1697 GLOBAL_CALL, 1698 WITH_CALL, 1699 NAMED_PROPERTY_CALL, 1700 KEYED_PROPERTY_CALL, 1701 NAMED_SUPER_PROPERTY_CALL, 1702 KEYED_SUPER_PROPERTY_CALL, 1703 SUPER_CALL, 1704 RESOLVED_PROPERTY_CALL, 1705 OTHER_CALL 1706 }; 1707 1708 enum PossiblyEval { 1709 IS_POSSIBLY_EVAL, 1710 NOT_EVAL, 1711 }; 1712 1713 // Helpers to determine how to handle the call. 1714 CallType GetCallType() const; 1715 1716 enum class TaggedTemplateTag { kTrue }; 1717 1718 private: 1719 friend class AstNodeFactory; 1720 1721 Call(Expression* expression, ZonePtrList<Expression>* arguments, int pos, 1722 PossiblyEval possibly_eval) 1723 : Expression(pos, kCall), expression_(expression), arguments_(arguments) { 1724 bit_field_ |= 1725 IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL) | 1726 IsTaggedTemplateField::encode(false); 1727 } 1728 1729 Call(Expression* expression, ZonePtrList<Expression>* arguments, int pos, 1730 TaggedTemplateTag tag) 1731 : Expression(pos, kCall), expression_(expression), arguments_(arguments) { 1732 bit_field_ |= IsPossiblyEvalField::encode(false) | 1733 IsTaggedTemplateField::encode(true); 1734 } 1735 1736 class IsPossiblyEvalField 1737 : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; 1738 class IsTaggedTemplateField 1739 : public BitField<bool, IsPossiblyEvalField::kNext, 1> {}; 1740 1741 Expression* expression_; 1742 ZonePtrList<Expression>* arguments_; 1743 }; 1744 1745 1746 class CallNew final : public Expression { 1747 public: 1748 Expression* expression() const { return expression_; } 1749 ZonePtrList<Expression>* arguments() const { return arguments_; } 1750 1751 bool only_last_arg_is_spread() { 1752 return !arguments_->is_empty() && arguments_->last()->IsSpread(); 1753 } 1754 1755 private: 1756 friend class AstNodeFactory; 1757 1758 CallNew(Expression* expression, ZonePtrList<Expression>* arguments, int pos) 1759 : Expression(pos, kCallNew), 1760 expression_(expression), 1761 arguments_(arguments) {} 1762 1763 Expression* expression_; 1764 ZonePtrList<Expression>* arguments_; 1765 }; 1766 1767 // The CallRuntime class does not represent any official JavaScript 1768 // language construct. Instead it is used to call a C or JS function 1769 // with a set of arguments. This is used from the builtins that are 1770 // implemented in JavaScript. 1771 class CallRuntime final : public Expression { 1772 public: 1773 ZonePtrList<Expression>* arguments() const { return arguments_; } 1774 bool is_jsruntime() const { return function_ == nullptr; } 1775 1776 int context_index() const { 1777 DCHECK(is_jsruntime()); 1778 return context_index_; 1779 } 1780 const Runtime::Function* function() const { 1781 DCHECK(!is_jsruntime()); 1782 return function_; 1783 } 1784 1785 const char* debug_name(); 1786 1787 private: 1788 friend class AstNodeFactory; 1789 1790 CallRuntime(const Runtime::Function* function, 1791 ZonePtrList<Expression>* arguments, int pos) 1792 : Expression(pos, kCallRuntime), 1793 function_(function), 1794 arguments_(arguments) {} 1795 CallRuntime(int context_index, ZonePtrList<Expression>* arguments, int pos) 1796 : Expression(pos, kCallRuntime), 1797 context_index_(context_index), 1798 function_(nullptr), 1799 arguments_(arguments) {} 1800 1801 int context_index_; 1802 const Runtime::Function* function_; 1803 ZonePtrList<Expression>* arguments_; 1804 }; 1805 1806 1807 class UnaryOperation final : public Expression { 1808 public: 1809 Token::Value op() const { return OperatorField::decode(bit_field_); } 1810 Expression* expression() const { return expression_; } 1811 1812 private: 1813 friend class AstNodeFactory; 1814 1815 UnaryOperation(Token::Value op, Expression* expression, int pos) 1816 : Expression(pos, kUnaryOperation), expression_(expression) { 1817 bit_field_ |= OperatorField::encode(op); 1818 DCHECK(Token::IsUnaryOp(op)); 1819 } 1820 1821 Expression* expression_; 1822 1823 class OperatorField 1824 : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {}; 1825 }; 1826 1827 1828 class BinaryOperation final : public Expression { 1829 public: 1830 Token::Value op() const { return OperatorField::decode(bit_field_); } 1831 Expression* left() const { return left_; } 1832 Expression* right() const { return right_; } 1833 1834 // Returns true if one side is a Smi literal, returning the other side's 1835 // sub-expression in |subexpr| and the literal Smi in |literal|. 1836 bool IsSmiLiteralOperation(Expression** subexpr, Smi** literal); 1837 1838 private: 1839 friend class AstNodeFactory; 1840 1841 BinaryOperation(Token::Value op, Expression* left, Expression* right, int pos) 1842 : Expression(pos, kBinaryOperation), left_(left), right_(right) { 1843 bit_field_ |= OperatorField::encode(op); 1844 DCHECK(Token::IsBinaryOp(op)); 1845 } 1846 1847 Expression* left_; 1848 Expression* right_; 1849 1850 class OperatorField 1851 : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {}; 1852 }; 1853 1854 class NaryOperation final : public Expression { 1855 public: 1856 Token::Value op() const { return OperatorField::decode(bit_field_); } 1857 Expression* first() const { return first_; } 1858 Expression* subsequent(size_t index) const { 1859 return subsequent_[index].expression; 1860 } 1861 1862 size_t subsequent_length() const { return subsequent_.size(); } 1863 int subsequent_op_position(size_t index) const { 1864 return subsequent_[index].op_position; 1865 } 1866 1867 void AddSubsequent(Expression* expr, int pos) { 1868 subsequent_.emplace_back(expr, pos); 1869 } 1870 1871 private: 1872 friend class AstNodeFactory; 1873 1874 NaryOperation(Zone* zone, Token::Value op, Expression* first, 1875 size_t initial_subsequent_size) 1876 : Expression(first->position(), kNaryOperation), 1877 first_(first), 1878 subsequent_(zone) { 1879 bit_field_ |= OperatorField::encode(op); 1880 DCHECK(Token::IsBinaryOp(op)); 1881 DCHECK_NE(op, Token::EXP); 1882 subsequent_.reserve(initial_subsequent_size); 1883 } 1884 1885 // Nary operations store the first (lhs) child expression inline, and the 1886 // child expressions (rhs of each op) are stored out-of-line, along with 1887 // their operation's position. Note that the Nary operation expression's 1888 // position has no meaning. 1889 // 1890 // So an nary add: 1891 // 1892 // expr + expr + expr + ... 1893 // 1894 // is stored as: 1895 // 1896 // (expr) [(+ expr), (+ expr), ...] 1897 // '-.--' '-----------.-----------' 1898 // first subsequent entry list 1899 1900 Expression* first_; 1901 1902 struct NaryOperationEntry { 1903 Expression* expression; 1904 int op_position; 1905 NaryOperationEntry(Expression* e, int pos) 1906 : expression(e), op_position(pos) {} 1907 }; 1908 ZoneVector<NaryOperationEntry> subsequent_; 1909 1910 class OperatorField 1911 : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {}; 1912 }; 1913 1914 class CountOperation final : public Expression { 1915 public: 1916 bool is_prefix() const { return IsPrefixField::decode(bit_field_); } 1917 bool is_postfix() const { return !is_prefix(); } 1918 1919 Token::Value op() const { return TokenField::decode(bit_field_); } 1920 1921 Expression* expression() const { return expression_; } 1922 1923 private: 1924 friend class AstNodeFactory; 1925 1926 CountOperation(Token::Value op, bool is_prefix, Expression* expr, int pos) 1927 : Expression(pos, kCountOperation), expression_(expr) { 1928 bit_field_ |= IsPrefixField::encode(is_prefix) | TokenField::encode(op); 1929 } 1930 1931 class IsPrefixField 1932 : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; 1933 class TokenField : public BitField<Token::Value, IsPrefixField::kNext, 7> {}; 1934 1935 Expression* expression_; 1936 }; 1937 1938 1939 class CompareOperation final : public Expression { 1940 public: 1941 Token::Value op() const { return OperatorField::decode(bit_field_); } 1942 Expression* left() const { return left_; } 1943 Expression* right() const { return right_; } 1944 1945 // Match special cases. 1946 bool IsLiteralCompareTypeof(Expression** expr, Literal** literal); 1947 bool IsLiteralCompareUndefined(Expression** expr); 1948 bool IsLiteralCompareNull(Expression** expr); 1949 1950 private: 1951 friend class AstNodeFactory; 1952 1953 CompareOperation(Token::Value op, Expression* left, Expression* right, 1954 int pos) 1955 : Expression(pos, kCompareOperation), left_(left), right_(right) { 1956 bit_field_ |= OperatorField::encode(op); 1957 DCHECK(Token::IsCompareOp(op)); 1958 } 1959 1960 Expression* left_; 1961 Expression* right_; 1962 1963 class OperatorField 1964 : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {}; 1965 }; 1966 1967 1968 class Spread final : public Expression { 1969 public: 1970 Expression* expression() const { return expression_; } 1971 1972 int expression_position() const { return expr_pos_; } 1973 1974 private: 1975 friend class AstNodeFactory; 1976 1977 Spread(Expression* expression, int pos, int expr_pos) 1978 : Expression(pos, kSpread), 1979 expr_pos_(expr_pos), 1980 expression_(expression) {} 1981 1982 int expr_pos_; 1983 Expression* expression_; 1984 }; 1985 1986 // The StoreInArrayLiteral node corresponds to the StaInArrayLiteral bytecode. 1987 // It is used in the rewriting of destructuring assignments that contain an 1988 // array rest pattern. 1989 class StoreInArrayLiteral final : public Expression { 1990 public: 1991 Expression* array() const { return array_; } 1992 Expression* index() const { return index_; } 1993 Expression* value() const { return value_; } 1994 1995 private: 1996 friend class AstNodeFactory; 1997 1998 StoreInArrayLiteral(Expression* array, Expression* index, Expression* value, 1999 int position) 2000 : Expression(position, kStoreInArrayLiteral), 2001 array_(array), 2002 index_(index), 2003 value_(value) {} 2004 2005 Expression* array_; 2006 Expression* index_; 2007 Expression* value_; 2008 }; 2009 2010 class Conditional final : public Expression { 2011 public: 2012 Expression* condition() const { return condition_; } 2013 Expression* then_expression() const { return then_expression_; } 2014 Expression* else_expression() const { return else_expression_; } 2015 2016 private: 2017 friend class AstNodeFactory; 2018 2019 Conditional(Expression* condition, Expression* then_expression, 2020 Expression* else_expression, int position) 2021 : Expression(position, kConditional), 2022 condition_(condition), 2023 then_expression_(then_expression), 2024 else_expression_(else_expression) {} 2025 2026 Expression* condition_; 2027 Expression* then_expression_; 2028 Expression* else_expression_; 2029 }; 2030 2031 class Assignment : public Expression { 2032 public: 2033 Token::Value op() const { return TokenField::decode(bit_field_); } 2034 Expression* target() const { return target_; } 2035 Expression* value() const { return value_; } 2036 2037 // The assignment was generated as part of block-scoped sloppy-mode 2038 // function hoisting, see 2039 // ES#sec-block-level-function-declarations-web-legacy-compatibility-semantics 2040 LookupHoistingMode lookup_hoisting_mode() const { 2041 return static_cast<LookupHoistingMode>( 2042 LookupHoistingModeField::decode(bit_field_)); 2043 } 2044 void set_lookup_hoisting_mode(LookupHoistingMode mode) { 2045 bit_field_ = 2046 LookupHoistingModeField::update(bit_field_, static_cast<bool>(mode)); 2047 } 2048 2049 protected: 2050 Assignment(NodeType type, Token::Value op, Expression* target, 2051 Expression* value, int pos); 2052 2053 private: 2054 friend class AstNodeFactory; 2055 2056 class TokenField 2057 : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {}; 2058 class LookupHoistingModeField : public BitField<bool, TokenField::kNext, 1> { 2059 }; 2060 2061 Expression* target_; 2062 Expression* value_; 2063 }; 2064 2065 class CompoundAssignment final : public Assignment { 2066 public: 2067 BinaryOperation* binary_operation() const { return binary_operation_; } 2068 2069 private: 2070 friend class AstNodeFactory; 2071 2072 CompoundAssignment(Token::Value op, Expression* target, Expression* value, 2073 int pos, BinaryOperation* binary_operation) 2074 : Assignment(kCompoundAssignment, op, target, value, pos), 2075 binary_operation_(binary_operation) {} 2076 2077 BinaryOperation* binary_operation_; 2078 }; 2079 2080 // The RewritableExpression class is a wrapper for AST nodes that wait 2081 // for some potential rewriting. However, even if such nodes are indeed 2082 // rewritten, the RewritableExpression wrapper nodes will survive in the 2083 // final AST and should be just ignored, i.e., they should be treated as 2084 // equivalent to the wrapped nodes. For this reason and to simplify later 2085 // phases, RewritableExpressions are considered as exceptions of AST nodes 2086 // in the following sense: 2087 // 2088 // 1. IsRewritableExpression and AsRewritableExpression behave as usual. 2089 // 2. All other Is* and As* methods are practically delegated to the 2090 // wrapped node, i.e. IsArrayLiteral() will return true iff the 2091 // wrapped node is an array literal. 2092 // 2093 // Furthermore, an invariant that should be respected is that the wrapped 2094 // node is not a RewritableExpression. 2095 class RewritableExpression final : public Expression { 2096 public: 2097 Expression* expression() const { return expr_; } 2098 bool is_rewritten() const { return IsRewrittenField::decode(bit_field_); } 2099 void set_rewritten() { 2100 bit_field_ = IsRewrittenField::update(bit_field_, true); 2101 } 2102 2103 void Rewrite(Expression* new_expression) { 2104 DCHECK(!is_rewritten()); 2105 DCHECK_NOT_NULL(new_expression); 2106 DCHECK(!new_expression->IsRewritableExpression()); 2107 expr_ = new_expression; 2108 set_rewritten(); 2109 } 2110 2111 Scope* scope() const { return scope_; } 2112 void set_scope(Scope* scope) { scope_ = scope; } 2113 2114 private: 2115 friend class AstNodeFactory; 2116 2117 RewritableExpression(Expression* expression, Scope* scope) 2118 : Expression(expression->position(), kRewritableExpression), 2119 expr_(expression), 2120 scope_(scope) { 2121 bit_field_ |= IsRewrittenField::encode(false); 2122 DCHECK(!expression->IsRewritableExpression()); 2123 } 2124 2125 Expression* expr_; 2126 Scope* scope_; 2127 2128 class IsRewrittenField 2129 : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; 2130 }; 2131 2132 // There are several types of Suspend node: 2133 // 2134 // Yield 2135 // YieldStar 2136 // Await 2137 // 2138 // Our Yield is different from the JS yield in that it "returns" its argument as 2139 // is, without wrapping it in an iterator result object. Such wrapping, if 2140 // desired, must be done beforehand (see the parser). 2141 class Suspend : public Expression { 2142 public: 2143 // With {kNoControl}, the {Suspend} behaves like yield, except that it never 2144 // throws and never causes the current generator to return. This is used to 2145 // desugar yield*. 2146 // TODO(caitp): remove once yield* desugaring for async generators is handled 2147 // in BytecodeGenerator. 2148 enum OnAbruptResume { kOnExceptionThrow, kNoControl }; 2149 2150 Expression* expression() const { return expression_; } 2151 OnAbruptResume on_abrupt_resume() const { 2152 return OnAbruptResumeField::decode(bit_field_); 2153 } 2154 2155 private: 2156 friend class AstNodeFactory; 2157 friend class Yield; 2158 friend class YieldStar; 2159 friend class Await; 2160 2161 Suspend(NodeType node_type, Expression* expression, int pos, 2162 OnAbruptResume on_abrupt_resume) 2163 : Expression(pos, node_type), expression_(expression) { 2164 bit_field_ |= OnAbruptResumeField::encode(on_abrupt_resume); 2165 } 2166 2167 Expression* expression_; 2168 2169 class OnAbruptResumeField 2170 : public BitField<OnAbruptResume, Expression::kNextBitFieldIndex, 1> {}; 2171 }; 2172 2173 class Yield final : public Suspend { 2174 private: 2175 friend class AstNodeFactory; 2176 Yield(Expression* expression, int pos, OnAbruptResume on_abrupt_resume) 2177 : Suspend(kYield, expression, pos, on_abrupt_resume) {} 2178 }; 2179 2180 class YieldStar final : public Suspend { 2181 private: 2182 friend class AstNodeFactory; 2183 YieldStar(Expression* expression, int pos) 2184 : Suspend(kYieldStar, expression, pos, 2185 Suspend::OnAbruptResume::kNoControl) {} 2186 }; 2187 2188 class Await final : public Suspend { 2189 private: 2190 friend class AstNodeFactory; 2191 2192 Await(Expression* expression, int pos) 2193 : Suspend(kAwait, expression, pos, Suspend::kOnExceptionThrow) {} 2194 }; 2195 2196 class Throw final : public Expression { 2197 public: 2198 Expression* exception() const { return exception_; } 2199 2200 private: 2201 friend class AstNodeFactory; 2202 2203 Throw(Expression* exception, int pos) 2204 : Expression(pos, kThrow), exception_(exception) {} 2205 2206 Expression* exception_; 2207 }; 2208 2209 2210 class FunctionLiteral final : public Expression { 2211 public: 2212 enum FunctionType { 2213 kAnonymousExpression, 2214 kNamedExpression, 2215 kDeclaration, 2216 kAccessorOrMethod, 2217 kWrapped, 2218 }; 2219 2220 enum IdType { kIdTypeInvalid = -1, kIdTypeTopLevel = 0 }; 2221 2222 enum ParameterFlag { kNoDuplicateParameters, kHasDuplicateParameters }; 2223 2224 enum EagerCompileHint { kShouldEagerCompile, kShouldLazyCompile }; 2225 2226 // Empty handle means that the function does not have a shared name (i.e. 2227 // the name will be set dynamically after creation of the function closure). 2228 MaybeHandle<String> name() const { 2229 return raw_name_ ? raw_name_->string() : MaybeHandle<String>(); 2230 } 2231 Handle<String> name(Isolate* isolate) const; 2232 bool has_shared_name() const { return raw_name_ != nullptr; } 2233 const AstConsString* raw_name() const { return raw_name_; } 2234 void set_raw_name(const AstConsString* name) { raw_name_ = name; } 2235 DeclarationScope* scope() const { return scope_; } 2236 ZonePtrList<Statement>* body() const { return body_; } 2237 void set_function_token_position(int pos) { function_token_position_ = pos; } 2238 int function_token_position() const { return function_token_position_; } 2239 int start_position() const; 2240 int end_position() const; 2241 bool is_declaration() const { return function_type() == kDeclaration; } 2242 bool is_named_expression() const { 2243 return function_type() == kNamedExpression; 2244 } 2245 bool is_anonymous_expression() const { 2246 return function_type() == kAnonymousExpression; 2247 } 2248 2249 void mark_as_iife() { bit_field_ = IIFEBit::update(bit_field_, true); } 2250 bool is_iife() const { return IIFEBit::decode(bit_field_); } 2251 bool is_top_level() const { 2252 return function_literal_id() == FunctionLiteral::kIdTypeTopLevel; 2253 } 2254 bool is_wrapped() const { return function_type() == kWrapped; } 2255 LanguageMode language_mode() const; 2256 2257 static bool NeedsHomeObject(Expression* expr); 2258 2259 int expected_property_count() { 2260 // Not valid for lazy functions. 2261 DCHECK_NOT_NULL(body_); 2262 return expected_property_count_; 2263 } 2264 int parameter_count() { return parameter_count_; } 2265 int function_length() { return function_length_; } 2266 2267 bool AllowsLazyCompilation(); 2268 2269 bool CanSuspend() { 2270 if (suspend_count() > 0) { 2271 DCHECK(IsResumableFunction(kind())); 2272 return true; 2273 } 2274 return false; 2275 } 2276 2277 // Returns either name or inferred name as a cstring. 2278 std::unique_ptr<char[]> GetDebugName() const; 2279 2280 Handle<String> inferred_name() const { 2281 if (!inferred_name_.is_null()) { 2282 DCHECK_NULL(raw_inferred_name_); 2283 return inferred_name_; 2284 } 2285 if (raw_inferred_name_ != nullptr) { 2286 return raw_inferred_name_->string(); 2287 } 2288 UNREACHABLE(); 2289 } 2290 const AstConsString* raw_inferred_name() { return raw_inferred_name_; } 2291 2292 // Only one of {set_inferred_name, set_raw_inferred_name} should be called. 2293 void set_inferred_name(Handle<String> inferred_name); 2294 void set_raw_inferred_name(const AstConsString* raw_inferred_name); 2295 2296 bool pretenure() const { return Pretenure::decode(bit_field_); } 2297 void set_pretenure() { bit_field_ = Pretenure::update(bit_field_, true); } 2298 2299 bool has_duplicate_parameters() const { 2300 // Not valid for lazy functions. 2301 DCHECK_NOT_NULL(body_); 2302 return HasDuplicateParameters::decode(bit_field_); 2303 } 2304 2305 // This is used as a heuristic on when to eagerly compile a function 2306 // literal. We consider the following constructs as hints that the 2307 // function will be called immediately: 2308 // - (function() { ... })(); 2309 // - var x = function() { ... }(); 2310 bool ShouldEagerCompile() const; 2311 void SetShouldEagerCompile(); 2312 2313 FunctionType function_type() const { 2314 return FunctionTypeBits::decode(bit_field_); 2315 } 2316 FunctionKind kind() const; 2317 2318 bool dont_optimize() { 2319 return dont_optimize_reason() != BailoutReason::kNoReason; 2320 } 2321 BailoutReason dont_optimize_reason() { 2322 return DontOptimizeReasonField::decode(bit_field_); 2323 } 2324 void set_dont_optimize_reason(BailoutReason reason) { 2325 bit_field_ = DontOptimizeReasonField::update(bit_field_, reason); 2326 } 2327 2328 bool IsAnonymousFunctionDefinition() const { 2329 return is_anonymous_expression(); 2330 } 2331 2332 int suspend_count() { return suspend_count_; } 2333 void set_suspend_count(int suspend_count) { suspend_count_ = suspend_count; } 2334 2335 int return_position() { 2336 return std::max( 2337 start_position(), 2338 end_position() - (HasBracesField::decode(bit_field_) ? 1 : 0)); 2339 } 2340 2341 int function_literal_id() const { return function_literal_id_; } 2342 void set_function_literal_id(int function_literal_id) { 2343 function_literal_id_ = function_literal_id; 2344 } 2345 2346 void set_requires_instance_fields_initializer(bool value) { 2347 bit_field_ = RequiresInstanceFieldsInitializer::update(bit_field_, value); 2348 } 2349 bool requires_instance_fields_initializer() const { 2350 return RequiresInstanceFieldsInitializer::decode(bit_field_); 2351 } 2352 2353 ProducedPreParsedScopeData* produced_preparsed_scope_data() const { 2354 return produced_preparsed_scope_data_; 2355 } 2356 2357 private: 2358 friend class AstNodeFactory; 2359 2360 FunctionLiteral( 2361 Zone* zone, const AstRawString* name, AstValueFactory* ast_value_factory, 2362 DeclarationScope* scope, ZonePtrList<Statement>* body, 2363 int expected_property_count, int parameter_count, int function_length, 2364 FunctionType function_type, ParameterFlag has_duplicate_parameters, 2365 EagerCompileHint eager_compile_hint, int position, bool has_braces, 2366 int function_literal_id, 2367 ProducedPreParsedScopeData* produced_preparsed_scope_data = nullptr) 2368 : Expression(position, kFunctionLiteral), 2369 expected_property_count_(expected_property_count), 2370 parameter_count_(parameter_count), 2371 function_length_(function_length), 2372 function_token_position_(kNoSourcePosition), 2373 suspend_count_(0), 2374 function_literal_id_(function_literal_id), 2375 raw_name_(name ? ast_value_factory->NewConsString(name) : nullptr), 2376 scope_(scope), 2377 body_(body), 2378 raw_inferred_name_(ast_value_factory->empty_cons_string()), 2379 produced_preparsed_scope_data_(produced_preparsed_scope_data) { 2380 bit_field_ |= FunctionTypeBits::encode(function_type) | 2381 Pretenure::encode(false) | 2382 HasDuplicateParameters::encode(has_duplicate_parameters == 2383 kHasDuplicateParameters) | 2384 DontOptimizeReasonField::encode(BailoutReason::kNoReason) | 2385 RequiresInstanceFieldsInitializer::encode(false) | 2386 HasBracesField::encode(has_braces) | IIFEBit::encode(false); 2387 if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile(); 2388 DCHECK_EQ(body == nullptr, expected_property_count < 0); 2389 } 2390 2391 class FunctionTypeBits 2392 : public BitField<FunctionType, Expression::kNextBitFieldIndex, 3> {}; 2393 class Pretenure : public BitField<bool, FunctionTypeBits::kNext, 1> {}; 2394 class HasDuplicateParameters : public BitField<bool, Pretenure::kNext, 1> {}; 2395 class DontOptimizeReasonField 2396 : public BitField<BailoutReason, HasDuplicateParameters::kNext, 8> {}; 2397 class RequiresInstanceFieldsInitializer 2398 : public BitField<bool, DontOptimizeReasonField::kNext, 1> {}; 2399 class HasBracesField 2400 : public BitField<bool, RequiresInstanceFieldsInitializer::kNext, 1> {}; 2401 class IIFEBit : public BitField<bool, HasBracesField::kNext, 1> {}; 2402 2403 int expected_property_count_; 2404 int parameter_count_; 2405 int function_length_; 2406 int function_token_position_; 2407 int suspend_count_; 2408 int function_literal_id_; 2409 2410 const AstConsString* raw_name_; 2411 DeclarationScope* scope_; 2412 ZonePtrList<Statement>* body_; 2413 const AstConsString* raw_inferred_name_; 2414 Handle<String> inferred_name_; 2415 ProducedPreParsedScopeData* produced_preparsed_scope_data_; 2416 }; 2417 2418 // Property is used for passing information 2419 // about a class literal's properties from the parser to the code generator. 2420 class ClassLiteralProperty final : public LiteralProperty { 2421 public: 2422 enum Kind : uint8_t { METHOD, GETTER, SETTER, PUBLIC_FIELD, PRIVATE_FIELD }; 2423 2424 Kind kind() const { return kind_; } 2425 2426 bool is_static() const { return is_static_; } 2427 2428 void set_computed_name_var(Variable* var) { 2429 DCHECK_EQ(PUBLIC_FIELD, kind()); 2430 private_or_computed_name_var_ = var; 2431 } 2432 Variable* computed_name_var() const { 2433 DCHECK_EQ(PUBLIC_FIELD, kind()); 2434 return private_or_computed_name_var_; 2435 } 2436 2437 void set_private_field_name_var(Variable* var) { 2438 DCHECK_EQ(PRIVATE_FIELD, kind()); 2439 private_or_computed_name_var_ = var; 2440 } 2441 Variable* private_field_name_var() const { 2442 DCHECK_EQ(PRIVATE_FIELD, kind()); 2443 return private_or_computed_name_var_; 2444 } 2445 2446 private: 2447 friend class AstNodeFactory; 2448 2449 ClassLiteralProperty(Expression* key, Expression* value, Kind kind, 2450 bool is_static, bool is_computed_name); 2451 2452 Kind kind_; 2453 bool is_static_; 2454 Variable* private_or_computed_name_var_; 2455 }; 2456 2457 class InitializeClassFieldsStatement final : public Statement { 2458 public: 2459 typedef ClassLiteralProperty Property; 2460 2461 ZonePtrList<Property>* fields() const { return fields_; } 2462 2463 private: 2464 friend class AstNodeFactory; 2465 2466 InitializeClassFieldsStatement(ZonePtrList<Property>* fields, int pos) 2467 : Statement(pos, kInitializeClassFieldsStatement), fields_(fields) {} 2468 2469 ZonePtrList<Property>* fields_; 2470 }; 2471 2472 class ClassLiteral final : public Expression { 2473 public: 2474 typedef ClassLiteralProperty Property; 2475 2476 Scope* scope() const { return scope_; } 2477 Variable* class_variable() const { return class_variable_; } 2478 Expression* extends() const { return extends_; } 2479 FunctionLiteral* constructor() const { return constructor_; } 2480 ZonePtrList<Property>* properties() const { return properties_; } 2481 int start_position() const { return position(); } 2482 int end_position() const { return end_position_; } 2483 bool has_name_static_property() const { 2484 return HasNameStaticProperty::decode(bit_field_); 2485 } 2486 bool has_static_computed_names() const { 2487 return HasStaticComputedNames::decode(bit_field_); 2488 } 2489 2490 bool is_anonymous_expression() const { 2491 return IsAnonymousExpression::decode(bit_field_); 2492 } 2493 bool IsAnonymousFunctionDefinition() const { 2494 return is_anonymous_expression(); 2495 } 2496 2497 FunctionLiteral* static_fields_initializer() const { 2498 return static_fields_initializer_; 2499 } 2500 2501 FunctionLiteral* instance_fields_initializer_function() const { 2502 return instance_fields_initializer_function_; 2503 } 2504 2505 private: 2506 friend class AstNodeFactory; 2507 2508 ClassLiteral(Scope* scope, Variable* class_variable, Expression* extends, 2509 FunctionLiteral* constructor, ZonePtrList<Property>* properties, 2510 FunctionLiteral* static_fields_initializer, 2511 FunctionLiteral* instance_fields_initializer_function, 2512 int start_position, int end_position, 2513 bool has_name_static_property, bool has_static_computed_names, 2514 bool is_anonymous) 2515 : Expression(start_position, kClassLiteral), 2516 end_position_(end_position), 2517 scope_(scope), 2518 class_variable_(class_variable), 2519 extends_(extends), 2520 constructor_(constructor), 2521 properties_(properties), 2522 static_fields_initializer_(static_fields_initializer), 2523 instance_fields_initializer_function_( 2524 instance_fields_initializer_function) { 2525 bit_field_ |= HasNameStaticProperty::encode(has_name_static_property) | 2526 HasStaticComputedNames::encode(has_static_computed_names) | 2527 IsAnonymousExpression::encode(is_anonymous); 2528 } 2529 2530 int end_position_; 2531 Scope* scope_; 2532 Variable* class_variable_; 2533 Expression* extends_; 2534 FunctionLiteral* constructor_; 2535 ZonePtrList<Property>* properties_; 2536 FunctionLiteral* static_fields_initializer_; 2537 FunctionLiteral* instance_fields_initializer_function_; 2538 class HasNameStaticProperty 2539 : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; 2540 class HasStaticComputedNames 2541 : public BitField<bool, HasNameStaticProperty::kNext, 1> {}; 2542 class IsAnonymousExpression 2543 : public BitField<bool, HasStaticComputedNames::kNext, 1> {}; 2544 }; 2545 2546 2547 class NativeFunctionLiteral final : public Expression { 2548 public: 2549 Handle<String> name() const { return name_->string(); } 2550 const AstRawString* raw_name() const { return name_; } 2551 v8::Extension* extension() const { return extension_; } 2552 2553 private: 2554 friend class AstNodeFactory; 2555 2556 NativeFunctionLiteral(const AstRawString* name, v8::Extension* extension, 2557 int pos) 2558 : Expression(pos, kNativeFunctionLiteral), 2559 name_(name), 2560 extension_(extension) {} 2561 2562 const AstRawString* name_; 2563 v8::Extension* extension_; 2564 }; 2565 2566 2567 class ThisFunction final : public Expression { 2568 private: 2569 friend class AstNodeFactory; 2570 explicit ThisFunction(int pos) : Expression(pos, kThisFunction) {} 2571 }; 2572 2573 2574 class SuperPropertyReference final : public Expression { 2575 public: 2576 VariableProxy* this_var() const { return this_var_; } 2577 Expression* home_object() const { return home_object_; } 2578 2579 private: 2580 friend class AstNodeFactory; 2581 2582 SuperPropertyReference(VariableProxy* this_var, Expression* home_object, 2583 int pos) 2584 : Expression(pos, kSuperPropertyReference), 2585 this_var_(this_var), 2586 home_object_(home_object) { 2587 DCHECK(this_var->is_this()); 2588 DCHECK(home_object->IsProperty()); 2589 } 2590 2591 VariableProxy* this_var_; 2592 Expression* home_object_; 2593 }; 2594 2595 2596 class SuperCallReference final : public Expression { 2597 public: 2598 VariableProxy* this_var() const { return this_var_; } 2599 VariableProxy* new_target_var() const { return new_target_var_; } 2600 VariableProxy* this_function_var() const { return this_function_var_; } 2601 2602 private: 2603 friend class AstNodeFactory; 2604 2605 SuperCallReference(VariableProxy* this_var, VariableProxy* new_target_var, 2606 VariableProxy* this_function_var, int pos) 2607 : Expression(pos, kSuperCallReference), 2608 this_var_(this_var), 2609 new_target_var_(new_target_var), 2610 this_function_var_(this_function_var) { 2611 DCHECK(this_var->is_this()); 2612 DCHECK(new_target_var->raw_name()->IsOneByteEqualTo(".new.target")); 2613 DCHECK(this_function_var->raw_name()->IsOneByteEqualTo(".this_function")); 2614 } 2615 2616 VariableProxy* this_var_; 2617 VariableProxy* new_target_var_; 2618 VariableProxy* this_function_var_; 2619 }; 2620 2621 // This AST Node is used to represent a dynamic import call -- 2622 // import(argument). 2623 class ImportCallExpression final : public Expression { 2624 public: 2625 Expression* argument() const { return argument_; } 2626 2627 private: 2628 friend class AstNodeFactory; 2629 2630 ImportCallExpression(Expression* argument, int pos) 2631 : Expression(pos, kImportCallExpression), argument_(argument) {} 2632 2633 Expression* argument_; 2634 }; 2635 2636 // This class is produced when parsing the () in arrow functions without any 2637 // arguments and is not actually a valid expression. 2638 class EmptyParentheses final : public Expression { 2639 private: 2640 friend class AstNodeFactory; 2641 2642 explicit EmptyParentheses(int pos) : Expression(pos, kEmptyParentheses) {} 2643 }; 2644 2645 // Represents the spec operation `GetIterator()` 2646 // (defined at https://tc39.github.io/ecma262/#sec-getiterator). Ignition 2647 // desugars this into a LoadIC / JSLoadNamed, CallIC, and a type-check to 2648 // validate return value of the Symbol.iterator() call. 2649 enum class IteratorType { kNormal, kAsync }; 2650 class GetIterator final : public Expression { 2651 public: 2652 IteratorType hint() const { return hint_; } 2653 2654 Expression* iterable() const { return iterable_; } 2655 2656 Expression* iterable_for_call_printer() const { 2657 return destructured_iterable_ != nullptr ? destructured_iterable_ 2658 : iterable_; 2659 } 2660 2661 private: 2662 friend class AstNodeFactory; 2663 2664 GetIterator(Expression* iterable, Expression* destructured_iterable, 2665 IteratorType hint, int pos) 2666 : Expression(pos, kGetIterator), 2667 hint_(hint), 2668 iterable_(iterable), 2669 destructured_iterable_(destructured_iterable) {} 2670 2671 GetIterator(Expression* iterable, IteratorType hint, int pos) 2672 : Expression(pos, kGetIterator), 2673 hint_(hint), 2674 iterable_(iterable), 2675 destructured_iterable_(nullptr) {} 2676 2677 IteratorType hint_; 2678 Expression* iterable_; 2679 2680 // iterable_ is the variable proxy, while destructured_iterable_ points to 2681 // the raw value stored in the variable proxy. This is only used for 2682 // pretty printing error messages. 2683 Expression* destructured_iterable_; 2684 }; 2685 2686 // Represents the spec operation `GetTemplateObject(templateLiteral)` 2687 // (defined at https://tc39.github.io/ecma262/#sec-gettemplateobject). 2688 class GetTemplateObject final : public Expression { 2689 public: 2690 const ZonePtrList<const AstRawString>* cooked_strings() const { 2691 return cooked_strings_; 2692 } 2693 const ZonePtrList<const AstRawString>* raw_strings() const { 2694 return raw_strings_; 2695 } 2696 2697 Handle<TemplateObjectDescription> GetOrBuildDescription(Isolate* isolate); 2698 2699 private: 2700 friend class AstNodeFactory; 2701 2702 GetTemplateObject(const ZonePtrList<const AstRawString>* cooked_strings, 2703 const ZonePtrList<const AstRawString>* raw_strings, int pos) 2704 : Expression(pos, kGetTemplateObject), 2705 cooked_strings_(cooked_strings), 2706 raw_strings_(raw_strings) {} 2707 2708 const ZonePtrList<const AstRawString>* cooked_strings_; 2709 const ZonePtrList<const AstRawString>* raw_strings_; 2710 }; 2711 2712 class TemplateLiteral final : public Expression { 2713 public: 2714 const ZonePtrList<const AstRawString>* string_parts() const { 2715 return string_parts_; 2716 } 2717 const ZonePtrList<Expression>* substitutions() const { 2718 return substitutions_; 2719 } 2720 2721 private: 2722 friend class AstNodeFactory; 2723 TemplateLiteral(const ZonePtrList<const AstRawString>* parts, 2724 const ZonePtrList<Expression>* substitutions, int pos) 2725 : Expression(pos, kTemplateLiteral), 2726 string_parts_(parts), 2727 substitutions_(substitutions) {} 2728 2729 const ZonePtrList<const AstRawString>* string_parts_; 2730 const ZonePtrList<Expression>* substitutions_; 2731 }; 2732 2733 // ---------------------------------------------------------------------------- 2734 // Basic visitor 2735 // Sub-class should parametrize AstVisitor with itself, e.g.: 2736 // class SpecificVisitor : public AstVisitor<SpecificVisitor> { ... } 2737 2738 template <class Subclass> 2739 class AstVisitor BASE_EMBEDDED { 2740 public: 2741 void Visit(AstNode* node) { impl()->Visit(node); } 2742 2743 void VisitDeclarations(Declaration::List* declarations) { 2744 for (Declaration* decl : *declarations) Visit(decl); 2745 } 2746 2747 void VisitStatements(ZonePtrList<Statement>* statements) { 2748 for (int i = 0; i < statements->length(); i++) { 2749 Statement* stmt = statements->at(i); 2750 Visit(stmt); 2751 if (stmt->IsJump()) break; 2752 } 2753 } 2754 2755 void VisitExpressions(ZonePtrList<Expression>* expressions) { 2756 for (int i = 0; i < expressions->length(); i++) { 2757 // The variable statement visiting code may pass null expressions 2758 // to this code. Maybe this should be handled by introducing an 2759 // undefined expression or literal? Revisit this code if this 2760 // changes. 2761 Expression* expression = expressions->at(i); 2762 if (expression != nullptr) Visit(expression); 2763 } 2764 } 2765 2766 protected: 2767 Subclass* impl() { return static_cast<Subclass*>(this); } 2768 }; 2769 2770 #define GENERATE_VISIT_CASE(NodeType) \ 2771 case AstNode::k##NodeType: \ 2772 return this->impl()->Visit##NodeType(static_cast<NodeType*>(node)); 2773 2774 #define GENERATE_AST_VISITOR_SWITCH() \ 2775 switch (node->node_type()) { \ 2776 AST_NODE_LIST(GENERATE_VISIT_CASE) \ 2777 } 2778 2779 #define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS() \ 2780 public: \ 2781 void VisitNoStackOverflowCheck(AstNode* node) { \ 2782 GENERATE_AST_VISITOR_SWITCH() \ 2783 } \ 2784 \ 2785 void Visit(AstNode* node) { \ 2786 if (CheckStackOverflow()) return; \ 2787 VisitNoStackOverflowCheck(node); \ 2788 } \ 2789 \ 2790 void SetStackOverflow() { stack_overflow_ = true; } \ 2791 void ClearStackOverflow() { stack_overflow_ = false; } \ 2792 bool HasStackOverflow() const { return stack_overflow_; } \ 2793 \ 2794 bool CheckStackOverflow() { \ 2795 if (stack_overflow_) return true; \ 2796 if (GetCurrentStackPosition() < stack_limit_) { \ 2797 stack_overflow_ = true; \ 2798 return true; \ 2799 } \ 2800 return false; \ 2801 } \ 2802 \ 2803 private: \ 2804 void InitializeAstVisitor(Isolate* isolate) { \ 2805 stack_limit_ = isolate->stack_guard()->real_climit(); \ 2806 stack_overflow_ = false; \ 2807 } \ 2808 \ 2809 void InitializeAstVisitor(uintptr_t stack_limit) { \ 2810 stack_limit_ = stack_limit; \ 2811 stack_overflow_ = false; \ 2812 } \ 2813 \ 2814 uintptr_t stack_limit_; \ 2815 bool stack_overflow_ 2816 2817 #define DEFINE_AST_VISITOR_MEMBERS_WITHOUT_STACKOVERFLOW() \ 2818 public: \ 2819 void Visit(AstNode* node) { GENERATE_AST_VISITOR_SWITCH() } \ 2820 \ 2821 private: 2822 2823 // ---------------------------------------------------------------------------- 2824 // AstNode factory 2825 2826 class AstNodeFactory final BASE_EMBEDDED { 2827 public: 2828 AstNodeFactory(AstValueFactory* ast_value_factory, Zone* zone) 2829 : zone_(zone), ast_value_factory_(ast_value_factory) {} 2830 2831 AstValueFactory* ast_value_factory() const { return ast_value_factory_; } 2832 2833 VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy, int pos) { 2834 return new (zone_) VariableDeclaration(proxy, pos); 2835 } 2836 2837 NestedVariableDeclaration* NewNestedVariableDeclaration(VariableProxy* proxy, 2838 Scope* scope, 2839 int pos) { 2840 return new (zone_) NestedVariableDeclaration(proxy, scope, pos); 2841 } 2842 2843 FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy, 2844 FunctionLiteral* fun, int pos) { 2845 return new (zone_) FunctionDeclaration(proxy, fun, pos); 2846 } 2847 2848 Block* NewBlock(int capacity, bool ignore_completion_value, 2849 ZonePtrList<const AstRawString>* labels = nullptr) { 2850 return labels != nullptr 2851 ? new (zone_) LabeledBlock(zone_, labels, capacity, 2852 ignore_completion_value) 2853 : new (zone_) 2854 Block(zone_, labels, capacity, ignore_completion_value); 2855 } 2856 2857 #define STATEMENT_WITH_LABELS(NodeType) \ 2858 NodeType* New##NodeType(ZonePtrList<const AstRawString>* labels, \ 2859 ZonePtrList<const AstRawString>* own_labels, \ 2860 int pos) { \ 2861 return new (zone_) NodeType(labels, own_labels, pos); \ 2862 } 2863 STATEMENT_WITH_LABELS(DoWhileStatement) 2864 STATEMENT_WITH_LABELS(WhileStatement) 2865 STATEMENT_WITH_LABELS(ForStatement) 2866 #undef STATEMENT_WITH_LABELS 2867 2868 SwitchStatement* NewSwitchStatement(ZonePtrList<const AstRawString>* labels, 2869 Expression* tag, int pos) { 2870 return new (zone_) SwitchStatement(zone_, labels, tag, pos); 2871 } 2872 2873 ForEachStatement* NewForEachStatement( 2874 ForEachStatement::VisitMode visit_mode, 2875 ZonePtrList<const AstRawString>* labels, 2876 ZonePtrList<const AstRawString>* own_labels, int pos) { 2877 switch (visit_mode) { 2878 case ForEachStatement::ENUMERATE: { 2879 return new (zone_) ForInStatement(labels, own_labels, pos); 2880 } 2881 case ForEachStatement::ITERATE: { 2882 return new (zone_) ForOfStatement(labels, own_labels, pos); 2883 } 2884 } 2885 UNREACHABLE(); 2886 } 2887 2888 ForOfStatement* NewForOfStatement(ZonePtrList<const AstRawString>* labels, 2889 ZonePtrList<const AstRawString>* own_labels, 2890 int pos) { 2891 return new (zone_) ForOfStatement(labels, own_labels, pos); 2892 } 2893 2894 ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) { 2895 return new (zone_) ExpressionStatement(expression, pos); 2896 } 2897 2898 ContinueStatement* NewContinueStatement(IterationStatement* target, int pos) { 2899 return new (zone_) ContinueStatement(target, pos); 2900 } 2901 2902 BreakStatement* NewBreakStatement(BreakableStatement* target, int pos) { 2903 return new (zone_) BreakStatement(target, pos); 2904 } 2905 2906 ReturnStatement* NewReturnStatement(Expression* expression, int pos, 2907 int end_position = kNoSourcePosition) { 2908 return new (zone_) ReturnStatement(expression, ReturnStatement::kNormal, 2909 pos, end_position); 2910 } 2911 2912 ReturnStatement* NewAsyncReturnStatement( 2913 Expression* expression, int pos, int end_position = kNoSourcePosition) { 2914 return new (zone_) ReturnStatement( 2915 expression, ReturnStatement::kAsyncReturn, pos, end_position); 2916 } 2917 2918 WithStatement* NewWithStatement(Scope* scope, 2919 Expression* expression, 2920 Statement* statement, 2921 int pos) { 2922 return new (zone_) WithStatement(scope, expression, statement, pos); 2923 } 2924 2925 IfStatement* NewIfStatement(Expression* condition, Statement* then_statement, 2926 Statement* else_statement, int pos) { 2927 return new (zone_) 2928 IfStatement(condition, then_statement, else_statement, pos); 2929 } 2930 2931 TryCatchStatement* NewTryCatchStatement(Block* try_block, Scope* scope, 2932 Block* catch_block, int pos) { 2933 return new (zone_) TryCatchStatement(try_block, scope, catch_block, 2934 HandlerTable::CAUGHT, pos); 2935 } 2936 2937 TryCatchStatement* NewTryCatchStatementForReThrow(Block* try_block, 2938 Scope* scope, 2939 Block* catch_block, 2940 int pos) { 2941 return new (zone_) TryCatchStatement(try_block, scope, catch_block, 2942 HandlerTable::UNCAUGHT, pos); 2943 } 2944 2945 TryCatchStatement* NewTryCatchStatementForDesugaring(Block* try_block, 2946 Scope* scope, 2947 Block* catch_block, 2948 int pos) { 2949 return new (zone_) TryCatchStatement(try_block, scope, catch_block, 2950 HandlerTable::DESUGARING, pos); 2951 } 2952 2953 TryCatchStatement* NewTryCatchStatementForAsyncAwait(Block* try_block, 2954 Scope* scope, 2955 Block* catch_block, 2956 int pos) { 2957 return new (zone_) TryCatchStatement(try_block, scope, catch_block, 2958 HandlerTable::ASYNC_AWAIT, pos); 2959 } 2960 2961 TryFinallyStatement* NewTryFinallyStatement(Block* try_block, 2962 Block* finally_block, int pos) { 2963 return new (zone_) TryFinallyStatement(try_block, finally_block, pos); 2964 } 2965 2966 DebuggerStatement* NewDebuggerStatement(int pos) { 2967 return new (zone_) DebuggerStatement(pos); 2968 } 2969 2970 EmptyStatement* NewEmptyStatement(int pos) { 2971 return new (zone_) EmptyStatement(pos); 2972 } 2973 2974 SloppyBlockFunctionStatement* NewSloppyBlockFunctionStatement() { 2975 return new (zone_) 2976 SloppyBlockFunctionStatement(NewEmptyStatement(kNoSourcePosition)); 2977 } 2978 2979 CaseClause* NewCaseClause(Expression* label, 2980 ZonePtrList<Statement>* statements) { 2981 return new (zone_) CaseClause(label, statements); 2982 } 2983 2984 Literal* NewStringLiteral(const AstRawString* string, int pos) { 2985 return new (zone_) Literal(string, pos); 2986 } 2987 2988 // A JavaScript symbol (ECMA-262 edition 6). 2989 Literal* NewSymbolLiteral(AstSymbol symbol, int pos) { 2990 return new (zone_) Literal(symbol, pos); 2991 } 2992 2993 Literal* NewNumberLiteral(double number, int pos); 2994 2995 Literal* NewSmiLiteral(int number, int pos) { 2996 return new (zone_) Literal(number, pos); 2997 } 2998 2999 Literal* NewBigIntLiteral(AstBigInt bigint, int pos) { 3000 return new (zone_) Literal(bigint, pos); 3001 } 3002 3003 Literal* NewBooleanLiteral(bool b, int pos) { 3004 return new (zone_) Literal(b, pos); 3005 } 3006 3007 Literal* NewNullLiteral(int pos) { 3008 return new (zone_) Literal(Literal::kNull, pos); 3009 } 3010 3011 Literal* NewUndefinedLiteral(int pos) { 3012 return new (zone_) Literal(Literal::kUndefined, pos); 3013 } 3014 3015 Literal* NewTheHoleLiteral() { 3016 return new (zone_) Literal(Literal::kTheHole, kNoSourcePosition); 3017 } 3018 3019 ObjectLiteral* NewObjectLiteral( 3020 ZonePtrList<ObjectLiteral::Property>* properties, 3021 uint32_t boilerplate_properties, int pos, bool has_rest_property) { 3022 return new (zone_) ObjectLiteral(properties, boilerplate_properties, pos, 3023 has_rest_property); 3024 } 3025 3026 ObjectLiteral::Property* NewObjectLiteralProperty( 3027 Expression* key, Expression* value, ObjectLiteralProperty::Kind kind, 3028 bool is_computed_name) { 3029 return new (zone_) 3030 ObjectLiteral::Property(key, value, kind, is_computed_name); 3031 } 3032 3033 ObjectLiteral::Property* NewObjectLiteralProperty(Expression* key, 3034 Expression* value, 3035 bool is_computed_name) { 3036 return new (zone_) ObjectLiteral::Property(ast_value_factory_, key, value, 3037 is_computed_name); 3038 } 3039 3040 RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern, int flags, 3041 int pos) { 3042 return new (zone_) RegExpLiteral(pattern, flags, pos); 3043 } 3044 3045 ArrayLiteral* NewArrayLiteral(ZonePtrList<Expression>* values, int pos) { 3046 return new (zone_) ArrayLiteral(values, -1, pos); 3047 } 3048 3049 ArrayLiteral* NewArrayLiteral(ZonePtrList<Expression>* values, 3050 int first_spread_index, int pos) { 3051 return new (zone_) ArrayLiteral(values, first_spread_index, pos); 3052 } 3053 3054 VariableProxy* NewVariableProxy(Variable* var, 3055 int start_position = kNoSourcePosition) { 3056 return new (zone_) VariableProxy(var, start_position); 3057 } 3058 3059 VariableProxy* NewVariableProxy(const AstRawString* name, 3060 VariableKind variable_kind, 3061 int start_position = kNoSourcePosition) { 3062 DCHECK_NOT_NULL(name); 3063 return new (zone_) VariableProxy(name, variable_kind, start_position); 3064 } 3065 3066 // Recreates the VariableProxy in this Zone. 3067 VariableProxy* CopyVariableProxy(VariableProxy* proxy) { 3068 return new (zone_) VariableProxy(proxy); 3069 } 3070 3071 Variable* CopyVariable(Variable* variable) { 3072 return new (zone_) Variable(variable); 3073 } 3074 3075 Property* NewProperty(Expression* obj, Expression* key, int pos) { 3076 return new (zone_) Property(obj, key, pos); 3077 } 3078 3079 ResolvedProperty* NewResolvedProperty(VariableProxy* obj, 3080 VariableProxy* property, 3081 int pos = kNoSourcePosition) { 3082 return new (zone_) ResolvedProperty(obj, property, pos); 3083 } 3084 3085 Call* NewCall(Expression* expression, ZonePtrList<Expression>* arguments, 3086 int pos, Call::PossiblyEval possibly_eval = Call::NOT_EVAL) { 3087 return new (zone_) Call(expression, arguments, pos, possibly_eval); 3088 } 3089 3090 Call* NewTaggedTemplate(Expression* expression, 3091 ZonePtrList<Expression>* arguments, int pos) { 3092 return new (zone_) 3093 Call(expression, arguments, pos, Call::TaggedTemplateTag::kTrue); 3094 } 3095 3096 CallNew* NewCallNew(Expression* expression, 3097 ZonePtrList<Expression>* arguments, int pos) { 3098 return new (zone_) CallNew(expression, arguments, pos); 3099 } 3100 3101 CallRuntime* NewCallRuntime(Runtime::FunctionId id, 3102 ZonePtrList<Expression>* arguments, int pos) { 3103 return new (zone_) CallRuntime(Runtime::FunctionForId(id), arguments, pos); 3104 } 3105 3106 CallRuntime* NewCallRuntime(const Runtime::Function* function, 3107 ZonePtrList<Expression>* arguments, int pos) { 3108 return new (zone_) CallRuntime(function, arguments, pos); 3109 } 3110 3111 CallRuntime* NewCallRuntime(int context_index, 3112 ZonePtrList<Expression>* arguments, int pos) { 3113 return new (zone_) CallRuntime(context_index, arguments, pos); 3114 } 3115 3116 UnaryOperation* NewUnaryOperation(Token::Value op, 3117 Expression* expression, 3118 int pos) { 3119 return new (zone_) UnaryOperation(op, expression, pos); 3120 } 3121 3122 BinaryOperation* NewBinaryOperation(Token::Value op, 3123 Expression* left, 3124 Expression* right, 3125 int pos) { 3126 return new (zone_) BinaryOperation(op, left, right, pos); 3127 } 3128 3129 NaryOperation* NewNaryOperation(Token::Value op, Expression* first, 3130 size_t initial_subsequent_size) { 3131 return new (zone_) NaryOperation(zone_, op, first, initial_subsequent_size); 3132 } 3133 3134 CountOperation* NewCountOperation(Token::Value op, 3135 bool is_prefix, 3136 Expression* expr, 3137 int pos) { 3138 return new (zone_) CountOperation(op, is_prefix, expr, pos); 3139 } 3140 3141 CompareOperation* NewCompareOperation(Token::Value op, 3142 Expression* left, 3143 Expression* right, 3144 int pos) { 3145 return new (zone_) CompareOperation(op, left, right, pos); 3146 } 3147 3148 Spread* NewSpread(Expression* expression, int pos, int expr_pos) { 3149 return new (zone_) Spread(expression, pos, expr_pos); 3150 } 3151 3152 StoreInArrayLiteral* NewStoreInArrayLiteral(Expression* array, 3153 Expression* index, 3154 Expression* value, int pos) { 3155 return new (zone_) StoreInArrayLiteral(array, index, value, pos); 3156 } 3157 3158 Conditional* NewConditional(Expression* condition, 3159 Expression* then_expression, 3160 Expression* else_expression, 3161 int position) { 3162 return new (zone_) 3163 Conditional(condition, then_expression, else_expression, position); 3164 } 3165 3166 RewritableExpression* NewRewritableExpression(Expression* expression, 3167 Scope* scope) { 3168 DCHECK_NOT_NULL(expression); 3169 return new (zone_) RewritableExpression(expression, scope); 3170 } 3171 3172 Assignment* NewAssignment(Token::Value op, 3173 Expression* target, 3174 Expression* value, 3175 int pos) { 3176 DCHECK(Token::IsAssignmentOp(op)); 3177 3178 if (op != Token::INIT && target->IsVariableProxy()) { 3179 target->AsVariableProxy()->set_is_assigned(); 3180 } 3181 3182 if (op == Token::ASSIGN || op == Token::INIT) { 3183 return new (zone_) 3184 Assignment(AstNode::kAssignment, op, target, value, pos); 3185 } else { 3186 return new (zone_) CompoundAssignment( 3187 op, target, value, pos, 3188 NewBinaryOperation(Token::BinaryOpForAssignment(op), target, value, 3189 pos + 1)); 3190 } 3191 } 3192 3193 Suspend* NewYield(Expression* expression, int pos, 3194 Suspend::OnAbruptResume on_abrupt_resume) { 3195 if (!expression) expression = NewUndefinedLiteral(pos); 3196 return new (zone_) Yield(expression, pos, on_abrupt_resume); 3197 } 3198 3199 YieldStar* NewYieldStar(Expression* expression, int pos) { 3200 DCHECK_NOT_NULL(expression); 3201 return new (zone_) YieldStar(expression, pos); 3202 } 3203 3204 Await* NewAwait(Expression* expression, int pos) { 3205 if (!expression) expression = NewUndefinedLiteral(pos); 3206 return new (zone_) Await(expression, pos); 3207 } 3208 3209 Throw* NewThrow(Expression* exception, int pos) { 3210 return new (zone_) Throw(exception, pos); 3211 } 3212 3213 FunctionLiteral* NewFunctionLiteral( 3214 const AstRawString* name, DeclarationScope* scope, 3215 ZonePtrList<Statement>* body, int expected_property_count, 3216 int parameter_count, int function_length, 3217 FunctionLiteral::ParameterFlag has_duplicate_parameters, 3218 FunctionLiteral::FunctionType function_type, 3219 FunctionLiteral::EagerCompileHint eager_compile_hint, int position, 3220 bool has_braces, int function_literal_id, 3221 ProducedPreParsedScopeData* produced_preparsed_scope_data = nullptr) { 3222 return new (zone_) FunctionLiteral( 3223 zone_, name, ast_value_factory_, scope, body, expected_property_count, 3224 parameter_count, function_length, function_type, 3225 has_duplicate_parameters, eager_compile_hint, position, has_braces, 3226 function_literal_id, produced_preparsed_scope_data); 3227 } 3228 3229 // Creates a FunctionLiteral representing a top-level script, the 3230 // result of an eval (top-level or otherwise), or the result of calling 3231 // the Function constructor. 3232 FunctionLiteral* NewScriptOrEvalFunctionLiteral(DeclarationScope* scope, 3233 ZonePtrList<Statement>* body, 3234 int expected_property_count, 3235 int parameter_count) { 3236 return new (zone_) FunctionLiteral( 3237 zone_, ast_value_factory_->empty_string(), ast_value_factory_, scope, 3238 body, expected_property_count, parameter_count, parameter_count, 3239 FunctionLiteral::kAnonymousExpression, 3240 FunctionLiteral::kNoDuplicateParameters, 3241 FunctionLiteral::kShouldLazyCompile, 0, /* has_braces */ false, 3242 FunctionLiteral::kIdTypeTopLevel); 3243 } 3244 3245 ClassLiteral::Property* NewClassLiteralProperty( 3246 Expression* key, Expression* value, ClassLiteralProperty::Kind kind, 3247 bool is_static, bool is_computed_name) { 3248 return new (zone_) 3249 ClassLiteral::Property(key, value, kind, is_static, is_computed_name); 3250 } 3251 3252 ClassLiteral* NewClassLiteral( 3253 Scope* scope, Variable* variable, Expression* extends, 3254 FunctionLiteral* constructor, 3255 ZonePtrList<ClassLiteral::Property>* properties, 3256 FunctionLiteral* static_fields_initializer, 3257 FunctionLiteral* instance_fields_initializer_function, int start_position, 3258 int end_position, bool has_name_static_property, 3259 bool has_static_computed_names, bool is_anonymous) { 3260 return new (zone_) ClassLiteral( 3261 scope, variable, extends, constructor, properties, 3262 static_fields_initializer, instance_fields_initializer_function, 3263 start_position, end_position, has_name_static_property, 3264 has_static_computed_names, is_anonymous); 3265 } 3266 3267 NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name, 3268 v8::Extension* extension, 3269 int pos) { 3270 return new (zone_) NativeFunctionLiteral(name, extension, pos); 3271 } 3272 3273 DoExpression* NewDoExpression(Block* block, Variable* result_var, int pos) { 3274 VariableProxy* result = NewVariableProxy(result_var, pos); 3275 return new (zone_) DoExpression(block, result, pos); 3276 } 3277 3278 ThisFunction* NewThisFunction(int pos) { 3279 return new (zone_) ThisFunction(pos); 3280 } 3281 3282 SuperPropertyReference* NewSuperPropertyReference(VariableProxy* this_var, 3283 Expression* home_object, 3284 int pos) { 3285 return new (zone_) SuperPropertyReference(this_var, home_object, pos); 3286 } 3287 3288 SuperCallReference* NewSuperCallReference(VariableProxy* this_var, 3289 VariableProxy* new_target_var, 3290 VariableProxy* this_function_var, 3291 int pos) { 3292 return new (zone_) 3293 SuperCallReference(this_var, new_target_var, this_function_var, pos); 3294 } 3295 3296 EmptyParentheses* NewEmptyParentheses(int pos) { 3297 return new (zone_) EmptyParentheses(pos); 3298 } 3299 3300 GetIterator* NewGetIterator(Expression* iterable, 3301 Expression* destructured_iterable, 3302 IteratorType hint, int pos) { 3303 return new (zone_) GetIterator(iterable, destructured_iterable, hint, pos); 3304 } 3305 3306 GetIterator* NewGetIterator(Expression* iterable, IteratorType hint, 3307 int pos) { 3308 return new (zone_) GetIterator(iterable, hint, pos); 3309 } 3310 3311 GetTemplateObject* NewGetTemplateObject( 3312 const ZonePtrList<const AstRawString>* cooked_strings, 3313 const ZonePtrList<const AstRawString>* raw_strings, int pos) { 3314 return new (zone_) GetTemplateObject(cooked_strings, raw_strings, pos); 3315 } 3316 3317 TemplateLiteral* NewTemplateLiteral( 3318 const ZonePtrList<const AstRawString>* string_parts, 3319 const ZonePtrList<Expression>* substitutions, int pos) { 3320 return new (zone_) TemplateLiteral(string_parts, substitutions, pos); 3321 } 3322 3323 ImportCallExpression* NewImportCallExpression(Expression* args, int pos) { 3324 return new (zone_) ImportCallExpression(args, pos); 3325 } 3326 3327 InitializeClassFieldsStatement* NewInitializeClassFieldsStatement( 3328 ZonePtrList<ClassLiteral::Property>* args, int pos) { 3329 return new (zone_) InitializeClassFieldsStatement(args, pos); 3330 } 3331 3332 Zone* zone() const { return zone_; } 3333 void set_zone(Zone* zone) { zone_ = zone; } 3334 3335 private: 3336 // This zone may be deallocated upon returning from parsing a function body 3337 // which we can guarantee is not going to be compiled or have its AST 3338 // inspected. 3339 // See ParseFunctionLiteral in parser.cc for preconditions. 3340 Zone* zone_; 3341 AstValueFactory* ast_value_factory_; 3342 }; 3343 3344 3345 // Type testing & conversion functions overridden by concrete subclasses. 3346 // Inline functions for AstNode. 3347 3348 #define DECLARE_NODE_FUNCTIONS(type) \ 3349 bool AstNode::Is##type() const { \ 3350 NodeType mine = node_type(); \ 3351 if (mine == AstNode::kRewritableExpression && \ 3352 AstNode::k##type != AstNode::kRewritableExpression) \ 3353 mine = reinterpret_cast<const RewritableExpression*>(this) \ 3354 ->expression() \ 3355 ->node_type(); \ 3356 return mine == AstNode::k##type; \ 3357 } \ 3358 type* AstNode::As##type() { \ 3359 NodeType mine = node_type(); \ 3360 AstNode* result = this; \ 3361 if (mine == AstNode::kRewritableExpression && \ 3362 AstNode::k##type != AstNode::kRewritableExpression) { \ 3363 result = \ 3364 reinterpret_cast<const RewritableExpression*>(this)->expression(); \ 3365 mine = result->node_type(); \ 3366 } \ 3367 return mine == AstNode::k##type ? reinterpret_cast<type*>(result) \ 3368 : nullptr; \ 3369 } \ 3370 const type* AstNode::As##type() const { \ 3371 NodeType mine = node_type(); \ 3372 const AstNode* result = this; \ 3373 if (mine == AstNode::kRewritableExpression && \ 3374 AstNode::k##type != AstNode::kRewritableExpression) { \ 3375 result = \ 3376 reinterpret_cast<const RewritableExpression*>(this)->expression(); \ 3377 mine = result->node_type(); \ 3378 } \ 3379 return mine == AstNode::k##type ? reinterpret_cast<const type*>(result) \ 3380 : nullptr; \ 3381 } 3382 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) 3383 #undef DECLARE_NODE_FUNCTIONS 3384 3385 } // namespace internal 3386 } // namespace v8 3387 3388 #endif // V8_AST_AST_H_ 3389