1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include "assembler.h"
35 #include "feedback-slots.h"
40 #include "small-pointer-list.h"
41 #include "smart-pointers.h"
45 #include "variables.h"
46 #include "interface.h"
52 // The abstract syntax tree is an intermediate, light-weight
53 // representation of the parsed JavaScript code suitable for
54 // compilation to native code.
56 // Nodes are allocated in a separate zone, which allows faster
57 // allocation and constant-time deallocation of the entire syntax
61 // ----------------------------------------------------------------------------
62 // Nodes of the abstract syntax tree. Only concrete classes are
65 #define DECLARATION_NODE_LIST(V) \
66 V(VariableDeclaration) \
67 V(FunctionDeclaration) \
68 V(ModuleDeclaration) \
69 V(ImportDeclaration) \
70 V(ExportDeclaration) \
72 #define MODULE_NODE_LIST(V) \
78 #define STATEMENT_NODE_LIST(V) \
81 V(ExpressionStatement) \
84 V(ContinueStatement) \
94 V(TryCatchStatement) \
95 V(TryFinallyStatement) \
98 #define EXPRESSION_NODE_LIST(V) \
100 V(NativeFunctionLiteral) \
117 V(CompareOperation) \
121 #define AST_NODE_LIST(V) \
122 DECLARATION_NODE_LIST(V) \
123 MODULE_NODE_LIST(V) \
124 STATEMENT_NODE_LIST(V) \
125 EXPRESSION_NODE_LIST(V)
127 // Forward declarations
128 class AstConstructionVisitor;
129 template<class> class AstNodeFactory;
133 class BreakableStatement;
135 class IterationStatement;
136 class MaterializedLiteral;
138 class TargetCollector;
139 class TypeFeedbackOracle;
141 class RegExpAlternative;
142 class RegExpAssertion;
144 class RegExpBackReference;
146 class RegExpCharacterClass;
147 class RegExpCompiler;
148 class RegExpDisjunction;
150 class RegExpLookahead;
151 class RegExpQuantifier;
154 #define DEF_FORWARD_DECLARATION(type) class type;
155 AST_NODE_LIST(DEF_FORWARD_DECLARATION)
156 #undef DEF_FORWARD_DECLARATION
159 // Typedef only introduced to avoid unreadable code.
160 // Please do appreciate the required space in "> >".
161 typedef ZoneList<Handle<String> > ZoneStringList;
162 typedef ZoneList<Handle<Object> > ZoneObjectList;
165 #define DECLARE_NODE_TYPE(type) \
166 virtual void Accept(AstVisitor* v) V8_OVERRIDE; \
167 virtual AstNode::NodeType node_type() const V8_FINAL V8_OVERRIDE { \
168 return AstNode::k##type; \
170 template<class> friend class AstNodeFactory;
173 enum AstPropertiesFlag {
181 class AstProperties V8_FINAL BASE_EMBEDDED {
183 class Flags : public EnumSet<AstPropertiesFlag, int> {};
185 AstProperties() : node_count_(0) {}
187 Flags* flags() { return &flags_; }
188 int node_count() { return node_count_; }
189 void add_node_count(int count) { node_count_ += count; }
197 class AstNode: public ZoneObject {
199 #define DECLARE_TYPE_ENUM(type) k##type,
201 AST_NODE_LIST(DECLARE_TYPE_ENUM)
204 #undef DECLARE_TYPE_ENUM
206 void* operator new(size_t size, Zone* zone) {
207 return zone->New(static_cast<int>(size));
210 explicit AstNode(int position): position_(position) {}
211 virtual ~AstNode() {}
213 virtual void Accept(AstVisitor* v) = 0;
214 virtual NodeType node_type() const = 0;
215 int position() const { return position_; }
217 // Type testing & conversion functions overridden by concrete subclasses.
218 #define DECLARE_NODE_FUNCTIONS(type) \
219 bool Is##type() { return node_type() == AstNode::k##type; } \
220 type* As##type() { return Is##type() ? reinterpret_cast<type*>(this) : NULL; }
221 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
222 #undef DECLARE_NODE_FUNCTIONS
224 virtual TargetCollector* AsTargetCollector() { return NULL; }
225 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
226 virtual IterationStatement* AsIterationStatement() { return NULL; }
227 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
230 static int GetNextId(Zone* zone) {
231 return ReserveIdRange(zone, 1);
234 static int ReserveIdRange(Zone* zone, int n) {
235 int tmp = zone->isolate()->ast_node_id();
236 zone->isolate()->set_ast_node_id(tmp + n);
240 // Some nodes re-use bailout IDs for type feedback.
241 static TypeFeedbackId reuse(BailoutId id) {
242 return TypeFeedbackId(id.ToInt());
247 // Hidden to prevent accidental usage. It would have to load the
248 // current zone from the TLS.
249 void* operator new(size_t size);
251 friend class CaseClause; // Generates AST IDs.
257 class Statement : public AstNode {
259 explicit Statement(Zone* zone, int position) : AstNode(position) {}
261 bool IsEmpty() { return AsEmptyStatement() != NULL; }
262 virtual bool IsJump() const { return false; }
266 class SmallMapList V8_FINAL {
269 SmallMapList(int capacity, Zone* zone) : list_(capacity, zone) {}
271 void Reserve(int capacity, Zone* zone) { list_.Reserve(capacity, zone); }
272 void Clear() { list_.Clear(); }
273 void Sort() { list_.Sort(); }
275 bool is_empty() const { return list_.is_empty(); }
276 int length() const { return list_.length(); }
278 void AddMapIfMissing(Handle<Map> map, Zone* zone) {
279 map = Map::CurrentMapForDeprecated(map);
280 if (map.is_null()) return;
281 for (int i = 0; i < length(); ++i) {
282 if (at(i).is_identical_to(map)) return;
287 void FilterForPossibleTransitions(Map* root_map) {
288 for (int i = list_.length() - 1; i >= 0; i--) {
289 if (at(i)->FindRootMap() != root_map) {
290 list_.RemoveElement(list_.at(i));
295 void Add(Handle<Map> handle, Zone* zone) {
296 list_.Add(handle.location(), zone);
299 Handle<Map> at(int i) const {
300 return Handle<Map>(list_.at(i));
303 Handle<Map> first() const { return at(0); }
304 Handle<Map> last() const { return at(length() - 1); }
307 // The list stores pointers to Map*, that is Map**, so it's GC safe.
308 SmallPointerList<Map*> list_;
310 DISALLOW_COPY_AND_ASSIGN(SmallMapList);
314 class Expression : public AstNode {
317 // Not assigned a context yet, or else will not be visited during
320 // Evaluated for its side effects.
322 // Evaluated for its value (and side effects).
324 // Evaluated for control flow (and side effects).
328 virtual bool IsValidLeftHandSide() { return false; }
330 // Helpers for ToBoolean conversion.
331 virtual bool ToBooleanIsTrue() { return false; }
332 virtual bool ToBooleanIsFalse() { return false; }
334 // Symbols that cannot be parsed as array indices are considered property
335 // names. We do not treat symbols that can be array indexes as property
336 // names because [] for string objects is handled only by keyed ICs.
337 virtual bool IsPropertyName() { return false; }
339 // True iff the result can be safely overwritten (to avoid allocation).
340 // False for operations that can return one of their operands.
341 virtual bool ResultOverwriteAllowed() { return false; }
343 // True iff the expression is a literal represented as a smi.
346 // True iff the expression is a string literal.
347 bool IsStringLiteral();
349 // True iff the expression is the null literal.
350 bool IsNullLiteral();
352 // True if we can prove that the expression is the undefined literal.
353 bool IsUndefinedLiteral(Isolate* isolate);
355 // Expression type bounds
356 Bounds bounds() { return bounds_; }
357 void set_bounds(Bounds bounds) { bounds_ = bounds; }
359 // Type feedback information for assignments and properties.
360 virtual bool IsMonomorphic() {
364 virtual SmallMapList* GetReceiverTypes() {
368 virtual KeyedAccessStoreMode GetStoreMode() {
370 return STANDARD_STORE;
373 // TODO(rossberg): this should move to its own AST node eventually.
374 virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
375 byte to_boolean_types() const { return to_boolean_types_; }
377 BailoutId id() const { return id_; }
378 TypeFeedbackId test_id() const { return test_id_; }
381 Expression(Zone* zone, int pos)
383 bounds_(Bounds::Unbounded(zone)),
384 id_(GetNextId(zone)),
385 test_id_(GetNextId(zone)) {}
386 void set_to_boolean_types(byte types) { to_boolean_types_ = types; }
390 byte to_boolean_types_;
393 const TypeFeedbackId test_id_;
397 class BreakableStatement : public Statement {
400 TARGET_FOR_ANONYMOUS,
401 TARGET_FOR_NAMED_ONLY
404 // The labels associated with this statement. May be NULL;
405 // if it is != NULL, guaranteed to contain at least one entry.
406 ZoneStringList* labels() const { return labels_; }
408 // Type testing & conversion.
409 virtual BreakableStatement* AsBreakableStatement() V8_FINAL V8_OVERRIDE {
414 Label* break_target() { return &break_target_; }
417 bool is_target_for_anonymous() const {
418 return breakable_type_ == TARGET_FOR_ANONYMOUS;
421 BailoutId EntryId() const { return entry_id_; }
422 BailoutId ExitId() const { return exit_id_; }
426 Zone* zone, ZoneStringList* labels,
427 BreakableType breakable_type, int position)
428 : Statement(zone, position),
430 breakable_type_(breakable_type),
431 entry_id_(GetNextId(zone)),
432 exit_id_(GetNextId(zone)) {
433 ASSERT(labels == NULL || labels->length() > 0);
438 ZoneStringList* labels_;
439 BreakableType breakable_type_;
441 const BailoutId entry_id_;
442 const BailoutId exit_id_;
446 class Block V8_FINAL : public BreakableStatement {
448 DECLARE_NODE_TYPE(Block)
450 void AddStatement(Statement* statement, Zone* zone) {
451 statements_.Add(statement, zone);
454 ZoneList<Statement*>* statements() { return &statements_; }
455 bool is_initializer_block() const { return is_initializer_block_; }
457 virtual bool IsJump() const V8_OVERRIDE {
458 return !statements_.is_empty() && statements_.last()->IsJump()
459 && labels() == NULL; // Good enough as an approximation...
462 Scope* scope() const { return scope_; }
463 void set_scope(Scope* scope) { scope_ = scope; }
467 ZoneStringList* labels,
469 bool is_initializer_block,
471 : BreakableStatement(zone, labels, TARGET_FOR_NAMED_ONLY, pos),
472 statements_(capacity, zone),
473 is_initializer_block_(is_initializer_block),
478 ZoneList<Statement*> statements_;
479 bool is_initializer_block_;
484 class Declaration : public AstNode {
486 VariableProxy* proxy() const { return proxy_; }
487 VariableMode mode() const { return mode_; }
488 Scope* scope() const { return scope_; }
489 virtual InitializationFlag initialization() const = 0;
490 virtual bool IsInlineable() const;
493 Declaration(Zone* zone,
494 VariableProxy* proxy,
502 ASSERT(IsDeclaredVariableMode(mode));
506 VariableProxy* proxy_;
509 // Nested scope from which the declaration originated.
514 class VariableDeclaration V8_FINAL : public Declaration {
516 DECLARE_NODE_TYPE(VariableDeclaration)
518 virtual InitializationFlag initialization() const V8_OVERRIDE {
519 return mode() == VAR ? kCreatedInitialized : kNeedsInitialization;
523 VariableDeclaration(Zone* zone,
524 VariableProxy* proxy,
528 : Declaration(zone, proxy, mode, scope, pos) {
533 class FunctionDeclaration V8_FINAL : public Declaration {
535 DECLARE_NODE_TYPE(FunctionDeclaration)
537 FunctionLiteral* fun() const { return fun_; }
538 virtual InitializationFlag initialization() const V8_OVERRIDE {
539 return kCreatedInitialized;
541 virtual bool IsInlineable() const V8_OVERRIDE;
544 FunctionDeclaration(Zone* zone,
545 VariableProxy* proxy,
547 FunctionLiteral* fun,
550 : Declaration(zone, proxy, mode, scope, pos),
552 // At the moment there are no "const functions" in JavaScript...
553 ASSERT(mode == VAR || mode == LET);
558 FunctionLiteral* fun_;
562 class ModuleDeclaration V8_FINAL : public Declaration {
564 DECLARE_NODE_TYPE(ModuleDeclaration)
566 Module* module() const { return module_; }
567 virtual InitializationFlag initialization() const V8_OVERRIDE {
568 return kCreatedInitialized;
572 ModuleDeclaration(Zone* zone,
573 VariableProxy* proxy,
577 : Declaration(zone, proxy, MODULE, scope, pos),
586 class ImportDeclaration V8_FINAL : public Declaration {
588 DECLARE_NODE_TYPE(ImportDeclaration)
590 Module* module() const { return module_; }
591 virtual InitializationFlag initialization() const V8_OVERRIDE {
592 return kCreatedInitialized;
596 ImportDeclaration(Zone* zone,
597 VariableProxy* proxy,
601 : Declaration(zone, proxy, LET, scope, pos),
610 class ExportDeclaration V8_FINAL : public Declaration {
612 DECLARE_NODE_TYPE(ExportDeclaration)
614 virtual InitializationFlag initialization() const V8_OVERRIDE {
615 return kCreatedInitialized;
619 ExportDeclaration(Zone* zone, VariableProxy* proxy, Scope* scope, int pos)
620 : Declaration(zone, proxy, LET, scope, pos) {}
624 class Module : public AstNode {
626 Interface* interface() const { return interface_; }
627 Block* body() const { return body_; }
630 Module(Zone* zone, int pos)
632 interface_(Interface::NewModule(zone)),
634 Module(Zone* zone, Interface* interface, int pos, Block* body = NULL)
636 interface_(interface),
640 Interface* interface_;
645 class ModuleLiteral V8_FINAL : public Module {
647 DECLARE_NODE_TYPE(ModuleLiteral)
650 ModuleLiteral(Zone* zone, Block* body, Interface* interface, int pos)
651 : Module(zone, interface, pos, body) {}
655 class ModuleVariable V8_FINAL : public Module {
657 DECLARE_NODE_TYPE(ModuleVariable)
659 VariableProxy* proxy() const { return proxy_; }
662 inline ModuleVariable(Zone* zone, VariableProxy* proxy, int pos);
665 VariableProxy* proxy_;
669 class ModulePath V8_FINAL : public Module {
671 DECLARE_NODE_TYPE(ModulePath)
673 Module* module() const { return module_; }
674 Handle<String> name() const { return name_; }
677 ModulePath(Zone* zone, Module* module, Handle<String> name, int pos)
685 Handle<String> name_;
689 class ModuleUrl V8_FINAL : public Module {
691 DECLARE_NODE_TYPE(ModuleUrl)
693 Handle<String> url() const { return url_; }
696 ModuleUrl(Zone* zone, Handle<String> url, int pos)
697 : Module(zone, pos), url_(url) {
705 class ModuleStatement V8_FINAL : public Statement {
707 DECLARE_NODE_TYPE(ModuleStatement)
709 VariableProxy* proxy() const { return proxy_; }
710 Block* body() const { return body_; }
713 ModuleStatement(Zone* zone, VariableProxy* proxy, Block* body, int pos)
714 : Statement(zone, pos),
720 VariableProxy* proxy_;
725 class IterationStatement : public BreakableStatement {
727 // Type testing & conversion.
728 virtual IterationStatement* AsIterationStatement() V8_FINAL V8_OVERRIDE {
732 Statement* body() const { return body_; }
734 BailoutId OsrEntryId() const { return osr_entry_id_; }
735 virtual BailoutId ContinueId() const = 0;
736 virtual BailoutId StackCheckId() const = 0;
739 Label* continue_target() { return &continue_target_; }
742 IterationStatement(Zone* zone, ZoneStringList* labels, int pos)
743 : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos),
745 osr_entry_id_(GetNextId(zone)) {
748 void Initialize(Statement* body) {
754 Label continue_target_;
756 const BailoutId osr_entry_id_;
760 class DoWhileStatement V8_FINAL : public IterationStatement {
762 DECLARE_NODE_TYPE(DoWhileStatement)
764 void Initialize(Expression* cond, Statement* body) {
765 IterationStatement::Initialize(body);
769 Expression* cond() const { return cond_; }
771 virtual BailoutId ContinueId() const V8_OVERRIDE { return continue_id_; }
772 virtual BailoutId StackCheckId() const V8_OVERRIDE { return back_edge_id_; }
773 BailoutId BackEdgeId() const { return back_edge_id_; }
776 DoWhileStatement(Zone* zone, ZoneStringList* labels, int pos)
777 : IterationStatement(zone, labels, pos),
779 continue_id_(GetNextId(zone)),
780 back_edge_id_(GetNextId(zone)) {
786 const BailoutId continue_id_;
787 const BailoutId back_edge_id_;
791 class WhileStatement V8_FINAL : public IterationStatement {
793 DECLARE_NODE_TYPE(WhileStatement)
795 void Initialize(Expression* cond, Statement* body) {
796 IterationStatement::Initialize(body);
800 Expression* cond() const { return cond_; }
801 bool may_have_function_literal() const {
802 return may_have_function_literal_;
804 void set_may_have_function_literal(bool value) {
805 may_have_function_literal_ = value;
808 virtual BailoutId ContinueId() const V8_OVERRIDE { return EntryId(); }
809 virtual BailoutId StackCheckId() const V8_OVERRIDE { return body_id_; }
810 BailoutId BodyId() const { return body_id_; }
813 WhileStatement(Zone* zone, ZoneStringList* labels, int pos)
814 : IterationStatement(zone, labels, pos),
816 may_have_function_literal_(true),
817 body_id_(GetNextId(zone)) {
823 // True if there is a function literal subexpression in the condition.
824 bool may_have_function_literal_;
826 const BailoutId body_id_;
830 class ForStatement V8_FINAL : public IterationStatement {
832 DECLARE_NODE_TYPE(ForStatement)
834 void Initialize(Statement* init,
838 IterationStatement::Initialize(body);
844 Statement* init() const { return init_; }
845 Expression* cond() const { return cond_; }
846 Statement* next() const { return next_; }
848 bool may_have_function_literal() const {
849 return may_have_function_literal_;
851 void set_may_have_function_literal(bool value) {
852 may_have_function_literal_ = value;
855 virtual BailoutId ContinueId() const V8_OVERRIDE { return continue_id_; }
856 virtual BailoutId StackCheckId() const V8_OVERRIDE { return body_id_; }
857 BailoutId BodyId() const { return body_id_; }
859 bool is_fast_smi_loop() { return loop_variable_ != NULL; }
860 Variable* loop_variable() { return loop_variable_; }
861 void set_loop_variable(Variable* var) { loop_variable_ = var; }
864 ForStatement(Zone* zone, ZoneStringList* labels, int pos)
865 : IterationStatement(zone, labels, pos),
869 may_have_function_literal_(true),
870 loop_variable_(NULL),
871 continue_id_(GetNextId(zone)),
872 body_id_(GetNextId(zone)) {
880 // True if there is a function literal subexpression in the condition.
881 bool may_have_function_literal_;
882 Variable* loop_variable_;
884 const BailoutId continue_id_;
885 const BailoutId body_id_;
889 class ForEachStatement : public IterationStatement {
892 ENUMERATE, // for (each in subject) body;
893 ITERATE // for (each of subject) body;
896 void Initialize(Expression* each, Expression* subject, Statement* body) {
897 IterationStatement::Initialize(body);
902 Expression* each() const { return each_; }
903 Expression* subject() const { return subject_; }
906 ForEachStatement(Zone* zone, ZoneStringList* labels, int pos)
907 : IterationStatement(zone, labels, pos),
914 Expression* subject_;
918 class ForInStatement V8_FINAL : public ForEachStatement,
919 public FeedbackSlotInterface {
921 DECLARE_NODE_TYPE(ForInStatement)
923 Expression* enumerable() const {
927 // Type feedback information.
928 virtual ComputablePhase GetComputablePhase() { return DURING_PARSE; }
929 virtual int ComputeFeedbackSlotCount(Isolate* isolate) { return 1; }
930 virtual void SetFirstFeedbackSlot(int slot) { for_in_feedback_slot_ = slot; }
932 int ForInFeedbackSlot() {
933 ASSERT(for_in_feedback_slot_ != kInvalidFeedbackSlot);
934 return for_in_feedback_slot_;
937 enum ForInType { FAST_FOR_IN, SLOW_FOR_IN };
938 ForInType for_in_type() const { return for_in_type_; }
939 void set_for_in_type(ForInType type) { for_in_type_ = type; }
941 BailoutId BodyId() const { return body_id_; }
942 BailoutId PrepareId() const { return prepare_id_; }
943 virtual BailoutId ContinueId() const V8_OVERRIDE { return EntryId(); }
944 virtual BailoutId StackCheckId() const V8_OVERRIDE { return body_id_; }
947 ForInStatement(Zone* zone, ZoneStringList* labels, int pos)
948 : ForEachStatement(zone, labels, pos),
949 for_in_type_(SLOW_FOR_IN),
950 for_in_feedback_slot_(kInvalidFeedbackSlot),
951 body_id_(GetNextId(zone)),
952 prepare_id_(GetNextId(zone)) {
955 ForInType for_in_type_;
956 int for_in_feedback_slot_;
957 const BailoutId body_id_;
958 const BailoutId prepare_id_;
962 class ForOfStatement V8_FINAL : public ForEachStatement {
964 DECLARE_NODE_TYPE(ForOfStatement)
966 void Initialize(Expression* each,
969 Expression* assign_iterator,
970 Expression* next_result,
971 Expression* result_done,
972 Expression* assign_each) {
973 ForEachStatement::Initialize(each, subject, body);
974 assign_iterator_ = assign_iterator;
975 next_result_ = next_result;
976 result_done_ = result_done;
977 assign_each_ = assign_each;
980 Expression* iterable() const {
984 // var iterator = iterable;
985 Expression* assign_iterator() const {
986 return assign_iterator_;
989 // var result = iterator.next();
990 Expression* next_result() const {
995 Expression* result_done() const {
999 // each = result.value
1000 Expression* assign_each() const {
1001 return assign_each_;
1004 virtual BailoutId ContinueId() const V8_OVERRIDE { return EntryId(); }
1005 virtual BailoutId StackCheckId() const V8_OVERRIDE { return BackEdgeId(); }
1007 BailoutId BackEdgeId() const { return back_edge_id_; }
1010 ForOfStatement(Zone* zone, ZoneStringList* labels, int pos)
1011 : ForEachStatement(zone, labels, pos),
1012 assign_iterator_(NULL),
1016 back_edge_id_(GetNextId(zone)) {
1019 Expression* assign_iterator_;
1020 Expression* next_result_;
1021 Expression* result_done_;
1022 Expression* assign_each_;
1023 const BailoutId back_edge_id_;
1027 class ExpressionStatement V8_FINAL : public Statement {
1029 DECLARE_NODE_TYPE(ExpressionStatement)
1031 void set_expression(Expression* e) { expression_ = e; }
1032 Expression* expression() const { return expression_; }
1033 virtual bool IsJump() const V8_OVERRIDE { return expression_->IsThrow(); }
1036 ExpressionStatement(Zone* zone, Expression* expression, int pos)
1037 : Statement(zone, pos), expression_(expression) { }
1040 Expression* expression_;
1044 class JumpStatement : public Statement {
1046 virtual bool IsJump() const V8_FINAL V8_OVERRIDE { return true; }
1049 explicit JumpStatement(Zone* zone, int pos) : Statement(zone, pos) {}
1053 class ContinueStatement V8_FINAL : public JumpStatement {
1055 DECLARE_NODE_TYPE(ContinueStatement)
1057 IterationStatement* target() const { return target_; }
1060 explicit ContinueStatement(Zone* zone, IterationStatement* target, int pos)
1061 : JumpStatement(zone, pos), target_(target) { }
1064 IterationStatement* target_;
1068 class BreakStatement V8_FINAL : public JumpStatement {
1070 DECLARE_NODE_TYPE(BreakStatement)
1072 BreakableStatement* target() const { return target_; }
1075 explicit BreakStatement(Zone* zone, BreakableStatement* target, int pos)
1076 : JumpStatement(zone, pos), target_(target) { }
1079 BreakableStatement* target_;
1083 class ReturnStatement V8_FINAL : public JumpStatement {
1085 DECLARE_NODE_TYPE(ReturnStatement)
1087 Expression* expression() const { return expression_; }
1090 explicit ReturnStatement(Zone* zone, Expression* expression, int pos)
1091 : JumpStatement(zone, pos), expression_(expression) { }
1094 Expression* expression_;
1098 class WithStatement V8_FINAL : public Statement {
1100 DECLARE_NODE_TYPE(WithStatement)
1102 Scope* scope() { return scope_; }
1103 Expression* expression() const { return expression_; }
1104 Statement* statement() const { return statement_; }
1108 Zone* zone, Scope* scope,
1109 Expression* expression, Statement* statement, int pos)
1110 : Statement(zone, pos),
1112 expression_(expression),
1113 statement_(statement) { }
1117 Expression* expression_;
1118 Statement* statement_;
1122 class CaseClause V8_FINAL : public Expression {
1124 DECLARE_NODE_TYPE(CaseClause)
1126 bool is_default() const { return label_ == NULL; }
1127 Expression* label() const {
1128 CHECK(!is_default());
1131 Label* body_target() { return &body_target_; }
1132 ZoneList<Statement*>* statements() const { return statements_; }
1134 BailoutId EntryId() const { return entry_id_; }
1136 // Type feedback information.
1137 TypeFeedbackId CompareId() { return compare_id_; }
1138 Type* compare_type() { return compare_type_; }
1139 void set_compare_type(Type* type) { compare_type_ = type; }
1142 CaseClause(Zone* zone,
1144 ZoneList<Statement*>* statements,
1149 ZoneList<Statement*>* statements_;
1150 Type* compare_type_;
1152 const TypeFeedbackId compare_id_;
1153 const BailoutId entry_id_;
1157 class SwitchStatement V8_FINAL : public BreakableStatement {
1159 DECLARE_NODE_TYPE(SwitchStatement)
1161 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
1166 Expression* tag() const { return tag_; }
1167 ZoneList<CaseClause*>* cases() const { return cases_; }
1170 SwitchStatement(Zone* zone, ZoneStringList* labels, int pos)
1171 : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos),
1177 ZoneList<CaseClause*>* cases_;
1181 // If-statements always have non-null references to their then- and
1182 // else-parts. When parsing if-statements with no explicit else-part,
1183 // the parser implicitly creates an empty statement. Use the
1184 // HasThenStatement() and HasElseStatement() functions to check if a
1185 // given if-statement has a then- or an else-part containing code.
1186 class IfStatement V8_FINAL : public Statement {
1188 DECLARE_NODE_TYPE(IfStatement)
1190 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
1191 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
1193 Expression* condition() const { return condition_; }
1194 Statement* then_statement() const { return then_statement_; }
1195 Statement* else_statement() const { return else_statement_; }
1197 virtual bool IsJump() const V8_OVERRIDE {
1198 return HasThenStatement() && then_statement()->IsJump()
1199 && HasElseStatement() && else_statement()->IsJump();
1202 BailoutId IfId() const { return if_id_; }
1203 BailoutId ThenId() const { return then_id_; }
1204 BailoutId ElseId() const { return else_id_; }
1207 IfStatement(Zone* zone,
1208 Expression* condition,
1209 Statement* then_statement,
1210 Statement* else_statement,
1212 : Statement(zone, pos),
1213 condition_(condition),
1214 then_statement_(then_statement),
1215 else_statement_(else_statement),
1216 if_id_(GetNextId(zone)),
1217 then_id_(GetNextId(zone)),
1218 else_id_(GetNextId(zone)) {
1222 Expression* condition_;
1223 Statement* then_statement_;
1224 Statement* else_statement_;
1225 const BailoutId if_id_;
1226 const BailoutId then_id_;
1227 const BailoutId else_id_;
1231 // NOTE: TargetCollectors are represented as nodes to fit in the target
1232 // stack in the compiler; this should probably be reworked.
1233 class TargetCollector V8_FINAL : public AstNode {
1235 explicit TargetCollector(Zone* zone)
1236 : AstNode(RelocInfo::kNoPosition), targets_(0, zone) { }
1238 // Adds a jump target to the collector. The collector stores a pointer not
1239 // a copy of the target to make binding work, so make sure not to pass in
1240 // references to something on the stack.
1241 void AddTarget(Label* target, Zone* zone);
1243 // Virtual behaviour. TargetCollectors are never part of the AST.
1244 virtual void Accept(AstVisitor* v) V8_OVERRIDE { UNREACHABLE(); }
1245 virtual NodeType node_type() const V8_OVERRIDE { return kInvalid; }
1246 virtual TargetCollector* AsTargetCollector() V8_OVERRIDE { return this; }
1248 ZoneList<Label*>* targets() { return &targets_; }
1251 ZoneList<Label*> targets_;
1255 class TryStatement : public Statement {
1257 void set_escaping_targets(ZoneList<Label*>* targets) {
1258 escaping_targets_ = targets;
1261 int index() const { return index_; }
1262 Block* try_block() const { return try_block_; }
1263 ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
1266 TryStatement(Zone* zone, int index, Block* try_block, int pos)
1267 : Statement(zone, pos),
1269 try_block_(try_block),
1270 escaping_targets_(NULL) { }
1273 // Unique (per-function) index of this handler. This is not an AST ID.
1277 ZoneList<Label*>* escaping_targets_;
1281 class TryCatchStatement V8_FINAL : public TryStatement {
1283 DECLARE_NODE_TYPE(TryCatchStatement)
1285 Scope* scope() { return scope_; }
1286 Variable* variable() { return variable_; }
1287 Block* catch_block() const { return catch_block_; }
1290 TryCatchStatement(Zone* zone,
1297 : TryStatement(zone, index, try_block, pos),
1299 variable_(variable),
1300 catch_block_(catch_block) {
1305 Variable* variable_;
1306 Block* catch_block_;
1310 class TryFinallyStatement V8_FINAL : public TryStatement {
1312 DECLARE_NODE_TYPE(TryFinallyStatement)
1314 Block* finally_block() const { return finally_block_; }
1317 TryFinallyStatement(
1318 Zone* zone, int index, Block* try_block, Block* finally_block, int pos)
1319 : TryStatement(zone, index, try_block, pos),
1320 finally_block_(finally_block) { }
1323 Block* finally_block_;
1327 class DebuggerStatement V8_FINAL : public Statement {
1329 DECLARE_NODE_TYPE(DebuggerStatement)
1332 explicit DebuggerStatement(Zone* zone, int pos): Statement(zone, pos) {}
1336 class EmptyStatement V8_FINAL : public Statement {
1338 DECLARE_NODE_TYPE(EmptyStatement)
1341 explicit EmptyStatement(Zone* zone, int pos): Statement(zone, pos) {}
1345 class Literal V8_FINAL : public Expression {
1347 DECLARE_NODE_TYPE(Literal)
1349 virtual bool IsPropertyName() V8_OVERRIDE {
1350 if (value_->IsInternalizedString()) {
1352 return !String::cast(*value_)->AsArrayIndex(&ignored);
1357 Handle<String> AsPropertyName() {
1358 ASSERT(IsPropertyName());
1359 return Handle<String>::cast(value_);
1362 virtual bool ToBooleanIsTrue() V8_OVERRIDE {
1363 return value_->BooleanValue();
1365 virtual bool ToBooleanIsFalse() V8_OVERRIDE {
1366 return !value_->BooleanValue();
1369 // Identity testers.
1370 bool IsNull() const {
1371 ASSERT(!value_.is_null());
1372 return value_->IsNull();
1374 bool IsTrue() const {
1375 ASSERT(!value_.is_null());
1376 return value_->IsTrue();
1378 bool IsFalse() const {
1379 ASSERT(!value_.is_null());
1380 return value_->IsFalse();
1383 Handle<Object> value() const { return value_; }
1385 // Support for using Literal as a HashMap key. NOTE: Currently, this works
1386 // only for string and number literals!
1387 uint32_t Hash() { return ToString()->Hash(); }
1389 static bool Match(void* literal1, void* literal2) {
1390 Handle<String> s1 = static_cast<Literal*>(literal1)->ToString();
1391 Handle<String> s2 = static_cast<Literal*>(literal2)->ToString();
1392 return s1->Equals(*s2);
1395 TypeFeedbackId LiteralFeedbackId() const { return reuse(id()); }
1398 Literal(Zone* zone, Handle<Object> value, int position)
1399 : Expression(zone, position),
1401 isolate_(zone->isolate()) { }
1404 Handle<String> ToString();
1406 Handle<Object> value_;
1407 // TODO(dcarney): remove. this is only needed for Match and Hash.
1412 // Base class for literals that needs space in the corresponding JSFunction.
1413 class MaterializedLiteral : public Expression {
1415 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
1417 int literal_index() { return literal_index_; }
1420 // only callable after initialization.
1421 ASSERT(depth_ >= 1);
1426 MaterializedLiteral(Zone* zone,
1429 : Expression(zone, pos),
1430 literal_index_(literal_index),
1434 // A materialized literal is simple if the values consist of only
1435 // constants and simple object and array literals.
1436 bool is_simple() const { return is_simple_; }
1437 void set_is_simple(bool is_simple) { is_simple_ = is_simple; }
1438 friend class CompileTimeValue;
1440 void set_depth(int depth) {
1445 // Populate the constant properties/elements fixed array.
1446 void BuildConstants(Isolate* isolate);
1447 friend class ArrayLiteral;
1448 friend class ObjectLiteral;
1450 // If the expression is a literal, return the literal value;
1451 // if the expression is a materialized literal and is simple return a
1452 // compile time value as encoded by CompileTimeValue::GetValue().
1453 // Otherwise, return undefined literal as the placeholder
1454 // in the object literal boilerplate.
1455 Handle<Object> GetBoilerplateValue(Expression* expression, Isolate* isolate);
1464 // Property is used for passing information
1465 // about an object literal's properties from the parser
1466 // to the code generator.
1467 class ObjectLiteralProperty V8_FINAL : public ZoneObject {
1470 CONSTANT, // Property with constant value (compile time).
1471 COMPUTED, // Property with computed value (execution time).
1472 MATERIALIZED_LITERAL, // Property value is a materialized literal.
1473 GETTER, SETTER, // Property is an accessor function.
1474 PROTOTYPE // Property is __proto__.
1477 ObjectLiteralProperty(Zone* zone, Literal* key, Expression* value);
1479 Literal* key() { return key_; }
1480 Expression* value() { return value_; }
1481 Kind kind() { return kind_; }
1483 // Type feedback information.
1484 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1485 bool IsMonomorphic() { return !receiver_type_.is_null(); }
1486 Handle<Map> GetReceiverType() { return receiver_type_; }
1488 bool IsCompileTimeValue();
1490 void set_emit_store(bool emit_store);
1494 template<class> friend class AstNodeFactory;
1496 ObjectLiteralProperty(Zone* zone, bool is_getter, FunctionLiteral* value);
1497 void set_key(Literal* key) { key_ = key; }
1504 Handle<Map> receiver_type_;
1508 // An object literal has a boilerplate object that is used
1509 // for minimizing the work when constructing it at runtime.
1510 class ObjectLiteral V8_FINAL : public MaterializedLiteral {
1512 typedef ObjectLiteralProperty Property;
1514 DECLARE_NODE_TYPE(ObjectLiteral)
1516 Handle<FixedArray> constant_properties() const {
1517 return constant_properties_;
1519 ZoneList<Property*>* properties() const { return properties_; }
1520 bool fast_elements() const { return fast_elements_; }
1521 bool may_store_doubles() const { return may_store_doubles_; }
1522 bool has_function() const { return has_function_; }
1524 // Decide if a property should be in the object boilerplate.
1525 static bool IsBoilerplateProperty(Property* property);
1527 // Populate the constant properties fixed array.
1528 void BuildConstantProperties(Isolate* isolate);
1530 // Mark all computed expressions that are bound to a key that
1531 // is shadowed by a later occurrence of the same key. For the
1532 // marked expressions, no store code is emitted.
1533 void CalculateEmitStore(Zone* zone);
1538 kHasFunction = 1 << 1
1541 struct Accessors: public ZoneObject {
1542 Accessors() : getter(NULL), setter(NULL) { }
1548 ObjectLiteral(Zone* zone,
1549 ZoneList<Property*>* properties,
1551 int boilerplate_properties,
1554 : MaterializedLiteral(zone, literal_index, pos),
1555 properties_(properties),
1556 boilerplate_properties_(boilerplate_properties),
1557 fast_elements_(false),
1558 may_store_doubles_(false),
1559 has_function_(has_function) {}
1562 Handle<FixedArray> constant_properties_;
1563 ZoneList<Property*>* properties_;
1564 int boilerplate_properties_;
1565 bool fast_elements_;
1566 bool may_store_doubles_;
1571 // Node for capturing a regexp literal.
1572 class RegExpLiteral V8_FINAL : public MaterializedLiteral {
1574 DECLARE_NODE_TYPE(RegExpLiteral)
1576 Handle<String> pattern() const { return pattern_; }
1577 Handle<String> flags() const { return flags_; }
1580 RegExpLiteral(Zone* zone,
1581 Handle<String> pattern,
1582 Handle<String> flags,
1585 : MaterializedLiteral(zone, literal_index, pos),
1592 Handle<String> pattern_;
1593 Handle<String> flags_;
1597 // An array literal has a literals object that is used
1598 // for minimizing the work when constructing it at runtime.
1599 class ArrayLiteral V8_FINAL : public MaterializedLiteral {
1601 DECLARE_NODE_TYPE(ArrayLiteral)
1603 Handle<FixedArray> constant_elements() const { return constant_elements_; }
1604 ZoneList<Expression*>* values() const { return values_; }
1606 // Return an AST id for an element that is used in simulate instructions.
1607 BailoutId GetIdForElement(int i) {
1608 return BailoutId(first_element_id_.ToInt() + i);
1611 // Populate the constant elements fixed array.
1612 void BuildConstantElements(Isolate* isolate);
1616 kShallowElements = 1,
1617 kDisableMementos = 1 << 1
1621 ArrayLiteral(Zone* zone,
1622 ZoneList<Expression*>* values,
1625 : MaterializedLiteral(zone, literal_index, pos),
1627 first_element_id_(ReserveIdRange(zone, values->length())) {}
1630 Handle<FixedArray> constant_elements_;
1631 ZoneList<Expression*>* values_;
1632 const BailoutId first_element_id_;
1636 class VariableProxy V8_FINAL : public Expression {
1638 DECLARE_NODE_TYPE(VariableProxy)
1640 virtual bool IsValidLeftHandSide() V8_OVERRIDE {
1641 return var_ == NULL ? true : var_->IsValidLeftHandSide();
1644 bool IsVariable(Handle<String> n) {
1645 return !is_this() && name().is_identical_to(n);
1648 bool IsArguments() { return var_ != NULL && var_->is_arguments(); }
1654 Handle<String> name() const { return name_; }
1655 Variable* var() const { return var_; }
1656 bool is_this() const { return is_this_; }
1657 Interface* interface() const { return interface_; }
1660 void MarkAsTrivial() { is_trivial_ = true; }
1661 void MarkAsLValue() { is_lvalue_ = true; }
1663 // Bind this proxy to the variable var. Interfaces must match.
1664 void BindTo(Variable* var);
1667 VariableProxy(Zone* zone, Variable* var, int position);
1669 VariableProxy(Zone* zone,
1670 Handle<String> name,
1672 Interface* interface,
1675 Handle<String> name_;
1676 Variable* var_; // resolved variable, or NULL
1679 // True if this variable proxy is being used in an assignment
1680 // or with a increment/decrement operator.
1682 Interface* interface_;
1686 class Property V8_FINAL : public Expression {
1688 DECLARE_NODE_TYPE(Property)
1690 virtual bool IsValidLeftHandSide() V8_OVERRIDE { return true; }
1692 Expression* obj() const { return obj_; }
1693 Expression* key() const { return key_; }
1695 BailoutId LoadId() const { return load_id_; }
1697 bool IsStringAccess() const { return is_string_access_; }
1698 bool IsFunctionPrototype() const { return is_function_prototype_; }
1700 // Type feedback information.
1701 virtual bool IsMonomorphic() V8_OVERRIDE {
1702 return receiver_types_.length() == 1;
1704 virtual SmallMapList* GetReceiverTypes() V8_OVERRIDE {
1705 return &receiver_types_;
1707 virtual KeyedAccessStoreMode GetStoreMode() V8_OVERRIDE {
1708 return STANDARD_STORE;
1710 bool IsUninitialized() { return !is_for_call_ && is_uninitialized_; }
1711 bool HasNoTypeInformation() {
1712 return is_uninitialized_;
1714 void set_is_uninitialized(bool b) { is_uninitialized_ = b; }
1715 void set_is_string_access(bool b) { is_string_access_ = b; }
1716 void set_is_function_prototype(bool b) { is_function_prototype_ = b; }
1717 void mark_for_call() { is_for_call_ = true; }
1718 bool IsForCall() { return is_for_call_; }
1720 TypeFeedbackId PropertyFeedbackId() { return reuse(id()); }
1723 Property(Zone* zone,
1727 : Expression(zone, pos),
1730 load_id_(GetNextId(zone)),
1731 is_for_call_(false),
1732 is_uninitialized_(false),
1733 is_string_access_(false),
1734 is_function_prototype_(false) { }
1739 const BailoutId load_id_;
1741 SmallMapList receiver_types_;
1742 bool is_for_call_ : 1;
1743 bool is_uninitialized_ : 1;
1744 bool is_string_access_ : 1;
1745 bool is_function_prototype_ : 1;
1749 class Call V8_FINAL : public Expression, public FeedbackSlotInterface {
1751 DECLARE_NODE_TYPE(Call)
1753 Expression* expression() const { return expression_; }
1754 ZoneList<Expression*>* arguments() const { return arguments_; }
1756 // Type feedback information.
1757 virtual ComputablePhase GetComputablePhase() { return AFTER_SCOPING; }
1758 virtual int ComputeFeedbackSlotCount(Isolate* isolate);
1759 virtual void SetFirstFeedbackSlot(int slot) {
1760 call_feedback_slot_ = slot;
1763 bool HasCallFeedbackSlot() const {
1764 return call_feedback_slot_ != kInvalidFeedbackSlot;
1766 int CallFeedbackSlot() const { return call_feedback_slot_; }
1768 virtual SmallMapList* GetReceiverTypes() V8_OVERRIDE {
1769 if (expression()->IsProperty()) {
1770 return expression()->AsProperty()->GetReceiverTypes();
1775 virtual bool IsMonomorphic() V8_OVERRIDE {
1776 if (expression()->IsProperty()) {
1777 return expression()->AsProperty()->IsMonomorphic();
1779 return !target_.is_null();
1782 Handle<JSFunction> target() { return target_; }
1784 Handle<Cell> cell() { return cell_; }
1786 void set_target(Handle<JSFunction> target) { target_ = target; }
1787 bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
1789 BailoutId ReturnId() const { return return_id_; }
1799 // Helpers to determine how to handle the call.
1800 CallType GetCallType(Isolate* isolate) const;
1803 // Used to assert that the FullCodeGenerator records the return site.
1804 bool return_is_recorded_;
1809 Expression* expression,
1810 ZoneList<Expression*>* arguments,
1812 : Expression(zone, pos),
1813 expression_(expression),
1814 arguments_(arguments),
1815 call_feedback_slot_(kInvalidFeedbackSlot),
1816 return_id_(GetNextId(zone)) {
1817 if (expression->IsProperty()) {
1818 expression->AsProperty()->mark_for_call();
1823 Expression* expression_;
1824 ZoneList<Expression*>* arguments_;
1826 Handle<JSFunction> target_;
1828 int call_feedback_slot_;
1830 const BailoutId return_id_;
1834 class CallNew V8_FINAL : public Expression, public FeedbackSlotInterface {
1836 DECLARE_NODE_TYPE(CallNew)
1838 Expression* expression() const { return expression_; }
1839 ZoneList<Expression*>* arguments() const { return arguments_; }
1841 // Type feedback information.
1842 virtual ComputablePhase GetComputablePhase() { return DURING_PARSE; }
1843 virtual int ComputeFeedbackSlotCount(Isolate* isolate) {
1844 return FLAG_pretenuring_call_new ? 2 : 1;
1846 virtual void SetFirstFeedbackSlot(int slot) {
1847 callnew_feedback_slot_ = slot;
1850 int CallNewFeedbackSlot() {
1851 ASSERT(callnew_feedback_slot_ != kInvalidFeedbackSlot);
1852 return callnew_feedback_slot_;
1854 int AllocationSiteFeedbackSlot() {
1855 ASSERT(callnew_feedback_slot_ != kInvalidFeedbackSlot);
1856 ASSERT(FLAG_pretenuring_call_new);
1857 return callnew_feedback_slot_ + 1;
1860 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1861 virtual bool IsMonomorphic() V8_OVERRIDE { return is_monomorphic_; }
1862 Handle<JSFunction> target() const { return target_; }
1863 ElementsKind elements_kind() const { return elements_kind_; }
1864 Handle<AllocationSite> allocation_site() const {
1865 return allocation_site_;
1868 static int feedback_slots() { return 1; }
1870 BailoutId ReturnId() const { return return_id_; }
1874 Expression* expression,
1875 ZoneList<Expression*>* arguments,
1877 : Expression(zone, pos),
1878 expression_(expression),
1879 arguments_(arguments),
1880 is_monomorphic_(false),
1881 elements_kind_(GetInitialFastElementsKind()),
1882 callnew_feedback_slot_(kInvalidFeedbackSlot),
1883 return_id_(GetNextId(zone)) { }
1886 Expression* expression_;
1887 ZoneList<Expression*>* arguments_;
1889 bool is_monomorphic_;
1890 Handle<JSFunction> target_;
1891 ElementsKind elements_kind_;
1892 Handle<AllocationSite> allocation_site_;
1893 int callnew_feedback_slot_;
1895 const BailoutId return_id_;
1899 // The CallRuntime class does not represent any official JavaScript
1900 // language construct. Instead it is used to call a C or JS function
1901 // with a set of arguments. This is used from the builtins that are
1902 // implemented in JavaScript (see "v8natives.js").
1903 class CallRuntime V8_FINAL : public Expression {
1905 DECLARE_NODE_TYPE(CallRuntime)
1907 Handle<String> name() const { return name_; }
1908 const Runtime::Function* function() const { return function_; }
1909 ZoneList<Expression*>* arguments() const { return arguments_; }
1910 bool is_jsruntime() const { return function_ == NULL; }
1912 TypeFeedbackId CallRuntimeFeedbackId() const { return reuse(id()); }
1915 CallRuntime(Zone* zone,
1916 Handle<String> name,
1917 const Runtime::Function* function,
1918 ZoneList<Expression*>* arguments,
1920 : Expression(zone, pos),
1922 function_(function),
1923 arguments_(arguments) { }
1926 Handle<String> name_;
1927 const Runtime::Function* function_;
1928 ZoneList<Expression*>* arguments_;
1932 class UnaryOperation V8_FINAL : public Expression {
1934 DECLARE_NODE_TYPE(UnaryOperation)
1936 Token::Value op() const { return op_; }
1937 Expression* expression() const { return expression_; }
1939 BailoutId MaterializeTrueId() { return materialize_true_id_; }
1940 BailoutId MaterializeFalseId() { return materialize_false_id_; }
1942 virtual void RecordToBooleanTypeFeedback(
1943 TypeFeedbackOracle* oracle) V8_OVERRIDE;
1946 UnaryOperation(Zone* zone,
1948 Expression* expression,
1950 : Expression(zone, pos),
1952 expression_(expression),
1953 materialize_true_id_(GetNextId(zone)),
1954 materialize_false_id_(GetNextId(zone)) {
1955 ASSERT(Token::IsUnaryOp(op));
1960 Expression* expression_;
1962 // For unary not (Token::NOT), the AST ids where true and false will
1963 // actually be materialized, respectively.
1964 const BailoutId materialize_true_id_;
1965 const BailoutId materialize_false_id_;
1969 class BinaryOperation V8_FINAL : public Expression {
1971 DECLARE_NODE_TYPE(BinaryOperation)
1973 virtual bool ResultOverwriteAllowed();
1975 Token::Value op() const { return op_; }
1976 Expression* left() const { return left_; }
1977 Expression* right() const { return right_; }
1978 Handle<AllocationSite> allocation_site() const { return allocation_site_; }
1979 void set_allocation_site(Handle<AllocationSite> allocation_site) {
1980 allocation_site_ = allocation_site;
1983 BailoutId RightId() const { return right_id_; }
1985 TypeFeedbackId BinaryOperationFeedbackId() const { return reuse(id()); }
1986 Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
1987 void set_fixed_right_arg(Maybe<int> arg) { fixed_right_arg_ = arg; }
1989 virtual void RecordToBooleanTypeFeedback(
1990 TypeFeedbackOracle* oracle) V8_OVERRIDE;
1993 BinaryOperation(Zone* zone,
1998 : Expression(zone, pos),
2002 right_id_(GetNextId(zone)) {
2003 ASSERT(Token::IsBinaryOp(op));
2010 Handle<AllocationSite> allocation_site_;
2012 // TODO(rossberg): the fixed arg should probably be represented as a Constant
2013 // type for the RHS.
2014 Maybe<int> fixed_right_arg_;
2016 // The short-circuit logical operations need an AST ID for their
2017 // right-hand subexpression.
2018 const BailoutId right_id_;
2022 class CountOperation V8_FINAL : public Expression {
2024 DECLARE_NODE_TYPE(CountOperation)
2026 bool is_prefix() const { return is_prefix_; }
2027 bool is_postfix() const { return !is_prefix_; }
2029 Token::Value op() const { return op_; }
2030 Token::Value binary_op() {
2031 return (op() == Token::INC) ? Token::ADD : Token::SUB;
2034 Expression* expression() const { return expression_; }
2036 virtual bool IsMonomorphic() V8_OVERRIDE {
2037 return receiver_types_.length() == 1;
2039 virtual SmallMapList* GetReceiverTypes() V8_OVERRIDE {
2040 return &receiver_types_;
2042 virtual KeyedAccessStoreMode GetStoreMode() V8_OVERRIDE {
2045 Type* type() const { return type_; }
2046 void set_store_mode(KeyedAccessStoreMode mode) { store_mode_ = mode; }
2047 void set_type(Type* type) { type_ = type; }
2049 BailoutId AssignmentId() const { return assignment_id_; }
2051 TypeFeedbackId CountBinOpFeedbackId() const { return count_id_; }
2052 TypeFeedbackId CountStoreFeedbackId() const { return reuse(id()); }
2055 CountOperation(Zone* zone,
2060 : Expression(zone, pos),
2062 is_prefix_(is_prefix),
2063 store_mode_(STANDARD_STORE),
2065 assignment_id_(GetNextId(zone)),
2066 count_id_(GetNextId(zone)) {}
2070 bool is_prefix_ : 1;
2071 KeyedAccessStoreMode store_mode_ : 5; // Windows treats as signed,
2072 // must have extra bit.
2075 Expression* expression_;
2076 const BailoutId assignment_id_;
2077 const TypeFeedbackId count_id_;
2078 SmallMapList receiver_types_;
2082 class CompareOperation V8_FINAL : public Expression {
2084 DECLARE_NODE_TYPE(CompareOperation)
2086 Token::Value op() const { return op_; }
2087 Expression* left() const { return left_; }
2088 Expression* right() const { return right_; }
2090 // Type feedback information.
2091 TypeFeedbackId CompareOperationFeedbackId() const { return reuse(id()); }
2092 Type* combined_type() const { return combined_type_; }
2093 void set_combined_type(Type* type) { combined_type_ = type; }
2095 // Match special cases.
2096 bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
2097 bool IsLiteralCompareUndefined(Expression** expr, Isolate* isolate);
2098 bool IsLiteralCompareNull(Expression** expr);
2101 CompareOperation(Zone* zone,
2106 : Expression(zone, pos),
2110 combined_type_(Type::None(zone)) {
2111 ASSERT(Token::IsCompareOp(op));
2119 Type* combined_type_;
2123 class Conditional V8_FINAL : public Expression {
2125 DECLARE_NODE_TYPE(Conditional)
2127 Expression* condition() const { return condition_; }
2128 Expression* then_expression() const { return then_expression_; }
2129 Expression* else_expression() const { return else_expression_; }
2131 BailoutId ThenId() const { return then_id_; }
2132 BailoutId ElseId() const { return else_id_; }
2135 Conditional(Zone* zone,
2136 Expression* condition,
2137 Expression* then_expression,
2138 Expression* else_expression,
2140 : Expression(zone, position),
2141 condition_(condition),
2142 then_expression_(then_expression),
2143 else_expression_(else_expression),
2144 then_id_(GetNextId(zone)),
2145 else_id_(GetNextId(zone)) { }
2148 Expression* condition_;
2149 Expression* then_expression_;
2150 Expression* else_expression_;
2151 const BailoutId then_id_;
2152 const BailoutId else_id_;
2156 class Assignment V8_FINAL : public Expression {
2158 DECLARE_NODE_TYPE(Assignment)
2160 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
2162 Token::Value binary_op() const;
2164 Token::Value op() const { return op_; }
2165 Expression* target() const { return target_; }
2166 Expression* value() const { return value_; }
2167 BinaryOperation* binary_operation() const { return binary_operation_; }
2169 // This check relies on the definition order of token in token.h.
2170 bool is_compound() const { return op() > Token::ASSIGN; }
2172 BailoutId AssignmentId() const { return assignment_id_; }
2174 // Type feedback information.
2175 TypeFeedbackId AssignmentFeedbackId() { return reuse(id()); }
2176 virtual bool IsMonomorphic() V8_OVERRIDE {
2177 return receiver_types_.length() == 1;
2179 bool IsUninitialized() { return is_uninitialized_; }
2180 bool HasNoTypeInformation() {
2181 return is_uninitialized_;
2183 virtual SmallMapList* GetReceiverTypes() V8_OVERRIDE {
2184 return &receiver_types_;
2186 virtual KeyedAccessStoreMode GetStoreMode() V8_OVERRIDE {
2189 void set_is_uninitialized(bool b) { is_uninitialized_ = b; }
2190 void set_store_mode(KeyedAccessStoreMode mode) { store_mode_ = mode; }
2193 Assignment(Zone* zone,
2199 template<class Visitor>
2200 void Init(Zone* zone, AstNodeFactory<Visitor>* factory) {
2201 ASSERT(Token::IsAssignmentOp(op_));
2202 if (is_compound()) {
2203 binary_operation_ = factory->NewBinaryOperation(
2204 binary_op(), target_, value_, position() + 1);
2210 Expression* target_;
2212 BinaryOperation* binary_operation_;
2213 const BailoutId assignment_id_;
2215 bool is_uninitialized_ : 1;
2216 KeyedAccessStoreMode store_mode_ : 5; // Windows treats as signed,
2217 // must have extra bit.
2218 SmallMapList receiver_types_;
2222 class Yield V8_FINAL : public Expression {
2224 DECLARE_NODE_TYPE(Yield)
2227 INITIAL, // The initial yield that returns the unboxed generator object.
2228 SUSPEND, // A normal yield: { value: EXPRESSION, done: false }
2229 DELEGATING, // A yield*.
2230 FINAL // A return: { value: EXPRESSION, done: true }
2233 Expression* generator_object() const { return generator_object_; }
2234 Expression* expression() const { return expression_; }
2235 Kind yield_kind() const { return yield_kind_; }
2237 // Delegating yield surrounds the "yield" in a "try/catch". This index
2238 // locates the catch handler in the handler table, and is equivalent to
2239 // TryCatchStatement::index().
2241 ASSERT(yield_kind() == DELEGATING);
2244 void set_index(int index) {
2245 ASSERT(yield_kind() == DELEGATING);
2251 Expression* generator_object,
2252 Expression* expression,
2255 : Expression(zone, pos),
2256 generator_object_(generator_object),
2257 expression_(expression),
2258 yield_kind_(yield_kind),
2262 Expression* generator_object_;
2263 Expression* expression_;
2269 class Throw V8_FINAL : public Expression {
2271 DECLARE_NODE_TYPE(Throw)
2273 Expression* exception() const { return exception_; }
2276 Throw(Zone* zone, Expression* exception, int pos)
2277 : Expression(zone, pos), exception_(exception) {}
2280 Expression* exception_;
2284 class FunctionLiteral V8_FINAL : public Expression {
2287 ANONYMOUS_EXPRESSION,
2292 enum ParameterFlag {
2293 kNoDuplicateParameters = 0,
2294 kHasDuplicateParameters = 1
2297 enum IsFunctionFlag {
2302 enum IsParenthesizedFlag {
2307 enum IsGeneratorFlag {
2312 DECLARE_NODE_TYPE(FunctionLiteral)
2314 Handle<String> name() const { return name_; }
2315 Scope* scope() const { return scope_; }
2316 ZoneList<Statement*>* body() const { return body_; }
2317 void set_function_token_position(int pos) { function_token_position_ = pos; }
2318 int function_token_position() const { return function_token_position_; }
2319 int start_position() const;
2320 int end_position() const;
2321 int SourceSize() const { return end_position() - start_position(); }
2322 bool is_expression() const { return IsExpression::decode(bitfield_); }
2323 bool is_anonymous() const { return IsAnonymous::decode(bitfield_); }
2324 StrictMode strict_mode() const;
2326 int materialized_literal_count() { return materialized_literal_count_; }
2327 int expected_property_count() { return expected_property_count_; }
2328 int handler_count() { return handler_count_; }
2329 int parameter_count() { return parameter_count_; }
2331 bool AllowsLazyCompilation();
2332 bool AllowsLazyCompilationWithoutContext();
2334 void InitializeSharedInfo(Handle<Code> code);
2336 Handle<String> debug_name() const {
2337 if (name_->length() > 0) return name_;
2338 return inferred_name();
2341 Handle<String> inferred_name() const { return inferred_name_; }
2342 void set_inferred_name(Handle<String> inferred_name) {
2343 inferred_name_ = inferred_name;
2346 // shared_info may be null if it's not cached in full code.
2347 Handle<SharedFunctionInfo> shared_info() { return shared_info_; }
2349 bool pretenure() { return Pretenure::decode(bitfield_); }
2350 void set_pretenure() { bitfield_ |= Pretenure::encode(true); }
2352 bool has_duplicate_parameters() {
2353 return HasDuplicateParameters::decode(bitfield_);
2356 bool is_function() { return IsFunction::decode(bitfield_) == kIsFunction; }
2358 // This is used as a heuristic on when to eagerly compile a function
2359 // literal. We consider the following constructs as hints that the
2360 // function will be called immediately:
2361 // - (function() { ... })();
2362 // - var x = function() { ... }();
2363 bool is_parenthesized() {
2364 return IsParenthesized::decode(bitfield_) == kIsParenthesized;
2366 void set_parenthesized() {
2367 bitfield_ = IsParenthesized::update(bitfield_, kIsParenthesized);
2370 bool is_generator() {
2371 return IsGenerator::decode(bitfield_) == kIsGenerator;
2374 int ast_node_count() { return ast_properties_.node_count(); }
2375 AstProperties::Flags* flags() { return ast_properties_.flags(); }
2376 void set_ast_properties(AstProperties* ast_properties) {
2377 ast_properties_ = *ast_properties;
2379 void set_slot_processor(DeferredFeedbackSlotProcessor* slot_processor) {
2380 slot_processor_ = *slot_processor;
2382 void ProcessFeedbackSlots(Isolate* isolate) {
2383 slot_processor_.ProcessFeedbackSlots(isolate);
2386 return slot_processor_.slot_count();
2388 bool dont_optimize() { return dont_optimize_reason_ != kNoReason; }
2389 BailoutReason dont_optimize_reason() { return dont_optimize_reason_; }
2390 void set_dont_optimize_reason(BailoutReason reason) {
2391 dont_optimize_reason_ = reason;
2395 FunctionLiteral(Zone* zone,
2396 Handle<String> name,
2398 ZoneList<Statement*>* body,
2399 int materialized_literal_count,
2400 int expected_property_count,
2402 int parameter_count,
2403 FunctionType function_type,
2404 ParameterFlag has_duplicate_parameters,
2405 IsFunctionFlag is_function,
2406 IsParenthesizedFlag is_parenthesized,
2407 IsGeneratorFlag is_generator,
2409 : Expression(zone, position),
2413 inferred_name_(zone->isolate()->factory()->empty_string()),
2414 dont_optimize_reason_(kNoReason),
2415 materialized_literal_count_(materialized_literal_count),
2416 expected_property_count_(expected_property_count),
2417 handler_count_(handler_count),
2418 parameter_count_(parameter_count),
2419 function_token_position_(RelocInfo::kNoPosition) {
2421 IsExpression::encode(function_type != DECLARATION) |
2422 IsAnonymous::encode(function_type == ANONYMOUS_EXPRESSION) |
2423 Pretenure::encode(false) |
2424 HasDuplicateParameters::encode(has_duplicate_parameters) |
2425 IsFunction::encode(is_function) |
2426 IsParenthesized::encode(is_parenthesized) |
2427 IsGenerator::encode(is_generator);
2431 Handle<String> name_;
2432 Handle<SharedFunctionInfo> shared_info_;
2434 ZoneList<Statement*>* body_;
2435 Handle<String> inferred_name_;
2436 AstProperties ast_properties_;
2437 DeferredFeedbackSlotProcessor slot_processor_;
2438 BailoutReason dont_optimize_reason_;
2440 int materialized_literal_count_;
2441 int expected_property_count_;
2443 int parameter_count_;
2444 int function_token_position_;
2447 class IsExpression: public BitField<bool, 0, 1> {};
2448 class IsAnonymous: public BitField<bool, 1, 1> {};
2449 class Pretenure: public BitField<bool, 2, 1> {};
2450 class HasDuplicateParameters: public BitField<ParameterFlag, 3, 1> {};
2451 class IsFunction: public BitField<IsFunctionFlag, 4, 1> {};
2452 class IsParenthesized: public BitField<IsParenthesizedFlag, 5, 1> {};
2453 class IsGenerator: public BitField<IsGeneratorFlag, 6, 1> {};
2457 class NativeFunctionLiteral V8_FINAL : public Expression {
2459 DECLARE_NODE_TYPE(NativeFunctionLiteral)
2461 Handle<String> name() const { return name_; }
2462 v8::Extension* extension() const { return extension_; }
2465 NativeFunctionLiteral(
2466 Zone* zone, Handle<String> name, v8::Extension* extension, int pos)
2467 : Expression(zone, pos), name_(name), extension_(extension) {}
2470 Handle<String> name_;
2471 v8::Extension* extension_;
2475 class ThisFunction V8_FINAL : public Expression {
2477 DECLARE_NODE_TYPE(ThisFunction)
2480 explicit ThisFunction(Zone* zone, int pos): Expression(zone, pos) {}
2483 #undef DECLARE_NODE_TYPE
2486 // ----------------------------------------------------------------------------
2487 // Regular expressions
2490 class RegExpVisitor BASE_EMBEDDED {
2492 virtual ~RegExpVisitor() { }
2493 #define MAKE_CASE(Name) \
2494 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
2495 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
2500 class RegExpTree : public ZoneObject {
2502 static const int kInfinity = kMaxInt;
2503 virtual ~RegExpTree() {}
2504 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
2505 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2506 RegExpNode* on_success) = 0;
2507 virtual bool IsTextElement() { return false; }
2508 virtual bool IsAnchoredAtStart() { return false; }
2509 virtual bool IsAnchoredAtEnd() { return false; }
2510 virtual int min_match() = 0;
2511 virtual int max_match() = 0;
2512 // Returns the interval of registers used for captures within this
2514 virtual Interval CaptureRegisters() { return Interval::Empty(); }
2515 virtual void AppendToText(RegExpText* text, Zone* zone);
2516 SmartArrayPointer<const char> ToString(Zone* zone);
2517 #define MAKE_ASTYPE(Name) \
2518 virtual RegExp##Name* As##Name(); \
2519 virtual bool Is##Name();
2520 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
2525 class RegExpDisjunction V8_FINAL : public RegExpTree {
2527 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
2528 virtual void* Accept(RegExpVisitor* visitor, void* data) V8_OVERRIDE;
2529 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2530 RegExpNode* on_success) V8_OVERRIDE;
2531 virtual RegExpDisjunction* AsDisjunction() V8_OVERRIDE;
2532 virtual Interval CaptureRegisters() V8_OVERRIDE;
2533 virtual bool IsDisjunction() V8_OVERRIDE;
2534 virtual bool IsAnchoredAtStart() V8_OVERRIDE;
2535 virtual bool IsAnchoredAtEnd() V8_OVERRIDE;
2536 virtual int min_match() V8_OVERRIDE { return min_match_; }
2537 virtual int max_match() V8_OVERRIDE { return max_match_; }
2538 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
2540 ZoneList<RegExpTree*>* alternatives_;
2546 class RegExpAlternative V8_FINAL : public RegExpTree {
2548 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
2549 virtual void* Accept(RegExpVisitor* visitor, void* data) V8_OVERRIDE;
2550 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2551 RegExpNode* on_success) V8_OVERRIDE;
2552 virtual RegExpAlternative* AsAlternative() V8_OVERRIDE;
2553 virtual Interval CaptureRegisters() V8_OVERRIDE;
2554 virtual bool IsAlternative() V8_OVERRIDE;
2555 virtual bool IsAnchoredAtStart() V8_OVERRIDE;
2556 virtual bool IsAnchoredAtEnd() V8_OVERRIDE;
2557 virtual int min_match() V8_OVERRIDE { return min_match_; }
2558 virtual int max_match() V8_OVERRIDE { return max_match_; }
2559 ZoneList<RegExpTree*>* nodes() { return nodes_; }
2561 ZoneList<RegExpTree*>* nodes_;
2567 class RegExpAssertion V8_FINAL : public RegExpTree {
2569 enum AssertionType {
2577 explicit RegExpAssertion(AssertionType type) : assertion_type_(type) { }
2578 virtual void* Accept(RegExpVisitor* visitor, void* data) V8_OVERRIDE;
2579 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2580 RegExpNode* on_success) V8_OVERRIDE;
2581 virtual RegExpAssertion* AsAssertion() V8_OVERRIDE;
2582 virtual bool IsAssertion() V8_OVERRIDE;
2583 virtual bool IsAnchoredAtStart() V8_OVERRIDE;
2584 virtual bool IsAnchoredAtEnd() V8_OVERRIDE;
2585 virtual int min_match() V8_OVERRIDE { return 0; }
2586 virtual int max_match() V8_OVERRIDE { return 0; }
2587 AssertionType assertion_type() { return assertion_type_; }
2589 AssertionType assertion_type_;
2593 class CharacterSet V8_FINAL BASE_EMBEDDED {
2595 explicit CharacterSet(uc16 standard_set_type)
2597 standard_set_type_(standard_set_type) {}
2598 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
2600 standard_set_type_(0) {}
2601 ZoneList<CharacterRange>* ranges(Zone* zone);
2602 uc16 standard_set_type() { return standard_set_type_; }
2603 void set_standard_set_type(uc16 special_set_type) {
2604 standard_set_type_ = special_set_type;
2606 bool is_standard() { return standard_set_type_ != 0; }
2607 void Canonicalize();
2609 ZoneList<CharacterRange>* ranges_;
2610 // If non-zero, the value represents a standard set (e.g., all whitespace
2611 // characters) without having to expand the ranges.
2612 uc16 standard_set_type_;
2616 class RegExpCharacterClass V8_FINAL : public RegExpTree {
2618 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
2620 is_negated_(is_negated) { }
2621 explicit RegExpCharacterClass(uc16 type)
2623 is_negated_(false) { }
2624 virtual void* Accept(RegExpVisitor* visitor, void* data) V8_OVERRIDE;
2625 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2626 RegExpNode* on_success) V8_OVERRIDE;
2627 virtual RegExpCharacterClass* AsCharacterClass() V8_OVERRIDE;
2628 virtual bool IsCharacterClass() V8_OVERRIDE;
2629 virtual bool IsTextElement() V8_OVERRIDE { return true; }
2630 virtual int min_match() V8_OVERRIDE { return 1; }
2631 virtual int max_match() V8_OVERRIDE { return 1; }
2632 virtual void AppendToText(RegExpText* text, Zone* zone) V8_OVERRIDE;
2633 CharacterSet character_set() { return set_; }
2634 // TODO(lrn): Remove need for complex version if is_standard that
2635 // recognizes a mangled standard set and just do { return set_.is_special(); }
2636 bool is_standard(Zone* zone);
2637 // Returns a value representing the standard character set if is_standard()
2639 // Currently used values are:
2640 // s : unicode whitespace
2641 // S : unicode non-whitespace
2642 // w : ASCII word character (digit, letter, underscore)
2643 // W : non-ASCII word character
2645 // D : non-ASCII digit
2646 // . : non-unicode non-newline
2647 // * : All characters
2648 uc16 standard_type() { return set_.standard_set_type(); }
2649 ZoneList<CharacterRange>* ranges(Zone* zone) { return set_.ranges(zone); }
2650 bool is_negated() { return is_negated_; }
2658 class RegExpAtom V8_FINAL : public RegExpTree {
2660 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
2661 virtual void* Accept(RegExpVisitor* visitor, void* data) V8_OVERRIDE;
2662 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2663 RegExpNode* on_success) V8_OVERRIDE;
2664 virtual RegExpAtom* AsAtom() V8_OVERRIDE;
2665 virtual bool IsAtom() V8_OVERRIDE;
2666 virtual bool IsTextElement() V8_OVERRIDE { return true; }
2667 virtual int min_match() V8_OVERRIDE { return data_.length(); }
2668 virtual int max_match() V8_OVERRIDE { return data_.length(); }
2669 virtual void AppendToText(RegExpText* text, Zone* zone) V8_OVERRIDE;
2670 Vector<const uc16> data() { return data_; }
2671 int length() { return data_.length(); }
2673 Vector<const uc16> data_;
2677 class RegExpText V8_FINAL : public RegExpTree {
2679 explicit RegExpText(Zone* zone) : elements_(2, zone), length_(0) {}
2680 virtual void* Accept(RegExpVisitor* visitor, void* data) V8_OVERRIDE;
2681 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2682 RegExpNode* on_success) V8_OVERRIDE;
2683 virtual RegExpText* AsText() V8_OVERRIDE;
2684 virtual bool IsText() V8_OVERRIDE;
2685 virtual bool IsTextElement() V8_OVERRIDE { return true; }
2686 virtual int min_match() V8_OVERRIDE { return length_; }
2687 virtual int max_match() V8_OVERRIDE { return length_; }
2688 virtual void AppendToText(RegExpText* text, Zone* zone) V8_OVERRIDE;
2689 void AddElement(TextElement elm, Zone* zone) {
2690 elements_.Add(elm, zone);
2691 length_ += elm.length();
2693 ZoneList<TextElement>* elements() { return &elements_; }
2695 ZoneList<TextElement> elements_;
2700 class RegExpQuantifier V8_FINAL : public RegExpTree {
2702 enum QuantifierType { GREEDY, NON_GREEDY, POSSESSIVE };
2703 RegExpQuantifier(int min, int max, QuantifierType type, RegExpTree* body)
2707 min_match_(min * body->min_match()),
2708 quantifier_type_(type) {
2709 if (max > 0 && body->max_match() > kInfinity / max) {
2710 max_match_ = kInfinity;
2712 max_match_ = max * body->max_match();
2715 virtual void* Accept(RegExpVisitor* visitor, void* data) V8_OVERRIDE;
2716 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2717 RegExpNode* on_success) V8_OVERRIDE;
2718 static RegExpNode* ToNode(int min,
2722 RegExpCompiler* compiler,
2723 RegExpNode* on_success,
2724 bool not_at_start = false);
2725 virtual RegExpQuantifier* AsQuantifier() V8_OVERRIDE;
2726 virtual Interval CaptureRegisters() V8_OVERRIDE;
2727 virtual bool IsQuantifier() V8_OVERRIDE;
2728 virtual int min_match() V8_OVERRIDE { return min_match_; }
2729 virtual int max_match() V8_OVERRIDE { return max_match_; }
2730 int min() { return min_; }
2731 int max() { return max_; }
2732 bool is_possessive() { return quantifier_type_ == POSSESSIVE; }
2733 bool is_non_greedy() { return quantifier_type_ == NON_GREEDY; }
2734 bool is_greedy() { return quantifier_type_ == GREEDY; }
2735 RegExpTree* body() { return body_; }
2743 QuantifierType quantifier_type_;
2747 class RegExpCapture V8_FINAL : public RegExpTree {
2749 explicit RegExpCapture(RegExpTree* body, int index)
2750 : body_(body), index_(index) { }
2751 virtual void* Accept(RegExpVisitor* visitor, void* data) V8_OVERRIDE;
2752 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2753 RegExpNode* on_success) V8_OVERRIDE;
2754 static RegExpNode* ToNode(RegExpTree* body,
2756 RegExpCompiler* compiler,
2757 RegExpNode* on_success);
2758 virtual RegExpCapture* AsCapture() V8_OVERRIDE;
2759 virtual bool IsAnchoredAtStart() V8_OVERRIDE;
2760 virtual bool IsAnchoredAtEnd() V8_OVERRIDE;
2761 virtual Interval CaptureRegisters() V8_OVERRIDE;
2762 virtual bool IsCapture() V8_OVERRIDE;
2763 virtual int min_match() V8_OVERRIDE { return body_->min_match(); }
2764 virtual int max_match() V8_OVERRIDE { return body_->max_match(); }
2765 RegExpTree* body() { return body_; }
2766 int index() { return index_; }
2767 static int StartRegister(int index) { return index * 2; }
2768 static int EndRegister(int index) { return index * 2 + 1; }
2776 class RegExpLookahead V8_FINAL : public RegExpTree {
2778 RegExpLookahead(RegExpTree* body,
2783 is_positive_(is_positive),
2784 capture_count_(capture_count),
2785 capture_from_(capture_from) { }
2787 virtual void* Accept(RegExpVisitor* visitor, void* data) V8_OVERRIDE;
2788 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2789 RegExpNode* on_success) V8_OVERRIDE;
2790 virtual RegExpLookahead* AsLookahead() V8_OVERRIDE;
2791 virtual Interval CaptureRegisters() V8_OVERRIDE;
2792 virtual bool IsLookahead() V8_OVERRIDE;
2793 virtual bool IsAnchoredAtStart() V8_OVERRIDE;
2794 virtual int min_match() V8_OVERRIDE { return 0; }
2795 virtual int max_match() V8_OVERRIDE { return 0; }
2796 RegExpTree* body() { return body_; }
2797 bool is_positive() { return is_positive_; }
2798 int capture_count() { return capture_count_; }
2799 int capture_from() { return capture_from_; }
2809 class RegExpBackReference V8_FINAL : public RegExpTree {
2811 explicit RegExpBackReference(RegExpCapture* capture)
2812 : capture_(capture) { }
2813 virtual void* Accept(RegExpVisitor* visitor, void* data) V8_OVERRIDE;
2814 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2815 RegExpNode* on_success) V8_OVERRIDE;
2816 virtual RegExpBackReference* AsBackReference() V8_OVERRIDE;
2817 virtual bool IsBackReference() V8_OVERRIDE;
2818 virtual int min_match() V8_OVERRIDE { return 0; }
2819 virtual int max_match() V8_OVERRIDE { return capture_->max_match(); }
2820 int index() { return capture_->index(); }
2821 RegExpCapture* capture() { return capture_; }
2823 RegExpCapture* capture_;
2827 class RegExpEmpty V8_FINAL : public RegExpTree {
2830 virtual void* Accept(RegExpVisitor* visitor, void* data) V8_OVERRIDE;
2831 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2832 RegExpNode* on_success) V8_OVERRIDE;
2833 virtual RegExpEmpty* AsEmpty() V8_OVERRIDE;
2834 virtual bool IsEmpty() V8_OVERRIDE;
2835 virtual int min_match() V8_OVERRIDE { return 0; }
2836 virtual int max_match() V8_OVERRIDE { return 0; }
2837 static RegExpEmpty* GetInstance() {
2838 static RegExpEmpty* instance = ::new RegExpEmpty();
2844 // ----------------------------------------------------------------------------
2845 // Out-of-line inline constructors (to side-step cyclic dependencies).
2847 inline ModuleVariable::ModuleVariable(Zone* zone, VariableProxy* proxy, int pos)
2848 : Module(zone, proxy->interface(), pos),
2853 // ----------------------------------------------------------------------------
2855 // - leaf node visitors are abstract.
2857 class AstVisitor BASE_EMBEDDED {
2860 virtual ~AstVisitor() {}
2862 // Stack overflow check and dynamic dispatch.
2863 virtual void Visit(AstNode* node) = 0;
2865 // Iteration left-to-right.
2866 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
2867 virtual void VisitStatements(ZoneList<Statement*>* statements);
2868 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
2870 // Individual AST nodes.
2871 #define DEF_VISIT(type) \
2872 virtual void Visit##type(type* node) = 0;
2873 AST_NODE_LIST(DEF_VISIT)
2878 #define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS() \
2880 virtual void Visit(AstNode* node) V8_FINAL V8_OVERRIDE { \
2881 if (!CheckStackOverflow()) node->Accept(this); \
2884 void SetStackOverflow() { stack_overflow_ = true; } \
2885 void ClearStackOverflow() { stack_overflow_ = false; } \
2886 bool HasStackOverflow() const { return stack_overflow_; } \
2888 bool CheckStackOverflow() { \
2889 if (stack_overflow_) return true; \
2890 StackLimitCheck check(zone_->isolate()); \
2891 if (!check.HasOverflowed()) return false; \
2892 return (stack_overflow_ = true); \
2896 void InitializeAstVisitor(Zone* zone) { \
2898 stack_overflow_ = false; \
2900 Zone* zone() { return zone_; } \
2901 Isolate* isolate() { return zone_->isolate(); } \
2904 bool stack_overflow_
2907 // ----------------------------------------------------------------------------
2908 // Construction time visitor.
2910 class AstConstructionVisitor BASE_EMBEDDED {
2912 explicit AstConstructionVisitor(Zone* zone)
2913 : dont_optimize_reason_(kNoReason),
2916 AstProperties* ast_properties() { return &properties_; }
2917 BailoutReason dont_optimize_reason() { return dont_optimize_reason_; }
2918 DeferredFeedbackSlotProcessor* slot_processor() { return &slot_processor_; }
2921 template<class> friend class AstNodeFactory;
2924 #define DEF_VISIT(type) \
2925 void Visit##type(type* node);
2926 AST_NODE_LIST(DEF_VISIT)
2929 void increase_node_count() { properties_.add_node_count(1); }
2930 void add_flag(AstPropertiesFlag flag) { properties_.flags()->Add(flag); }
2931 void set_dont_optimize_reason(BailoutReason reason) {
2932 dont_optimize_reason_ = reason;
2935 void add_slot_node(FeedbackSlotInterface* slot_node) {
2936 slot_processor_.add_slot_node(zone_, slot_node);
2939 AstProperties properties_;
2940 DeferredFeedbackSlotProcessor slot_processor_;
2941 BailoutReason dont_optimize_reason_;
2946 class AstNullVisitor BASE_EMBEDDED {
2948 explicit AstNullVisitor(Zone* zone) {}
2951 #define DEF_VISIT(type) \
2952 void Visit##type(type* node) {}
2953 AST_NODE_LIST(DEF_VISIT)
2959 // ----------------------------------------------------------------------------
2962 template<class Visitor>
2963 class AstNodeFactory V8_FINAL BASE_EMBEDDED {
2965 explicit AstNodeFactory(Zone* zone)
2969 Visitor* visitor() { return &visitor_; }
2971 #define VISIT_AND_RETURN(NodeType, node) \
2972 visitor_.Visit##NodeType((node)); \
2975 VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
2979 VariableDeclaration* decl =
2980 new(zone_) VariableDeclaration(zone_, proxy, mode, scope, pos);
2981 VISIT_AND_RETURN(VariableDeclaration, decl)
2984 FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy,
2986 FunctionLiteral* fun,
2989 FunctionDeclaration* decl =
2990 new(zone_) FunctionDeclaration(zone_, proxy, mode, fun, scope, pos);
2991 VISIT_AND_RETURN(FunctionDeclaration, decl)
2994 ModuleDeclaration* NewModuleDeclaration(VariableProxy* proxy,
2998 ModuleDeclaration* decl =
2999 new(zone_) ModuleDeclaration(zone_, proxy, module, scope, pos);
3000 VISIT_AND_RETURN(ModuleDeclaration, decl)
3003 ImportDeclaration* NewImportDeclaration(VariableProxy* proxy,
3007 ImportDeclaration* decl =
3008 new(zone_) ImportDeclaration(zone_, proxy, module, scope, pos);
3009 VISIT_AND_RETURN(ImportDeclaration, decl)
3012 ExportDeclaration* NewExportDeclaration(VariableProxy* proxy,
3015 ExportDeclaration* decl =
3016 new(zone_) ExportDeclaration(zone_, proxy, scope, pos);
3017 VISIT_AND_RETURN(ExportDeclaration, decl)
3020 ModuleLiteral* NewModuleLiteral(Block* body, Interface* interface, int pos) {
3021 ModuleLiteral* module =
3022 new(zone_) ModuleLiteral(zone_, body, interface, pos);
3023 VISIT_AND_RETURN(ModuleLiteral, module)
3026 ModuleVariable* NewModuleVariable(VariableProxy* proxy, int pos) {
3027 ModuleVariable* module = new(zone_) ModuleVariable(zone_, proxy, pos);
3028 VISIT_AND_RETURN(ModuleVariable, module)
3031 ModulePath* NewModulePath(Module* origin, Handle<String> name, int pos) {
3032 ModulePath* module = new(zone_) ModulePath(zone_, origin, name, pos);
3033 VISIT_AND_RETURN(ModulePath, module)
3036 ModuleUrl* NewModuleUrl(Handle<String> url, int pos) {
3037 ModuleUrl* module = new(zone_) ModuleUrl(zone_, url, pos);
3038 VISIT_AND_RETURN(ModuleUrl, module)
3041 Block* NewBlock(ZoneStringList* labels,
3043 bool is_initializer_block,
3045 Block* block = new(zone_) Block(
3046 zone_, labels, capacity, is_initializer_block, pos);
3047 VISIT_AND_RETURN(Block, block)
3050 #define STATEMENT_WITH_LABELS(NodeType) \
3051 NodeType* New##NodeType(ZoneStringList* labels, int pos) { \
3052 NodeType* stmt = new(zone_) NodeType(zone_, labels, pos); \
3053 VISIT_AND_RETURN(NodeType, stmt); \
3055 STATEMENT_WITH_LABELS(DoWhileStatement)
3056 STATEMENT_WITH_LABELS(WhileStatement)
3057 STATEMENT_WITH_LABELS(ForStatement)
3058 STATEMENT_WITH_LABELS(SwitchStatement)
3059 #undef STATEMENT_WITH_LABELS
3061 ForEachStatement* NewForEachStatement(ForEachStatement::VisitMode visit_mode,
3062 ZoneStringList* labels,
3064 switch (visit_mode) {
3065 case ForEachStatement::ENUMERATE: {
3066 ForInStatement* stmt = new(zone_) ForInStatement(zone_, labels, pos);
3067 VISIT_AND_RETURN(ForInStatement, stmt);
3069 case ForEachStatement::ITERATE: {
3070 ForOfStatement* stmt = new(zone_) ForOfStatement(zone_, labels, pos);
3071 VISIT_AND_RETURN(ForOfStatement, stmt);
3078 ModuleStatement* NewModuleStatement(
3079 VariableProxy* proxy, Block* body, int pos) {
3080 ModuleStatement* stmt = new(zone_) ModuleStatement(zone_, proxy, body, pos);
3081 VISIT_AND_RETURN(ModuleStatement, stmt)
3084 ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
3085 ExpressionStatement* stmt =
3086 new(zone_) ExpressionStatement(zone_, expression, pos);
3087 VISIT_AND_RETURN(ExpressionStatement, stmt)
3090 ContinueStatement* NewContinueStatement(IterationStatement* target, int pos) {
3091 ContinueStatement* stmt = new(zone_) ContinueStatement(zone_, target, pos);
3092 VISIT_AND_RETURN(ContinueStatement, stmt)
3095 BreakStatement* NewBreakStatement(BreakableStatement* target, int pos) {
3096 BreakStatement* stmt = new(zone_) BreakStatement(zone_, target, pos);
3097 VISIT_AND_RETURN(BreakStatement, stmt)
3100 ReturnStatement* NewReturnStatement(Expression* expression, int pos) {
3101 ReturnStatement* stmt = new(zone_) ReturnStatement(zone_, expression, pos);
3102 VISIT_AND_RETURN(ReturnStatement, stmt)
3105 WithStatement* NewWithStatement(Scope* scope,
3106 Expression* expression,
3107 Statement* statement,
3109 WithStatement* stmt = new(zone_) WithStatement(
3110 zone_, scope, expression, statement, pos);
3111 VISIT_AND_RETURN(WithStatement, stmt)
3114 IfStatement* NewIfStatement(Expression* condition,
3115 Statement* then_statement,
3116 Statement* else_statement,
3118 IfStatement* stmt = new(zone_) IfStatement(
3119 zone_, condition, then_statement, else_statement, pos);
3120 VISIT_AND_RETURN(IfStatement, stmt)
3123 TryCatchStatement* NewTryCatchStatement(int index,
3129 TryCatchStatement* stmt = new(zone_) TryCatchStatement(
3130 zone_, index, try_block, scope, variable, catch_block, pos);
3131 VISIT_AND_RETURN(TryCatchStatement, stmt)
3134 TryFinallyStatement* NewTryFinallyStatement(int index,
3136 Block* finally_block,
3138 TryFinallyStatement* stmt = new(zone_) TryFinallyStatement(
3139 zone_, index, try_block, finally_block, pos);
3140 VISIT_AND_RETURN(TryFinallyStatement, stmt)
3143 DebuggerStatement* NewDebuggerStatement(int pos) {
3144 DebuggerStatement* stmt = new(zone_) DebuggerStatement(zone_, pos);
3145 VISIT_AND_RETURN(DebuggerStatement, stmt)
3148 EmptyStatement* NewEmptyStatement(int pos) {
3149 return new(zone_) EmptyStatement(zone_, pos);
3152 CaseClause* NewCaseClause(
3153 Expression* label, ZoneList<Statement*>* statements, int pos) {
3154 CaseClause* clause =
3155 new(zone_) CaseClause(zone_, label, statements, pos);
3156 VISIT_AND_RETURN(CaseClause, clause)
3159 Literal* NewLiteral(Handle<Object> handle, int pos) {
3160 Literal* lit = new(zone_) Literal(zone_, handle, pos);
3161 VISIT_AND_RETURN(Literal, lit)
3164 Literal* NewNumberLiteral(double number, int pos) {
3166 zone_->isolate()->factory()->NewNumber(number, TENURED), pos);
3169 ObjectLiteral* NewObjectLiteral(
3170 ZoneList<ObjectLiteral::Property*>* properties,
3172 int boilerplate_properties,
3175 ObjectLiteral* lit = new(zone_) ObjectLiteral(
3176 zone_, properties, literal_index, boilerplate_properties,
3178 VISIT_AND_RETURN(ObjectLiteral, lit)
3181 ObjectLiteral::Property* NewObjectLiteralProperty(Literal* key,
3182 Expression* value) {
3183 return new(zone_) ObjectLiteral::Property(zone_, key, value);
3186 ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter,
3187 FunctionLiteral* value,
3189 ObjectLiteral::Property* prop =
3190 new(zone_) ObjectLiteral::Property(zone_, is_getter, value);
3191 prop->set_key(NewLiteral(value->name(), pos));
3192 return prop; // Not an AST node, will not be visited.
3195 RegExpLiteral* NewRegExpLiteral(Handle<String> pattern,
3196 Handle<String> flags,
3199 RegExpLiteral* lit =
3200 new(zone_) RegExpLiteral(zone_, pattern, flags, literal_index, pos);
3201 VISIT_AND_RETURN(RegExpLiteral, lit);
3204 ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
3207 ArrayLiteral* lit = new(zone_) ArrayLiteral(
3208 zone_, values, literal_index, pos);
3209 VISIT_AND_RETURN(ArrayLiteral, lit)
3212 VariableProxy* NewVariableProxy(Variable* var,
3213 int pos = RelocInfo::kNoPosition) {
3214 VariableProxy* proxy = new(zone_) VariableProxy(zone_, var, pos);
3215 VISIT_AND_RETURN(VariableProxy, proxy)
3218 VariableProxy* NewVariableProxy(Handle<String> name,
3220 Interface* interface = Interface::NewValue(),
3221 int position = RelocInfo::kNoPosition) {
3222 VariableProxy* proxy =
3223 new(zone_) VariableProxy(zone_, name, is_this, interface, position);
3224 VISIT_AND_RETURN(VariableProxy, proxy)
3227 Property* NewProperty(Expression* obj, Expression* key, int pos) {
3228 Property* prop = new(zone_) Property(zone_, obj, key, pos);
3229 VISIT_AND_RETURN(Property, prop)
3232 Call* NewCall(Expression* expression,
3233 ZoneList<Expression*>* arguments,
3235 Call* call = new(zone_) Call(zone_, expression, arguments, pos);
3236 VISIT_AND_RETURN(Call, call)
3239 CallNew* NewCallNew(Expression* expression,
3240 ZoneList<Expression*>* arguments,
3242 CallNew* call = new(zone_) CallNew(zone_, expression, arguments, pos);
3243 VISIT_AND_RETURN(CallNew, call)
3246 CallRuntime* NewCallRuntime(Handle<String> name,
3247 const Runtime::Function* function,
3248 ZoneList<Expression*>* arguments,
3251 new(zone_) CallRuntime(zone_, name, function, arguments, pos);
3252 VISIT_AND_RETURN(CallRuntime, call)
3255 UnaryOperation* NewUnaryOperation(Token::Value op,
3256 Expression* expression,
3258 UnaryOperation* node =
3259 new(zone_) UnaryOperation(zone_, op, expression, pos);
3260 VISIT_AND_RETURN(UnaryOperation, node)
3263 BinaryOperation* NewBinaryOperation(Token::Value op,
3267 BinaryOperation* node =
3268 new(zone_) BinaryOperation(zone_, op, left, right, pos);
3269 VISIT_AND_RETURN(BinaryOperation, node)
3272 CountOperation* NewCountOperation(Token::Value op,
3276 CountOperation* node =
3277 new(zone_) CountOperation(zone_, op, is_prefix, expr, pos);
3278 VISIT_AND_RETURN(CountOperation, node)
3281 CompareOperation* NewCompareOperation(Token::Value op,
3285 CompareOperation* node =
3286 new(zone_) CompareOperation(zone_, op, left, right, pos);
3287 VISIT_AND_RETURN(CompareOperation, node)
3290 Conditional* NewConditional(Expression* condition,
3291 Expression* then_expression,
3292 Expression* else_expression,
3294 Conditional* cond = new(zone_) Conditional(
3295 zone_, condition, then_expression, else_expression, position);
3296 VISIT_AND_RETURN(Conditional, cond)
3299 Assignment* NewAssignment(Token::Value op,
3303 Assignment* assign =
3304 new(zone_) Assignment(zone_, op, target, value, pos);
3305 assign->Init(zone_, this);
3306 VISIT_AND_RETURN(Assignment, assign)
3309 Yield* NewYield(Expression *generator_object,
3310 Expression* expression,
3311 Yield::Kind yield_kind,
3313 Yield* yield = new(zone_) Yield(
3314 zone_, generator_object, expression, yield_kind, pos);
3315 VISIT_AND_RETURN(Yield, yield)
3318 Throw* NewThrow(Expression* exception, int pos) {
3319 Throw* t = new(zone_) Throw(zone_, exception, pos);
3320 VISIT_AND_RETURN(Throw, t)
3323 FunctionLiteral* NewFunctionLiteral(
3324 Handle<String> name,
3326 ZoneList<Statement*>* body,
3327 int materialized_literal_count,
3328 int expected_property_count,
3330 int parameter_count,
3331 FunctionLiteral::ParameterFlag has_duplicate_parameters,
3332 FunctionLiteral::FunctionType function_type,
3333 FunctionLiteral::IsFunctionFlag is_function,
3334 FunctionLiteral::IsParenthesizedFlag is_parenthesized,
3335 FunctionLiteral::IsGeneratorFlag is_generator,
3337 FunctionLiteral* lit = new(zone_) FunctionLiteral(
3338 zone_, name, scope, body,
3339 materialized_literal_count, expected_property_count, handler_count,
3340 parameter_count, function_type, has_duplicate_parameters, is_function,
3341 is_parenthesized, is_generator, position);
3342 // Top-level literal doesn't count for the AST's properties.
3343 if (is_function == FunctionLiteral::kIsFunction) {
3344 visitor_.VisitFunctionLiteral(lit);
3349 NativeFunctionLiteral* NewNativeFunctionLiteral(
3350 Handle<String> name, v8::Extension* extension, int pos) {
3351 NativeFunctionLiteral* lit =
3352 new(zone_) NativeFunctionLiteral(zone_, name, extension, pos);
3353 VISIT_AND_RETURN(NativeFunctionLiteral, lit)
3356 ThisFunction* NewThisFunction(int pos) {
3357 ThisFunction* fun = new(zone_) ThisFunction(zone_, pos);
3358 VISIT_AND_RETURN(ThisFunction, fun)
3361 #undef VISIT_AND_RETURN
3369 } } // namespace v8::internal