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