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