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