Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1004)

Side by Side Diff: src/ast.h

Issue 9221011: Collect AstNode type information (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback (embedded AstProperties and AstConstructionVisitor) Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/ast.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 21 matching lines...) Expand all
32 32
33 #include "assembler.h" 33 #include "assembler.h"
34 #include "factory.h" 34 #include "factory.h"
35 #include "isolate.h" 35 #include "isolate.h"
36 #include "jsregexp.h" 36 #include "jsregexp.h"
37 #include "list-inl.h" 37 #include "list-inl.h"
38 #include "runtime.h" 38 #include "runtime.h"
39 #include "small-pointer-list.h" 39 #include "small-pointer-list.h"
40 #include "smart-array-pointer.h" 40 #include "smart-array-pointer.h"
41 #include "token.h" 41 #include "token.h"
42 #include "utils.h"
42 #include "variables.h" 43 #include "variables.h"
43 #include "zone-inl.h" 44 #include "zone-inl.h"
44 45
45 namespace v8 { 46 namespace v8 {
46 namespace internal { 47 namespace internal {
47 48
48 // The abstract syntax tree is an intermediate, light-weight 49 // The abstract syntax tree is an intermediate, light-weight
49 // representation of the parsed JavaScript code suitable for 50 // representation of the parsed JavaScript code suitable for
50 // compilation to native code. 51 // compilation to native code.
51 52
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 V(BinaryOperation) \ 97 V(BinaryOperation) \
97 V(CompareOperation) \ 98 V(CompareOperation) \
98 V(ThisFunction) 99 V(ThisFunction)
99 100
100 #define AST_NODE_LIST(V) \ 101 #define AST_NODE_LIST(V) \
101 V(Declaration) \ 102 V(Declaration) \
102 STATEMENT_NODE_LIST(V) \ 103 STATEMENT_NODE_LIST(V) \
103 EXPRESSION_NODE_LIST(V) 104 EXPRESSION_NODE_LIST(V)
104 105
105 // Forward declarations 106 // Forward declarations
107 class AstConstructionVisitor;
108 template<class> class AstNodeFactory;
106 class AstVisitor; 109 class AstVisitor;
107 class BreakableStatement; 110 class BreakableStatement;
108 class Expression; 111 class Expression;
109 class IterationStatement; 112 class IterationStatement;
110 class MaterializedLiteral; 113 class MaterializedLiteral;
111 class Statement; 114 class Statement;
112 class TargetCollector; 115 class TargetCollector;
113 class TypeFeedbackOracle; 116 class TypeFeedbackOracle;
114 117
115 class RegExpAlternative; 118 class RegExpAlternative;
(...skipping 13 matching lines...) Expand all
129 AST_NODE_LIST(DEF_FORWARD_DECLARATION) 132 AST_NODE_LIST(DEF_FORWARD_DECLARATION)
130 #undef DEF_FORWARD_DECLARATION 133 #undef DEF_FORWARD_DECLARATION
131 134
132 135
133 // Typedef only introduced to avoid unreadable code. 136 // Typedef only introduced to avoid unreadable code.
134 // Please do appreciate the required space in "> >". 137 // Please do appreciate the required space in "> >".
135 typedef ZoneList<Handle<String> > ZoneStringList; 138 typedef ZoneList<Handle<String> > ZoneStringList;
136 typedef ZoneList<Handle<Object> > ZoneObjectList; 139 typedef ZoneList<Handle<Object> > ZoneObjectList;
137 140
138 141
142 #define DECLARE_NODE_TYPE(type) \
143 virtual void Accept(AstVisitor* v); \
144 virtual AstNode::Type node_type() const { return AstNode::k##type; } \
145
146
147 enum AstPropertiesFlag {
148 kDontCrankshaft,
Kevin Millikin (Chromium) 2012/02/08 09:13:18 To be pedantic (everybody loves that), "Crankshaft
Jakob Kummerow 2012/02/08 09:51:02 Done.
149 kDontInline,
150 kDontSelfOptimize,
151 kDontSoftInline
152 };
153
154
155 class AstProperties BASE_EMBEDDED {
156 public:
157 class Flags : public EnumSet<AstPropertiesFlag, int> {};
158
159 AstProperties() : node_count_(0) { }
160
161 explicit AstProperties(const AstProperties& other)
Kevin Millikin (Chromium) 2012/02/08 09:13:18 Default copy constructor and assignment operator s
Jakob Kummerow 2012/02/08 09:51:02 Done.
162 : flags_(other.flags_),
163 node_count_(other.node_count_) { }
164
165 void operator=(const AstProperties& other) {
166 flags_ = other.flags_;
167 node_count_ = other.node_count_;
168 }
169
170 Flags* flags() { return &flags_; }
171 int node_count() { return node_count_; }
172 void add_node_count(int count) { node_count_ += count; }
173
174 private:
175 Flags flags_;
176 int node_count_;
177 };
178
179
139 class AstNode: public ZoneObject { 180 class AstNode: public ZoneObject {
140 public: 181 public:
141 #define DECLARE_TYPE_ENUM(type) k##type, 182 #define DECLARE_TYPE_ENUM(type) k##type,
142 enum Type { 183 enum Type {
143 AST_NODE_LIST(DECLARE_TYPE_ENUM) 184 AST_NODE_LIST(DECLARE_TYPE_ENUM)
144 kInvalid = -1 185 kInvalid = -1
145 }; 186 };
146 #undef DECLARE_TYPE_ENUM 187 #undef DECLARE_TYPE_ENUM
147 188
148 static const int kNoNumber = -1; 189 static const int kNoNumber = -1;
149 static const int kFunctionEntryId = 2; // Using 0 could disguise errors. 190 static const int kFunctionEntryId = 2; // Using 0 could disguise errors.
150 // This AST id identifies the point after the declarations have been 191 // This AST id identifies the point after the declarations have been
151 // visited. We need it to capture the environment effects of declarations 192 // visited. We need it to capture the environment effects of declarations
152 // that emit code (function declarations). 193 // that emit code (function declarations).
153 static const int kDeclarationsId = 3; 194 static const int kDeclarationsId = 3;
154 195
155 // Override ZoneObject's new to count allocated AST nodes.
156 void* operator new(size_t size, Zone* zone) { 196 void* operator new(size_t size, Zone* zone) {
157 Isolate* isolate = zone->isolate();
158 isolate->set_ast_node_count(isolate->ast_node_count() + 1);
159 return zone->New(static_cast<int>(size)); 197 return zone->New(static_cast<int>(size));
160 } 198 }
161 199
162 AstNode() {} 200 AstNode() { }
163 201
164 virtual ~AstNode() { } 202 virtual ~AstNode() { }
165 203
166 virtual void Accept(AstVisitor* v) = 0; 204 virtual void Accept(AstVisitor* v) = 0;
167 virtual Type node_type() const { return kInvalid; } 205 virtual Type node_type() const { return kInvalid; }
168 206
169 // Type testing & conversion functions overridden by concrete subclasses. 207 // Type testing & conversion functions overridden by concrete subclasses.
170 #define DECLARE_NODE_FUNCTIONS(type) \ 208 #define DECLARE_NODE_FUNCTIONS(type) \
171 bool Is##type() { return node_type() == AstNode::k##type; } \ 209 bool Is##type() { return node_type() == AstNode::k##type; } \
172 type* As##type() { return Is##type() ? reinterpret_cast<type*>(this) : NULL; } 210 type* As##type() { return Is##type() ? reinterpret_cast<type*>(this) : NULL; }
173 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) 211 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
174 #undef DECLARE_NODE_FUNCTIONS 212 #undef DECLARE_NODE_FUNCTIONS
175 213
176 virtual Statement* AsStatement() { return NULL; } 214 virtual Statement* AsStatement() { return NULL; }
177 virtual Expression* AsExpression() { return NULL; } 215 virtual Expression* AsExpression() { return NULL; }
178 virtual TargetCollector* AsTargetCollector() { return NULL; } 216 virtual TargetCollector* AsTargetCollector() { return NULL; }
179 virtual BreakableStatement* AsBreakableStatement() { return NULL; } 217 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
180 virtual IterationStatement* AsIterationStatement() { return NULL; } 218 virtual IterationStatement* AsIterationStatement() { return NULL; }
181 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; } 219 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
182 220
183 // True if the node is simple enough for us to inline calls containing it.
184 virtual bool IsInlineable() const = 0;
185
186 static int Count() { return Isolate::Current()->ast_node_count(); }
187 static void ResetIds() { Isolate::Current()->set_ast_node_id(0); } 221 static void ResetIds() { Isolate::Current()->set_ast_node_id(0); }
188 222
189 protected: 223 protected:
190 static unsigned GetNextId(Isolate* isolate) { 224 static int GetNextId(Isolate* isolate) {
191 return ReserveIdRange(isolate, 1); 225 return ReserveIdRange(isolate, 1);
192 } 226 }
193 227
194 static unsigned ReserveIdRange(Isolate* isolate, int n) { 228 static int ReserveIdRange(Isolate* isolate, int n) {
195 unsigned tmp = isolate->ast_node_id(); 229 int tmp = isolate->ast_node_id();
196 isolate->set_ast_node_id(tmp + n); 230 isolate->set_ast_node_id(tmp + n);
197 return tmp; 231 return tmp;
198 } 232 }
199 233
200 private: 234 private:
201 // Hidden to prevent accidental usage. It would have to load the 235 // Hidden to prevent accidental usage. It would have to load the
202 // current zone from the TLS. 236 // current zone from the TLS.
203 void* operator new(size_t size); 237 void* operator new(size_t size);
204 238
205 friend class CaseClause; // Generates AST IDs. 239 friend class CaseClause; // Generates AST IDs.
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 ASSERT(IsMonomorphic()); 353 ASSERT(IsMonomorphic());
320 SmallMapList* types = GetReceiverTypes(); 354 SmallMapList* types = GetReceiverTypes();
321 ASSERT(types != NULL && types->length() == 1); 355 ASSERT(types != NULL && types->length() == 1);
322 return types->at(0); 356 return types->at(0);
323 } 357 }
324 358
325 unsigned id() const { return id_; } 359 unsigned id() const { return id_; }
326 unsigned test_id() const { return test_id_; } 360 unsigned test_id() const { return test_id_; }
327 361
328 private: 362 private:
329 unsigned id_; 363 int id_;
330 unsigned test_id_; 364 int test_id_;
331 }; 365 };
332 366
333 367
334 class BreakableStatement: public Statement { 368 class BreakableStatement: public Statement {
335 public: 369 public:
336 enum Type { 370 enum Type {
337 TARGET_FOR_ANONYMOUS, 371 TARGET_FOR_ANONYMOUS,
338 TARGET_FOR_NAMED_ONLY 372 TARGET_FOR_NAMED_ONLY
339 }; 373 };
340 374
(...skipping 28 matching lines...) Expand all
369 ZoneStringList* labels_; 403 ZoneStringList* labels_;
370 Type type_; 404 Type type_;
371 Label break_target_; 405 Label break_target_;
372 int entry_id_; 406 int entry_id_;
373 int exit_id_; 407 int exit_id_;
374 }; 408 };
375 409
376 410
377 class Block: public BreakableStatement { 411 class Block: public BreakableStatement {
378 public: 412 public:
379 Block(Isolate* isolate,
380 ZoneStringList* labels,
381 int capacity,
382 bool is_initializer_block)
383 : BreakableStatement(isolate, labels, TARGET_FOR_NAMED_ONLY),
384 statements_(capacity),
385 is_initializer_block_(is_initializer_block),
386 block_scope_(NULL) {
387 }
388
389
390 DECLARE_NODE_TYPE(Block) 413 DECLARE_NODE_TYPE(Block)
391 414
392 virtual bool IsInlineable() const;
393
394 void AddStatement(Statement* statement) { statements_.Add(statement); } 415 void AddStatement(Statement* statement) { statements_.Add(statement); }
395 416
396 ZoneList<Statement*>* statements() { return &statements_; } 417 ZoneList<Statement*>* statements() { return &statements_; }
397 bool is_initializer_block() const { return is_initializer_block_; } 418 bool is_initializer_block() const { return is_initializer_block_; }
398 419
399 Scope* block_scope() const { return block_scope_; } 420 Scope* block_scope() const { return block_scope_; }
400 void set_block_scope(Scope* block_scope) { block_scope_ = block_scope; } 421 void set_block_scope(Scope* block_scope) { block_scope_ = block_scope; }
401 422
423 protected:
424 template<class> friend class AstNodeFactory;
425
426 Block(Isolate* isolate,
427 ZoneStringList* labels,
428 int capacity,
429 bool is_initializer_block)
430 : BreakableStatement(isolate, labels, TARGET_FOR_NAMED_ONLY),
431 statements_(capacity),
432 is_initializer_block_(is_initializer_block),
433 block_scope_(NULL) {
434 }
435
402 private: 436 private:
403 ZoneList<Statement*> statements_; 437 ZoneList<Statement*> statements_;
404 bool is_initializer_block_; 438 bool is_initializer_block_;
405 Scope* block_scope_; 439 Scope* block_scope_;
406 }; 440 };
407 441
408 442
409 class Declaration: public AstNode { 443 class Declaration: public AstNode {
410 public: 444 public:
445 DECLARE_NODE_TYPE(Declaration)
446
447 VariableProxy* proxy() const { return proxy_; }
448 VariableMode mode() const { return mode_; }
449 FunctionLiteral* fun() const { return fun_; } // may be NULL
450 bool IsInlineable() const;
451 Scope* scope() const { return scope_; }
452
453 protected:
454 template<class> friend class AstNodeFactory;
455
411 Declaration(VariableProxy* proxy, 456 Declaration(VariableProxy* proxy,
412 VariableMode mode, 457 VariableMode mode,
413 FunctionLiteral* fun, 458 FunctionLiteral* fun,
414 Scope* scope) 459 Scope* scope)
415 : proxy_(proxy), 460 : proxy_(proxy),
416 mode_(mode), 461 mode_(mode),
417 fun_(fun), 462 fun_(fun),
418 scope_(scope) { 463 scope_(scope) {
419 ASSERT(mode == VAR || 464 ASSERT(mode == VAR ||
420 mode == CONST || 465 mode == CONST ||
421 mode == CONST_HARMONY || 466 mode == CONST_HARMONY ||
422 mode == LET); 467 mode == LET);
423 // At the moment there are no "const functions"'s in JavaScript... 468 // At the moment there are no "const functions"'s in JavaScript...
424 ASSERT(fun == NULL || mode == VAR || mode == LET); 469 ASSERT(fun == NULL || mode == VAR || mode == LET);
425 } 470 }
426 471
427 DECLARE_NODE_TYPE(Declaration)
428
429 VariableProxy* proxy() const { return proxy_; }
430 VariableMode mode() const { return mode_; }
431 FunctionLiteral* fun() const { return fun_; } // may be NULL
432 virtual bool IsInlineable() const;
433 Scope* scope() const { return scope_; }
434
435 private: 472 private:
436 VariableProxy* proxy_; 473 VariableProxy* proxy_;
437 VariableMode mode_; 474 VariableMode mode_;
438 FunctionLiteral* fun_; 475 FunctionLiteral* fun_;
439 476
440 // Nested scope from which the declaration originated. 477 // Nested scope from which the declaration originated.
441 Scope* scope_; 478 Scope* scope_;
442 }; 479 };
443 480
444 481
(...skipping 25 matching lines...) Expand all
470 507
471 private: 508 private:
472 Statement* body_; 509 Statement* body_;
473 Label continue_target_; 510 Label continue_target_;
474 int osr_entry_id_; 511 int osr_entry_id_;
475 }; 512 };
476 513
477 514
478 class DoWhileStatement: public IterationStatement { 515 class DoWhileStatement: public IterationStatement {
479 public: 516 public:
480 DoWhileStatement(Isolate* isolate, ZoneStringList* labels)
481 : IterationStatement(isolate, labels),
482 cond_(NULL),
483 condition_position_(-1),
484 continue_id_(GetNextId(isolate)),
485 back_edge_id_(GetNextId(isolate)) {
486 }
487
488 DECLARE_NODE_TYPE(DoWhileStatement) 517 DECLARE_NODE_TYPE(DoWhileStatement)
489 518
490 void Initialize(Expression* cond, Statement* body) { 519 void Initialize(Expression* cond, Statement* body) {
491 IterationStatement::Initialize(body); 520 IterationStatement::Initialize(body);
492 cond_ = cond; 521 cond_ = cond;
493 } 522 }
494 523
495 Expression* cond() const { return cond_; } 524 Expression* cond() const { return cond_; }
496 525
497 // Position where condition expression starts. We need it to make 526 // Position where condition expression starts. We need it to make
498 // the loop's condition a breakable location. 527 // the loop's condition a breakable location.
499 int condition_position() { return condition_position_; } 528 int condition_position() { return condition_position_; }
500 void set_condition_position(int pos) { condition_position_ = pos; } 529 void set_condition_position(int pos) { condition_position_ = pos; }
501 530
502 // Bailout support. 531 // Bailout support.
503 virtual int ContinueId() const { return continue_id_; } 532 virtual int ContinueId() const { return continue_id_; }
504 virtual int StackCheckId() const { return back_edge_id_; } 533 virtual int StackCheckId() const { return back_edge_id_; }
505 int BackEdgeId() const { return back_edge_id_; } 534 int BackEdgeId() const { return back_edge_id_; }
506 535
507 virtual bool IsInlineable() const; 536 protected:
537 template<class> friend class AstNodeFactory;
538
539 DoWhileStatement(Isolate* isolate, ZoneStringList* labels)
540 : IterationStatement(isolate, labels),
541 cond_(NULL),
542 condition_position_(-1),
543 continue_id_(GetNextId(isolate)),
544 back_edge_id_(GetNextId(isolate)) {
545 }
508 546
509 private: 547 private:
510 Expression* cond_; 548 Expression* cond_;
511 int condition_position_; 549 int condition_position_;
512 int continue_id_; 550 int continue_id_;
513 int back_edge_id_; 551 int back_edge_id_;
514 }; 552 };
515 553
516 554
517 class WhileStatement: public IterationStatement { 555 class WhileStatement: public IterationStatement {
518 public: 556 public:
519 WhileStatement(Isolate* isolate, ZoneStringList* labels)
520 : IterationStatement(isolate, labels),
521 cond_(NULL),
522 may_have_function_literal_(true),
523 body_id_(GetNextId(isolate)) {
524 }
525
526 DECLARE_NODE_TYPE(WhileStatement) 557 DECLARE_NODE_TYPE(WhileStatement)
527 558
528 void Initialize(Expression* cond, Statement* body) { 559 void Initialize(Expression* cond, Statement* body) {
529 IterationStatement::Initialize(body); 560 IterationStatement::Initialize(body);
530 cond_ = cond; 561 cond_ = cond;
531 } 562 }
532 563
533 Expression* cond() const { return cond_; } 564 Expression* cond() const { return cond_; }
534 bool may_have_function_literal() const { 565 bool may_have_function_literal() const {
535 return may_have_function_literal_; 566 return may_have_function_literal_;
536 } 567 }
537 void set_may_have_function_literal(bool value) { 568 void set_may_have_function_literal(bool value) {
538 may_have_function_literal_ = value; 569 may_have_function_literal_ = value;
539 } 570 }
540 virtual bool IsInlineable() const;
541 571
542 // Bailout support. 572 // Bailout support.
543 virtual int ContinueId() const { return EntryId(); } 573 virtual int ContinueId() const { return EntryId(); }
544 virtual int StackCheckId() const { return body_id_; } 574 virtual int StackCheckId() const { return body_id_; }
545 int BodyId() const { return body_id_; } 575 int BodyId() const { return body_id_; }
546 576
577 protected:
578 template<class> friend class AstNodeFactory;
579
580 WhileStatement(Isolate* isolate, ZoneStringList* labels)
581 : IterationStatement(isolate, labels),
582 cond_(NULL),
583 may_have_function_literal_(true),
584 body_id_(GetNextId(isolate)) {
585 }
586
547 private: 587 private:
548 Expression* cond_; 588 Expression* cond_;
549 // True if there is a function literal subexpression in the condition. 589 // True if there is a function literal subexpression in the condition.
550 bool may_have_function_literal_; 590 bool may_have_function_literal_;
551 int body_id_; 591 int body_id_;
552 }; 592 };
553 593
554 594
555 class ForStatement: public IterationStatement { 595 class ForStatement: public IterationStatement {
556 public: 596 public:
557 ForStatement(Isolate* isolate, ZoneStringList* labels)
558 : IterationStatement(isolate, labels),
559 init_(NULL),
560 cond_(NULL),
561 next_(NULL),
562 may_have_function_literal_(true),
563 loop_variable_(NULL),
564 continue_id_(GetNextId(isolate)),
565 body_id_(GetNextId(isolate)) {
566 }
567
568 DECLARE_NODE_TYPE(ForStatement) 597 DECLARE_NODE_TYPE(ForStatement)
569 598
570 void Initialize(Statement* init, 599 void Initialize(Statement* init,
571 Expression* cond, 600 Expression* cond,
572 Statement* next, 601 Statement* next,
573 Statement* body) { 602 Statement* body) {
574 IterationStatement::Initialize(body); 603 IterationStatement::Initialize(body);
575 init_ = init; 604 init_ = init;
576 cond_ = cond; 605 cond_ = cond;
577 next_ = next; 606 next_ = next;
(...skipping 11 matching lines...) Expand all
589 } 618 }
590 619
591 // Bailout support. 620 // Bailout support.
592 virtual int ContinueId() const { return continue_id_; } 621 virtual int ContinueId() const { return continue_id_; }
593 virtual int StackCheckId() const { return body_id_; } 622 virtual int StackCheckId() const { return body_id_; }
594 int BodyId() const { return body_id_; } 623 int BodyId() const { return body_id_; }
595 624
596 bool is_fast_smi_loop() { return loop_variable_ != NULL; } 625 bool is_fast_smi_loop() { return loop_variable_ != NULL; }
597 Variable* loop_variable() { return loop_variable_; } 626 Variable* loop_variable() { return loop_variable_; }
598 void set_loop_variable(Variable* var) { loop_variable_ = var; } 627 void set_loop_variable(Variable* var) { loop_variable_ = var; }
599 virtual bool IsInlineable() const; 628
629 protected:
630 template<class> friend class AstNodeFactory;
631
632 ForStatement(Isolate* isolate, ZoneStringList* labels)
633 : IterationStatement(isolate, labels),
634 init_(NULL),
635 cond_(NULL),
636 next_(NULL),
637 may_have_function_literal_(true),
638 loop_variable_(NULL),
639 continue_id_(GetNextId(isolate)),
640 body_id_(GetNextId(isolate)) {
641 }
600 642
601 private: 643 private:
602 Statement* init_; 644 Statement* init_;
603 Expression* cond_; 645 Expression* cond_;
604 Statement* next_; 646 Statement* next_;
605 // True if there is a function literal subexpression in the condition. 647 // True if there is a function literal subexpression in the condition.
606 bool may_have_function_literal_; 648 bool may_have_function_literal_;
607 Variable* loop_variable_; 649 Variable* loop_variable_;
608 int continue_id_; 650 int continue_id_;
609 int body_id_; 651 int body_id_;
610 }; 652 };
611 653
612 654
613 class ForInStatement: public IterationStatement { 655 class ForInStatement: public IterationStatement {
614 public: 656 public:
615 ForInStatement(Isolate* isolate, ZoneStringList* labels)
616 : IterationStatement(isolate, labels),
617 each_(NULL),
618 enumerable_(NULL),
619 assignment_id_(GetNextId(isolate)) {
620 }
621
622 DECLARE_NODE_TYPE(ForInStatement) 657 DECLARE_NODE_TYPE(ForInStatement)
623 658
624 void Initialize(Expression* each, Expression* enumerable, Statement* body) { 659 void Initialize(Expression* each, Expression* enumerable, Statement* body) {
625 IterationStatement::Initialize(body); 660 IterationStatement::Initialize(body);
626 each_ = each; 661 each_ = each;
627 enumerable_ = enumerable; 662 enumerable_ = enumerable;
628 } 663 }
629 664
630 Expression* each() const { return each_; } 665 Expression* each() const { return each_; }
631 Expression* enumerable() const { return enumerable_; } 666 Expression* enumerable() const { return enumerable_; }
632 virtual bool IsInlineable() const;
633 667
634 // Bailout support. 668 // Bailout support.
635 int AssignmentId() const { return assignment_id_; } 669 int AssignmentId() const { return assignment_id_; }
636 virtual int ContinueId() const { return EntryId(); } 670 virtual int ContinueId() const { return EntryId(); }
637 virtual int StackCheckId() const { return EntryId(); } 671 virtual int StackCheckId() const { return EntryId(); }
638 672
673 protected:
674 template<class> friend class AstNodeFactory;
675
676 ForInStatement(Isolate* isolate, ZoneStringList* labels)
677 : IterationStatement(isolate, labels),
678 each_(NULL),
679 enumerable_(NULL),
680 assignment_id_(GetNextId(isolate)) {
681 }
682
639 private: 683 private:
640 Expression* each_; 684 Expression* each_;
641 Expression* enumerable_; 685 Expression* enumerable_;
642 int assignment_id_; 686 int assignment_id_;
643 }; 687 };
644 688
645 689
646 class ExpressionStatement: public Statement { 690 class ExpressionStatement: public Statement {
647 public: 691 public:
648 explicit ExpressionStatement(Expression* expression)
649 : expression_(expression) { }
650
651 DECLARE_NODE_TYPE(ExpressionStatement) 692 DECLARE_NODE_TYPE(ExpressionStatement)
652 693
653 virtual bool IsInlineable() const;
654
655 void set_expression(Expression* e) { expression_ = e; } 694 void set_expression(Expression* e) { expression_ = e; }
656 Expression* expression() const { return expression_; } 695 Expression* expression() const { return expression_; }
657 696
697 protected:
698 template<class> friend class AstNodeFactory;
699
700 explicit ExpressionStatement(Expression* expression)
701 : expression_(expression) { }
702
658 private: 703 private:
659 Expression* expression_; 704 Expression* expression_;
660 }; 705 };
661 706
662 707
663 class ContinueStatement: public Statement { 708 class ContinueStatement: public Statement {
664 public: 709 public:
710 DECLARE_NODE_TYPE(ContinueStatement)
711
712 IterationStatement* target() const { return target_; }
713
714 protected:
715 template<class> friend class AstNodeFactory;
716
665 explicit ContinueStatement(IterationStatement* target) 717 explicit ContinueStatement(IterationStatement* target)
666 : target_(target) { } 718 : target_(target) { }
667 719
668 DECLARE_NODE_TYPE(ContinueStatement)
669
670 IterationStatement* target() const { return target_; }
671 virtual bool IsInlineable() const;
672
673 private: 720 private:
674 IterationStatement* target_; 721 IterationStatement* target_;
675 }; 722 };
676 723
677 724
678 class BreakStatement: public Statement { 725 class BreakStatement: public Statement {
679 public: 726 public:
727 DECLARE_NODE_TYPE(BreakStatement)
728
729 BreakableStatement* target() const { return target_; }
730
731 protected:
732 template<class> friend class AstNodeFactory;
733
680 explicit BreakStatement(BreakableStatement* target) 734 explicit BreakStatement(BreakableStatement* target)
681 : target_(target) { } 735 : target_(target) { }
682 736
683 DECLARE_NODE_TYPE(BreakStatement)
684
685 BreakableStatement* target() const { return target_; }
686 virtual bool IsInlineable() const;
687
688 private: 737 private:
689 BreakableStatement* target_; 738 BreakableStatement* target_;
690 }; 739 };
691 740
692 741
693 class ReturnStatement: public Statement { 742 class ReturnStatement: public Statement {
694 public: 743 public:
744 DECLARE_NODE_TYPE(ReturnStatement)
745
746 Expression* expression() const { return expression_; }
747
748 protected:
749 template<class> friend class AstNodeFactory;
750
695 explicit ReturnStatement(Expression* expression) 751 explicit ReturnStatement(Expression* expression)
696 : expression_(expression) { } 752 : expression_(expression) { }
697 753
698 DECLARE_NODE_TYPE(ReturnStatement)
699
700 Expression* expression() const { return expression_; }
701 virtual bool IsInlineable() const;
702
703 private: 754 private:
704 Expression* expression_; 755 Expression* expression_;
705 }; 756 };
706 757
707 758
708 class WithStatement: public Statement { 759 class WithStatement: public Statement {
709 public: 760 public:
710 WithStatement(Expression* expression, Statement* statement)
711 : expression_(expression), statement_(statement) { }
712
713 DECLARE_NODE_TYPE(WithStatement) 761 DECLARE_NODE_TYPE(WithStatement)
714 762
715 Expression* expression() const { return expression_; } 763 Expression* expression() const { return expression_; }
716 Statement* statement() const { return statement_; } 764 Statement* statement() const { return statement_; }
717 765
718 virtual bool IsInlineable() const; 766 protected:
767 template<class> friend class AstNodeFactory;
768
769 WithStatement(Expression* expression, Statement* statement)
770 : expression_(expression),
771 statement_(statement) { }
719 772
720 private: 773 private:
721 Expression* expression_; 774 Expression* expression_;
722 Statement* statement_; 775 Statement* statement_;
723 }; 776 };
724 777
725 778
726 class CaseClause: public ZoneObject { 779 class CaseClause: public ZoneObject {
727 public: 780 public:
728 CaseClause(Isolate* isolate, 781 CaseClause(Isolate* isolate,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 OBJECT_ONLY 817 OBJECT_ONLY
765 }; 818 };
766 CompareTypeFeedback compare_type_; 819 CompareTypeFeedback compare_type_;
767 int compare_id_; 820 int compare_id_;
768 int entry_id_; 821 int entry_id_;
769 }; 822 };
770 823
771 824
772 class SwitchStatement: public BreakableStatement { 825 class SwitchStatement: public BreakableStatement {
773 public: 826 public:
774 SwitchStatement(Isolate* isolate, ZoneStringList* labels)
775 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
776 tag_(NULL),
777 cases_(NULL) {
778 }
779
780
781 DECLARE_NODE_TYPE(SwitchStatement) 827 DECLARE_NODE_TYPE(SwitchStatement)
782 828
783 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) { 829 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
784 tag_ = tag; 830 tag_ = tag;
785 cases_ = cases; 831 cases_ = cases;
786 } 832 }
787 833
788 Expression* tag() const { return tag_; } 834 Expression* tag() const { return tag_; }
789 ZoneList<CaseClause*>* cases() const { return cases_; } 835 ZoneList<CaseClause*>* cases() const { return cases_; }
790 virtual bool IsInlineable() const; 836
837 protected:
838 template<class> friend class AstNodeFactory;
839
840 SwitchStatement(Isolate* isolate, ZoneStringList* labels)
841 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
842 tag_(NULL),
843 cases_(NULL) { }
791 844
792 private: 845 private:
793 Expression* tag_; 846 Expression* tag_;
794 ZoneList<CaseClause*>* cases_; 847 ZoneList<CaseClause*>* cases_;
795 }; 848 };
796 849
797 850
798 // If-statements always have non-null references to their then- and 851 // If-statements always have non-null references to their then- and
799 // else-parts. When parsing if-statements with no explicit else-part, 852 // else-parts. When parsing if-statements with no explicit else-part,
800 // the parser implicitly creates an empty statement. Use the 853 // the parser implicitly creates an empty statement. Use the
801 // HasThenStatement() and HasElseStatement() functions to check if a 854 // HasThenStatement() and HasElseStatement() functions to check if a
802 // given if-statement has a then- or an else-part containing code. 855 // given if-statement has a then- or an else-part containing code.
803 class IfStatement: public Statement { 856 class IfStatement: public Statement {
804 public: 857 public:
805 IfStatement(Isolate* isolate,
806 Expression* condition,
807 Statement* then_statement,
808 Statement* else_statement)
809 : condition_(condition),
810 then_statement_(then_statement),
811 else_statement_(else_statement),
812 if_id_(GetNextId(isolate)),
813 then_id_(GetNextId(isolate)),
814 else_id_(GetNextId(isolate)) {
815 }
816
817 DECLARE_NODE_TYPE(IfStatement) 858 DECLARE_NODE_TYPE(IfStatement)
818 859
819 virtual bool IsInlineable() const;
820
821 bool HasThenStatement() const { return !then_statement()->IsEmpty(); } 860 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
822 bool HasElseStatement() const { return !else_statement()->IsEmpty(); } 861 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
823 862
824 Expression* condition() const { return condition_; } 863 Expression* condition() const { return condition_; }
825 Statement* then_statement() const { return then_statement_; } 864 Statement* then_statement() const { return then_statement_; }
826 Statement* else_statement() const { return else_statement_; } 865 Statement* else_statement() const { return else_statement_; }
827 866
828 int IfId() const { return if_id_; } 867 int IfId() const { return if_id_; }
829 int ThenId() const { return then_id_; } 868 int ThenId() const { return then_id_; }
830 int ElseId() const { return else_id_; } 869 int ElseId() const { return else_id_; }
831 870
871 protected:
872 template<class> friend class AstNodeFactory;
873
874 IfStatement(Isolate* isolate,
875 Expression* condition,
876 Statement* then_statement,
877 Statement* else_statement)
878 : condition_(condition),
879 then_statement_(then_statement),
880 else_statement_(else_statement),
881 if_id_(GetNextId(isolate)),
882 then_id_(GetNextId(isolate)),
883 else_id_(GetNextId(isolate)) {
884 }
885
832 private: 886 private:
833 Expression* condition_; 887 Expression* condition_;
834 Statement* then_statement_; 888 Statement* then_statement_;
835 Statement* else_statement_; 889 Statement* else_statement_;
836 int if_id_; 890 int if_id_;
837 int then_id_; 891 int then_id_;
838 int else_id_; 892 int else_id_;
839 }; 893 };
840 894
841 895
842 // NOTE: TargetCollectors are represented as nodes to fit in the target 896 // NOTE: TargetCollectors are represented as nodes to fit in the target
843 // stack in the compiler; this should probably be reworked. 897 // stack in the compiler; this should probably be reworked.
844 class TargetCollector: public AstNode { 898 class TargetCollector: public AstNode {
845 public: 899 public:
846 TargetCollector(): targets_(0) { } 900 TargetCollector() : targets_(0) { }
847 901
848 // Adds a jump target to the collector. The collector stores a pointer not 902 // Adds a jump target to the collector. The collector stores a pointer not
849 // a copy of the target to make binding work, so make sure not to pass in 903 // a copy of the target to make binding work, so make sure not to pass in
850 // references to something on the stack. 904 // references to something on the stack.
851 void AddTarget(Label* target); 905 void AddTarget(Label* target);
852 906
853 // Virtual behaviour. TargetCollectors are never part of the AST. 907 // Virtual behaviour. TargetCollectors are never part of the AST.
854 virtual void Accept(AstVisitor* v) { UNREACHABLE(); } 908 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
855 virtual TargetCollector* AsTargetCollector() { return this; } 909 virtual TargetCollector* AsTargetCollector() { return this; }
856 910
857 ZoneList<Label*>* targets() { return &targets_; } 911 ZoneList<Label*>* targets() { return &targets_; }
858 virtual bool IsInlineable() const;
859 912
860 private: 913 private:
861 ZoneList<Label*> targets_; 914 ZoneList<Label*> targets_;
862 }; 915 };
863 916
864 917
865 class TryStatement: public Statement { 918 class TryStatement: public Statement {
866 public: 919 public:
867 explicit TryStatement(int index, Block* try_block)
868 : index_(index),
869 try_block_(try_block),
870 escaping_targets_(NULL) {
871 }
872
873 void set_escaping_targets(ZoneList<Label*>* targets) { 920 void set_escaping_targets(ZoneList<Label*>* targets) {
874 escaping_targets_ = targets; 921 escaping_targets_ = targets;
875 } 922 }
876 923
877 int index() const { return index_; } 924 int index() const { return index_; }
878 Block* try_block() const { return try_block_; } 925 Block* try_block() const { return try_block_; }
879 ZoneList<Label*>* escaping_targets() const { return escaping_targets_; } 926 ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
880 virtual bool IsInlineable() const; 927
928 protected:
929 TryStatement(int index, Block* try_block)
930 : index_(index),
931 try_block_(try_block),
932 escaping_targets_(NULL) { }
881 933
882 private: 934 private:
883 // Unique (per-function) index of this handler. This is not an AST ID. 935 // Unique (per-function) index of this handler. This is not an AST ID.
884 int index_; 936 int index_;
885 937
886 Block* try_block_; 938 Block* try_block_;
887 ZoneList<Label*>* escaping_targets_; 939 ZoneList<Label*>* escaping_targets_;
888 }; 940 };
889 941
890 942
891 class TryCatchStatement: public TryStatement { 943 class TryCatchStatement: public TryStatement {
892 public: 944 public:
945 DECLARE_NODE_TYPE(TryCatchStatement)
946
947 Scope* scope() { return scope_; }
948 Variable* variable() { return variable_; }
949 Block* catch_block() const { return catch_block_; }
950
951 protected:
952 template<class> friend class AstNodeFactory;
953
893 TryCatchStatement(int index, 954 TryCatchStatement(int index,
894 Block* try_block, 955 Block* try_block,
895 Scope* scope, 956 Scope* scope,
896 Variable* variable, 957 Variable* variable,
897 Block* catch_block) 958 Block* catch_block)
898 : TryStatement(index, try_block), 959 : TryStatement(index, try_block),
899 scope_(scope), 960 scope_(scope),
900 variable_(variable), 961 variable_(variable),
901 catch_block_(catch_block) { 962 catch_block_(catch_block) {
902 } 963 }
903 964
904 DECLARE_NODE_TYPE(TryCatchStatement)
905
906 Scope* scope() { return scope_; }
907 Variable* variable() { return variable_; }
908 Block* catch_block() const { return catch_block_; }
909 virtual bool IsInlineable() const;
910
911 private: 965 private:
912 Scope* scope_; 966 Scope* scope_;
913 Variable* variable_; 967 Variable* variable_;
914 Block* catch_block_; 968 Block* catch_block_;
915 }; 969 };
916 970
917 971
918 class TryFinallyStatement: public TryStatement { 972 class TryFinallyStatement: public TryStatement {
919 public: 973 public:
974 DECLARE_NODE_TYPE(TryFinallyStatement)
975
976 Block* finally_block() const { return finally_block_; }
977
978 protected:
979 template<class> friend class AstNodeFactory;
980
920 TryFinallyStatement(int index, Block* try_block, Block* finally_block) 981 TryFinallyStatement(int index, Block* try_block, Block* finally_block)
921 : TryStatement(index, try_block), 982 : TryStatement(index, try_block),
922 finally_block_(finally_block) { } 983 finally_block_(finally_block) { }
923 984
924 DECLARE_NODE_TYPE(TryFinallyStatement)
925
926 Block* finally_block() const { return finally_block_; }
927 virtual bool IsInlineable() const;
928
929 private: 985 private:
930 Block* finally_block_; 986 Block* finally_block_;
931 }; 987 };
932 988
933 989
934 class DebuggerStatement: public Statement { 990 class DebuggerStatement: public Statement {
935 public: 991 public:
936 DECLARE_NODE_TYPE(DebuggerStatement) 992 DECLARE_NODE_TYPE(DebuggerStatement)
937 virtual bool IsInlineable() const; 993
994 protected:
995 template<class> friend class AstNodeFactory;
996
997 DebuggerStatement() {}
938 }; 998 };
939 999
940 1000
941 class EmptyStatement: public Statement { 1001 class EmptyStatement: public Statement {
942 public: 1002 public:
943 DECLARE_NODE_TYPE(EmptyStatement) 1003 DECLARE_NODE_TYPE(EmptyStatement)
944 1004
945 virtual bool IsInlineable() const; 1005 protected:
1006 template<class> friend class AstNodeFactory;
1007
1008 EmptyStatement() {}
946 }; 1009 };
947 1010
948 1011
949 class Literal: public Expression { 1012 class Literal: public Expression {
950 public: 1013 public:
951 Literal(Isolate* isolate, Handle<Object> handle)
952 : Expression(isolate), handle_(handle) { }
953
954 DECLARE_NODE_TYPE(Literal) 1014 DECLARE_NODE_TYPE(Literal)
955 1015
956 // Check if this literal is identical to the other literal. 1016 // Check if this literal is identical to the other literal.
957 bool IsIdenticalTo(const Literal* other) const { 1017 bool IsIdenticalTo(const Literal* other) const {
958 return handle_.is_identical_to(other->handle_); 1018 return handle_.is_identical_to(other->handle_);
959 } 1019 }
960 1020
961 virtual bool IsPropertyName() { 1021 virtual bool IsPropertyName() {
962 if (handle_->IsSymbol()) { 1022 if (handle_->IsSymbol()) {
963 uint32_t ignored; 1023 uint32_t ignored;
(...skipping 18 matching lines...) Expand all
982 bool IsTrue() const { 1042 bool IsTrue() const {
983 ASSERT(!handle_.is_null()); 1043 ASSERT(!handle_.is_null());
984 return handle_->IsTrue(); 1044 return handle_->IsTrue();
985 } 1045 }
986 bool IsFalse() const { 1046 bool IsFalse() const {
987 ASSERT(!handle_.is_null()); 1047 ASSERT(!handle_.is_null());
988 return handle_->IsFalse(); 1048 return handle_->IsFalse();
989 } 1049 }
990 1050
991 Handle<Object> handle() const { return handle_; } 1051 Handle<Object> handle() const { return handle_; }
992 virtual bool IsInlineable() const; 1052
1053 protected:
1054 template<class> friend class AstNodeFactory;
1055
1056 Literal(Isolate* isolate, Handle<Object> handle)
1057 : Expression(isolate),
1058 handle_(handle) { }
993 1059
994 private: 1060 private:
995 Handle<Object> handle_; 1061 Handle<Object> handle_;
996 }; 1062 };
997 1063
998 1064
999 // Base class for literals that needs space in the corresponding JSFunction. 1065 // Base class for literals that needs space in the corresponding JSFunction.
1000 class MaterializedLiteral: public Expression { 1066 class MaterializedLiteral: public Expression {
1001 public: 1067 public:
1002 MaterializedLiteral(Isolate* isolate,
1003 int literal_index,
1004 bool is_simple,
1005 int depth)
1006 : Expression(isolate),
1007 literal_index_(literal_index),
1008 is_simple_(is_simple),
1009 depth_(depth) {}
1010
1011 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; } 1068 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
1012 1069
1013 int literal_index() { return literal_index_; } 1070 int literal_index() { return literal_index_; }
1014 1071
1015 // A materialized literal is simple if the values consist of only 1072 // A materialized literal is simple if the values consist of only
1016 // constants and simple object and array literals. 1073 // constants and simple object and array literals.
1017 bool is_simple() const { return is_simple_; } 1074 bool is_simple() const { return is_simple_; }
1018 1075
1019 int depth() const { return depth_; } 1076 int depth() const { return depth_; }
1020 virtual bool IsInlineable() const; 1077
1078 protected:
1079 MaterializedLiteral(Isolate* isolate,
1080 int literal_index,
1081 bool is_simple,
1082 int depth)
1083 : Expression(isolate),
1084 literal_index_(literal_index),
1085 is_simple_(is_simple),
1086 depth_(depth) {}
1021 1087
1022 private: 1088 private:
1023 int literal_index_; 1089 int literal_index_;
1024 bool is_simple_; 1090 bool is_simple_;
1025 int depth_; 1091 int depth_;
1026 }; 1092 };
1027 1093
1028 1094
1029 // An object literal has a boilerplate object that is used 1095 // An object literal has a boilerplate object that is used
1030 // for minimizing the work when constructing it at runtime. 1096 // for minimizing the work when constructing it at runtime.
1031 class ObjectLiteral: public MaterializedLiteral { 1097 class ObjectLiteral: public MaterializedLiteral {
1032 public: 1098 public:
1033 // Property is used for passing information 1099 // Property is used for passing information
1034 // about an object literal's properties from the parser 1100 // about an object literal's properties from the parser
1035 // to the code generator. 1101 // to the code generator.
1036 class Property: public ZoneObject { 1102 class Property: public ZoneObject {
1037 public: 1103 public:
1038 enum Kind { 1104 enum Kind {
1039 CONSTANT, // Property with constant value (compile time). 1105 CONSTANT, // Property with constant value (compile time).
1040 COMPUTED, // Property with computed value (execution time). 1106 COMPUTED, // Property with computed value (execution time).
1041 MATERIALIZED_LITERAL, // Property value is a materialized literal. 1107 MATERIALIZED_LITERAL, // Property value is a materialized literal.
1042 GETTER, SETTER, // Property is an accessor function. 1108 GETTER, SETTER, // Property is an accessor function.
1043 PROTOTYPE // Property is __proto__. 1109 PROTOTYPE // Property is __proto__.
1044 }; 1110 };
1045 1111
1046 Property(Literal* key, Expression* value); 1112 Property(Literal* key, Expression* value);
1047 Property(bool is_getter, FunctionLiteral* value);
1048 1113
1049 Literal* key() { return key_; } 1114 Literal* key() { return key_; }
1050 Expression* value() { return value_; } 1115 Expression* value() { return value_; }
1051 Kind kind() { return kind_; } 1116 Kind kind() { return kind_; }
1052 1117
1053 bool IsCompileTimeValue(); 1118 bool IsCompileTimeValue();
1054 1119
1055 void set_emit_store(bool emit_store); 1120 void set_emit_store(bool emit_store);
1056 bool emit_store(); 1121 bool emit_store();
1057 1122
1123 protected:
1124 template<class> friend class AstNodeFactory;
1125
1126 Property(bool is_getter, FunctionLiteral* value);
1127 void set_key(Literal* key) { key_ = key; }
1128
1058 private: 1129 private:
1059 Literal* key_; 1130 Literal* key_;
1060 Expression* value_; 1131 Expression* value_;
1061 Kind kind_; 1132 Kind kind_;
1062 bool emit_store_; 1133 bool emit_store_;
1063 }; 1134 };
1064 1135
1065 ObjectLiteral(Isolate* isolate,
1066 Handle<FixedArray> constant_properties,
1067 ZoneList<Property*>* properties,
1068 int literal_index,
1069 bool is_simple,
1070 bool fast_elements,
1071 int depth,
1072 bool has_function)
1073 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
1074 constant_properties_(constant_properties),
1075 properties_(properties),
1076 fast_elements_(fast_elements),
1077 has_function_(has_function) {}
1078
1079 DECLARE_NODE_TYPE(ObjectLiteral) 1136 DECLARE_NODE_TYPE(ObjectLiteral)
1080 1137
1081 Handle<FixedArray> constant_properties() const { 1138 Handle<FixedArray> constant_properties() const {
1082 return constant_properties_; 1139 return constant_properties_;
1083 } 1140 }
1084 ZoneList<Property*>* properties() const { return properties_; } 1141 ZoneList<Property*>* properties() const { return properties_; }
1085 1142
1086 bool fast_elements() const { return fast_elements_; } 1143 bool fast_elements() const { return fast_elements_; }
1087 1144
1088 bool has_function() { return has_function_; } 1145 bool has_function() { return has_function_; }
1089 1146
1090 // Mark all computed expressions that are bound to a key that 1147 // Mark all computed expressions that are bound to a key that
1091 // is shadowed by a later occurrence of the same key. For the 1148 // is shadowed by a later occurrence of the same key. For the
1092 // marked expressions, no store code is emitted. 1149 // marked expressions, no store code is emitted.
1093 void CalculateEmitStore(); 1150 void CalculateEmitStore();
1094 1151
1095 enum Flags { 1152 enum Flags {
1096 kNoFlags = 0, 1153 kNoFlags = 0,
1097 kFastElements = 1, 1154 kFastElements = 1,
1098 kHasFunction = 1 << 1 1155 kHasFunction = 1 << 1
1099 }; 1156 };
1100 1157
1158 protected:
1159 template<class> friend class AstNodeFactory;
1160
1161 ObjectLiteral(Isolate* isolate,
1162 Handle<FixedArray> constant_properties,
1163 ZoneList<Property*>* properties,
1164 int literal_index,
1165 bool is_simple,
1166 bool fast_elements,
1167 int depth,
1168 bool has_function)
1169 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
1170 constant_properties_(constant_properties),
1171 properties_(properties),
1172 fast_elements_(fast_elements),
1173 has_function_(has_function) {}
1174
1101 private: 1175 private:
1102 Handle<FixedArray> constant_properties_; 1176 Handle<FixedArray> constant_properties_;
1103 ZoneList<Property*>* properties_; 1177 ZoneList<Property*>* properties_;
1104 bool fast_elements_; 1178 bool fast_elements_;
1105 bool has_function_; 1179 bool has_function_;
1106 }; 1180 };
1107 1181
1108 1182
1109 // Node for capturing a regexp literal. 1183 // Node for capturing a regexp literal.
1110 class RegExpLiteral: public MaterializedLiteral { 1184 class RegExpLiteral: public MaterializedLiteral {
1111 public: 1185 public:
1186 DECLARE_NODE_TYPE(RegExpLiteral)
1187
1188 Handle<String> pattern() const { return pattern_; }
1189 Handle<String> flags() const { return flags_; }
1190
1191 protected:
1192 template<class> friend class AstNodeFactory;
1193
1112 RegExpLiteral(Isolate* isolate, 1194 RegExpLiteral(Isolate* isolate,
1113 Handle<String> pattern, 1195 Handle<String> pattern,
1114 Handle<String> flags, 1196 Handle<String> flags,
1115 int literal_index) 1197 int literal_index)
1116 : MaterializedLiteral(isolate, literal_index, false, 1), 1198 : MaterializedLiteral(isolate, literal_index, false, 1),
1117 pattern_(pattern), 1199 pattern_(pattern),
1118 flags_(flags) {} 1200 flags_(flags) {}
1119 1201
1120 DECLARE_NODE_TYPE(RegExpLiteral)
1121
1122 Handle<String> pattern() const { return pattern_; }
1123 Handle<String> flags() const { return flags_; }
1124
1125 private: 1202 private:
1126 Handle<String> pattern_; 1203 Handle<String> pattern_;
1127 Handle<String> flags_; 1204 Handle<String> flags_;
1128 }; 1205 };
1129 1206
1130 // An array literal has a literals object that is used 1207 // An array literal has a literals object that is used
1131 // for minimizing the work when constructing it at runtime. 1208 // for minimizing the work when constructing it at runtime.
1132 class ArrayLiteral: public MaterializedLiteral { 1209 class ArrayLiteral: public MaterializedLiteral {
1133 public: 1210 public:
1211 DECLARE_NODE_TYPE(ArrayLiteral)
1212
1213 Handle<FixedArray> constant_elements() const { return constant_elements_; }
1214 ZoneList<Expression*>* values() const { return values_; }
1215
1216 // Return an AST id for an element that is used in simulate instructions.
1217 int GetIdForElement(int i) { return first_element_id_ + i; }
1218
1219 protected:
1220 template<class> friend class AstNodeFactory;
1221
1134 ArrayLiteral(Isolate* isolate, 1222 ArrayLiteral(Isolate* isolate,
1135 Handle<FixedArray> constant_elements, 1223 Handle<FixedArray> constant_elements,
1136 ZoneList<Expression*>* values, 1224 ZoneList<Expression*>* values,
1137 int literal_index, 1225 int literal_index,
1138 bool is_simple, 1226 bool is_simple,
1139 int depth) 1227 int depth)
1140 : MaterializedLiteral(isolate, literal_index, is_simple, depth), 1228 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
1141 constant_elements_(constant_elements), 1229 constant_elements_(constant_elements),
1142 values_(values), 1230 values_(values),
1143 first_element_id_(ReserveIdRange(isolate, values->length())) {} 1231 first_element_id_(ReserveIdRange(isolate, values->length())) {}
1144 1232
1145 DECLARE_NODE_TYPE(ArrayLiteral)
1146
1147 Handle<FixedArray> constant_elements() const { return constant_elements_; }
1148 ZoneList<Expression*>* values() const { return values_; }
1149
1150 // Return an AST id for an element that is used in simulate instructions.
1151 int GetIdForElement(int i) { return first_element_id_ + i; }
1152
1153 private: 1233 private:
1154 Handle<FixedArray> constant_elements_; 1234 Handle<FixedArray> constant_elements_;
1155 ZoneList<Expression*>* values_; 1235 ZoneList<Expression*>* values_;
1156 int first_element_id_; 1236 int first_element_id_;
1157 }; 1237 };
1158 1238
1159 1239
1160 class VariableProxy: public Expression { 1240 class VariableProxy: public Expression {
1161 public: 1241 public:
1162 VariableProxy(Isolate* isolate, Variable* var);
1163
1164 VariableProxy(Isolate* isolate,
1165 Handle<String> name,
1166 bool is_this,
1167 int position = RelocInfo::kNoPosition);
1168
1169 DECLARE_NODE_TYPE(VariableProxy) 1242 DECLARE_NODE_TYPE(VariableProxy)
1170 1243
1171 virtual bool IsValidLeftHandSide() { 1244 virtual bool IsValidLeftHandSide() {
1172 return var_ == NULL ? true : var_->IsValidLeftHandSide(); 1245 return var_ == NULL ? true : var_->IsValidLeftHandSide();
1173 } 1246 }
1174 1247
1175 virtual bool IsInlineable() const;
1176
1177 bool IsVariable(Handle<String> n) { 1248 bool IsVariable(Handle<String> n) {
1178 return !is_this() && name().is_identical_to(n); 1249 return !is_this() && name().is_identical_to(n);
1179 } 1250 }
1180 1251
1181 bool IsArguments() { return var_ != NULL && var_->is_arguments(); } 1252 bool IsArguments() { return var_ != NULL && var_->is_arguments(); }
1182 1253
1183 bool IsLValue() { 1254 bool IsLValue() {
1184 return is_lvalue_; 1255 return is_lvalue_;
1185 } 1256 }
1186 1257
1187 Handle<String> name() const { return name_; } 1258 Handle<String> name() const { return name_; }
1188 Variable* var() const { return var_; } 1259 Variable* var() const { return var_; }
1189 bool is_this() const { return is_this_; } 1260 bool is_this() const { return is_this_; }
1190 int position() const { return position_; } 1261 int position() const { return position_; }
1191 1262
1192 void MarkAsTrivial() { is_trivial_ = true; } 1263 void MarkAsTrivial() { is_trivial_ = true; }
1193 void MarkAsLValue() { is_lvalue_ = true; } 1264 void MarkAsLValue() { is_lvalue_ = true; }
1194 1265
1195 // Bind this proxy to the variable var. 1266 // Bind this proxy to the variable var.
1196 void BindTo(Variable* var); 1267 void BindTo(Variable* var);
1197 1268
1198 protected: 1269 protected:
1270 template<class> friend class AstNodeFactory;
1271
1272 VariableProxy(Isolate* isolate, Variable* var);
1273
1274 VariableProxy(Isolate* isolate,
1275 Handle<String> name,
1276 bool is_this,
1277 int position);
1278
1199 Handle<String> name_; 1279 Handle<String> name_;
1200 Variable* var_; // resolved variable, or NULL 1280 Variable* var_; // resolved variable, or NULL
1201 bool is_this_; 1281 bool is_this_;
1202 bool is_trivial_; 1282 bool is_trivial_;
1203 // True if this variable proxy is being used in an assignment 1283 // True if this variable proxy is being used in an assignment
1204 // or with a increment/decrement operator. 1284 // or with a increment/decrement operator.
1205 bool is_lvalue_; 1285 bool is_lvalue_;
1206 int position_; 1286 int position_;
1207 }; 1287 };
1208 1288
1209 1289
1210 class Property: public Expression { 1290 class Property: public Expression {
1211 public: 1291 public:
1212 Property(Isolate* isolate,
1213 Expression* obj,
1214 Expression* key,
1215 int pos)
1216 : Expression(isolate),
1217 obj_(obj),
1218 key_(key),
1219 pos_(pos),
1220 is_monomorphic_(false),
1221 is_array_length_(false),
1222 is_string_length_(false),
1223 is_string_access_(false),
1224 is_function_prototype_(false) { }
1225
1226 DECLARE_NODE_TYPE(Property) 1292 DECLARE_NODE_TYPE(Property)
1227 1293
1228 virtual bool IsValidLeftHandSide() { return true; } 1294 virtual bool IsValidLeftHandSide() { return true; }
1229 virtual bool IsInlineable() const;
1230 1295
1231 Expression* obj() const { return obj_; } 1296 Expression* obj() const { return obj_; }
1232 Expression* key() const { return key_; } 1297 Expression* key() const { return key_; }
1233 virtual int position() const { return pos_; } 1298 virtual int position() const { return pos_; }
1234 1299
1235 bool IsStringLength() const { return is_string_length_; } 1300 bool IsStringLength() const { return is_string_length_; }
1236 bool IsStringAccess() const { return is_string_access_; } 1301 bool IsStringAccess() const { return is_string_access_; }
1237 bool IsFunctionPrototype() const { return is_function_prototype_; } 1302 bool IsFunctionPrototype() const { return is_function_prototype_; }
1238 1303
1239 // Type feedback information. 1304 // Type feedback information.
1240 void RecordTypeFeedback(TypeFeedbackOracle* oracle); 1305 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1241 virtual bool IsMonomorphic() { return is_monomorphic_; } 1306 virtual bool IsMonomorphic() { return is_monomorphic_; }
1242 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; } 1307 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1243 bool IsArrayLength() { return is_array_length_; } 1308 bool IsArrayLength() { return is_array_length_; }
1244 1309
1310 protected:
1311 template<class> friend class AstNodeFactory;
1312
1313 Property(Isolate* isolate,
1314 Expression* obj,
1315 Expression* key,
1316 int pos)
1317 : Expression(isolate),
1318 obj_(obj),
1319 key_(key),
1320 pos_(pos),
1321 is_monomorphic_(false),
1322 is_array_length_(false),
1323 is_string_length_(false),
1324 is_string_access_(false),
1325 is_function_prototype_(false) { }
1326
1245 private: 1327 private:
1246 Expression* obj_; 1328 Expression* obj_;
1247 Expression* key_; 1329 Expression* key_;
1248 int pos_; 1330 int pos_;
1249 1331
1250 SmallMapList receiver_types_; 1332 SmallMapList receiver_types_;
1251 bool is_monomorphic_ : 1; 1333 bool is_monomorphic_ : 1;
1252 bool is_array_length_ : 1; 1334 bool is_array_length_ : 1;
1253 bool is_string_length_ : 1; 1335 bool is_string_length_ : 1;
1254 bool is_string_access_ : 1; 1336 bool is_string_access_ : 1;
1255 bool is_function_prototype_ : 1; 1337 bool is_function_prototype_ : 1;
1256 }; 1338 };
1257 1339
1258 1340
1259 class Call: public Expression { 1341 class Call: public Expression {
1260 public: 1342 public:
1261 Call(Isolate* isolate,
1262 Expression* expression,
1263 ZoneList<Expression*>* arguments,
1264 int pos)
1265 : Expression(isolate),
1266 expression_(expression),
1267 arguments_(arguments),
1268 pos_(pos),
1269 is_monomorphic_(false),
1270 check_type_(RECEIVER_MAP_CHECK),
1271 return_id_(GetNextId(isolate)) {
1272 }
1273
1274 DECLARE_NODE_TYPE(Call) 1343 DECLARE_NODE_TYPE(Call)
1275 1344
1276 virtual bool IsInlineable() const;
1277
1278 Expression* expression() const { return expression_; } 1345 Expression* expression() const { return expression_; }
1279 ZoneList<Expression*>* arguments() const { return arguments_; } 1346 ZoneList<Expression*>* arguments() const { return arguments_; }
1280 virtual int position() const { return pos_; } 1347 virtual int position() const { return pos_; }
1281 1348
1282 void RecordTypeFeedback(TypeFeedbackOracle* oracle, 1349 void RecordTypeFeedback(TypeFeedbackOracle* oracle,
1283 CallKind call_kind); 1350 CallKind call_kind);
1284 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; } 1351 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1285 virtual bool IsMonomorphic() { return is_monomorphic_; } 1352 virtual bool IsMonomorphic() { return is_monomorphic_; }
1286 CheckType check_type() const { return check_type_; } 1353 CheckType check_type() const { return check_type_; }
1287 Handle<JSFunction> target() { return target_; } 1354 Handle<JSFunction> target() { return target_; }
1288 Handle<JSObject> holder() { return holder_; } 1355 Handle<JSObject> holder() { return holder_; }
1289 Handle<JSGlobalPropertyCell> cell() { return cell_; } 1356 Handle<JSGlobalPropertyCell> cell() { return cell_; }
1290 1357
1291 bool ComputeTarget(Handle<Map> type, Handle<String> name); 1358 bool ComputeTarget(Handle<Map> type, Handle<String> name);
1292 bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup); 1359 bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
1293 1360
1294 // Bailout support. 1361 // Bailout support.
1295 int ReturnId() const { return return_id_; } 1362 int ReturnId() const { return return_id_; }
1296 1363
1297 #ifdef DEBUG 1364 #ifdef DEBUG
1298 // Used to assert that the FullCodeGenerator records the return site. 1365 // Used to assert that the FullCodeGenerator records the return site.
1299 bool return_is_recorded_; 1366 bool return_is_recorded_;
1300 #endif 1367 #endif
1301 1368
1369 protected:
1370 template<class> friend class AstNodeFactory;
1371
1372 Call(Isolate* isolate,
1373 Expression* expression,
1374 ZoneList<Expression*>* arguments,
1375 int pos)
1376 : Expression(isolate),
1377 expression_(expression),
1378 arguments_(arguments),
1379 pos_(pos),
1380 is_monomorphic_(false),
1381 check_type_(RECEIVER_MAP_CHECK),
1382 return_id_(GetNextId(isolate)) { }
1383
1302 private: 1384 private:
1303 Expression* expression_; 1385 Expression* expression_;
1304 ZoneList<Expression*>* arguments_; 1386 ZoneList<Expression*>* arguments_;
1305 int pos_; 1387 int pos_;
1306 1388
1307 bool is_monomorphic_; 1389 bool is_monomorphic_;
1308 CheckType check_type_; 1390 CheckType check_type_;
1309 SmallMapList receiver_types_; 1391 SmallMapList receiver_types_;
1310 Handle<JSFunction> target_; 1392 Handle<JSFunction> target_;
1311 Handle<JSObject> holder_; 1393 Handle<JSObject> holder_;
1312 Handle<JSGlobalPropertyCell> cell_; 1394 Handle<JSGlobalPropertyCell> cell_;
1313 1395
1314 int return_id_; 1396 int return_id_;
1315 }; 1397 };
1316 1398
1317 1399
1318 class CallNew: public Expression { 1400 class CallNew: public Expression {
1319 public: 1401 public:
1402 DECLARE_NODE_TYPE(CallNew)
1403
1404 Expression* expression() const { return expression_; }
1405 ZoneList<Expression*>* arguments() const { return arguments_; }
1406 virtual int position() const { return pos_; }
1407
1408 protected:
1409 template<class> friend class AstNodeFactory;
1410
1320 CallNew(Isolate* isolate, 1411 CallNew(Isolate* isolate,
1321 Expression* expression, 1412 Expression* expression,
1322 ZoneList<Expression*>* arguments, 1413 ZoneList<Expression*>* arguments,
1323 int pos) 1414 int pos)
1324 : Expression(isolate), 1415 : Expression(isolate),
1325 expression_(expression), 1416 expression_(expression),
1326 arguments_(arguments), 1417 arguments_(arguments),
1327 pos_(pos) { } 1418 pos_(pos) { }
1328 1419
1329 DECLARE_NODE_TYPE(CallNew)
1330
1331 virtual bool IsInlineable() const;
1332
1333 Expression* expression() const { return expression_; }
1334 ZoneList<Expression*>* arguments() const { return arguments_; }
1335 virtual int position() const { return pos_; }
1336
1337 private: 1420 private:
1338 Expression* expression_; 1421 Expression* expression_;
1339 ZoneList<Expression*>* arguments_; 1422 ZoneList<Expression*>* arguments_;
1340 int pos_; 1423 int pos_;
1341 }; 1424 };
1342 1425
1343 1426
1344 // The CallRuntime class does not represent any official JavaScript 1427 // The CallRuntime class does not represent any official JavaScript
1345 // language construct. Instead it is used to call a C or JS function 1428 // language construct. Instead it is used to call a C or JS function
1346 // with a set of arguments. This is used from the builtins that are 1429 // with a set of arguments. This is used from the builtins that are
1347 // implemented in JavaScript (see "v8natives.js"). 1430 // implemented in JavaScript (see "v8natives.js").
1348 class CallRuntime: public Expression { 1431 class CallRuntime: public Expression {
1349 public: 1432 public:
1433 DECLARE_NODE_TYPE(CallRuntime)
1434
1435 Handle<String> name() const { return name_; }
1436 const Runtime::Function* function() const { return function_; }
1437 ZoneList<Expression*>* arguments() const { return arguments_; }
1438 bool is_jsruntime() const { return function_ == NULL; }
1439
1440 protected:
1441 template<class> friend class AstNodeFactory;
1442
1350 CallRuntime(Isolate* isolate, 1443 CallRuntime(Isolate* isolate,
1351 Handle<String> name, 1444 Handle<String> name,
1352 const Runtime::Function* function, 1445 const Runtime::Function* function,
1353 ZoneList<Expression*>* arguments) 1446 ZoneList<Expression*>* arguments)
1354 : Expression(isolate), 1447 : Expression(isolate),
1355 name_(name), 1448 name_(name),
1356 function_(function), 1449 function_(function),
1357 arguments_(arguments) { } 1450 arguments_(arguments) { }
1358 1451
1359 DECLARE_NODE_TYPE(CallRuntime)
1360
1361 virtual bool IsInlineable() const;
1362
1363 Handle<String> name() const { return name_; }
1364 const Runtime::Function* function() const { return function_; }
1365 ZoneList<Expression*>* arguments() const { return arguments_; }
1366 bool is_jsruntime() const { return function_ == NULL; }
1367
1368 private: 1452 private:
1369 Handle<String> name_; 1453 Handle<String> name_;
1370 const Runtime::Function* function_; 1454 const Runtime::Function* function_;
1371 ZoneList<Expression*>* arguments_; 1455 ZoneList<Expression*>* arguments_;
1372 }; 1456 };
1373 1457
1374 1458
1375 class UnaryOperation: public Expression { 1459 class UnaryOperation: public Expression {
1376 public: 1460 public:
1461 DECLARE_NODE_TYPE(UnaryOperation)
1462
1463 virtual bool ResultOverwriteAllowed();
1464
1465 Token::Value op() const { return op_; }
1466 Expression* expression() const { return expression_; }
1467 virtual int position() const { return pos_; }
1468
1469 int MaterializeTrueId() { return materialize_true_id_; }
1470 int MaterializeFalseId() { return materialize_false_id_; }
1471
1472 protected:
1473 template<class> friend class AstNodeFactory;
1474
1377 UnaryOperation(Isolate* isolate, 1475 UnaryOperation(Isolate* isolate,
1378 Token::Value op, 1476 Token::Value op,
1379 Expression* expression, 1477 Expression* expression,
1380 int pos) 1478 int pos)
1381 : Expression(isolate), 1479 : Expression(isolate),
1382 op_(op), 1480 op_(op),
1383 expression_(expression), 1481 expression_(expression),
1384 pos_(pos), 1482 pos_(pos),
1385 materialize_true_id_(AstNode::kNoNumber), 1483 materialize_true_id_(AstNode::kNoNumber),
1386 materialize_false_id_(AstNode::kNoNumber) { 1484 materialize_false_id_(AstNode::kNoNumber) {
1387 ASSERT(Token::IsUnaryOp(op)); 1485 ASSERT(Token::IsUnaryOp(op));
1388 if (op == Token::NOT) { 1486 if (op == Token::NOT) {
1389 materialize_true_id_ = GetNextId(isolate); 1487 materialize_true_id_ = GetNextId(isolate);
1390 materialize_false_id_ = GetNextId(isolate); 1488 materialize_false_id_ = GetNextId(isolate);
1391 } 1489 }
1392 } 1490 }
1393 1491
1394 DECLARE_NODE_TYPE(UnaryOperation)
1395
1396 virtual bool IsInlineable() const;
1397
1398 virtual bool ResultOverwriteAllowed();
1399
1400 Token::Value op() const { return op_; }
1401 Expression* expression() const { return expression_; }
1402 virtual int position() const { return pos_; }
1403
1404 int MaterializeTrueId() { return materialize_true_id_; }
1405 int MaterializeFalseId() { return materialize_false_id_; }
1406
1407 private: 1492 private:
1408 Token::Value op_; 1493 Token::Value op_;
1409 Expression* expression_; 1494 Expression* expression_;
1410 int pos_; 1495 int pos_;
1411 1496
1412 // For unary not (Token::NOT), the AST ids where true and false will 1497 // For unary not (Token::NOT), the AST ids where true and false will
1413 // actually be materialized, respectively. 1498 // actually be materialized, respectively.
1414 int materialize_true_id_; 1499 int materialize_true_id_;
1415 int materialize_false_id_; 1500 int materialize_false_id_;
1416 }; 1501 };
1417 1502
1418 1503
1419 class BinaryOperation: public Expression { 1504 class BinaryOperation: public Expression {
1420 public: 1505 public:
1421 BinaryOperation(Isolate* isolate,
1422 Token::Value op,
1423 Expression* left,
1424 Expression* right,
1425 int pos)
1426 : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) {
1427 ASSERT(Token::IsBinaryOp(op));
1428 right_id_ = (op == Token::AND || op == Token::OR)
1429 ? static_cast<int>(GetNextId(isolate))
1430 : AstNode::kNoNumber;
1431 }
1432
1433 DECLARE_NODE_TYPE(BinaryOperation) 1506 DECLARE_NODE_TYPE(BinaryOperation)
1434 1507
1435 virtual bool IsInlineable() const;
1436
1437 virtual bool ResultOverwriteAllowed(); 1508 virtual bool ResultOverwriteAllowed();
1438 1509
1439 Token::Value op() const { return op_; } 1510 Token::Value op() const { return op_; }
1440 Expression* left() const { return left_; } 1511 Expression* left() const { return left_; }
1441 Expression* right() const { return right_; } 1512 Expression* right() const { return right_; }
1442 virtual int position() const { return pos_; } 1513 virtual int position() const { return pos_; }
1443 1514
1444 // Bailout support. 1515 // Bailout support.
1445 int RightId() const { return right_id_; } 1516 int RightId() const { return right_id_; }
1446 1517
1518 protected:
1519 template<class> friend class AstNodeFactory;
1520
1521 BinaryOperation(Isolate* isolate,
1522 Token::Value op,
1523 Expression* left,
1524 Expression* right,
1525 int pos)
1526 : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) {
1527 ASSERT(Token::IsBinaryOp(op));
1528 right_id_ = (op == Token::AND || op == Token::OR)
1529 ? GetNextId(isolate)
1530 : AstNode::kNoNumber;
1531 }
1532
1447 private: 1533 private:
1448 Token::Value op_; 1534 Token::Value op_;
1449 Expression* left_; 1535 Expression* left_;
1450 Expression* right_; 1536 Expression* right_;
1451 int pos_; 1537 int pos_;
1452 // The short-circuit logical operations have an AST ID for their 1538 // The short-circuit logical operations have an AST ID for their
1453 // right-hand subexpression. 1539 // right-hand subexpression.
1454 int right_id_; 1540 int right_id_;
1455 }; 1541 };
1456 1542
1457 1543
1458 class CountOperation: public Expression { 1544 class CountOperation: public Expression {
1459 public: 1545 public:
1460 CountOperation(Isolate* isolate,
1461 Token::Value op,
1462 bool is_prefix,
1463 Expression* expr,
1464 int pos)
1465 : Expression(isolate),
1466 op_(op),
1467 is_prefix_(is_prefix),
1468 expression_(expr),
1469 pos_(pos),
1470 assignment_id_(GetNextId(isolate)),
1471 count_id_(GetNextId(isolate)) {}
1472
1473 DECLARE_NODE_TYPE(CountOperation) 1546 DECLARE_NODE_TYPE(CountOperation)
1474 1547
1475 bool is_prefix() const { return is_prefix_; } 1548 bool is_prefix() const { return is_prefix_; }
1476 bool is_postfix() const { return !is_prefix_; } 1549 bool is_postfix() const { return !is_prefix_; }
1477 1550
1478 Token::Value op() const { return op_; } 1551 Token::Value op() const { return op_; }
1479 Token::Value binary_op() { 1552 Token::Value binary_op() {
1480 return (op() == Token::INC) ? Token::ADD : Token::SUB; 1553 return (op() == Token::INC) ? Token::ADD : Token::SUB;
1481 } 1554 }
1482 1555
1483 Expression* expression() const { return expression_; } 1556 Expression* expression() const { return expression_; }
1484 virtual int position() const { return pos_; } 1557 virtual int position() const { return pos_; }
1485 1558
1486 virtual void MarkAsStatement() { is_prefix_ = true; } 1559 virtual void MarkAsStatement() { is_prefix_ = true; }
1487 1560
1488 virtual bool IsInlineable() const;
1489
1490 void RecordTypeFeedback(TypeFeedbackOracle* oracle); 1561 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1491 virtual bool IsMonomorphic() { return is_monomorphic_; } 1562 virtual bool IsMonomorphic() { return is_monomorphic_; }
1492 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; } 1563 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1493 1564
1494 // Bailout support. 1565 // Bailout support.
1495 int AssignmentId() const { return assignment_id_; } 1566 int AssignmentId() const { return assignment_id_; }
1496 int CountId() const { return count_id_; } 1567 int CountId() const { return count_id_; }
1497 1568
1569 protected:
1570 template<class> friend class AstNodeFactory;
1571
1572 CountOperation(Isolate* isolate,
1573 Token::Value op,
1574 bool is_prefix,
1575 Expression* expr,
1576 int pos)
1577 : Expression(isolate),
1578 op_(op),
1579 is_prefix_(is_prefix),
1580 expression_(expr),
1581 pos_(pos),
1582 assignment_id_(GetNextId(isolate)),
1583 count_id_(GetNextId(isolate)) {}
1584
1498 private: 1585 private:
1499 Token::Value op_; 1586 Token::Value op_;
1500 bool is_prefix_; 1587 bool is_prefix_;
1501 bool is_monomorphic_; 1588 bool is_monomorphic_;
1502 Expression* expression_; 1589 Expression* expression_;
1503 int pos_; 1590 int pos_;
1504 int assignment_id_; 1591 int assignment_id_;
1505 int count_id_; 1592 int count_id_;
1506 SmallMapList receiver_types_; 1593 SmallMapList receiver_types_;
1507 }; 1594 };
1508 1595
1509 1596
1510 class CompareOperation: public Expression { 1597 class CompareOperation: public Expression {
1511 public: 1598 public:
1512 CompareOperation(Isolate* isolate,
1513 Token::Value op,
1514 Expression* left,
1515 Expression* right,
1516 int pos)
1517 : Expression(isolate),
1518 op_(op),
1519 left_(left),
1520 right_(right),
1521 pos_(pos),
1522 compare_type_(NONE) {
1523 ASSERT(Token::IsCompareOp(op));
1524 }
1525
1526 DECLARE_NODE_TYPE(CompareOperation) 1599 DECLARE_NODE_TYPE(CompareOperation)
1527 1600
1528 Token::Value op() const { return op_; } 1601 Token::Value op() const { return op_; }
1529 Expression* left() const { return left_; } 1602 Expression* left() const { return left_; }
1530 Expression* right() const { return right_; } 1603 Expression* right() const { return right_; }
1531 virtual int position() const { return pos_; } 1604 virtual int position() const { return pos_; }
1532 1605
1533 virtual bool IsInlineable() const;
1534
1535 // Type feedback information. 1606 // Type feedback information.
1536 void RecordTypeFeedback(TypeFeedbackOracle* oracle); 1607 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1537 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; } 1608 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
1538 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; } 1609 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1539 1610
1540 // Match special cases. 1611 // Match special cases.
1541 bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check); 1612 bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
1542 bool IsLiteralCompareUndefined(Expression** expr); 1613 bool IsLiteralCompareUndefined(Expression** expr);
1543 bool IsLiteralCompareNull(Expression** expr); 1614 bool IsLiteralCompareNull(Expression** expr);
1544 1615
1616 protected:
1617 template<class> friend class AstNodeFactory;
1618
1619 CompareOperation(Isolate* isolate,
1620 Token::Value op,
1621 Expression* left,
1622 Expression* right,
1623 int pos)
1624 : Expression(isolate),
1625 op_(op),
1626 left_(left),
1627 right_(right),
1628 pos_(pos),
1629 compare_type_(NONE) {
1630 ASSERT(Token::IsCompareOp(op));
1631 }
1632
1545 private: 1633 private:
1546 Token::Value op_; 1634 Token::Value op_;
1547 Expression* left_; 1635 Expression* left_;
1548 Expression* right_; 1636 Expression* right_;
1549 int pos_; 1637 int pos_;
1550 1638
1551 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY }; 1639 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
1552 CompareTypeFeedback compare_type_; 1640 CompareTypeFeedback compare_type_;
1553 }; 1641 };
1554 1642
1555 1643
1556 class Conditional: public Expression { 1644 class Conditional: public Expression {
1557 public: 1645 public:
1646 DECLARE_NODE_TYPE(Conditional)
1647
1648 Expression* condition() const { return condition_; }
1649 Expression* then_expression() const { return then_expression_; }
1650 Expression* else_expression() const { return else_expression_; }
1651
1652 int then_expression_position() const { return then_expression_position_; }
1653 int else_expression_position() const { return else_expression_position_; }
1654
1655 int ThenId() const { return then_id_; }
1656 int ElseId() const { return else_id_; }
1657
1658 protected:
1659 template<class> friend class AstNodeFactory;
1660
1558 Conditional(Isolate* isolate, 1661 Conditional(Isolate* isolate,
1559 Expression* condition, 1662 Expression* condition,
1560 Expression* then_expression, 1663 Expression* then_expression,
1561 Expression* else_expression, 1664 Expression* else_expression,
1562 int then_expression_position, 1665 int then_expression_position,
1563 int else_expression_position) 1666 int else_expression_position)
1564 : Expression(isolate), 1667 : Expression(isolate),
1565 condition_(condition), 1668 condition_(condition),
1566 then_expression_(then_expression), 1669 then_expression_(then_expression),
1567 else_expression_(else_expression), 1670 else_expression_(else_expression),
1568 then_expression_position_(then_expression_position), 1671 then_expression_position_(then_expression_position),
1569 else_expression_position_(else_expression_position), 1672 else_expression_position_(else_expression_position),
1570 then_id_(GetNextId(isolate)), 1673 then_id_(GetNextId(isolate)),
1571 else_id_(GetNextId(isolate)) { 1674 else_id_(GetNextId(isolate)) { }
1572 }
1573
1574 DECLARE_NODE_TYPE(Conditional)
1575
1576 virtual bool IsInlineable() const;
1577
1578 Expression* condition() const { return condition_; }
1579 Expression* then_expression() const { return then_expression_; }
1580 Expression* else_expression() const { return else_expression_; }
1581
1582 int then_expression_position() const { return then_expression_position_; }
1583 int else_expression_position() const { return else_expression_position_; }
1584
1585 int ThenId() const { return then_id_; }
1586 int ElseId() const { return else_id_; }
1587 1675
1588 private: 1676 private:
1589 Expression* condition_; 1677 Expression* condition_;
1590 Expression* then_expression_; 1678 Expression* then_expression_;
1591 Expression* else_expression_; 1679 Expression* else_expression_;
1592 int then_expression_position_; 1680 int then_expression_position_;
1593 int else_expression_position_; 1681 int else_expression_position_;
1594 int then_id_; 1682 int then_id_;
1595 int else_id_; 1683 int else_id_;
1596 }; 1684 };
1597 1685
1598 1686
1599 class Assignment: public Expression { 1687 class Assignment: public Expression {
1600 public: 1688 public:
1601 Assignment(Isolate* isolate,
1602 Token::Value op,
1603 Expression* target,
1604 Expression* value,
1605 int pos);
1606
1607 DECLARE_NODE_TYPE(Assignment) 1689 DECLARE_NODE_TYPE(Assignment)
1608 1690
1609 virtual bool IsInlineable() const;
1610
1611 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; } 1691 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1612 1692
1613 Token::Value binary_op() const; 1693 Token::Value binary_op() const;
1614 1694
1615 Token::Value op() const { return op_; } 1695 Token::Value op() const { return op_; }
1616 Expression* target() const { return target_; } 1696 Expression* target() const { return target_; }
1617 Expression* value() const { return value_; } 1697 Expression* value() const { return value_; }
1618 virtual int position() const { return pos_; } 1698 virtual int position() const { return pos_; }
1619 BinaryOperation* binary_operation() const { return binary_operation_; } 1699 BinaryOperation* binary_operation() const { return binary_operation_; }
1620 1700
(...skipping 11 matching lines...) Expand all
1632 1712
1633 // Type feedback information. 1713 // Type feedback information.
1634 void RecordTypeFeedback(TypeFeedbackOracle* oracle); 1714 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1635 virtual bool IsMonomorphic() { return is_monomorphic_; } 1715 virtual bool IsMonomorphic() { return is_monomorphic_; }
1636 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; } 1716 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1637 1717
1638 // Bailout support. 1718 // Bailout support.
1639 int CompoundLoadId() const { return compound_load_id_; } 1719 int CompoundLoadId() const { return compound_load_id_; }
1640 int AssignmentId() const { return assignment_id_; } 1720 int AssignmentId() const { return assignment_id_; }
1641 1721
1722 protected:
1723 template<class> friend class AstNodeFactory;
1724
1725 Assignment(Isolate* isolate,
1726 Token::Value op,
1727 Expression* target,
1728 Expression* value,
1729 int pos);
1730
1731 template<class Visitor>
1732 void Init(Isolate* isolate, AstNodeFactory<Visitor>* factory) {
1733 ASSERT(Token::IsAssignmentOp(op_));
1734 if (is_compound()) {
1735 binary_operation_ =
1736 factory->NewBinaryOperation(binary_op(), target_, value_, pos_ + 1);
1737 compound_load_id_ = GetNextId(isolate);
1738 }
1739 }
1740
1642 private: 1741 private:
1643 Token::Value op_; 1742 Token::Value op_;
1644 Expression* target_; 1743 Expression* target_;
1645 Expression* value_; 1744 Expression* value_;
1646 int pos_; 1745 int pos_;
1647 BinaryOperation* binary_operation_; 1746 BinaryOperation* binary_operation_;
1648 int compound_load_id_; 1747 int compound_load_id_;
1649 int assignment_id_; 1748 int assignment_id_;
1650 1749
1651 bool block_start_; 1750 bool block_start_;
1652 bool block_end_; 1751 bool block_end_;
1653 1752
1654 bool is_monomorphic_; 1753 bool is_monomorphic_;
1655 SmallMapList receiver_types_; 1754 SmallMapList receiver_types_;
1656 }; 1755 };
1657 1756
1658 1757
1659 class Throw: public Expression { 1758 class Throw: public Expression {
1660 public: 1759 public:
1661 Throw(Isolate* isolate, Expression* exception, int pos)
1662 : Expression(isolate), exception_(exception), pos_(pos) {}
1663
1664 DECLARE_NODE_TYPE(Throw) 1760 DECLARE_NODE_TYPE(Throw)
1665 1761
1666 Expression* exception() const { return exception_; } 1762 Expression* exception() const { return exception_; }
1667 virtual int position() const { return pos_; } 1763 virtual int position() const { return pos_; }
1668 virtual bool IsInlineable() const; 1764
1765 protected:
1766 template<class> friend class AstNodeFactory;
1767
1768 Throw(Isolate* isolate, Expression* exception, int pos)
1769 : Expression(isolate), exception_(exception), pos_(pos) {}
1669 1770
1670 private: 1771 private:
1671 Expression* exception_; 1772 Expression* exception_;
1672 int pos_; 1773 int pos_;
1673 }; 1774 };
1674 1775
1675 1776
1676 class FunctionLiteral: public Expression { 1777 class FunctionLiteral: public Expression {
1677 public: 1778 public:
1678 enum Type { 1779 enum Type {
1679 ANONYMOUS_EXPRESSION, 1780 ANONYMOUS_EXPRESSION,
1680 NAMED_EXPRESSION, 1781 NAMED_EXPRESSION,
1681 DECLARATION 1782 DECLARATION
1682 }; 1783 };
1683 1784
1684 FunctionLiteral(Isolate* isolate,
1685 Handle<String> name,
1686 Scope* scope,
1687 ZoneList<Statement*>* body,
1688 int materialized_literal_count,
1689 int expected_property_count,
1690 int handler_count,
1691 bool has_only_simple_this_property_assignments,
1692 Handle<FixedArray> this_property_assignments,
1693 int parameter_count,
1694 Type type,
1695 bool has_duplicate_parameters)
1696 : Expression(isolate),
1697 name_(name),
1698 scope_(scope),
1699 body_(body),
1700 this_property_assignments_(this_property_assignments),
1701 inferred_name_(isolate->factory()->empty_string()),
1702 materialized_literal_count_(materialized_literal_count),
1703 expected_property_count_(expected_property_count),
1704 handler_count_(handler_count),
1705 parameter_count_(parameter_count),
1706 function_token_position_(RelocInfo::kNoPosition) {
1707 bitfield_ =
1708 HasOnlySimpleThisPropertyAssignments::encode(
1709 has_only_simple_this_property_assignments) |
1710 IsExpression::encode(type != DECLARATION) |
1711 IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) |
1712 Pretenure::encode(false) |
1713 HasDuplicateParameters::encode(has_duplicate_parameters);
1714 }
1715
1716 DECLARE_NODE_TYPE(FunctionLiteral) 1785 DECLARE_NODE_TYPE(FunctionLiteral)
1717 1786
1718 Handle<String> name() const { return name_; } 1787 Handle<String> name() const { return name_; }
1719 Scope* scope() const { return scope_; } 1788 Scope* scope() const { return scope_; }
1720 ZoneList<Statement*>* body() const { return body_; } 1789 ZoneList<Statement*>* body() const { return body_; }
1721 void set_function_token_position(int pos) { function_token_position_ = pos; } 1790 void set_function_token_position(int pos) { function_token_position_ = pos; }
1722 int function_token_position() const { return function_token_position_; } 1791 int function_token_position() const { return function_token_position_; }
1723 int start_position() const; 1792 int start_position() const;
1724 int end_position() const; 1793 int end_position() const;
1725 bool is_expression() const { return IsExpression::decode(bitfield_); } 1794 bool is_expression() const { return IsExpression::decode(bitfield_); }
(...skipping 19 matching lines...) Expand all
1745 return inferred_name(); 1814 return inferred_name();
1746 } 1815 }
1747 1816
1748 Handle<String> inferred_name() const { return inferred_name_; } 1817 Handle<String> inferred_name() const { return inferred_name_; }
1749 void set_inferred_name(Handle<String> inferred_name) { 1818 void set_inferred_name(Handle<String> inferred_name) {
1750 inferred_name_ = inferred_name; 1819 inferred_name_ = inferred_name;
1751 } 1820 }
1752 1821
1753 bool pretenure() { return Pretenure::decode(bitfield_); } 1822 bool pretenure() { return Pretenure::decode(bitfield_); }
1754 void set_pretenure() { bitfield_ |= Pretenure::encode(true); } 1823 void set_pretenure() { bitfield_ |= Pretenure::encode(true); }
1755 virtual bool IsInlineable() const;
1756 1824
1757 bool has_duplicate_parameters() { 1825 bool has_duplicate_parameters() {
1758 return HasDuplicateParameters::decode(bitfield_); 1826 return HasDuplicateParameters::decode(bitfield_);
1759 } 1827 }
1760 1828
1829 bool ShouldSelfOptimize();
1830
1831 int ast_node_count() { return ast_properties_.node_count(); }
1832 AstProperties::Flags* flags() { return ast_properties_.flags(); }
1833 void set_ast_properties(AstProperties* ast_properties) {
1834 ast_properties_ = *ast_properties;
1835 }
1836
1837 protected:
1838 template<class> friend class AstNodeFactory;
1839
1840 FunctionLiteral(Isolate* isolate,
1841 Handle<String> name,
1842 Scope* scope,
1843 ZoneList<Statement*>* body,
1844 int materialized_literal_count,
1845 int expected_property_count,
1846 int handler_count,
1847 bool has_only_simple_this_property_assignments,
1848 Handle<FixedArray> this_property_assignments,
1849 int parameter_count,
1850 Type type,
1851 bool has_duplicate_parameters)
1852 : Expression(isolate),
1853 name_(name),
1854 scope_(scope),
1855 body_(body),
1856 this_property_assignments_(this_property_assignments),
1857 inferred_name_(isolate->factory()->empty_string()),
1858 materialized_literal_count_(materialized_literal_count),
1859 expected_property_count_(expected_property_count),
1860 handler_count_(handler_count),
1861 parameter_count_(parameter_count),
1862 function_token_position_(RelocInfo::kNoPosition) {
1863 bitfield_ =
1864 HasOnlySimpleThisPropertyAssignments::encode(
1865 has_only_simple_this_property_assignments) |
1866 IsExpression::encode(type != DECLARATION) |
1867 IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) |
1868 Pretenure::encode(false) |
1869 HasDuplicateParameters::encode(has_duplicate_parameters);
1870 }
1871
1761 private: 1872 private:
1762 Handle<String> name_; 1873 Handle<String> name_;
1763 Scope* scope_; 1874 Scope* scope_;
1764 ZoneList<Statement*>* body_; 1875 ZoneList<Statement*>* body_;
1765 Handle<FixedArray> this_property_assignments_; 1876 Handle<FixedArray> this_property_assignments_;
1766 Handle<String> inferred_name_; 1877 Handle<String> inferred_name_;
1878 AstProperties ast_properties_;
1767 1879
1768 int materialized_literal_count_; 1880 int materialized_literal_count_;
1769 int expected_property_count_; 1881 int expected_property_count_;
1770 int handler_count_; 1882 int handler_count_;
1771 int parameter_count_; 1883 int parameter_count_;
1772 int function_token_position_; 1884 int function_token_position_;
1773 1885
1774 unsigned bitfield_; 1886 unsigned bitfield_;
1775 class HasOnlySimpleThisPropertyAssignments: public BitField<bool, 0, 1> {}; 1887 class HasOnlySimpleThisPropertyAssignments: public BitField<bool, 0, 1> {};
1776 class IsExpression: public BitField<bool, 1, 1> {}; 1888 class IsExpression: public BitField<bool, 1, 1> {};
1777 class IsAnonymous: public BitField<bool, 2, 1> {}; 1889 class IsAnonymous: public BitField<bool, 2, 1> {};
1778 class Pretenure: public BitField<bool, 3, 1> {}; 1890 class Pretenure: public BitField<bool, 3, 1> {};
1779 class HasDuplicateParameters: public BitField<bool, 4, 1> {}; 1891 class HasDuplicateParameters: public BitField<bool, 4, 1> {};
1780 }; 1892 };
1781 1893
1782 1894
1783 class SharedFunctionInfoLiteral: public Expression { 1895 class SharedFunctionInfoLiteral: public Expression {
1784 public: 1896 public:
1785 SharedFunctionInfoLiteral(
1786 Isolate* isolate,
1787 Handle<SharedFunctionInfo> shared_function_info)
1788 : Expression(isolate), shared_function_info_(shared_function_info) { }
1789
1790 DECLARE_NODE_TYPE(SharedFunctionInfoLiteral) 1897 DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
1791 1898
1792 Handle<SharedFunctionInfo> shared_function_info() const { 1899 Handle<SharedFunctionInfo> shared_function_info() const {
1793 return shared_function_info_; 1900 return shared_function_info_;
1794 } 1901 }
1795 virtual bool IsInlineable() const; 1902
1903 protected:
1904 template<class> friend class AstNodeFactory;
1905
1906 SharedFunctionInfoLiteral(
1907 Isolate* isolate,
1908 Handle<SharedFunctionInfo> shared_function_info)
1909 : Expression(isolate),
1910 shared_function_info_(shared_function_info) { }
1796 1911
1797 private: 1912 private:
1798 Handle<SharedFunctionInfo> shared_function_info_; 1913 Handle<SharedFunctionInfo> shared_function_info_;
1799 }; 1914 };
1800 1915
1801 1916
1802 class ThisFunction: public Expression { 1917 class ThisFunction: public Expression {
1803 public: 1918 public:
1804 explicit ThisFunction(Isolate* isolate) : Expression(isolate) {}
1805 DECLARE_NODE_TYPE(ThisFunction) 1919 DECLARE_NODE_TYPE(ThisFunction)
1806 virtual bool IsInlineable() const; 1920
1921 protected:
1922 template<class> friend class AstNodeFactory;
1923
1924 explicit ThisFunction(Isolate* isolate): Expression(isolate) {}
1807 }; 1925 };
1808 1926
1809 1927
1810 // ---------------------------------------------------------------------------- 1928 // ----------------------------------------------------------------------------
1811 // Regular expressions 1929 // Regular expressions
1812 1930
1813 1931
1814 class RegExpVisitor BASE_EMBEDDED { 1932 class RegExpVisitor BASE_EMBEDDED {
1815 public: 1933 public:
1816 virtual ~RegExpVisitor() { } 1934 virtual ~RegExpVisitor() { }
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
2200 2318
2201 protected: 2319 protected:
2202 Isolate* isolate() { return isolate_; } 2320 Isolate* isolate() { return isolate_; }
2203 2321
2204 private: 2322 private:
2205 Isolate* isolate_; 2323 Isolate* isolate_;
2206 bool stack_overflow_; 2324 bool stack_overflow_;
2207 }; 2325 };
2208 2326
2209 2327
2328 // ----------------------------------------------------------------------------
2329 // Construction time visitor.
2330
2331 class AstConstructionVisitor BASE_EMBEDDED {
2332 public:
2333 AstConstructionVisitor() { }
2334
2335 AstProperties* ast_properties() { return &properties_; }
2336
2337 private:
2338 template<class> friend class AstNodeFactory;
2339
2340 // Node visitors.
2341 #define DEF_VISIT(type) \
2342 void Visit##type(type* node);
2343 AST_NODE_LIST(DEF_VISIT)
2344 #undef DEF_VISIT
2345
2346 void increase_node_count() { properties_.add_node_count(1); }
2347 void add_flag(AstPropertiesFlag flag) { properties_.flags()->Add(flag); }
2348
2349 AstProperties properties_;
2350 };
2351
2352
2353 class AstNullVisitor BASE_EMBEDDED {
2354 public:
2355 // Node visitors.
2356 #define DEF_VISIT(type) \
2357 void Visit##type(type* node) {}
2358 AST_NODE_LIST(DEF_VISIT)
2359 #undef DEF_VISIT
2360 };
2361
2362
2363
2364 // ----------------------------------------------------------------------------
2365 // AstNode factory
2366
2367 template<class Visitor>
2368 class AstNodeFactory BASE_EMBEDDED {
2369 public:
2370 explicit AstNodeFactory(Isolate* isolate)
2371 : isolate_(isolate),
2372 zone_(isolate_->zone()) { }
2373
2374 Visitor* visitor() { return &visitor_; }
2375
2376 #define VISIT_AND_RETURN(NodeType, node) \
2377 visitor_.Visit##NodeType((node)); \
2378 return node;
2379
2380 Block* NewBlock(ZoneStringList* labels,
2381 int capacity,
2382 bool is_initializer_block) {
2383 Block* block = new(zone_) Block(
2384 isolate_, labels, capacity, is_initializer_block);
2385 VISIT_AND_RETURN(Block, block)
2386 }
2387
2388 Declaration* NewDeclaration(VariableProxy* proxy,
2389 VariableMode mode,
2390 FunctionLiteral* fun,
2391 Scope* scope) {
2392 Declaration* decl = new(zone_) Declaration(proxy, mode, fun, scope);
2393 VISIT_AND_RETURN(Declaration, decl)
2394 }
2395
2396 #define STATEMENT_WITH_LABELS(NodeType) \
2397 NodeType* New##NodeType(ZoneStringList* labels) { \
2398 NodeType* stmt = new(zone_) NodeType(isolate_, labels); \
2399 VISIT_AND_RETURN(NodeType, stmt); \
2400 }
2401 STATEMENT_WITH_LABELS(DoWhileStatement)
2402 STATEMENT_WITH_LABELS(WhileStatement)
2403 STATEMENT_WITH_LABELS(ForStatement)
2404 STATEMENT_WITH_LABELS(ForInStatement)
2405 STATEMENT_WITH_LABELS(SwitchStatement)
2406 #undef STATEMENT_WITH_LABELS
2407
2408 ExpressionStatement* NewExpressionStatement(Expression* expression) {
2409 ExpressionStatement* stmt = new(zone_) ExpressionStatement(expression);
2410 VISIT_AND_RETURN(ExpressionStatement, stmt)
2411 }
2412
2413 ContinueStatement* NewContinueStatement(IterationStatement* target) {
2414 ContinueStatement* stmt = new(zone_) ContinueStatement(target);
2415 VISIT_AND_RETURN(ContinueStatement, stmt)
2416 }
2417
2418 BreakStatement* NewBreakStatement(BreakableStatement* target) {
2419 BreakStatement* stmt = new(zone_) BreakStatement(target);
2420 VISIT_AND_RETURN(BreakStatement, stmt)
2421 }
2422
2423 ReturnStatement* NewReturnStatement(Expression* expression) {
2424 ReturnStatement* stmt = new(zone_) ReturnStatement(expression);
2425 VISIT_AND_RETURN(ReturnStatement, stmt)
2426 }
2427
2428 WithStatement* NewWithStatement(Expression* expression,
2429 Statement* statement) {
2430 WithStatement* stmt = new(zone_) WithStatement(expression, statement);
2431 VISIT_AND_RETURN(WithStatement, stmt)
2432 }
2433
2434 IfStatement* NewIfStatement(Expression* condition,
2435 Statement* then_statement,
2436 Statement* else_statement) {
2437 IfStatement* stmt = new(zone_) IfStatement(
2438 isolate_, condition, then_statement, else_statement);
2439 VISIT_AND_RETURN(IfStatement, stmt)
2440 }
2441
2442 TryCatchStatement* NewTryCatchStatement(int index,
2443 Block* try_block,
2444 Scope* scope,
2445 Variable* variable,
2446 Block* catch_block) {
2447 TryCatchStatement* stmt = new(zone_) TryCatchStatement(
2448 index, try_block, scope, variable, catch_block);
2449 VISIT_AND_RETURN(TryCatchStatement, stmt)
2450 }
2451
2452 TryFinallyStatement* NewTryFinallyStatement(int index,
2453 Block* try_block,
2454 Block* finally_block) {
2455 TryFinallyStatement* stmt =
2456 new(zone_) TryFinallyStatement(index, try_block, finally_block);
2457 VISIT_AND_RETURN(TryFinallyStatement, stmt)
2458 }
2459
2460 DebuggerStatement* NewDebuggerStatement() {
2461 DebuggerStatement* stmt = new(zone_) DebuggerStatement();
2462 VISIT_AND_RETURN(DebuggerStatement, stmt)
2463 }
2464
2465 EmptyStatement* NewEmptyStatement() {
2466 return new(zone_) EmptyStatement();
2467 }
2468
2469 Literal* NewLiteral(Handle<Object> handle) {
2470 Literal* lit = new(zone_) Literal(isolate_, handle);
2471 VISIT_AND_RETURN(Literal, lit)
2472 }
2473
2474 Literal* NewNumberLiteral(double number) {
2475 return NewLiteral(isolate_->factory()->NewNumber(number, TENURED));
2476 }
2477
2478 ObjectLiteral* NewObjectLiteral(
2479 Handle<FixedArray> constant_properties,
2480 ZoneList<ObjectLiteral::Property*>* properties,
2481 int literal_index,
2482 bool is_simple,
2483 bool fast_elements,
2484 int depth,
2485 bool has_function) {
2486 ObjectLiteral* lit = new(zone_) ObjectLiteral(
2487 isolate_, constant_properties, properties, literal_index,
2488 is_simple, fast_elements, depth, has_function);
2489 VISIT_AND_RETURN(ObjectLiteral, lit)
2490 }
2491
2492 ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter,
2493 FunctionLiteral* value) {
2494 ObjectLiteral::Property* prop =
2495 new(zone_) ObjectLiteral::Property(is_getter, value);
2496 prop->set_key(NewLiteral(value->name()));
2497 return prop; // Not an AST node, will not be visited.
2498 }
2499
2500 RegExpLiteral* NewRegExpLiteral(Handle<String> pattern,
2501 Handle<String> flags,
2502 int literal_index) {
2503 RegExpLiteral* lit =
2504 new(zone_) RegExpLiteral(isolate_, pattern, flags, literal_index);
2505 VISIT_AND_RETURN(RegExpLiteral, lit);
2506 }
2507
2508 ArrayLiteral* NewArrayLiteral(Handle<FixedArray> constant_elements,
2509 ZoneList<Expression*>* values,
2510 int literal_index,
2511 bool is_simple,
2512 int depth) {
2513 ArrayLiteral* lit = new(zone_) ArrayLiteral(
2514 isolate_, constant_elements, values, literal_index, is_simple, depth);
2515 VISIT_AND_RETURN(ArrayLiteral, lit)
2516 }
2517
2518 VariableProxy* NewVariableProxy(Variable* var) {
2519 VariableProxy* proxy = new(zone_) VariableProxy(isolate_, var);
2520 VISIT_AND_RETURN(VariableProxy, proxy)
2521 }
2522
2523 VariableProxy* NewVariableProxy(Handle<String> name,
2524 bool is_this,
2525 int position = RelocInfo::kNoPosition) {
2526 VariableProxy* proxy =
2527 new(zone_) VariableProxy(isolate_, name, is_this, position);
2528 VISIT_AND_RETURN(VariableProxy, proxy)
2529 }
2530
2531 Property* NewProperty(Expression* obj, Expression* key, int pos) {
2532 Property* prop = new(zone_) Property(isolate_, obj, key, pos);
2533 VISIT_AND_RETURN(Property, prop)
2534 }
2535
2536 Call* NewCall(Expression* expression,
2537 ZoneList<Expression*>* arguments,
2538 int pos) {
2539 Call* call = new(zone_) Call(isolate_, expression, arguments, pos);
2540 VISIT_AND_RETURN(Call, call)
2541 }
2542
2543 CallNew* NewCallNew(Expression* expression,
2544 ZoneList<Expression*>* arguments,
2545 int pos) {
2546 CallNew* call = new(zone_) CallNew(isolate_, expression, arguments, pos);
2547 VISIT_AND_RETURN(CallNew, call)
2548 }
2549
2550 CallRuntime* NewCallRuntime(Handle<String> name,
2551 const Runtime::Function* function,
2552 ZoneList<Expression*>* arguments) {
2553 CallRuntime* call =
2554 new(zone_) CallRuntime(isolate_, name, function, arguments);
2555 VISIT_AND_RETURN(CallRuntime, call)
2556 }
2557
2558 UnaryOperation* NewUnaryOperation(Token::Value op,
2559 Expression* expression,
2560 int pos) {
2561 UnaryOperation* node =
2562 new(zone_) UnaryOperation(isolate_, op, expression, pos);
2563 VISIT_AND_RETURN(UnaryOperation, node)
2564 }
2565
2566 BinaryOperation* NewBinaryOperation(Token::Value op,
2567 Expression* left,
2568 Expression* right,
2569 int pos) {
2570 BinaryOperation* node =
2571 new(zone_) BinaryOperation(isolate_, op, left, right, pos);
2572 VISIT_AND_RETURN(BinaryOperation, node)
2573 }
2574
2575 CountOperation* NewCountOperation(Token::Value op,
2576 bool is_prefix,
2577 Expression* expr,
2578 int pos) {
2579 CountOperation* node =
2580 new(zone_) CountOperation(isolate_, op, is_prefix, expr, pos);
2581 VISIT_AND_RETURN(CountOperation, node)
2582 }
2583
2584 CompareOperation* NewCompareOperation(Token::Value op,
2585 Expression* left,
2586 Expression* right,
2587 int pos) {
2588 CompareOperation* node =
2589 new(zone_) CompareOperation(isolate_, op, left, right, pos);
2590 VISIT_AND_RETURN(CompareOperation, node)
2591 }
2592
2593 Conditional* NewConditional(Expression* condition,
2594 Expression* then_expression,
2595 Expression* else_expression,
2596 int then_expression_position,
2597 int else_expression_position) {
2598 Conditional* cond = new(zone_) Conditional(
2599 isolate_, condition, then_expression, else_expression,
2600 then_expression_position, else_expression_position);
2601 VISIT_AND_RETURN(Conditional, cond)
2602 }
2603
2604 Assignment* NewAssignment(Token::Value op,
2605 Expression* target,
2606 Expression* value,
2607 int pos) {
2608 Assignment* assign =
2609 new(zone_) Assignment(isolate_, op, target, value, pos);
2610 assign->Init(isolate_, this);
2611 VISIT_AND_RETURN(Assignment, assign)
2612 }
2613
2614 Throw* NewThrow(Expression* exception, int pos) {
2615 Throw* t = new(zone_) Throw(isolate_, exception, pos);
2616 VISIT_AND_RETURN(Throw, t)
2617 }
2618
2619 FunctionLiteral* NewFunctionLiteral(
2620 Handle<String> name,
2621 Scope* scope,
2622 ZoneList<Statement*>* body,
2623 int materialized_literal_count,
2624 int expected_property_count,
2625 int handler_count,
2626 bool has_only_simple_this_property_assignments,
2627 Handle<FixedArray> this_property_assignments,
2628 int parameter_count,
2629 bool has_duplicate_parameters,
2630 FunctionLiteral::Type type,
2631 bool visit_with_visitor) {
2632 FunctionLiteral* lit = new(zone_) FunctionLiteral(
2633 isolate_, name, scope, body,
2634 materialized_literal_count, expected_property_count, handler_count,
2635 has_only_simple_this_property_assignments, this_property_assignments,
2636 parameter_count, type, has_duplicate_parameters);
2637 if (visit_with_visitor) {
2638 visitor_.VisitFunctionLiteral(lit);
2639 }
2640 return lit;
2641 }
2642
2643 SharedFunctionInfoLiteral* NewSharedFunctionInfoLiteral(
2644 Handle<SharedFunctionInfo> shared_function_info) {
2645 SharedFunctionInfoLiteral* lit =
2646 new(zone_) SharedFunctionInfoLiteral(isolate_, shared_function_info);
2647 VISIT_AND_RETURN(SharedFunctionInfoLiteral, lit)
2648 }
2649
2650 ThisFunction* NewThisFunction() {
2651 ThisFunction* fun = new(zone_) ThisFunction(isolate_);
2652 VISIT_AND_RETURN(ThisFunction, fun)
2653 }
2654
2655 #undef VISIT_AND_RETURN
2656
2657 private:
2658 Isolate* isolate_;
2659 Zone* zone_;
2660 Visitor visitor_;
2661 };
2662
2663
2210 } } // namespace v8::internal 2664 } } // namespace v8::internal
2211 2665
2212 #endif // V8_AST_H_ 2666 #endif // V8_AST_H_
OLDNEW
« no previous file with comments | « no previous file | src/ast.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698