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