1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #ifndef V8_AST_H_
29 #define V8_AST_H_
30
31 #include "v8.h"
32
33 #include "assembler.h"
34 #include "factory.h"
35 #include "isolate.h"
36 #include "jsregexp.h"
37 #include "list-inl.h"
38 #include "runtime.h"
39 #include "small-pointer-list.h"
40 #include "smart-array-pointer.h"
41 #include "token.h"
42 #include "utils.h"
43 #include "variables.h"
44 #include "interface.h"
45 #include "zone-inl.h"
46
47 namespace v8 {
48 namespace internal {
49
50 // The abstract syntax tree is an intermediate, light-weight
51 // representation of the parsed JavaScript code suitable for
52 // compilation to native code.
53
54 // Nodes are allocated in a separate zone, which allows faster
55 // allocation and constant-time deallocation of the entire syntax
56 // tree.
57
58
59 // ----------------------------------------------------------------------------
60 // Nodes of the abstract syntax tree. Only concrete classes are
61 // enumerated here.
62
63 #define DECLARATION_NODE_LIST(V) \
64 V(VariableDeclaration) \
65 V(FunctionDeclaration) \
66 V(ModuleDeclaration) \
67 V(ImportDeclaration) \
68 V(ExportDeclaration) \
69
70 #define MODULE_NODE_LIST(V) \
71 V(ModuleLiteral) \
72 V(ModuleVariable) \
73 V(ModulePath) \
74 V(ModuleUrl)
75
76 #define STATEMENT_NODE_LIST(V) \
77 V(Block) \
78 V(ExpressionStatement) \
79 V(EmptyStatement) \
80 V(IfStatement) \
81 V(ContinueStatement) \
82 V(BreakStatement) \
83 V(ReturnStatement) \
84 V(WithStatement) \
85 V(SwitchStatement) \
86 V(DoWhileStatement) \
87 V(WhileStatement) \
88 V(ForStatement) \
89 V(ForInStatement) \
90 V(TryCatchStatement) \
91 V(TryFinallyStatement) \
92 V(DebuggerStatement)
93
94 #define EXPRESSION_NODE_LIST(V) \
95 V(FunctionLiteral) \
96 V(SharedFunctionInfoLiteral) \
97 V(Conditional) \
98 V(VariableProxy) \
99 V(Literal) \
100 V(RegExpLiteral) \
101 V(ObjectLiteral) \
102 V(ArrayLiteral) \
103 V(Assignment) \
104 V(Throw) \
105 V(Property) \
106 V(Call) \
107 V(CallNew) \
108 V(CallRuntime) \
109 V(UnaryOperation) \
110 V(CountOperation) \
111 V(BinaryOperation) \
112 V(CompareOperation) \
113 V(ThisFunction)
114
115 #define AST_NODE_LIST(V) \
116 DECLARATION_NODE_LIST(V) \
117 MODULE_NODE_LIST(V) \
118 STATEMENT_NODE_LIST(V) \
119 EXPRESSION_NODE_LIST(V)
120
121 // Forward declarations
122 class AstConstructionVisitor;
123 template<class> class AstNodeFactory;
124 class AstVisitor;
125 class Declaration;
126 class Module;
127 class BreakableStatement;
128 class Expression;
129 class IterationStatement;
130 class MaterializedLiteral;
131 class Statement;
132 class TargetCollector;
133 class TypeFeedbackOracle;
134
135 class RegExpAlternative;
136 class RegExpAssertion;
137 class RegExpAtom;
138 class RegExpBackReference;
139 class RegExpCapture;
140 class RegExpCharacterClass;
141 class RegExpCompiler;
142 class RegExpDisjunction;
143 class RegExpEmpty;
144 class RegExpLookahead;
145 class RegExpQuantifier;
146 class RegExpText;
147
148 #define DEF_FORWARD_DECLARATION(type) class type;
149 AST_NODE_LIST(DEF_FORWARD_DECLARATION)
150 #undef DEF_FORWARD_DECLARATION
151
152
153 // Typedef only introduced to avoid unreadable code.
154 // Please do appreciate the required space in "> >".
155 typedef ZoneList<Handle<String> > ZoneStringList;
156 typedef ZoneList<Handle<Object> > ZoneObjectList;
157
158
159 #define DECLARE_NODE_TYPE(type) \
160 virtual void Accept(AstVisitor* v); \
161 virtual AstNode::Type node_type() const { return AstNode::k##type; }
162
163
164 enum AstPropertiesFlag {
165 kDontInline,
166 kDontOptimize,
167 kDontSelfOptimize,
168 kDontSoftInline
169 };
170
171
172 class AstProperties BASE_EMBEDDED {
173 public:
174 class Flags : public EnumSet<AstPropertiesFlag, int> {};
175
AstProperties()176 AstProperties() : node_count_(0) { }
177
flags()178 Flags* flags() { return &flags_; }
node_count()179 int node_count() { return node_count_; }
add_node_count(int count)180 void add_node_count(int count) { node_count_ += count; }
181
182 private:
183 Flags flags_;
184 int node_count_;
185 };
186
187
188 class AstNode: public ZoneObject {
189 public:
190 #define DECLARE_TYPE_ENUM(type) k##type,
191 enum Type {
192 AST_NODE_LIST(DECLARE_TYPE_ENUM)
193 kInvalid = -1
194 };
195 #undef DECLARE_TYPE_ENUM
196
197 static const int kNoNumber = -1;
198 static const int kFunctionEntryId = 2; // Using 0 could disguise errors.
199 // This AST id identifies the point after the declarations have been
200 // visited. We need it to capture the environment effects of declarations
201 // that emit code (function declarations).
202 static const int kDeclarationsId = 3;
203
new(size_t size,Zone * zone)204 void* operator new(size_t size, Zone* zone) {
205 return zone->New(static_cast<int>(size));
206 }
207
AstNode()208 AstNode() { }
209
~AstNode()210 virtual ~AstNode() { }
211
212 virtual void Accept(AstVisitor* v) = 0;
node_type()213 virtual Type node_type() const { return kInvalid; }
214
215 // Type testing & conversion functions overridden by concrete subclasses.
216 #define DECLARE_NODE_FUNCTIONS(type) \
217 bool Is##type() { return node_type() == AstNode::k##type; } \
218 type* As##type() { return Is##type() ? reinterpret_cast<type*>(this) : NULL; }
AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)219 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
220 #undef DECLARE_NODE_FUNCTIONS
221
222 virtual Declaration* AsDeclaration() { return NULL; }
AsStatement()223 virtual Statement* AsStatement() { return NULL; }
AsExpression()224 virtual Expression* AsExpression() { return NULL; }
AsTargetCollector()225 virtual TargetCollector* AsTargetCollector() { return NULL; }
AsBreakableStatement()226 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
AsIterationStatement()227 virtual IterationStatement* AsIterationStatement() { return NULL; }
AsMaterializedLiteral()228 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
229
230 protected:
GetNextId(Isolate * isolate)231 static int GetNextId(Isolate* isolate) {
232 return ReserveIdRange(isolate, 1);
233 }
234
ReserveIdRange(Isolate * isolate,int n)235 static int ReserveIdRange(Isolate* isolate, int n) {
236 int tmp = isolate->ast_node_id();
237 isolate->set_ast_node_id(tmp + n);
238 return tmp;
239 }
240
241 private:
242 // Hidden to prevent accidental usage. It would have to load the
243 // current zone from the TLS.
244 void* operator new(size_t size);
245
246 friend class CaseClause; // Generates AST IDs.
247 };
248
249
250 class Statement: public AstNode {
251 public:
Statement()252 Statement() : statement_pos_(RelocInfo::kNoPosition) {}
253
AsStatement()254 virtual Statement* AsStatement() { return this; }
255
IsEmpty()256 bool IsEmpty() { return AsEmptyStatement() != NULL; }
257
set_statement_pos(int statement_pos)258 void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
statement_pos()259 int statement_pos() const { return statement_pos_; }
260
261 private:
262 int statement_pos_;
263 };
264
265
266 class SmallMapList {
267 public:
SmallMapList()268 SmallMapList() {}
SmallMapList(int capacity)269 explicit SmallMapList(int capacity) : list_(capacity) {}
270
Reserve(int capacity)271 void Reserve(int capacity) { list_.Reserve(capacity); }
Clear()272 void Clear() { list_.Clear(); }
273
is_empty()274 bool is_empty() const { return list_.is_empty(); }
length()275 int length() const { return list_.length(); }
276
Add(Handle<Map> handle)277 void Add(Handle<Map> handle) {
278 list_.Add(handle.location());
279 }
280
at(int i)281 Handle<Map> at(int i) const {
282 return Handle<Map>(list_.at(i));
283 }
284
first()285 Handle<Map> first() const { return at(0); }
last()286 Handle<Map> last() const { return at(length() - 1); }
287
288 private:
289 // The list stores pointers to Map*, that is Map**, so it's GC safe.
290 SmallPointerList<Map*> list_;
291
292 DISALLOW_COPY_AND_ASSIGN(SmallMapList);
293 };
294
295
296 class Expression: public AstNode {
297 public:
298 enum Context {
299 // Not assigned a context yet, or else will not be visited during
300 // code generation.
301 kUninitialized,
302 // Evaluated for its side effects.
303 kEffect,
304 // Evaluated for its value (and side effects).
305 kValue,
306 // Evaluated for control flow (and side effects).
307 kTest
308 };
309
position()310 virtual int position() const {
311 UNREACHABLE();
312 return 0;
313 }
314
AsExpression()315 virtual Expression* AsExpression() { return this; }
316
IsValidLeftHandSide()317 virtual bool IsValidLeftHandSide() { return false; }
318
319 // Helpers for ToBoolean conversion.
ToBooleanIsTrue()320 virtual bool ToBooleanIsTrue() { return false; }
ToBooleanIsFalse()321 virtual bool ToBooleanIsFalse() { return false; }
322
323 // Symbols that cannot be parsed as array indices are considered property
324 // names. We do not treat symbols that can be array indexes as property
325 // names because [] for string objects is handled only by keyed ICs.
IsPropertyName()326 virtual bool IsPropertyName() { return false; }
327
328 // True iff the result can be safely overwritten (to avoid allocation).
329 // False for operations that can return one of their operands.
ResultOverwriteAllowed()330 virtual bool ResultOverwriteAllowed() { return false; }
331
332 // True iff the expression is a literal represented as a smi.
333 bool IsSmiLiteral();
334
335 // True iff the expression is a string literal.
336 bool IsStringLiteral();
337
338 // True iff the expression is the null literal.
339 bool IsNullLiteral();
340
341 // Type feedback information for assignments and properties.
IsMonomorphic()342 virtual bool IsMonomorphic() {
343 UNREACHABLE();
344 return false;
345 }
GetReceiverTypes()346 virtual SmallMapList* GetReceiverTypes() {
347 UNREACHABLE();
348 return NULL;
349 }
GetMonomorphicReceiverType()350 Handle<Map> GetMonomorphicReceiverType() {
351 ASSERT(IsMonomorphic());
352 SmallMapList* types = GetReceiverTypes();
353 ASSERT(types != NULL && types->length() == 1);
354 return types->at(0);
355 }
356
id()357 unsigned id() const { return id_; }
test_id()358 unsigned test_id() const { return test_id_; }
359
360 protected:
Expression(Isolate * isolate)361 explicit Expression(Isolate* isolate)
362 : id_(GetNextId(isolate)),
363 test_id_(GetNextId(isolate)) {}
364
365 private:
366 int id_;
367 int test_id_;
368 };
369
370
371 class BreakableStatement: public Statement {
372 public:
373 enum Type {
374 TARGET_FOR_ANONYMOUS,
375 TARGET_FOR_NAMED_ONLY
376 };
377
378 // The labels associated with this statement. May be NULL;
379 // if it is != NULL, guaranteed to contain at least one entry.
labels()380 ZoneStringList* labels() const { return labels_; }
381
382 // Type testing & conversion.
AsBreakableStatement()383 virtual BreakableStatement* AsBreakableStatement() { return this; }
384
385 // Code generation
break_target()386 Label* break_target() { return &break_target_; }
387
388 // Testers.
is_target_for_anonymous()389 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
390
391 // Bailout support.
EntryId()392 int EntryId() const { return entry_id_; }
ExitId()393 int ExitId() const { return exit_id_; }
394
395 protected:
BreakableStatement(Isolate * isolate,ZoneStringList * labels,Type type)396 BreakableStatement(Isolate* isolate, ZoneStringList* labels, Type type)
397 : labels_(labels),
398 type_(type),
399 entry_id_(GetNextId(isolate)),
400 exit_id_(GetNextId(isolate)) {
401 ASSERT(labels == NULL || labels->length() > 0);
402 }
403
404
405 private:
406 ZoneStringList* labels_;
407 Type type_;
408 Label break_target_;
409 int entry_id_;
410 int exit_id_;
411 };
412
413
414 class Block: public BreakableStatement {
415 public:
DECLARE_NODE_TYPE(Block)416 DECLARE_NODE_TYPE(Block)
417
418 void AddStatement(Statement* statement) { statements_.Add(statement); }
419
statements()420 ZoneList<Statement*>* statements() { return &statements_; }
is_initializer_block()421 bool is_initializer_block() const { return is_initializer_block_; }
422
block_scope()423 Scope* block_scope() const { return block_scope_; }
set_block_scope(Scope * block_scope)424 void set_block_scope(Scope* block_scope) { block_scope_ = block_scope; }
425
426 protected:
427 template<class> friend class AstNodeFactory;
428
Block(Isolate * isolate,ZoneStringList * labels,int capacity,bool is_initializer_block)429 Block(Isolate* isolate,
430 ZoneStringList* labels,
431 int capacity,
432 bool is_initializer_block)
433 : BreakableStatement(isolate, labels, TARGET_FOR_NAMED_ONLY),
434 statements_(capacity),
435 is_initializer_block_(is_initializer_block),
436 block_scope_(NULL) {
437 }
438
439 private:
440 ZoneList<Statement*> statements_;
441 bool is_initializer_block_;
442 Scope* block_scope_;
443 };
444
445
446 class Declaration: public AstNode {
447 public:
proxy()448 VariableProxy* proxy() const { return proxy_; }
mode()449 VariableMode mode() const { return mode_; }
scope()450 Scope* scope() const { return scope_; }
451 virtual InitializationFlag initialization() const = 0;
452 virtual bool IsInlineable() const;
453
AsDeclaration()454 virtual Declaration* AsDeclaration() { return this; }
455
456 protected:
Declaration(VariableProxy * proxy,VariableMode mode,Scope * scope)457 Declaration(VariableProxy* proxy,
458 VariableMode mode,
459 Scope* scope)
460 : proxy_(proxy),
461 mode_(mode),
462 scope_(scope) {
463 ASSERT(mode == VAR ||
464 mode == CONST ||
465 mode == CONST_HARMONY ||
466 mode == LET);
467 }
468
469 private:
470 VariableProxy* proxy_;
471 VariableMode mode_;
472
473 // Nested scope from which the declaration originated.
474 Scope* scope_;
475 };
476
477
478 class VariableDeclaration: public Declaration {
479 public:
DECLARE_NODE_TYPE(VariableDeclaration)480 DECLARE_NODE_TYPE(VariableDeclaration)
481
482 virtual InitializationFlag initialization() const {
483 return mode() == VAR ? kCreatedInitialized : kNeedsInitialization;
484 }
485
486 protected:
487 template<class> friend class AstNodeFactory;
488
VariableDeclaration(VariableProxy * proxy,VariableMode mode,Scope * scope)489 VariableDeclaration(VariableProxy* proxy,
490 VariableMode mode,
491 Scope* scope)
492 : Declaration(proxy, mode, scope) {
493 }
494 };
495
496
497 class FunctionDeclaration: public Declaration {
498 public:
DECLARE_NODE_TYPE(FunctionDeclaration)499 DECLARE_NODE_TYPE(FunctionDeclaration)
500
501 FunctionLiteral* fun() const { return fun_; }
initialization()502 virtual InitializationFlag initialization() const {
503 return kCreatedInitialized;
504 }
505 virtual bool IsInlineable() const;
506
507 protected:
508 template<class> friend class AstNodeFactory;
509
FunctionDeclaration(VariableProxy * proxy,VariableMode mode,FunctionLiteral * fun,Scope * scope)510 FunctionDeclaration(VariableProxy* proxy,
511 VariableMode mode,
512 FunctionLiteral* fun,
513 Scope* scope)
514 : Declaration(proxy, mode, scope),
515 fun_(fun) {
516 // At the moment there are no "const functions" in JavaScript...
517 ASSERT(mode == VAR || mode == LET);
518 ASSERT(fun != NULL);
519 }
520
521 private:
522 FunctionLiteral* fun_;
523 };
524
525
526 class ModuleDeclaration: public Declaration {
527 public:
DECLARE_NODE_TYPE(ModuleDeclaration)528 DECLARE_NODE_TYPE(ModuleDeclaration)
529
530 Module* module() const { return module_; }
initialization()531 virtual InitializationFlag initialization() const {
532 return kCreatedInitialized;
533 }
534
535 protected:
536 template<class> friend class AstNodeFactory;
537
ModuleDeclaration(VariableProxy * proxy,Module * module,Scope * scope)538 ModuleDeclaration(VariableProxy* proxy,
539 Module* module,
540 Scope* scope)
541 : Declaration(proxy, LET, scope),
542 module_(module) {
543 }
544
545 private:
546 Module* module_;
547 };
548
549
550 class ImportDeclaration: public Declaration {
551 public:
DECLARE_NODE_TYPE(ImportDeclaration)552 DECLARE_NODE_TYPE(ImportDeclaration)
553
554 Module* module() const { return module_; }
initialization()555 virtual InitializationFlag initialization() const {
556 return kCreatedInitialized;
557 }
558
559 protected:
560 template<class> friend class AstNodeFactory;
561
ImportDeclaration(VariableProxy * proxy,Module * module,Scope * scope)562 ImportDeclaration(VariableProxy* proxy,
563 Module* module,
564 Scope* scope)
565 : Declaration(proxy, LET, scope),
566 module_(module) {
567 }
568
569 private:
570 Module* module_;
571 };
572
573
574 class ExportDeclaration: public Declaration {
575 public:
DECLARE_NODE_TYPE(ExportDeclaration)576 DECLARE_NODE_TYPE(ExportDeclaration)
577
578 virtual InitializationFlag initialization() const {
579 return kCreatedInitialized;
580 }
581
582 protected:
583 template<class> friend class AstNodeFactory;
584
ExportDeclaration(VariableProxy * proxy,Scope * scope)585 ExportDeclaration(VariableProxy* proxy,
586 Scope* scope)
587 : Declaration(proxy, LET, scope) {
588 }
589 };
590
591
592 class Module: public AstNode {
593 public:
interface()594 Interface* interface() const { return interface_; }
595
596 protected:
Module()597 Module() : interface_(Interface::NewModule()) {}
Module(Interface * interface)598 explicit Module(Interface* interface) : interface_(interface) {}
599
600 private:
601 Interface* interface_;
602 };
603
604
605 class ModuleLiteral: public Module {
606 public:
DECLARE_NODE_TYPE(ModuleLiteral)607 DECLARE_NODE_TYPE(ModuleLiteral)
608
609 Block* body() const { return body_; }
610
611 protected:
612 template<class> friend class AstNodeFactory;
613
ModuleLiteral(Block * body,Interface * interface)614 ModuleLiteral(Block* body, Interface* interface)
615 : Module(interface),
616 body_(body) {
617 }
618
619 private:
620 Block* body_;
621 };
622
623
624 class ModuleVariable: public Module {
625 public:
DECLARE_NODE_TYPE(ModuleVariable)626 DECLARE_NODE_TYPE(ModuleVariable)
627
628 VariableProxy* proxy() const { return proxy_; }
629
630 protected:
631 template<class> friend class AstNodeFactory;
632
633 inline explicit ModuleVariable(VariableProxy* proxy);
634
635 private:
636 VariableProxy* proxy_;
637 };
638
639
640 class ModulePath: public Module {
641 public:
DECLARE_NODE_TYPE(ModulePath)642 DECLARE_NODE_TYPE(ModulePath)
643
644 Module* module() const { return module_; }
name()645 Handle<String> name() const { return name_; }
646
647 protected:
648 template<class> friend class AstNodeFactory;
649
ModulePath(Module * module,Handle<String> name)650 ModulePath(Module* module, Handle<String> name)
651 : module_(module),
652 name_(name) {
653 }
654
655 private:
656 Module* module_;
657 Handle<String> name_;
658 };
659
660
661 class ModuleUrl: public Module {
662 public:
DECLARE_NODE_TYPE(ModuleUrl)663 DECLARE_NODE_TYPE(ModuleUrl)
664
665 Handle<String> url() const { return url_; }
666
667 protected:
668 template<class> friend class AstNodeFactory;
669
ModuleUrl(Handle<String> url)670 explicit ModuleUrl(Handle<String> url) : url_(url) {
671 }
672
673 private:
674 Handle<String> url_;
675 };
676
677
678 class IterationStatement: public BreakableStatement {
679 public:
680 // Type testing & conversion.
AsIterationStatement()681 virtual IterationStatement* AsIterationStatement() { return this; }
682
body()683 Statement* body() const { return body_; }
684
685 // Bailout support.
OsrEntryId()686 int OsrEntryId() const { return osr_entry_id_; }
687 virtual int ContinueId() const = 0;
688 virtual int StackCheckId() const = 0;
689
690 // Code generation
continue_target()691 Label* continue_target() { return &continue_target_; }
692
693 protected:
IterationStatement(Isolate * isolate,ZoneStringList * labels)694 IterationStatement(Isolate* isolate, ZoneStringList* labels)
695 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
696 body_(NULL),
697 osr_entry_id_(GetNextId(isolate)) {
698 }
699
Initialize(Statement * body)700 void Initialize(Statement* body) {
701 body_ = body;
702 }
703
704 private:
705 Statement* body_;
706 Label continue_target_;
707 int osr_entry_id_;
708 };
709
710
711 class DoWhileStatement: public IterationStatement {
712 public:
DECLARE_NODE_TYPE(DoWhileStatement)713 DECLARE_NODE_TYPE(DoWhileStatement)
714
715 void Initialize(Expression* cond, Statement* body) {
716 IterationStatement::Initialize(body);
717 cond_ = cond;
718 }
719
cond()720 Expression* cond() const { return cond_; }
721
722 // Position where condition expression starts. We need it to make
723 // the loop's condition a breakable location.
condition_position()724 int condition_position() { return condition_position_; }
set_condition_position(int pos)725 void set_condition_position(int pos) { condition_position_ = pos; }
726
727 // Bailout support.
ContinueId()728 virtual int ContinueId() const { return continue_id_; }
StackCheckId()729 virtual int StackCheckId() const { return back_edge_id_; }
BackEdgeId()730 int BackEdgeId() const { return back_edge_id_; }
731
732 protected:
733 template<class> friend class AstNodeFactory;
734
DoWhileStatement(Isolate * isolate,ZoneStringList * labels)735 DoWhileStatement(Isolate* isolate, ZoneStringList* labels)
736 : IterationStatement(isolate, labels),
737 cond_(NULL),
738 condition_position_(-1),
739 continue_id_(GetNextId(isolate)),
740 back_edge_id_(GetNextId(isolate)) {
741 }
742
743 private:
744 Expression* cond_;
745 int condition_position_;
746 int continue_id_;
747 int back_edge_id_;
748 };
749
750
751 class WhileStatement: public IterationStatement {
752 public:
DECLARE_NODE_TYPE(WhileStatement)753 DECLARE_NODE_TYPE(WhileStatement)
754
755 void Initialize(Expression* cond, Statement* body) {
756 IterationStatement::Initialize(body);
757 cond_ = cond;
758 }
759
cond()760 Expression* cond() const { return cond_; }
may_have_function_literal()761 bool may_have_function_literal() const {
762 return may_have_function_literal_;
763 }
set_may_have_function_literal(bool value)764 void set_may_have_function_literal(bool value) {
765 may_have_function_literal_ = value;
766 }
767
768 // Bailout support.
ContinueId()769 virtual int ContinueId() const { return EntryId(); }
StackCheckId()770 virtual int StackCheckId() const { return body_id_; }
BodyId()771 int BodyId() const { return body_id_; }
772
773 protected:
774 template<class> friend class AstNodeFactory;
775
WhileStatement(Isolate * isolate,ZoneStringList * labels)776 WhileStatement(Isolate* isolate, ZoneStringList* labels)
777 : IterationStatement(isolate, labels),
778 cond_(NULL),
779 may_have_function_literal_(true),
780 body_id_(GetNextId(isolate)) {
781 }
782
783 private:
784 Expression* cond_;
785 // True if there is a function literal subexpression in the condition.
786 bool may_have_function_literal_;
787 int body_id_;
788 };
789
790
791 class ForStatement: public IterationStatement {
792 public:
DECLARE_NODE_TYPE(ForStatement)793 DECLARE_NODE_TYPE(ForStatement)
794
795 void Initialize(Statement* init,
796 Expression* cond,
797 Statement* next,
798 Statement* body) {
799 IterationStatement::Initialize(body);
800 init_ = init;
801 cond_ = cond;
802 next_ = next;
803 }
804
init()805 Statement* init() const { return init_; }
cond()806 Expression* cond() const { return cond_; }
next()807 Statement* next() const { return next_; }
808
may_have_function_literal()809 bool may_have_function_literal() const {
810 return may_have_function_literal_;
811 }
set_may_have_function_literal(bool value)812 void set_may_have_function_literal(bool value) {
813 may_have_function_literal_ = value;
814 }
815
816 // Bailout support.
ContinueId()817 virtual int ContinueId() const { return continue_id_; }
StackCheckId()818 virtual int StackCheckId() const { return body_id_; }
BodyId()819 int BodyId() const { return body_id_; }
820
is_fast_smi_loop()821 bool is_fast_smi_loop() { return loop_variable_ != NULL; }
loop_variable()822 Variable* loop_variable() { return loop_variable_; }
set_loop_variable(Variable * var)823 void set_loop_variable(Variable* var) { loop_variable_ = var; }
824
825 protected:
826 template<class> friend class AstNodeFactory;
827
ForStatement(Isolate * isolate,ZoneStringList * labels)828 ForStatement(Isolate* isolate, ZoneStringList* labels)
829 : IterationStatement(isolate, labels),
830 init_(NULL),
831 cond_(NULL),
832 next_(NULL),
833 may_have_function_literal_(true),
834 loop_variable_(NULL),
835 continue_id_(GetNextId(isolate)),
836 body_id_(GetNextId(isolate)) {
837 }
838
839 private:
840 Statement* init_;
841 Expression* cond_;
842 Statement* next_;
843 // True if there is a function literal subexpression in the condition.
844 bool may_have_function_literal_;
845 Variable* loop_variable_;
846 int continue_id_;
847 int body_id_;
848 };
849
850
851 class ForInStatement: public IterationStatement {
852 public:
DECLARE_NODE_TYPE(ForInStatement)853 DECLARE_NODE_TYPE(ForInStatement)
854
855 void Initialize(Expression* each, Expression* enumerable, Statement* body) {
856 IterationStatement::Initialize(body);
857 each_ = each;
858 enumerable_ = enumerable;
859 }
860
each()861 Expression* each() const { return each_; }
enumerable()862 Expression* enumerable() const { return enumerable_; }
863
ContinueId()864 virtual int ContinueId() const { return EntryId(); }
StackCheckId()865 virtual int StackCheckId() const { return body_id_; }
BodyId()866 int BodyId() const { return body_id_; }
PrepareId()867 int PrepareId() const { return prepare_id_; }
868
869 protected:
870 template<class> friend class AstNodeFactory;
871
ForInStatement(Isolate * isolate,ZoneStringList * labels)872 ForInStatement(Isolate* isolate, ZoneStringList* labels)
873 : IterationStatement(isolate, labels),
874 each_(NULL),
875 enumerable_(NULL),
876 body_id_(GetNextId(isolate)),
877 prepare_id_(GetNextId(isolate)) {
878 }
879
880 private:
881 Expression* each_;
882 Expression* enumerable_;
883 int body_id_;
884 int prepare_id_;
885 };
886
887
888 class ExpressionStatement: public Statement {
889 public:
DECLARE_NODE_TYPE(ExpressionStatement)890 DECLARE_NODE_TYPE(ExpressionStatement)
891
892 void set_expression(Expression* e) { expression_ = e; }
expression()893 Expression* expression() const { return expression_; }
894
895 protected:
896 template<class> friend class AstNodeFactory;
897
ExpressionStatement(Expression * expression)898 explicit ExpressionStatement(Expression* expression)
899 : expression_(expression) { }
900
901 private:
902 Expression* expression_;
903 };
904
905
906 class ContinueStatement: public Statement {
907 public:
DECLARE_NODE_TYPE(ContinueStatement)908 DECLARE_NODE_TYPE(ContinueStatement)
909
910 IterationStatement* target() const { return target_; }
911
912 protected:
913 template<class> friend class AstNodeFactory;
914
ContinueStatement(IterationStatement * target)915 explicit ContinueStatement(IterationStatement* target)
916 : target_(target) { }
917
918 private:
919 IterationStatement* target_;
920 };
921
922
923 class BreakStatement: public Statement {
924 public:
DECLARE_NODE_TYPE(BreakStatement)925 DECLARE_NODE_TYPE(BreakStatement)
926
927 BreakableStatement* target() const { return target_; }
928
929 protected:
930 template<class> friend class AstNodeFactory;
931
BreakStatement(BreakableStatement * target)932 explicit BreakStatement(BreakableStatement* target)
933 : target_(target) { }
934
935 private:
936 BreakableStatement* target_;
937 };
938
939
940 class ReturnStatement: public Statement {
941 public:
DECLARE_NODE_TYPE(ReturnStatement)942 DECLARE_NODE_TYPE(ReturnStatement)
943
944 Expression* expression() const { return expression_; }
945
946 protected:
947 template<class> friend class AstNodeFactory;
948
ReturnStatement(Expression * expression)949 explicit ReturnStatement(Expression* expression)
950 : expression_(expression) { }
951
952 private:
953 Expression* expression_;
954 };
955
956
957 class WithStatement: public Statement {
958 public:
DECLARE_NODE_TYPE(WithStatement)959 DECLARE_NODE_TYPE(WithStatement)
960
961 Expression* expression() const { return expression_; }
statement()962 Statement* statement() const { return statement_; }
963
964 protected:
965 template<class> friend class AstNodeFactory;
966
WithStatement(Expression * expression,Statement * statement)967 WithStatement(Expression* expression, Statement* statement)
968 : expression_(expression),
969 statement_(statement) { }
970
971 private:
972 Expression* expression_;
973 Statement* statement_;
974 };
975
976
977 class CaseClause: public ZoneObject {
978 public:
979 CaseClause(Isolate* isolate,
980 Expression* label,
981 ZoneList<Statement*>* statements,
982 int pos);
983
is_default()984 bool is_default() const { return label_ == NULL; }
label()985 Expression* label() const {
986 CHECK(!is_default());
987 return label_;
988 }
body_target()989 Label* body_target() { return &body_target_; }
statements()990 ZoneList<Statement*>* statements() const { return statements_; }
991
position()992 int position() const { return position_; }
set_position(int pos)993 void set_position(int pos) { position_ = pos; }
994
EntryId()995 int EntryId() { return entry_id_; }
CompareId()996 int CompareId() { return compare_id_; }
997
998 // Type feedback information.
999 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
IsSmiCompare()1000 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
IsSymbolCompare()1001 bool IsSymbolCompare() { return compare_type_ == SYMBOL_ONLY; }
IsStringCompare()1002 bool IsStringCompare() { return compare_type_ == STRING_ONLY; }
IsObjectCompare()1003 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1004
1005 private:
1006 Expression* label_;
1007 Label body_target_;
1008 ZoneList<Statement*>* statements_;
1009 int position_;
1010 enum CompareTypeFeedback {
1011 NONE,
1012 SMI_ONLY,
1013 SYMBOL_ONLY,
1014 STRING_ONLY,
1015 OBJECT_ONLY
1016 };
1017 CompareTypeFeedback compare_type_;
1018 int compare_id_;
1019 int entry_id_;
1020 };
1021
1022
1023 class SwitchStatement: public BreakableStatement {
1024 public:
DECLARE_NODE_TYPE(SwitchStatement)1025 DECLARE_NODE_TYPE(SwitchStatement)
1026
1027 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
1028 tag_ = tag;
1029 cases_ = cases;
1030 }
1031
tag()1032 Expression* tag() const { return tag_; }
cases()1033 ZoneList<CaseClause*>* cases() const { return cases_; }
1034
1035 protected:
1036 template<class> friend class AstNodeFactory;
1037
SwitchStatement(Isolate * isolate,ZoneStringList * labels)1038 SwitchStatement(Isolate* isolate, ZoneStringList* labels)
1039 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
1040 tag_(NULL),
1041 cases_(NULL) { }
1042
1043 private:
1044 Expression* tag_;
1045 ZoneList<CaseClause*>* cases_;
1046 };
1047
1048
1049 // If-statements always have non-null references to their then- and
1050 // else-parts. When parsing if-statements with no explicit else-part,
1051 // the parser implicitly creates an empty statement. Use the
1052 // HasThenStatement() and HasElseStatement() functions to check if a
1053 // given if-statement has a then- or an else-part containing code.
1054 class IfStatement: public Statement {
1055 public:
DECLARE_NODE_TYPE(IfStatement)1056 DECLARE_NODE_TYPE(IfStatement)
1057
1058 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
HasElseStatement()1059 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
1060
condition()1061 Expression* condition() const { return condition_; }
then_statement()1062 Statement* then_statement() const { return then_statement_; }
else_statement()1063 Statement* else_statement() const { return else_statement_; }
1064
IfId()1065 int IfId() const { return if_id_; }
ThenId()1066 int ThenId() const { return then_id_; }
ElseId()1067 int ElseId() const { return else_id_; }
1068
1069 protected:
1070 template<class> friend class AstNodeFactory;
1071
IfStatement(Isolate * isolate,Expression * condition,Statement * then_statement,Statement * else_statement)1072 IfStatement(Isolate* isolate,
1073 Expression* condition,
1074 Statement* then_statement,
1075 Statement* else_statement)
1076 : condition_(condition),
1077 then_statement_(then_statement),
1078 else_statement_(else_statement),
1079 if_id_(GetNextId(isolate)),
1080 then_id_(GetNextId(isolate)),
1081 else_id_(GetNextId(isolate)) {
1082 }
1083
1084 private:
1085 Expression* condition_;
1086 Statement* then_statement_;
1087 Statement* else_statement_;
1088 int if_id_;
1089 int then_id_;
1090 int else_id_;
1091 };
1092
1093
1094 // NOTE: TargetCollectors are represented as nodes to fit in the target
1095 // stack in the compiler; this should probably be reworked.
1096 class TargetCollector: public AstNode {
1097 public:
TargetCollector()1098 TargetCollector() : targets_(0) { }
1099
1100 // Adds a jump target to the collector. The collector stores a pointer not
1101 // a copy of the target to make binding work, so make sure not to pass in
1102 // references to something on the stack.
1103 void AddTarget(Label* target);
1104
1105 // Virtual behaviour. TargetCollectors are never part of the AST.
Accept(AstVisitor * v)1106 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
AsTargetCollector()1107 virtual TargetCollector* AsTargetCollector() { return this; }
1108
targets()1109 ZoneList<Label*>* targets() { return &targets_; }
1110
1111 private:
1112 ZoneList<Label*> targets_;
1113 };
1114
1115
1116 class TryStatement: public Statement {
1117 public:
set_escaping_targets(ZoneList<Label * > * targets)1118 void set_escaping_targets(ZoneList<Label*>* targets) {
1119 escaping_targets_ = targets;
1120 }
1121
index()1122 int index() const { return index_; }
try_block()1123 Block* try_block() const { return try_block_; }
escaping_targets()1124 ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
1125
1126 protected:
TryStatement(int index,Block * try_block)1127 TryStatement(int index, Block* try_block)
1128 : index_(index),
1129 try_block_(try_block),
1130 escaping_targets_(NULL) { }
1131
1132 private:
1133 // Unique (per-function) index of this handler. This is not an AST ID.
1134 int index_;
1135
1136 Block* try_block_;
1137 ZoneList<Label*>* escaping_targets_;
1138 };
1139
1140
1141 class TryCatchStatement: public TryStatement {
1142 public:
DECLARE_NODE_TYPE(TryCatchStatement)1143 DECLARE_NODE_TYPE(TryCatchStatement)
1144
1145 Scope* scope() { return scope_; }
variable()1146 Variable* variable() { return variable_; }
catch_block()1147 Block* catch_block() const { return catch_block_; }
1148
1149 protected:
1150 template<class> friend class AstNodeFactory;
1151
TryCatchStatement(int index,Block * try_block,Scope * scope,Variable * variable,Block * catch_block)1152 TryCatchStatement(int index,
1153 Block* try_block,
1154 Scope* scope,
1155 Variable* variable,
1156 Block* catch_block)
1157 : TryStatement(index, try_block),
1158 scope_(scope),
1159 variable_(variable),
1160 catch_block_(catch_block) {
1161 }
1162
1163 private:
1164 Scope* scope_;
1165 Variable* variable_;
1166 Block* catch_block_;
1167 };
1168
1169
1170 class TryFinallyStatement: public TryStatement {
1171 public:
DECLARE_NODE_TYPE(TryFinallyStatement)1172 DECLARE_NODE_TYPE(TryFinallyStatement)
1173
1174 Block* finally_block() const { return finally_block_; }
1175
1176 protected:
1177 template<class> friend class AstNodeFactory;
1178
TryFinallyStatement(int index,Block * try_block,Block * finally_block)1179 TryFinallyStatement(int index, Block* try_block, Block* finally_block)
1180 : TryStatement(index, try_block),
1181 finally_block_(finally_block) { }
1182
1183 private:
1184 Block* finally_block_;
1185 };
1186
1187
1188 class DebuggerStatement: public Statement {
1189 public:
1190 DECLARE_NODE_TYPE(DebuggerStatement)
1191
1192 protected:
1193 template<class> friend class AstNodeFactory;
1194
DebuggerStatement()1195 DebuggerStatement() {}
1196 };
1197
1198
1199 class EmptyStatement: public Statement {
1200 public:
1201 DECLARE_NODE_TYPE(EmptyStatement)
1202
1203 protected:
1204 template<class> friend class AstNodeFactory;
1205
EmptyStatement()1206 EmptyStatement() {}
1207 };
1208
1209
1210 class Literal: public Expression {
1211 public:
DECLARE_NODE_TYPE(Literal)1212 DECLARE_NODE_TYPE(Literal)
1213
1214 virtual bool IsPropertyName() {
1215 if (handle_->IsSymbol()) {
1216 uint32_t ignored;
1217 return !String::cast(*handle_)->AsArrayIndex(&ignored);
1218 }
1219 return false;
1220 }
1221
AsPropertyName()1222 Handle<String> AsPropertyName() {
1223 ASSERT(IsPropertyName());
1224 return Handle<String>::cast(handle_);
1225 }
1226
ToBooleanIsTrue()1227 virtual bool ToBooleanIsTrue() { return handle_->ToBoolean()->IsTrue(); }
ToBooleanIsFalse()1228 virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
1229
1230 // Identity testers.
IsNull()1231 bool IsNull() const {
1232 ASSERT(!handle_.is_null());
1233 return handle_->IsNull();
1234 }
IsTrue()1235 bool IsTrue() const {
1236 ASSERT(!handle_.is_null());
1237 return handle_->IsTrue();
1238 }
IsFalse()1239 bool IsFalse() const {
1240 ASSERT(!handle_.is_null());
1241 return handle_->IsFalse();
1242 }
1243
handle()1244 Handle<Object> handle() const { return handle_; }
1245
1246 // Support for using Literal as a HashMap key. NOTE: Currently, this works
1247 // only for string and number literals!
Hash()1248 uint32_t Hash() { return ToString()->Hash(); }
1249
Match(void * literal1,void * literal2)1250 static bool Match(void* literal1, void* literal2) {
1251 Handle<String> s1 = static_cast<Literal*>(literal1)->ToString();
1252 Handle<String> s2 = static_cast<Literal*>(literal2)->ToString();
1253 return s1->Equals(*s2);
1254 }
1255
1256 protected:
1257 template<class> friend class AstNodeFactory;
1258
Literal(Isolate * isolate,Handle<Object> handle)1259 Literal(Isolate* isolate, Handle<Object> handle)
1260 : Expression(isolate),
1261 handle_(handle) { }
1262
1263 private:
1264 Handle<String> ToString();
1265
1266 Handle<Object> handle_;
1267 };
1268
1269
1270 // Base class for literals that needs space in the corresponding JSFunction.
1271 class MaterializedLiteral: public Expression {
1272 public:
AsMaterializedLiteral()1273 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
1274
literal_index()1275 int literal_index() { return literal_index_; }
1276
1277 // A materialized literal is simple if the values consist of only
1278 // constants and simple object and array literals.
is_simple()1279 bool is_simple() const { return is_simple_; }
1280
depth()1281 int depth() const { return depth_; }
1282
1283 protected:
MaterializedLiteral(Isolate * isolate,int literal_index,bool is_simple,int depth)1284 MaterializedLiteral(Isolate* isolate,
1285 int literal_index,
1286 bool is_simple,
1287 int depth)
1288 : Expression(isolate),
1289 literal_index_(literal_index),
1290 is_simple_(is_simple),
1291 depth_(depth) {}
1292
1293 private:
1294 int literal_index_;
1295 bool is_simple_;
1296 int depth_;
1297 };
1298
1299
1300 // An object literal has a boilerplate object that is used
1301 // for minimizing the work when constructing it at runtime.
1302 class ObjectLiteral: public MaterializedLiteral {
1303 public:
1304 // Property is used for passing information
1305 // about an object literal's properties from the parser
1306 // to the code generator.
1307 class Property: public ZoneObject {
1308 public:
1309 enum Kind {
1310 CONSTANT, // Property with constant value (compile time).
1311 COMPUTED, // Property with computed value (execution time).
1312 MATERIALIZED_LITERAL, // Property value is a materialized literal.
1313 GETTER, SETTER, // Property is an accessor function.
1314 PROTOTYPE // Property is __proto__.
1315 };
1316
1317 Property(Literal* key, Expression* value, Isolate* isolate);
1318
key()1319 Literal* key() { return key_; }
value()1320 Expression* value() { return value_; }
kind()1321 Kind kind() { return kind_; }
1322
1323 // Type feedback information.
1324 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
IsMonomorphic()1325 bool IsMonomorphic() { return !receiver_type_.is_null(); }
GetReceiverType()1326 Handle<Map> GetReceiverType() { return receiver_type_; }
1327
1328 bool IsCompileTimeValue();
1329
1330 void set_emit_store(bool emit_store);
1331 bool emit_store();
1332
1333 protected:
1334 template<class> friend class AstNodeFactory;
1335
1336 Property(bool is_getter, FunctionLiteral* value);
set_key(Literal * key)1337 void set_key(Literal* key) { key_ = key; }
1338
1339 private:
1340 Literal* key_;
1341 Expression* value_;
1342 Kind kind_;
1343 bool emit_store_;
1344 Handle<Map> receiver_type_;
1345 };
1346
DECLARE_NODE_TYPE(ObjectLiteral)1347 DECLARE_NODE_TYPE(ObjectLiteral)
1348
1349 Handle<FixedArray> constant_properties() const {
1350 return constant_properties_;
1351 }
properties()1352 ZoneList<Property*>* properties() const { return properties_; }
1353
fast_elements()1354 bool fast_elements() const { return fast_elements_; }
1355
has_function()1356 bool has_function() { return has_function_; }
1357
1358 // Mark all computed expressions that are bound to a key that
1359 // is shadowed by a later occurrence of the same key. For the
1360 // marked expressions, no store code is emitted.
1361 void CalculateEmitStore();
1362
1363 enum Flags {
1364 kNoFlags = 0,
1365 kFastElements = 1,
1366 kHasFunction = 1 << 1
1367 };
1368
1369 struct Accessors: public ZoneObject {
AccessorsAccessors1370 Accessors() : getter(NULL), setter(NULL) { }
1371 Expression* getter;
1372 Expression* setter;
1373 };
1374
1375 protected:
1376 template<class> friend class AstNodeFactory;
1377
ObjectLiteral(Isolate * isolate,Handle<FixedArray> constant_properties,ZoneList<Property * > * properties,int literal_index,bool is_simple,bool fast_elements,int depth,bool has_function)1378 ObjectLiteral(Isolate* isolate,
1379 Handle<FixedArray> constant_properties,
1380 ZoneList<Property*>* properties,
1381 int literal_index,
1382 bool is_simple,
1383 bool fast_elements,
1384 int depth,
1385 bool has_function)
1386 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
1387 constant_properties_(constant_properties),
1388 properties_(properties),
1389 fast_elements_(fast_elements),
1390 has_function_(has_function) {}
1391
1392 private:
1393 Handle<FixedArray> constant_properties_;
1394 ZoneList<Property*>* properties_;
1395 bool fast_elements_;
1396 bool has_function_;
1397 };
1398
1399
1400 // Node for capturing a regexp literal.
1401 class RegExpLiteral: public MaterializedLiteral {
1402 public:
DECLARE_NODE_TYPE(RegExpLiteral)1403 DECLARE_NODE_TYPE(RegExpLiteral)
1404
1405 Handle<String> pattern() const { return pattern_; }
flags()1406 Handle<String> flags() const { return flags_; }
1407
1408 protected:
1409 template<class> friend class AstNodeFactory;
1410
RegExpLiteral(Isolate * isolate,Handle<String> pattern,Handle<String> flags,int literal_index)1411 RegExpLiteral(Isolate* isolate,
1412 Handle<String> pattern,
1413 Handle<String> flags,
1414 int literal_index)
1415 : MaterializedLiteral(isolate, literal_index, false, 1),
1416 pattern_(pattern),
1417 flags_(flags) {}
1418
1419 private:
1420 Handle<String> pattern_;
1421 Handle<String> flags_;
1422 };
1423
1424 // An array literal has a literals object that is used
1425 // for minimizing the work when constructing it at runtime.
1426 class ArrayLiteral: public MaterializedLiteral {
1427 public:
DECLARE_NODE_TYPE(ArrayLiteral)1428 DECLARE_NODE_TYPE(ArrayLiteral)
1429
1430 Handle<FixedArray> constant_elements() const { return constant_elements_; }
values()1431 ZoneList<Expression*>* values() const { return values_; }
1432
1433 // Return an AST id for an element that is used in simulate instructions.
GetIdForElement(int i)1434 int GetIdForElement(int i) { return first_element_id_ + i; }
1435
1436 protected:
1437 template<class> friend class AstNodeFactory;
1438
ArrayLiteral(Isolate * isolate,Handle<FixedArray> constant_elements,ZoneList<Expression * > * values,int literal_index,bool is_simple,int depth)1439 ArrayLiteral(Isolate* isolate,
1440 Handle<FixedArray> constant_elements,
1441 ZoneList<Expression*>* values,
1442 int literal_index,
1443 bool is_simple,
1444 int depth)
1445 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
1446 constant_elements_(constant_elements),
1447 values_(values),
1448 first_element_id_(ReserveIdRange(isolate, values->length())) {}
1449
1450 private:
1451 Handle<FixedArray> constant_elements_;
1452 ZoneList<Expression*>* values_;
1453 int first_element_id_;
1454 };
1455
1456
1457 class VariableProxy: public Expression {
1458 public:
DECLARE_NODE_TYPE(VariableProxy)1459 DECLARE_NODE_TYPE(VariableProxy)
1460
1461 virtual bool IsValidLeftHandSide() {
1462 return var_ == NULL ? true : var_->IsValidLeftHandSide();
1463 }
1464
IsVariable(Handle<String> n)1465 bool IsVariable(Handle<String> n) {
1466 return !is_this() && name().is_identical_to(n);
1467 }
1468
IsArguments()1469 bool IsArguments() { return var_ != NULL && var_->is_arguments(); }
1470
IsLValue()1471 bool IsLValue() {
1472 return is_lvalue_;
1473 }
1474
name()1475 Handle<String> name() const { return name_; }
var()1476 Variable* var() const { return var_; }
is_this()1477 bool is_this() const { return is_this_; }
position()1478 int position() const { return position_; }
interface()1479 Interface* interface() const { return interface_; }
1480
1481
MarkAsTrivial()1482 void MarkAsTrivial() { is_trivial_ = true; }
MarkAsLValue()1483 void MarkAsLValue() { is_lvalue_ = true; }
1484
1485 // Bind this proxy to the variable var.
1486 void BindTo(Variable* var);
1487
1488 protected:
1489 template<class> friend class AstNodeFactory;
1490
1491 VariableProxy(Isolate* isolate, Variable* var);
1492
1493 VariableProxy(Isolate* isolate,
1494 Handle<String> name,
1495 bool is_this,
1496 int position,
1497 Interface* interface);
1498
1499 Handle<String> name_;
1500 Variable* var_; // resolved variable, or NULL
1501 bool is_this_;
1502 bool is_trivial_;
1503 // True if this variable proxy is being used in an assignment
1504 // or with a increment/decrement operator.
1505 bool is_lvalue_;
1506 int position_;
1507 Interface* interface_;
1508 };
1509
1510
1511 class Property: public Expression {
1512 public:
DECLARE_NODE_TYPE(Property)1513 DECLARE_NODE_TYPE(Property)
1514
1515 virtual bool IsValidLeftHandSide() { return true; }
1516
obj()1517 Expression* obj() const { return obj_; }
key()1518 Expression* key() const { return key_; }
position()1519 virtual int position() const { return pos_; }
1520
IsStringLength()1521 bool IsStringLength() const { return is_string_length_; }
IsStringAccess()1522 bool IsStringAccess() const { return is_string_access_; }
IsFunctionPrototype()1523 bool IsFunctionPrototype() const { return is_function_prototype_; }
1524
1525 // Type feedback information.
1526 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
IsMonomorphic()1527 virtual bool IsMonomorphic() { return is_monomorphic_; }
GetReceiverTypes()1528 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
IsArrayLength()1529 bool IsArrayLength() { return is_array_length_; }
IsUninitialized()1530 bool IsUninitialized() { return is_uninitialized_; }
1531
1532 protected:
1533 template<class> friend class AstNodeFactory;
1534
Property(Isolate * isolate,Expression * obj,Expression * key,int pos)1535 Property(Isolate* isolate,
1536 Expression* obj,
1537 Expression* key,
1538 int pos)
1539 : Expression(isolate),
1540 obj_(obj),
1541 key_(key),
1542 pos_(pos),
1543 is_monomorphic_(false),
1544 is_uninitialized_(false),
1545 is_array_length_(false),
1546 is_string_length_(false),
1547 is_string_access_(false),
1548 is_function_prototype_(false) { }
1549
1550 private:
1551 Expression* obj_;
1552 Expression* key_;
1553 int pos_;
1554
1555 SmallMapList receiver_types_;
1556 bool is_monomorphic_ : 1;
1557 bool is_uninitialized_ : 1;
1558 bool is_array_length_ : 1;
1559 bool is_string_length_ : 1;
1560 bool is_string_access_ : 1;
1561 bool is_function_prototype_ : 1;
1562 };
1563
1564
1565 class Call: public Expression {
1566 public:
DECLARE_NODE_TYPE(Call)1567 DECLARE_NODE_TYPE(Call)
1568
1569 Expression* expression() const { return expression_; }
arguments()1570 ZoneList<Expression*>* arguments() const { return arguments_; }
position()1571 virtual int position() const { return pos_; }
1572
1573 void RecordTypeFeedback(TypeFeedbackOracle* oracle,
1574 CallKind call_kind);
GetReceiverTypes()1575 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
IsMonomorphic()1576 virtual bool IsMonomorphic() { return is_monomorphic_; }
check_type()1577 CheckType check_type() const { return check_type_; }
target()1578 Handle<JSFunction> target() { return target_; }
holder()1579 Handle<JSObject> holder() { return holder_; }
cell()1580 Handle<JSGlobalPropertyCell> cell() { return cell_; }
1581
1582 bool ComputeTarget(Handle<Map> type, Handle<String> name);
1583 bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
1584
1585 // Bailout support.
ReturnId()1586 int ReturnId() const { return return_id_; }
1587
1588 #ifdef DEBUG
1589 // Used to assert that the FullCodeGenerator records the return site.
1590 bool return_is_recorded_;
1591 #endif
1592
1593 protected:
1594 template<class> friend class AstNodeFactory;
1595
Call(Isolate * isolate,Expression * expression,ZoneList<Expression * > * arguments,int pos)1596 Call(Isolate* isolate,
1597 Expression* expression,
1598 ZoneList<Expression*>* arguments,
1599 int pos)
1600 : Expression(isolate),
1601 expression_(expression),
1602 arguments_(arguments),
1603 pos_(pos),
1604 is_monomorphic_(false),
1605 check_type_(RECEIVER_MAP_CHECK),
1606 return_id_(GetNextId(isolate)) { }
1607
1608 private:
1609 Expression* expression_;
1610 ZoneList<Expression*>* arguments_;
1611 int pos_;
1612
1613 bool is_monomorphic_;
1614 CheckType check_type_;
1615 SmallMapList receiver_types_;
1616 Handle<JSFunction> target_;
1617 Handle<JSObject> holder_;
1618 Handle<JSGlobalPropertyCell> cell_;
1619
1620 int return_id_;
1621 };
1622
1623
1624 class CallNew: public Expression {
1625 public:
DECLARE_NODE_TYPE(CallNew)1626 DECLARE_NODE_TYPE(CallNew)
1627
1628 Expression* expression() const { return expression_; }
arguments()1629 ZoneList<Expression*>* arguments() const { return arguments_; }
position()1630 virtual int position() const { return pos_; }
1631
1632 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
IsMonomorphic()1633 virtual bool IsMonomorphic() { return is_monomorphic_; }
target()1634 Handle<JSFunction> target() { return target_; }
1635
1636 // Bailout support.
ReturnId()1637 int ReturnId() const { return return_id_; }
1638
1639 protected:
1640 template<class> friend class AstNodeFactory;
1641
CallNew(Isolate * isolate,Expression * expression,ZoneList<Expression * > * arguments,int pos)1642 CallNew(Isolate* isolate,
1643 Expression* expression,
1644 ZoneList<Expression*>* arguments,
1645 int pos)
1646 : Expression(isolate),
1647 expression_(expression),
1648 arguments_(arguments),
1649 pos_(pos),
1650 is_monomorphic_(false),
1651 return_id_(GetNextId(isolate)) { }
1652
1653 private:
1654 Expression* expression_;
1655 ZoneList<Expression*>* arguments_;
1656 int pos_;
1657
1658 bool is_monomorphic_;
1659 Handle<JSFunction> target_;
1660
1661 int return_id_;
1662 };
1663
1664
1665 // The CallRuntime class does not represent any official JavaScript
1666 // language construct. Instead it is used to call a C or JS function
1667 // with a set of arguments. This is used from the builtins that are
1668 // implemented in JavaScript (see "v8natives.js").
1669 class CallRuntime: public Expression {
1670 public:
DECLARE_NODE_TYPE(CallRuntime)1671 DECLARE_NODE_TYPE(CallRuntime)
1672
1673 Handle<String> name() const { return name_; }
function()1674 const Runtime::Function* function() const { return function_; }
arguments()1675 ZoneList<Expression*>* arguments() const { return arguments_; }
is_jsruntime()1676 bool is_jsruntime() const { return function_ == NULL; }
1677
1678 protected:
1679 template<class> friend class AstNodeFactory;
1680
CallRuntime(Isolate * isolate,Handle<String> name,const Runtime::Function * function,ZoneList<Expression * > * arguments)1681 CallRuntime(Isolate* isolate,
1682 Handle<String> name,
1683 const Runtime::Function* function,
1684 ZoneList<Expression*>* arguments)
1685 : Expression(isolate),
1686 name_(name),
1687 function_(function),
1688 arguments_(arguments) { }
1689
1690 private:
1691 Handle<String> name_;
1692 const Runtime::Function* function_;
1693 ZoneList<Expression*>* arguments_;
1694 };
1695
1696
1697 class UnaryOperation: public Expression {
1698 public:
1699 DECLARE_NODE_TYPE(UnaryOperation)
1700
1701 virtual bool ResultOverwriteAllowed();
1702
op()1703 Token::Value op() const { return op_; }
expression()1704 Expression* expression() const { return expression_; }
position()1705 virtual int position() const { return pos_; }
1706
MaterializeTrueId()1707 int MaterializeTrueId() { return materialize_true_id_; }
MaterializeFalseId()1708 int MaterializeFalseId() { return materialize_false_id_; }
1709
1710 protected:
1711 template<class> friend class AstNodeFactory;
1712
UnaryOperation(Isolate * isolate,Token::Value op,Expression * expression,int pos)1713 UnaryOperation(Isolate* isolate,
1714 Token::Value op,
1715 Expression* expression,
1716 int pos)
1717 : Expression(isolate),
1718 op_(op),
1719 expression_(expression),
1720 pos_(pos),
1721 materialize_true_id_(AstNode::kNoNumber),
1722 materialize_false_id_(AstNode::kNoNumber) {
1723 ASSERT(Token::IsUnaryOp(op));
1724 if (op == Token::NOT) {
1725 materialize_true_id_ = GetNextId(isolate);
1726 materialize_false_id_ = GetNextId(isolate);
1727 }
1728 }
1729
1730 private:
1731 Token::Value op_;
1732 Expression* expression_;
1733 int pos_;
1734
1735 // For unary not (Token::NOT), the AST ids where true and false will
1736 // actually be materialized, respectively.
1737 int materialize_true_id_;
1738 int materialize_false_id_;
1739 };
1740
1741
1742 class BinaryOperation: public Expression {
1743 public:
1744 DECLARE_NODE_TYPE(BinaryOperation)
1745
1746 virtual bool ResultOverwriteAllowed();
1747
op()1748 Token::Value op() const { return op_; }
left()1749 Expression* left() const { return left_; }
right()1750 Expression* right() const { return right_; }
position()1751 virtual int position() const { return pos_; }
1752
1753 // Bailout support.
RightId()1754 int RightId() const { return right_id_; }
1755
1756 protected:
1757 template<class> friend class AstNodeFactory;
1758
BinaryOperation(Isolate * isolate,Token::Value op,Expression * left,Expression * right,int pos)1759 BinaryOperation(Isolate* isolate,
1760 Token::Value op,
1761 Expression* left,
1762 Expression* right,
1763 int pos)
1764 : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) {
1765 ASSERT(Token::IsBinaryOp(op));
1766 right_id_ = (op == Token::AND || op == Token::OR)
1767 ? GetNextId(isolate)
1768 : AstNode::kNoNumber;
1769 }
1770
1771 private:
1772 Token::Value op_;
1773 Expression* left_;
1774 Expression* right_;
1775 int pos_;
1776 // The short-circuit logical operations have an AST ID for their
1777 // right-hand subexpression.
1778 int right_id_;
1779 };
1780
1781
1782 class CountOperation: public Expression {
1783 public:
DECLARE_NODE_TYPE(CountOperation)1784 DECLARE_NODE_TYPE(CountOperation)
1785
1786 bool is_prefix() const { return is_prefix_; }
is_postfix()1787 bool is_postfix() const { return !is_prefix_; }
1788
op()1789 Token::Value op() const { return op_; }
binary_op()1790 Token::Value binary_op() {
1791 return (op() == Token::INC) ? Token::ADD : Token::SUB;
1792 }
1793
expression()1794 Expression* expression() const { return expression_; }
position()1795 virtual int position() const { return pos_; }
1796
MarkAsStatement()1797 virtual void MarkAsStatement() { is_prefix_ = true; }
1798
1799 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
IsMonomorphic()1800 virtual bool IsMonomorphic() { return is_monomorphic_; }
GetReceiverTypes()1801 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1802
1803 // Bailout support.
AssignmentId()1804 int AssignmentId() const { return assignment_id_; }
CountId()1805 int CountId() const { return count_id_; }
1806
1807 protected:
1808 template<class> friend class AstNodeFactory;
1809
CountOperation(Isolate * isolate,Token::Value op,bool is_prefix,Expression * expr,int pos)1810 CountOperation(Isolate* isolate,
1811 Token::Value op,
1812 bool is_prefix,
1813 Expression* expr,
1814 int pos)
1815 : Expression(isolate),
1816 op_(op),
1817 is_prefix_(is_prefix),
1818 expression_(expr),
1819 pos_(pos),
1820 assignment_id_(GetNextId(isolate)),
1821 count_id_(GetNextId(isolate)) {}
1822
1823 private:
1824 Token::Value op_;
1825 bool is_prefix_;
1826 bool is_monomorphic_;
1827 Expression* expression_;
1828 int pos_;
1829 int assignment_id_;
1830 int count_id_;
1831 SmallMapList receiver_types_;
1832 };
1833
1834
1835 class CompareOperation: public Expression {
1836 public:
DECLARE_NODE_TYPE(CompareOperation)1837 DECLARE_NODE_TYPE(CompareOperation)
1838
1839 Token::Value op() const { return op_; }
left()1840 Expression* left() const { return left_; }
right()1841 Expression* right() const { return right_; }
position()1842 virtual int position() const { return pos_; }
1843
1844 // Type feedback information.
1845 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
IsSmiCompare()1846 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
IsObjectCompare()1847 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1848
1849 // Match special cases.
1850 bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
1851 bool IsLiteralCompareUndefined(Expression** expr);
1852 bool IsLiteralCompareNull(Expression** expr);
1853
1854 protected:
1855 template<class> friend class AstNodeFactory;
1856
CompareOperation(Isolate * isolate,Token::Value op,Expression * left,Expression * right,int pos)1857 CompareOperation(Isolate* isolate,
1858 Token::Value op,
1859 Expression* left,
1860 Expression* right,
1861 int pos)
1862 : Expression(isolate),
1863 op_(op),
1864 left_(left),
1865 right_(right),
1866 pos_(pos),
1867 compare_type_(NONE) {
1868 ASSERT(Token::IsCompareOp(op));
1869 }
1870
1871 private:
1872 Token::Value op_;
1873 Expression* left_;
1874 Expression* right_;
1875 int pos_;
1876
1877 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
1878 CompareTypeFeedback compare_type_;
1879 };
1880
1881
1882 class Conditional: public Expression {
1883 public:
DECLARE_NODE_TYPE(Conditional)1884 DECLARE_NODE_TYPE(Conditional)
1885
1886 Expression* condition() const { return condition_; }
then_expression()1887 Expression* then_expression() const { return then_expression_; }
else_expression()1888 Expression* else_expression() const { return else_expression_; }
1889
then_expression_position()1890 int then_expression_position() const { return then_expression_position_; }
else_expression_position()1891 int else_expression_position() const { return else_expression_position_; }
1892
ThenId()1893 int ThenId() const { return then_id_; }
ElseId()1894 int ElseId() const { return else_id_; }
1895
1896 protected:
1897 template<class> friend class AstNodeFactory;
1898
Conditional(Isolate * isolate,Expression * condition,Expression * then_expression,Expression * else_expression,int then_expression_position,int else_expression_position)1899 Conditional(Isolate* isolate,
1900 Expression* condition,
1901 Expression* then_expression,
1902 Expression* else_expression,
1903 int then_expression_position,
1904 int else_expression_position)
1905 : Expression(isolate),
1906 condition_(condition),
1907 then_expression_(then_expression),
1908 else_expression_(else_expression),
1909 then_expression_position_(then_expression_position),
1910 else_expression_position_(else_expression_position),
1911 then_id_(GetNextId(isolate)),
1912 else_id_(GetNextId(isolate)) { }
1913
1914 private:
1915 Expression* condition_;
1916 Expression* then_expression_;
1917 Expression* else_expression_;
1918 int then_expression_position_;
1919 int else_expression_position_;
1920 int then_id_;
1921 int else_id_;
1922 };
1923
1924
1925 class Assignment: public Expression {
1926 public:
DECLARE_NODE_TYPE(Assignment)1927 DECLARE_NODE_TYPE(Assignment)
1928
1929 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1930
1931 Token::Value binary_op() const;
1932
op()1933 Token::Value op() const { return op_; }
target()1934 Expression* target() const { return target_; }
value()1935 Expression* value() const { return value_; }
position()1936 virtual int position() const { return pos_; }
binary_operation()1937 BinaryOperation* binary_operation() const { return binary_operation_; }
1938
1939 // This check relies on the definition order of token in token.h.
is_compound()1940 bool is_compound() const { return op() > Token::ASSIGN; }
1941
1942 // An initialization block is a series of statments of the form
1943 // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1944 // ending of these blocks to allow for optimizations of initialization
1945 // blocks.
starts_initialization_block()1946 bool starts_initialization_block() { return block_start_; }
ends_initialization_block()1947 bool ends_initialization_block() { return block_end_; }
mark_block_start()1948 void mark_block_start() { block_start_ = true; }
mark_block_end()1949 void mark_block_end() { block_end_ = true; }
1950
1951 // Type feedback information.
1952 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
IsMonomorphic()1953 virtual bool IsMonomorphic() { return is_monomorphic_; }
GetReceiverTypes()1954 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1955
1956 // Bailout support.
CompoundLoadId()1957 int CompoundLoadId() const { return compound_load_id_; }
AssignmentId()1958 int AssignmentId() const { return assignment_id_; }
1959
1960 protected:
1961 template<class> friend class AstNodeFactory;
1962
1963 Assignment(Isolate* isolate,
1964 Token::Value op,
1965 Expression* target,
1966 Expression* value,
1967 int pos);
1968
1969 template<class Visitor>
Init(Isolate * isolate,AstNodeFactory<Visitor> * factory)1970 void Init(Isolate* isolate, AstNodeFactory<Visitor>* factory) {
1971 ASSERT(Token::IsAssignmentOp(op_));
1972 if (is_compound()) {
1973 binary_operation_ =
1974 factory->NewBinaryOperation(binary_op(), target_, value_, pos_ + 1);
1975 compound_load_id_ = GetNextId(isolate);
1976 }
1977 }
1978
1979 private:
1980 Token::Value op_;
1981 Expression* target_;
1982 Expression* value_;
1983 int pos_;
1984 BinaryOperation* binary_operation_;
1985 int compound_load_id_;
1986 int assignment_id_;
1987
1988 bool block_start_;
1989 bool block_end_;
1990
1991 bool is_monomorphic_;
1992 SmallMapList receiver_types_;
1993 };
1994
1995
1996 class Throw: public Expression {
1997 public:
DECLARE_NODE_TYPE(Throw)1998 DECLARE_NODE_TYPE(Throw)
1999
2000 Expression* exception() const { return exception_; }
position()2001 virtual int position() const { return pos_; }
2002
2003 protected:
2004 template<class> friend class AstNodeFactory;
2005
Throw(Isolate * isolate,Expression * exception,int pos)2006 Throw(Isolate* isolate, Expression* exception, int pos)
2007 : Expression(isolate), exception_(exception), pos_(pos) {}
2008
2009 private:
2010 Expression* exception_;
2011 int pos_;
2012 };
2013
2014
2015 class FunctionLiteral: public Expression {
2016 public:
2017 enum Type {
2018 ANONYMOUS_EXPRESSION,
2019 NAMED_EXPRESSION,
2020 DECLARATION
2021 };
2022
2023 enum ParameterFlag {
2024 kNoDuplicateParameters = 0,
2025 kHasDuplicateParameters = 1
2026 };
2027
2028 enum IsFunctionFlag {
2029 kGlobalOrEval,
2030 kIsFunction
2031 };
2032
DECLARE_NODE_TYPE(FunctionLiteral)2033 DECLARE_NODE_TYPE(FunctionLiteral)
2034
2035 Handle<String> name() const { return name_; }
scope()2036 Scope* scope() const { return scope_; }
body()2037 ZoneList<Statement*>* body() const { return body_; }
set_function_token_position(int pos)2038 void set_function_token_position(int pos) { function_token_position_ = pos; }
function_token_position()2039 int function_token_position() const { return function_token_position_; }
2040 int start_position() const;
2041 int end_position() const;
SourceSize()2042 int SourceSize() const { return end_position() - start_position(); }
is_expression()2043 bool is_expression() const { return IsExpression::decode(bitfield_); }
is_anonymous()2044 bool is_anonymous() const { return IsAnonymous::decode(bitfield_); }
is_classic_mode()2045 bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; }
2046 LanguageMode language_mode() const;
2047
materialized_literal_count()2048 int materialized_literal_count() { return materialized_literal_count_; }
expected_property_count()2049 int expected_property_count() { return expected_property_count_; }
handler_count()2050 int handler_count() { return handler_count_; }
has_only_simple_this_property_assignments()2051 bool has_only_simple_this_property_assignments() {
2052 return HasOnlySimpleThisPropertyAssignments::decode(bitfield_);
2053 }
this_property_assignments()2054 Handle<FixedArray> this_property_assignments() {
2055 return this_property_assignments_;
2056 }
parameter_count()2057 int parameter_count() { return parameter_count_; }
2058
2059 bool AllowsLazyCompilation();
2060
debug_name()2061 Handle<String> debug_name() const {
2062 if (name_->length() > 0) return name_;
2063 return inferred_name();
2064 }
2065
inferred_name()2066 Handle<String> inferred_name() const { return inferred_name_; }
set_inferred_name(Handle<String> inferred_name)2067 void set_inferred_name(Handle<String> inferred_name) {
2068 inferred_name_ = inferred_name;
2069 }
2070
pretenure()2071 bool pretenure() { return Pretenure::decode(bitfield_); }
set_pretenure()2072 void set_pretenure() { bitfield_ |= Pretenure::encode(true); }
2073
has_duplicate_parameters()2074 bool has_duplicate_parameters() {
2075 return HasDuplicateParameters::decode(bitfield_);
2076 }
2077
is_function()2078 bool is_function() { return IsFunction::decode(bitfield_) == kIsFunction; }
2079
ast_node_count()2080 int ast_node_count() { return ast_properties_.node_count(); }
flags()2081 AstProperties::Flags* flags() { return ast_properties_.flags(); }
set_ast_properties(AstProperties * ast_properties)2082 void set_ast_properties(AstProperties* ast_properties) {
2083 ast_properties_ = *ast_properties;
2084 }
2085
2086 protected:
2087 template<class> friend class AstNodeFactory;
2088
FunctionLiteral(Isolate * isolate,Handle<String> name,Scope * scope,ZoneList<Statement * > * body,int materialized_literal_count,int expected_property_count,int handler_count,bool has_only_simple_this_property_assignments,Handle<FixedArray> this_property_assignments,int parameter_count,Type type,ParameterFlag has_duplicate_parameters,IsFunctionFlag is_function)2089 FunctionLiteral(Isolate* isolate,
2090 Handle<String> name,
2091 Scope* scope,
2092 ZoneList<Statement*>* body,
2093 int materialized_literal_count,
2094 int expected_property_count,
2095 int handler_count,
2096 bool has_only_simple_this_property_assignments,
2097 Handle<FixedArray> this_property_assignments,
2098 int parameter_count,
2099 Type type,
2100 ParameterFlag has_duplicate_parameters,
2101 IsFunctionFlag is_function)
2102 : Expression(isolate),
2103 name_(name),
2104 scope_(scope),
2105 body_(body),
2106 this_property_assignments_(this_property_assignments),
2107 inferred_name_(isolate->factory()->empty_string()),
2108 materialized_literal_count_(materialized_literal_count),
2109 expected_property_count_(expected_property_count),
2110 handler_count_(handler_count),
2111 parameter_count_(parameter_count),
2112 function_token_position_(RelocInfo::kNoPosition) {
2113 bitfield_ =
2114 HasOnlySimpleThisPropertyAssignments::encode(
2115 has_only_simple_this_property_assignments) |
2116 IsExpression::encode(type != DECLARATION) |
2117 IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) |
2118 Pretenure::encode(false) |
2119 HasDuplicateParameters::encode(has_duplicate_parameters) |
2120 IsFunction::encode(is_function);
2121 }
2122
2123 private:
2124 Handle<String> name_;
2125 Scope* scope_;
2126 ZoneList<Statement*>* body_;
2127 Handle<FixedArray> this_property_assignments_;
2128 Handle<String> inferred_name_;
2129 AstProperties ast_properties_;
2130
2131 int materialized_literal_count_;
2132 int expected_property_count_;
2133 int handler_count_;
2134 int parameter_count_;
2135 int function_token_position_;
2136
2137 unsigned bitfield_;
2138 class HasOnlySimpleThisPropertyAssignments: public BitField<bool, 0, 1> {};
2139 class IsExpression: public BitField<bool, 1, 1> {};
2140 class IsAnonymous: public BitField<bool, 2, 1> {};
2141 class Pretenure: public BitField<bool, 3, 1> {};
2142 class HasDuplicateParameters: public BitField<ParameterFlag, 4, 1> {};
2143 class IsFunction: public BitField<IsFunctionFlag, 5, 1> {};
2144 };
2145
2146
2147 class SharedFunctionInfoLiteral: public Expression {
2148 public:
DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)2149 DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
2150
2151 Handle<SharedFunctionInfo> shared_function_info() const {
2152 return shared_function_info_;
2153 }
2154
2155 protected:
2156 template<class> friend class AstNodeFactory;
2157
SharedFunctionInfoLiteral(Isolate * isolate,Handle<SharedFunctionInfo> shared_function_info)2158 SharedFunctionInfoLiteral(
2159 Isolate* isolate,
2160 Handle<SharedFunctionInfo> shared_function_info)
2161 : Expression(isolate),
2162 shared_function_info_(shared_function_info) { }
2163
2164 private:
2165 Handle<SharedFunctionInfo> shared_function_info_;
2166 };
2167
2168
2169 class ThisFunction: public Expression {
2170 public:
2171 DECLARE_NODE_TYPE(ThisFunction)
2172
2173 protected:
2174 template<class> friend class AstNodeFactory;
2175
ThisFunction(Isolate * isolate)2176 explicit ThisFunction(Isolate* isolate): Expression(isolate) {}
2177 };
2178
2179 #undef DECLARE_NODE_TYPE
2180
2181
2182 // ----------------------------------------------------------------------------
2183 // Regular expressions
2184
2185
2186 class RegExpVisitor BASE_EMBEDDED {
2187 public:
~RegExpVisitor()2188 virtual ~RegExpVisitor() { }
2189 #define MAKE_CASE(Name) \
2190 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
2191 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
2192 #undef MAKE_CASE
2193 };
2194
2195
2196 class RegExpTree: public ZoneObject {
2197 public:
2198 static const int kInfinity = kMaxInt;
~RegExpTree()2199 virtual ~RegExpTree() { }
2200 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
2201 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2202 RegExpNode* on_success) = 0;
IsTextElement()2203 virtual bool IsTextElement() { return false; }
IsAnchoredAtStart()2204 virtual bool IsAnchoredAtStart() { return false; }
IsAnchoredAtEnd()2205 virtual bool IsAnchoredAtEnd() { return false; }
2206 virtual int min_match() = 0;
2207 virtual int max_match() = 0;
2208 // Returns the interval of registers used for captures within this
2209 // expression.
CaptureRegisters()2210 virtual Interval CaptureRegisters() { return Interval::Empty(); }
2211 virtual void AppendToText(RegExpText* text);
2212 SmartArrayPointer<const char> ToString();
2213 #define MAKE_ASTYPE(Name) \
2214 virtual RegExp##Name* As##Name(); \
2215 virtual bool Is##Name();
2216 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
2217 #undef MAKE_ASTYPE
2218 };
2219
2220
2221 class RegExpDisjunction: public RegExpTree {
2222 public:
2223 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
2224 virtual void* Accept(RegExpVisitor* visitor, void* data);
2225 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2226 RegExpNode* on_success);
2227 virtual RegExpDisjunction* AsDisjunction();
2228 virtual Interval CaptureRegisters();
2229 virtual bool IsDisjunction();
2230 virtual bool IsAnchoredAtStart();
2231 virtual bool IsAnchoredAtEnd();
min_match()2232 virtual int min_match() { return min_match_; }
max_match()2233 virtual int max_match() { return max_match_; }
alternatives()2234 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
2235 private:
2236 ZoneList<RegExpTree*>* alternatives_;
2237 int min_match_;
2238 int max_match_;
2239 };
2240
2241
2242 class RegExpAlternative: public RegExpTree {
2243 public:
2244 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
2245 virtual void* Accept(RegExpVisitor* visitor, void* data);
2246 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2247 RegExpNode* on_success);
2248 virtual RegExpAlternative* AsAlternative();
2249 virtual Interval CaptureRegisters();
2250 virtual bool IsAlternative();
2251 virtual bool IsAnchoredAtStart();
2252 virtual bool IsAnchoredAtEnd();
min_match()2253 virtual int min_match() { return min_match_; }
max_match()2254 virtual int max_match() { return max_match_; }
nodes()2255 ZoneList<RegExpTree*>* nodes() { return nodes_; }
2256 private:
2257 ZoneList<RegExpTree*>* nodes_;
2258 int min_match_;
2259 int max_match_;
2260 };
2261
2262
2263 class RegExpAssertion: public RegExpTree {
2264 public:
2265 enum Type {
2266 START_OF_LINE,
2267 START_OF_INPUT,
2268 END_OF_LINE,
2269 END_OF_INPUT,
2270 BOUNDARY,
2271 NON_BOUNDARY
2272 };
RegExpAssertion(Type type)2273 explicit RegExpAssertion(Type type) : type_(type) { }
2274 virtual void* Accept(RegExpVisitor* visitor, void* data);
2275 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2276 RegExpNode* on_success);
2277 virtual RegExpAssertion* AsAssertion();
2278 virtual bool IsAssertion();
2279 virtual bool IsAnchoredAtStart();
2280 virtual bool IsAnchoredAtEnd();
min_match()2281 virtual int min_match() { return 0; }
max_match()2282 virtual int max_match() { return 0; }
type()2283 Type type() { return type_; }
2284 private:
2285 Type type_;
2286 };
2287
2288
2289 class CharacterSet BASE_EMBEDDED {
2290 public:
CharacterSet(uc16 standard_set_type)2291 explicit CharacterSet(uc16 standard_set_type)
2292 : ranges_(NULL),
2293 standard_set_type_(standard_set_type) {}
CharacterSet(ZoneList<CharacterRange> * ranges)2294 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
2295 : ranges_(ranges),
2296 standard_set_type_(0) {}
2297 ZoneList<CharacterRange>* ranges();
standard_set_type()2298 uc16 standard_set_type() { return standard_set_type_; }
set_standard_set_type(uc16 special_set_type)2299 void set_standard_set_type(uc16 special_set_type) {
2300 standard_set_type_ = special_set_type;
2301 }
is_standard()2302 bool is_standard() { return standard_set_type_ != 0; }
2303 void Canonicalize();
2304 private:
2305 ZoneList<CharacterRange>* ranges_;
2306 // If non-zero, the value represents a standard set (e.g., all whitespace
2307 // characters) without having to expand the ranges.
2308 uc16 standard_set_type_;
2309 };
2310
2311
2312 class RegExpCharacterClass: public RegExpTree {
2313 public:
RegExpCharacterClass(ZoneList<CharacterRange> * ranges,bool is_negated)2314 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
2315 : set_(ranges),
2316 is_negated_(is_negated) { }
RegExpCharacterClass(uc16 type)2317 explicit RegExpCharacterClass(uc16 type)
2318 : set_(type),
2319 is_negated_(false) { }
2320 virtual void* Accept(RegExpVisitor* visitor, void* data);
2321 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2322 RegExpNode* on_success);
2323 virtual RegExpCharacterClass* AsCharacterClass();
2324 virtual bool IsCharacterClass();
IsTextElement()2325 virtual bool IsTextElement() { return true; }
min_match()2326 virtual int min_match() { return 1; }
max_match()2327 virtual int max_match() { return 1; }
2328 virtual void AppendToText(RegExpText* text);
character_set()2329 CharacterSet character_set() { return set_; }
2330 // TODO(lrn): Remove need for complex version if is_standard that
2331 // recognizes a mangled standard set and just do { return set_.is_special(); }
2332 bool is_standard();
2333 // Returns a value representing the standard character set if is_standard()
2334 // returns true.
2335 // Currently used values are:
2336 // s : unicode whitespace
2337 // S : unicode non-whitespace
2338 // w : ASCII word character (digit, letter, underscore)
2339 // W : non-ASCII word character
2340 // d : ASCII digit
2341 // D : non-ASCII digit
2342 // . : non-unicode non-newline
2343 // * : All characters
standard_type()2344 uc16 standard_type() { return set_.standard_set_type(); }
ranges()2345 ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
is_negated()2346 bool is_negated() { return is_negated_; }
2347
2348 private:
2349 CharacterSet set_;
2350 bool is_negated_;
2351 };
2352
2353
2354 class RegExpAtom: public RegExpTree {
2355 public:
RegExpAtom(Vector<const uc16> data)2356 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
2357 virtual void* Accept(RegExpVisitor* visitor, void* data);
2358 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2359 RegExpNode* on_success);
2360 virtual RegExpAtom* AsAtom();
2361 virtual bool IsAtom();
IsTextElement()2362 virtual bool IsTextElement() { return true; }
min_match()2363 virtual int min_match() { return data_.length(); }
max_match()2364 virtual int max_match() { return data_.length(); }
2365 virtual void AppendToText(RegExpText* text);
data()2366 Vector<const uc16> data() { return data_; }
length()2367 int length() { return data_.length(); }
2368 private:
2369 Vector<const uc16> data_;
2370 };
2371
2372
2373 class RegExpText: public RegExpTree {
2374 public:
RegExpText()2375 RegExpText() : elements_(2), length_(0) {}
2376 virtual void* Accept(RegExpVisitor* visitor, void* data);
2377 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2378 RegExpNode* on_success);
2379 virtual RegExpText* AsText();
2380 virtual bool IsText();
IsTextElement()2381 virtual bool IsTextElement() { return true; }
min_match()2382 virtual int min_match() { return length_; }
max_match()2383 virtual int max_match() { return length_; }
2384 virtual void AppendToText(RegExpText* text);
AddElement(TextElement elm)2385 void AddElement(TextElement elm) {
2386 elements_.Add(elm);
2387 length_ += elm.length();
2388 }
elements()2389 ZoneList<TextElement>* elements() { return &elements_; }
2390 private:
2391 ZoneList<TextElement> elements_;
2392 int length_;
2393 };
2394
2395
2396 class RegExpQuantifier: public RegExpTree {
2397 public:
2398 enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
RegExpQuantifier(int min,int max,Type type,RegExpTree * body)2399 RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
2400 : body_(body),
2401 min_(min),
2402 max_(max),
2403 min_match_(min * body->min_match()),
2404 type_(type) {
2405 if (max > 0 && body->max_match() > kInfinity / max) {
2406 max_match_ = kInfinity;
2407 } else {
2408 max_match_ = max * body->max_match();
2409 }
2410 }
2411 virtual void* Accept(RegExpVisitor* visitor, void* data);
2412 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2413 RegExpNode* on_success);
2414 static RegExpNode* ToNode(int min,
2415 int max,
2416 bool is_greedy,
2417 RegExpTree* body,
2418 RegExpCompiler* compiler,
2419 RegExpNode* on_success,
2420 bool not_at_start = false);
2421 virtual RegExpQuantifier* AsQuantifier();
2422 virtual Interval CaptureRegisters();
2423 virtual bool IsQuantifier();
min_match()2424 virtual int min_match() { return min_match_; }
max_match()2425 virtual int max_match() { return max_match_; }
min()2426 int min() { return min_; }
max()2427 int max() { return max_; }
is_possessive()2428 bool is_possessive() { return type_ == POSSESSIVE; }
is_non_greedy()2429 bool is_non_greedy() { return type_ == NON_GREEDY; }
is_greedy()2430 bool is_greedy() { return type_ == GREEDY; }
body()2431 RegExpTree* body() { return body_; }
2432
2433 private:
2434 RegExpTree* body_;
2435 int min_;
2436 int max_;
2437 int min_match_;
2438 int max_match_;
2439 Type type_;
2440 };
2441
2442
2443 class RegExpCapture: public RegExpTree {
2444 public:
RegExpCapture(RegExpTree * body,int index)2445 explicit RegExpCapture(RegExpTree* body, int index)
2446 : body_(body), index_(index) { }
2447 virtual void* Accept(RegExpVisitor* visitor, void* data);
2448 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2449 RegExpNode* on_success);
2450 static RegExpNode* ToNode(RegExpTree* body,
2451 int index,
2452 RegExpCompiler* compiler,
2453 RegExpNode* on_success);
2454 virtual RegExpCapture* AsCapture();
2455 virtual bool IsAnchoredAtStart();
2456 virtual bool IsAnchoredAtEnd();
2457 virtual Interval CaptureRegisters();
2458 virtual bool IsCapture();
min_match()2459 virtual int min_match() { return body_->min_match(); }
max_match()2460 virtual int max_match() { return body_->max_match(); }
body()2461 RegExpTree* body() { return body_; }
index()2462 int index() { return index_; }
StartRegister(int index)2463 static int StartRegister(int index) { return index * 2; }
EndRegister(int index)2464 static int EndRegister(int index) { return index * 2 + 1; }
2465
2466 private:
2467 RegExpTree* body_;
2468 int index_;
2469 };
2470
2471
2472 class RegExpLookahead: public RegExpTree {
2473 public:
RegExpLookahead(RegExpTree * body,bool is_positive,int capture_count,int capture_from)2474 RegExpLookahead(RegExpTree* body,
2475 bool is_positive,
2476 int capture_count,
2477 int capture_from)
2478 : body_(body),
2479 is_positive_(is_positive),
2480 capture_count_(capture_count),
2481 capture_from_(capture_from) { }
2482
2483 virtual void* Accept(RegExpVisitor* visitor, void* data);
2484 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2485 RegExpNode* on_success);
2486 virtual RegExpLookahead* AsLookahead();
2487 virtual Interval CaptureRegisters();
2488 virtual bool IsLookahead();
2489 virtual bool IsAnchoredAtStart();
min_match()2490 virtual int min_match() { return 0; }
max_match()2491 virtual int max_match() { return 0; }
body()2492 RegExpTree* body() { return body_; }
is_positive()2493 bool is_positive() { return is_positive_; }
capture_count()2494 int capture_count() { return capture_count_; }
capture_from()2495 int capture_from() { return capture_from_; }
2496
2497 private:
2498 RegExpTree* body_;
2499 bool is_positive_;
2500 int capture_count_;
2501 int capture_from_;
2502 };
2503
2504
2505 class RegExpBackReference: public RegExpTree {
2506 public:
RegExpBackReference(RegExpCapture * capture)2507 explicit RegExpBackReference(RegExpCapture* capture)
2508 : capture_(capture) { }
2509 virtual void* Accept(RegExpVisitor* visitor, void* data);
2510 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2511 RegExpNode* on_success);
2512 virtual RegExpBackReference* AsBackReference();
2513 virtual bool IsBackReference();
min_match()2514 virtual int min_match() { return 0; }
max_match()2515 virtual int max_match() { return capture_->max_match(); }
index()2516 int index() { return capture_->index(); }
capture()2517 RegExpCapture* capture() { return capture_; }
2518 private:
2519 RegExpCapture* capture_;
2520 };
2521
2522
2523 class RegExpEmpty: public RegExpTree {
2524 public:
RegExpEmpty()2525 RegExpEmpty() { }
2526 virtual void* Accept(RegExpVisitor* visitor, void* data);
2527 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2528 RegExpNode* on_success);
2529 virtual RegExpEmpty* AsEmpty();
2530 virtual bool IsEmpty();
min_match()2531 virtual int min_match() { return 0; }
max_match()2532 virtual int max_match() { return 0; }
GetInstance()2533 static RegExpEmpty* GetInstance() {
2534 static RegExpEmpty* instance = ::new RegExpEmpty();
2535 return instance;
2536 }
2537 };
2538
2539
2540 // ----------------------------------------------------------------------------
2541 // Out-of-line inline constructors (to side-step cyclic dependencies).
2542
ModuleVariable(VariableProxy * proxy)2543 inline ModuleVariable::ModuleVariable(VariableProxy* proxy)
2544 : Module(proxy->interface()),
2545 proxy_(proxy) {
2546 }
2547
2548
2549 // ----------------------------------------------------------------------------
2550 // Basic visitor
2551 // - leaf node visitors are abstract.
2552
2553 class AstVisitor BASE_EMBEDDED {
2554 public:
AstVisitor()2555 AstVisitor() : isolate_(Isolate::Current()), stack_overflow_(false) { }
~AstVisitor()2556 virtual ~AstVisitor() { }
2557
2558 // Stack overflow check and dynamic dispatch.
Visit(AstNode * node)2559 void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
2560
2561 // Iteration left-to-right.
2562 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
2563 virtual void VisitStatements(ZoneList<Statement*>* statements);
2564 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
2565
2566 // Stack overflow tracking support.
HasStackOverflow()2567 bool HasStackOverflow() const { return stack_overflow_; }
2568 bool CheckStackOverflow();
2569
2570 // If a stack-overflow exception is encountered when visiting a
2571 // node, calling SetStackOverflow will make sure that the visitor
2572 // bails out without visiting more nodes.
SetStackOverflow()2573 void SetStackOverflow() { stack_overflow_ = true; }
ClearStackOverflow()2574 void ClearStackOverflow() { stack_overflow_ = false; }
2575
2576 // Individual AST nodes.
2577 #define DEF_VISIT(type) \
2578 virtual void Visit##type(type* node) = 0;
AST_NODE_LIST(DEF_VISIT)2579 AST_NODE_LIST(DEF_VISIT)
2580 #undef DEF_VISIT
2581
2582 protected:
2583 Isolate* isolate() { return isolate_; }
2584
2585 private:
2586 Isolate* isolate_;
2587 bool stack_overflow_;
2588 };
2589
2590
2591 // ----------------------------------------------------------------------------
2592 // Construction time visitor.
2593
2594 class AstConstructionVisitor BASE_EMBEDDED {
2595 public:
AstConstructionVisitor()2596 AstConstructionVisitor() { }
2597
ast_properties()2598 AstProperties* ast_properties() { return &properties_; }
2599
2600 private:
2601 template<class> friend class AstNodeFactory;
2602
2603 // Node visitors.
2604 #define DEF_VISIT(type) \
2605 void Visit##type(type* node);
AST_NODE_LIST(DEF_VISIT)2606 AST_NODE_LIST(DEF_VISIT)
2607 #undef DEF_VISIT
2608
2609 void increase_node_count() { properties_.add_node_count(1); }
add_flag(AstPropertiesFlag flag)2610 void add_flag(AstPropertiesFlag flag) { properties_.flags()->Add(flag); }
2611
2612 AstProperties properties_;
2613 };
2614
2615
2616 class AstNullVisitor BASE_EMBEDDED {
2617 public:
2618 // Node visitors.
2619 #define DEF_VISIT(type) \
2620 void Visit##type(type* node) {}
2621 AST_NODE_LIST(DEF_VISIT)
2622 #undef DEF_VISIT
2623 };
2624
2625
2626
2627 // ----------------------------------------------------------------------------
2628 // AstNode factory
2629
2630 template<class Visitor>
2631 class AstNodeFactory BASE_EMBEDDED {
2632 public:
AstNodeFactory(Isolate * isolate)2633 explicit AstNodeFactory(Isolate* isolate)
2634 : isolate_(isolate),
2635 zone_(isolate_->zone()) { }
2636
visitor()2637 Visitor* visitor() { return &visitor_; }
2638
2639 #define VISIT_AND_RETURN(NodeType, node) \
2640 visitor_.Visit##NodeType((node)); \
2641 return node;
2642
NewVariableDeclaration(VariableProxy * proxy,VariableMode mode,Scope * scope)2643 VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
2644 VariableMode mode,
2645 Scope* scope) {
2646 VariableDeclaration* decl =
2647 new(zone_) VariableDeclaration(proxy, mode, scope);
2648 VISIT_AND_RETURN(VariableDeclaration, decl)
2649 }
2650
NewFunctionDeclaration(VariableProxy * proxy,VariableMode mode,FunctionLiteral * fun,Scope * scope)2651 FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy,
2652 VariableMode mode,
2653 FunctionLiteral* fun,
2654 Scope* scope) {
2655 FunctionDeclaration* decl =
2656 new(zone_) FunctionDeclaration(proxy, mode, fun, scope);
2657 VISIT_AND_RETURN(FunctionDeclaration, decl)
2658 }
2659
NewModuleDeclaration(VariableProxy * proxy,Module * module,Scope * scope)2660 ModuleDeclaration* NewModuleDeclaration(VariableProxy* proxy,
2661 Module* module,
2662 Scope* scope) {
2663 ModuleDeclaration* decl =
2664 new(zone_) ModuleDeclaration(proxy, module, scope);
2665 VISIT_AND_RETURN(ModuleDeclaration, decl)
2666 }
2667
NewImportDeclaration(VariableProxy * proxy,Module * module,Scope * scope)2668 ImportDeclaration* NewImportDeclaration(VariableProxy* proxy,
2669 Module* module,
2670 Scope* scope) {
2671 ImportDeclaration* decl =
2672 new(zone_) ImportDeclaration(proxy, module, scope);
2673 VISIT_AND_RETURN(ImportDeclaration, decl)
2674 }
2675
NewExportDeclaration(VariableProxy * proxy,Scope * scope)2676 ExportDeclaration* NewExportDeclaration(VariableProxy* proxy,
2677 Scope* scope) {
2678 ExportDeclaration* decl =
2679 new(zone_) ExportDeclaration(proxy, scope);
2680 VISIT_AND_RETURN(ExportDeclaration, decl)
2681 }
2682
NewModuleLiteral(Block * body,Interface * interface)2683 ModuleLiteral* NewModuleLiteral(Block* body, Interface* interface) {
2684 ModuleLiteral* module = new(zone_) ModuleLiteral(body, interface);
2685 VISIT_AND_RETURN(ModuleLiteral, module)
2686 }
2687
NewModuleVariable(VariableProxy * proxy)2688 ModuleVariable* NewModuleVariable(VariableProxy* proxy) {
2689 ModuleVariable* module = new(zone_) ModuleVariable(proxy);
2690 VISIT_AND_RETURN(ModuleVariable, module)
2691 }
2692
NewModulePath(Module * origin,Handle<String> name)2693 ModulePath* NewModulePath(Module* origin, Handle<String> name) {
2694 ModulePath* module = new(zone_) ModulePath(origin, name);
2695 VISIT_AND_RETURN(ModulePath, module)
2696 }
2697
NewModuleUrl(Handle<String> url)2698 ModuleUrl* NewModuleUrl(Handle<String> url) {
2699 ModuleUrl* module = new(zone_) ModuleUrl(url);
2700 VISIT_AND_RETURN(ModuleUrl, module)
2701 }
2702
NewBlock(ZoneStringList * labels,int capacity,bool is_initializer_block)2703 Block* NewBlock(ZoneStringList* labels,
2704 int capacity,
2705 bool is_initializer_block) {
2706 Block* block = new(zone_) Block(
2707 isolate_, labels, capacity, is_initializer_block);
2708 VISIT_AND_RETURN(Block, block)
2709 }
2710
2711 #define STATEMENT_WITH_LABELS(NodeType) \
2712 NodeType* New##NodeType(ZoneStringList* labels) { \
2713 NodeType* stmt = new(zone_) NodeType(isolate_, labels); \
2714 VISIT_AND_RETURN(NodeType, stmt); \
2715 }
2716 STATEMENT_WITH_LABELS(DoWhileStatement)
STATEMENT_WITH_LABELS(WhileStatement)2717 STATEMENT_WITH_LABELS(WhileStatement)
2718 STATEMENT_WITH_LABELS(ForStatement)
2719 STATEMENT_WITH_LABELS(ForInStatement)
2720 STATEMENT_WITH_LABELS(SwitchStatement)
2721 #undef STATEMENT_WITH_LABELS
2722
2723 ExpressionStatement* NewExpressionStatement(Expression* expression) {
2724 ExpressionStatement* stmt = new(zone_) ExpressionStatement(expression);
2725 VISIT_AND_RETURN(ExpressionStatement, stmt)
2726 }
2727
NewContinueStatement(IterationStatement * target)2728 ContinueStatement* NewContinueStatement(IterationStatement* target) {
2729 ContinueStatement* stmt = new(zone_) ContinueStatement(target);
2730 VISIT_AND_RETURN(ContinueStatement, stmt)
2731 }
2732
NewBreakStatement(BreakableStatement * target)2733 BreakStatement* NewBreakStatement(BreakableStatement* target) {
2734 BreakStatement* stmt = new(zone_) BreakStatement(target);
2735 VISIT_AND_RETURN(BreakStatement, stmt)
2736 }
2737
NewReturnStatement(Expression * expression)2738 ReturnStatement* NewReturnStatement(Expression* expression) {
2739 ReturnStatement* stmt = new(zone_) ReturnStatement(expression);
2740 VISIT_AND_RETURN(ReturnStatement, stmt)
2741 }
2742
NewWithStatement(Expression * expression,Statement * statement)2743 WithStatement* NewWithStatement(Expression* expression,
2744 Statement* statement) {
2745 WithStatement* stmt = new(zone_) WithStatement(expression, statement);
2746 VISIT_AND_RETURN(WithStatement, stmt)
2747 }
2748
NewIfStatement(Expression * condition,Statement * then_statement,Statement * else_statement)2749 IfStatement* NewIfStatement(Expression* condition,
2750 Statement* then_statement,
2751 Statement* else_statement) {
2752 IfStatement* stmt = new(zone_) IfStatement(
2753 isolate_, condition, then_statement, else_statement);
2754 VISIT_AND_RETURN(IfStatement, stmt)
2755 }
2756
NewTryCatchStatement(int index,Block * try_block,Scope * scope,Variable * variable,Block * catch_block)2757 TryCatchStatement* NewTryCatchStatement(int index,
2758 Block* try_block,
2759 Scope* scope,
2760 Variable* variable,
2761 Block* catch_block) {
2762 TryCatchStatement* stmt = new(zone_) TryCatchStatement(
2763 index, try_block, scope, variable, catch_block);
2764 VISIT_AND_RETURN(TryCatchStatement, stmt)
2765 }
2766
NewTryFinallyStatement(int index,Block * try_block,Block * finally_block)2767 TryFinallyStatement* NewTryFinallyStatement(int index,
2768 Block* try_block,
2769 Block* finally_block) {
2770 TryFinallyStatement* stmt =
2771 new(zone_) TryFinallyStatement(index, try_block, finally_block);
2772 VISIT_AND_RETURN(TryFinallyStatement, stmt)
2773 }
2774
NewDebuggerStatement()2775 DebuggerStatement* NewDebuggerStatement() {
2776 DebuggerStatement* stmt = new(zone_) DebuggerStatement();
2777 VISIT_AND_RETURN(DebuggerStatement, stmt)
2778 }
2779
NewEmptyStatement()2780 EmptyStatement* NewEmptyStatement() {
2781 return new(zone_) EmptyStatement();
2782 }
2783
NewLiteral(Handle<Object> handle)2784 Literal* NewLiteral(Handle<Object> handle) {
2785 Literal* lit = new(zone_) Literal(isolate_, handle);
2786 VISIT_AND_RETURN(Literal, lit)
2787 }
2788
NewNumberLiteral(double number)2789 Literal* NewNumberLiteral(double number) {
2790 return NewLiteral(isolate_->factory()->NewNumber(number, TENURED));
2791 }
2792
NewObjectLiteral(Handle<FixedArray> constant_properties,ZoneList<ObjectLiteral::Property * > * properties,int literal_index,bool is_simple,bool fast_elements,int depth,bool has_function)2793 ObjectLiteral* NewObjectLiteral(
2794 Handle<FixedArray> constant_properties,
2795 ZoneList<ObjectLiteral::Property*>* properties,
2796 int literal_index,
2797 bool is_simple,
2798 bool fast_elements,
2799 int depth,
2800 bool has_function) {
2801 ObjectLiteral* lit = new(zone_) ObjectLiteral(
2802 isolate_, constant_properties, properties, literal_index,
2803 is_simple, fast_elements, depth, has_function);
2804 VISIT_AND_RETURN(ObjectLiteral, lit)
2805 }
2806
NewObjectLiteralProperty(bool is_getter,FunctionLiteral * value)2807 ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter,
2808 FunctionLiteral* value) {
2809 ObjectLiteral::Property* prop =
2810 new(zone_) ObjectLiteral::Property(is_getter, value);
2811 prop->set_key(NewLiteral(value->name()));
2812 return prop; // Not an AST node, will not be visited.
2813 }
2814
NewRegExpLiteral(Handle<String> pattern,Handle<String> flags,int literal_index)2815 RegExpLiteral* NewRegExpLiteral(Handle<String> pattern,
2816 Handle<String> flags,
2817 int literal_index) {
2818 RegExpLiteral* lit =
2819 new(zone_) RegExpLiteral(isolate_, pattern, flags, literal_index);
2820 VISIT_AND_RETURN(RegExpLiteral, lit);
2821 }
2822
NewArrayLiteral(Handle<FixedArray> constant_elements,ZoneList<Expression * > * values,int literal_index,bool is_simple,int depth)2823 ArrayLiteral* NewArrayLiteral(Handle<FixedArray> constant_elements,
2824 ZoneList<Expression*>* values,
2825 int literal_index,
2826 bool is_simple,
2827 int depth) {
2828 ArrayLiteral* lit = new(zone_) ArrayLiteral(
2829 isolate_, constant_elements, values, literal_index, is_simple, depth);
2830 VISIT_AND_RETURN(ArrayLiteral, lit)
2831 }
2832
NewVariableProxy(Variable * var)2833 VariableProxy* NewVariableProxy(Variable* var) {
2834 VariableProxy* proxy = new(zone_) VariableProxy(isolate_, var);
2835 VISIT_AND_RETURN(VariableProxy, proxy)
2836 }
2837
2838 VariableProxy* NewVariableProxy(Handle<String> name,
2839 bool is_this,
2840 int position = RelocInfo::kNoPosition,
2841 Interface* interface =
2842 Interface::NewValue()) {
2843 VariableProxy* proxy =
2844 new(zone_) VariableProxy(isolate_, name, is_this, position, interface);
2845 VISIT_AND_RETURN(VariableProxy, proxy)
2846 }
2847
NewProperty(Expression * obj,Expression * key,int pos)2848 Property* NewProperty(Expression* obj, Expression* key, int pos) {
2849 Property* prop = new(zone_) Property(isolate_, obj, key, pos);
2850 VISIT_AND_RETURN(Property, prop)
2851 }
2852
NewCall(Expression * expression,ZoneList<Expression * > * arguments,int pos)2853 Call* NewCall(Expression* expression,
2854 ZoneList<Expression*>* arguments,
2855 int pos) {
2856 Call* call = new(zone_) Call(isolate_, expression, arguments, pos);
2857 VISIT_AND_RETURN(Call, call)
2858 }
2859
NewCallNew(Expression * expression,ZoneList<Expression * > * arguments,int pos)2860 CallNew* NewCallNew(Expression* expression,
2861 ZoneList<Expression*>* arguments,
2862 int pos) {
2863 CallNew* call = new(zone_) CallNew(isolate_, expression, arguments, pos);
2864 VISIT_AND_RETURN(CallNew, call)
2865 }
2866
NewCallRuntime(Handle<String> name,const Runtime::Function * function,ZoneList<Expression * > * arguments)2867 CallRuntime* NewCallRuntime(Handle<String> name,
2868 const Runtime::Function* function,
2869 ZoneList<Expression*>* arguments) {
2870 CallRuntime* call =
2871 new(zone_) CallRuntime(isolate_, name, function, arguments);
2872 VISIT_AND_RETURN(CallRuntime, call)
2873 }
2874
NewUnaryOperation(Token::Value op,Expression * expression,int pos)2875 UnaryOperation* NewUnaryOperation(Token::Value op,
2876 Expression* expression,
2877 int pos) {
2878 UnaryOperation* node =
2879 new(zone_) UnaryOperation(isolate_, op, expression, pos);
2880 VISIT_AND_RETURN(UnaryOperation, node)
2881 }
2882
NewBinaryOperation(Token::Value op,Expression * left,Expression * right,int pos)2883 BinaryOperation* NewBinaryOperation(Token::Value op,
2884 Expression* left,
2885 Expression* right,
2886 int pos) {
2887 BinaryOperation* node =
2888 new(zone_) BinaryOperation(isolate_, op, left, right, pos);
2889 VISIT_AND_RETURN(BinaryOperation, node)
2890 }
2891
NewCountOperation(Token::Value op,bool is_prefix,Expression * expr,int pos)2892 CountOperation* NewCountOperation(Token::Value op,
2893 bool is_prefix,
2894 Expression* expr,
2895 int pos) {
2896 CountOperation* node =
2897 new(zone_) CountOperation(isolate_, op, is_prefix, expr, pos);
2898 VISIT_AND_RETURN(CountOperation, node)
2899 }
2900
NewCompareOperation(Token::Value op,Expression * left,Expression * right,int pos)2901 CompareOperation* NewCompareOperation(Token::Value op,
2902 Expression* left,
2903 Expression* right,
2904 int pos) {
2905 CompareOperation* node =
2906 new(zone_) CompareOperation(isolate_, op, left, right, pos);
2907 VISIT_AND_RETURN(CompareOperation, node)
2908 }
2909
NewConditional(Expression * condition,Expression * then_expression,Expression * else_expression,int then_expression_position,int else_expression_position)2910 Conditional* NewConditional(Expression* condition,
2911 Expression* then_expression,
2912 Expression* else_expression,
2913 int then_expression_position,
2914 int else_expression_position) {
2915 Conditional* cond = new(zone_) Conditional(
2916 isolate_, condition, then_expression, else_expression,
2917 then_expression_position, else_expression_position);
2918 VISIT_AND_RETURN(Conditional, cond)
2919 }
2920
NewAssignment(Token::Value op,Expression * target,Expression * value,int pos)2921 Assignment* NewAssignment(Token::Value op,
2922 Expression* target,
2923 Expression* value,
2924 int pos) {
2925 Assignment* assign =
2926 new(zone_) Assignment(isolate_, op, target, value, pos);
2927 assign->Init(isolate_, this);
2928 VISIT_AND_RETURN(Assignment, assign)
2929 }
2930
NewThrow(Expression * exception,int pos)2931 Throw* NewThrow(Expression* exception, int pos) {
2932 Throw* t = new(zone_) Throw(isolate_, exception, pos);
2933 VISIT_AND_RETURN(Throw, t)
2934 }
2935
NewFunctionLiteral(Handle<String> name,Scope * scope,ZoneList<Statement * > * body,int materialized_literal_count,int expected_property_count,int handler_count,bool has_only_simple_this_property_assignments,Handle<FixedArray> this_property_assignments,int parameter_count,FunctionLiteral::ParameterFlag has_duplicate_parameters,FunctionLiteral::Type type,FunctionLiteral::IsFunctionFlag is_function)2936 FunctionLiteral* NewFunctionLiteral(
2937 Handle<String> name,
2938 Scope* scope,
2939 ZoneList<Statement*>* body,
2940 int materialized_literal_count,
2941 int expected_property_count,
2942 int handler_count,
2943 bool has_only_simple_this_property_assignments,
2944 Handle<FixedArray> this_property_assignments,
2945 int parameter_count,
2946 FunctionLiteral::ParameterFlag has_duplicate_parameters,
2947 FunctionLiteral::Type type,
2948 FunctionLiteral::IsFunctionFlag is_function) {
2949 FunctionLiteral* lit = new(zone_) FunctionLiteral(
2950 isolate_, name, scope, body,
2951 materialized_literal_count, expected_property_count, handler_count,
2952 has_only_simple_this_property_assignments, this_property_assignments,
2953 parameter_count, type, has_duplicate_parameters, is_function);
2954 // Top-level literal doesn't count for the AST's properties.
2955 if (is_function == FunctionLiteral::kIsFunction) {
2956 visitor_.VisitFunctionLiteral(lit);
2957 }
2958 return lit;
2959 }
2960
NewSharedFunctionInfoLiteral(Handle<SharedFunctionInfo> shared_function_info)2961 SharedFunctionInfoLiteral* NewSharedFunctionInfoLiteral(
2962 Handle<SharedFunctionInfo> shared_function_info) {
2963 SharedFunctionInfoLiteral* lit =
2964 new(zone_) SharedFunctionInfoLiteral(isolate_, shared_function_info);
2965 VISIT_AND_RETURN(SharedFunctionInfoLiteral, lit)
2966 }
2967
NewThisFunction()2968 ThisFunction* NewThisFunction() {
2969 ThisFunction* fun = new(zone_) ThisFunction(isolate_);
2970 VISIT_AND_RETURN(ThisFunction, fun)
2971 }
2972
2973 #undef VISIT_AND_RETURN
2974
2975 private:
2976 Isolate* isolate_;
2977 Zone* zone_;
2978 Visitor visitor_;
2979 };
2980
2981
2982 } } // namespace v8::internal
2983
2984 #endif // V8_AST_H_
2985