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