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