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