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"
39 #include "small-pointer-list.h"
40 #include "smart-array-pointer.h"
43 #include "variables.h"
44 #include "interface.h"
50 // The abstract syntax tree is an intermediate, light-weight
51 // representation of the parsed JavaScript code suitable for
52 // compilation to native code.
54 // Nodes are allocated in a separate zone, which allows faster
55 // allocation and constant-time deallocation of the entire syntax
59 // ----------------------------------------------------------------------------
60 // Nodes of the abstract syntax tree. Only concrete classes are
63 #define DECLARATION_NODE_LIST(V) \
64 V(VariableDeclaration) \
65 V(FunctionDeclaration) \
66 V(ModuleDeclaration) \
67 V(ImportDeclaration) \
68 V(ExportDeclaration) \
70 #define MODULE_NODE_LIST(V) \
76 #define STATEMENT_NODE_LIST(V) \
78 V(ExpressionStatement) \
81 V(ContinueStatement) \
90 V(TryCatchStatement) \
91 V(TryFinallyStatement) \
94 #define EXPRESSION_NODE_LIST(V) \
96 V(SharedFunctionInfoLiteral) \
112 V(CompareOperation) \
115 #define AST_NODE_LIST(V) \
116 DECLARATION_NODE_LIST(V) \
117 MODULE_NODE_LIST(V) \
118 STATEMENT_NODE_LIST(V) \
119 EXPRESSION_NODE_LIST(V)
121 // Forward declarations
122 class AstConstructionVisitor;
123 template<class> class AstNodeFactory;
127 class BreakableStatement;
129 class IterationStatement;
130 class MaterializedLiteral;
132 class TargetCollector;
133 class TypeFeedbackOracle;
135 class RegExpAlternative;
136 class RegExpAssertion;
138 class RegExpBackReference;
140 class RegExpCharacterClass;
141 class RegExpCompiler;
142 class RegExpDisjunction;
144 class RegExpLookahead;
145 class RegExpQuantifier;
148 #define DEF_FORWARD_DECLARATION(type) class type;
149 AST_NODE_LIST(DEF_FORWARD_DECLARATION)
150 #undef DEF_FORWARD_DECLARATION
153 // Typedef only introduced to avoid unreadable code.
154 // Please do appreciate the required space in "> >".
155 typedef ZoneList<Handle<String> > ZoneStringList;
156 typedef ZoneList<Handle<Object> > ZoneObjectList;
159 #define DECLARE_NODE_TYPE(type) \
160 virtual void Accept(AstVisitor* v); \
161 virtual AstNode::Type node_type() const { return AstNode::k##type; }
164 enum AstPropertiesFlag {
172 class AstProperties BASE_EMBEDDED {
174 class Flags : public EnumSet<AstPropertiesFlag, int> {};
176 AstProperties() : node_count_(0) { }
178 Flags* flags() { return &flags_; }
179 int node_count() { return node_count_; }
180 void add_node_count(int count) { node_count_ += count; }
188 class AstNode: public ZoneObject {
190 #define DECLARE_TYPE_ENUM(type) k##type,
192 AST_NODE_LIST(DECLARE_TYPE_ENUM)
195 #undef DECLARE_TYPE_ENUM
197 static const int kNoNumber = -1;
198 static const int kFunctionEntryId = 2; // Using 0 could disguise errors.
199 // This AST id identifies the point after the declarations have been
200 // visited. We need it to capture the environment effects of declarations
201 // that emit code (function declarations).
202 static const int kDeclarationsId = 3;
204 void* operator new(size_t size, Zone* zone) {
205 return zone->New(static_cast<int>(size));
210 virtual ~AstNode() { }
212 virtual void Accept(AstVisitor* v) = 0;
213 virtual Type node_type() const { return kInvalid; }
215 // Type testing & conversion functions overridden by concrete subclasses.
216 #define DECLARE_NODE_FUNCTIONS(type) \
217 bool Is##type() { return node_type() == AstNode::k##type; } \
218 type* As##type() { return Is##type() ? reinterpret_cast<type*>(this) : NULL; }
219 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
220 #undef DECLARE_NODE_FUNCTIONS
222 virtual Declaration* AsDeclaration() { return NULL; }
223 virtual Statement* AsStatement() { return NULL; }
224 virtual Expression* AsExpression() { return NULL; }
225 virtual TargetCollector* AsTargetCollector() { return NULL; }
226 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
227 virtual IterationStatement* AsIterationStatement() { return NULL; }
228 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
231 static int GetNextId(Isolate* isolate) {
232 return ReserveIdRange(isolate, 1);
235 static int ReserveIdRange(Isolate* isolate, int n) {
236 int tmp = isolate->ast_node_id();
237 isolate->set_ast_node_id(tmp + n);
242 // Hidden to prevent accidental usage. It would have to load the
243 // current zone from the TLS.
244 void* operator new(size_t size);
246 friend class CaseClause; // Generates AST IDs.
250 class Statement: public AstNode {
252 Statement() : statement_pos_(RelocInfo::kNoPosition) {}
254 virtual Statement* AsStatement() { return this; }
256 bool IsEmpty() { return AsEmptyStatement() != NULL; }
258 void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
259 int statement_pos() const { return statement_pos_; }
269 explicit SmallMapList(int capacity) : list_(capacity) {}
271 void Reserve(int capacity) { list_.Reserve(capacity); }
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 Add(Handle<Map> handle) {
279 list_.Add(handle.location());
282 Handle<Map> at(int i) const {
283 return Handle<Map>(list_.at(i));
286 Handle<Map> first() const { return at(0); }
287 Handle<Map> last() const { return at(length() - 1); }
290 // The list stores pointers to Map*, that is Map**, so it's GC safe.
291 SmallPointerList<Map*> list_;
293 DISALLOW_COPY_AND_ASSIGN(SmallMapList);
297 class Expression: public AstNode {
300 // Not assigned a context yet, or else will not be visited during
303 // Evaluated for its side effects.
305 // Evaluated for its value (and side effects).
307 // Evaluated for control flow (and side effects).
311 virtual int position() const {
316 virtual Expression* AsExpression() { return this; }
318 virtual bool IsValidLeftHandSide() { return false; }
320 // Helpers for ToBoolean conversion.
321 virtual bool ToBooleanIsTrue() { return false; }
322 virtual bool ToBooleanIsFalse() { return false; }
324 // Symbols that cannot be parsed as array indices are considered property
325 // names. We do not treat symbols that can be array indexes as property
326 // names because [] for string objects is handled only by keyed ICs.
327 virtual bool IsPropertyName() { return false; }
329 // True iff the result can be safely overwritten (to avoid allocation).
330 // False for operations that can return one of their operands.
331 virtual bool ResultOverwriteAllowed() { return false; }
333 // True iff the expression is a literal represented as a smi.
336 // True iff the expression is a string literal.
337 bool IsStringLiteral();
339 // True iff the expression is the null literal.
340 bool IsNullLiteral();
342 // Type feedback information for assignments and properties.
343 virtual bool IsMonomorphic() {
347 virtual SmallMapList* GetReceiverTypes() {
351 Handle<Map> GetMonomorphicReceiverType() {
352 ASSERT(IsMonomorphic());
353 SmallMapList* types = GetReceiverTypes();
354 ASSERT(types != NULL && types->length() == 1);
358 unsigned id() const { return id_; }
359 unsigned test_id() const { return test_id_; }
362 explicit Expression(Isolate* isolate)
363 : id_(GetNextId(isolate)),
364 test_id_(GetNextId(isolate)) {}
372 class BreakableStatement: public Statement {
375 TARGET_FOR_ANONYMOUS,
376 TARGET_FOR_NAMED_ONLY
379 // The labels associated with this statement. May be NULL;
380 // if it is != NULL, guaranteed to contain at least one entry.
381 ZoneStringList* labels() const { return labels_; }
383 // Type testing & conversion.
384 virtual BreakableStatement* AsBreakableStatement() { return this; }
387 Label* break_target() { return &break_target_; }
390 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
393 int EntryId() const { return entry_id_; }
394 int ExitId() const { return exit_id_; }
397 BreakableStatement(Isolate* isolate, ZoneStringList* labels, Type type)
400 entry_id_(GetNextId(isolate)),
401 exit_id_(GetNextId(isolate)) {
402 ASSERT(labels == NULL || labels->length() > 0);
407 ZoneStringList* labels_;
415 class Block: public BreakableStatement {
417 DECLARE_NODE_TYPE(Block)
419 void AddStatement(Statement* statement) { statements_.Add(statement); }
421 ZoneList<Statement*>* statements() { return &statements_; }
422 bool is_initializer_block() const { return is_initializer_block_; }
424 Scope* scope() const { return scope_; }
425 void set_scope(Scope* scope) { scope_ = scope; }
428 template<class> friend class AstNodeFactory;
430 Block(Isolate* isolate,
431 ZoneStringList* labels,
433 bool is_initializer_block)
434 : BreakableStatement(isolate, labels, TARGET_FOR_NAMED_ONLY),
435 statements_(capacity),
436 is_initializer_block_(is_initializer_block),
441 ZoneList<Statement*> statements_;
442 bool is_initializer_block_;
447 class Declaration: public AstNode {
449 VariableProxy* proxy() const { return proxy_; }
450 VariableMode mode() const { return mode_; }
451 Scope* scope() const { return scope_; }
452 virtual InitializationFlag initialization() const = 0;
453 virtual bool IsInlineable() const;
455 virtual Declaration* AsDeclaration() { return this; }
458 Declaration(VariableProxy* proxy,
464 ASSERT(mode == VAR ||
466 mode == CONST_HARMONY ||
471 VariableProxy* proxy_;
474 // Nested scope from which the declaration originated.
479 class VariableDeclaration: public Declaration {
481 DECLARE_NODE_TYPE(VariableDeclaration)
483 virtual InitializationFlag initialization() const {
484 return mode() == VAR ? kCreatedInitialized : kNeedsInitialization;
488 template<class> friend class AstNodeFactory;
490 VariableDeclaration(VariableProxy* proxy,
493 : Declaration(proxy, mode, scope) {
498 class FunctionDeclaration: public Declaration {
500 DECLARE_NODE_TYPE(FunctionDeclaration)
502 FunctionLiteral* fun() const { return fun_; }
503 virtual InitializationFlag initialization() const {
504 return kCreatedInitialized;
506 virtual bool IsInlineable() const;
509 template<class> friend class AstNodeFactory;
511 FunctionDeclaration(VariableProxy* proxy,
513 FunctionLiteral* fun,
515 : Declaration(proxy, mode, scope),
517 // At the moment there are no "const functions" in JavaScript...
518 ASSERT(mode == VAR || mode == LET);
523 FunctionLiteral* fun_;
527 class ModuleDeclaration: public Declaration {
529 DECLARE_NODE_TYPE(ModuleDeclaration)
531 Module* module() const { return module_; }
532 virtual InitializationFlag initialization() const {
533 return kCreatedInitialized;
537 template<class> friend class AstNodeFactory;
539 ModuleDeclaration(VariableProxy* proxy,
542 : Declaration(proxy, LET, scope),
551 class ImportDeclaration: public Declaration {
553 DECLARE_NODE_TYPE(ImportDeclaration)
555 Module* module() const { return module_; }
556 virtual InitializationFlag initialization() const {
557 return kCreatedInitialized;
561 template<class> friend class AstNodeFactory;
563 ImportDeclaration(VariableProxy* proxy,
566 : Declaration(proxy, LET, scope),
575 class ExportDeclaration: public Declaration {
577 DECLARE_NODE_TYPE(ExportDeclaration)
579 virtual InitializationFlag initialization() const {
580 return kCreatedInitialized;
584 template<class> friend class AstNodeFactory;
586 ExportDeclaration(VariableProxy* proxy,
588 : Declaration(proxy, LET, scope) {
593 class Module: public AstNode {
595 Interface* interface() const { return interface_; }
598 Module() : interface_(Interface::NewModule()) {}
599 explicit Module(Interface* interface) : interface_(interface) {}
602 Interface* interface_;
606 class ModuleLiteral: public Module {
608 DECLARE_NODE_TYPE(ModuleLiteral)
610 Block* body() const { return body_; }
611 Handle<Context> context() const { return context_; }
614 template<class> friend class AstNodeFactory;
616 ModuleLiteral(Block* body, Interface* interface)
623 Handle<Context> context_;
627 class ModuleVariable: public Module {
629 DECLARE_NODE_TYPE(ModuleVariable)
631 VariableProxy* proxy() const { return proxy_; }
634 template<class> friend class AstNodeFactory;
636 inline explicit ModuleVariable(VariableProxy* proxy);
639 VariableProxy* proxy_;
643 class ModulePath: public Module {
645 DECLARE_NODE_TYPE(ModulePath)
647 Module* module() const { return module_; }
648 Handle<String> name() const { return name_; }
651 template<class> friend class AstNodeFactory;
653 ModulePath(Module* module, Handle<String> name)
660 Handle<String> name_;
664 class ModuleUrl: public Module {
666 DECLARE_NODE_TYPE(ModuleUrl)
668 Handle<String> url() const { return url_; }
671 template<class> friend class AstNodeFactory;
673 explicit ModuleUrl(Handle<String> url) : url_(url) {
681 class IterationStatement: public BreakableStatement {
683 // Type testing & conversion.
684 virtual IterationStatement* AsIterationStatement() { return this; }
686 Statement* body() const { return body_; }
689 int OsrEntryId() const { return osr_entry_id_; }
690 virtual int ContinueId() const = 0;
691 virtual int StackCheckId() const = 0;
694 Label* continue_target() { return &continue_target_; }
697 IterationStatement(Isolate* isolate, ZoneStringList* labels)
698 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
700 osr_entry_id_(GetNextId(isolate)) {
703 void Initialize(Statement* body) {
709 Label continue_target_;
714 class DoWhileStatement: public IterationStatement {
716 DECLARE_NODE_TYPE(DoWhileStatement)
718 void Initialize(Expression* cond, Statement* body) {
719 IterationStatement::Initialize(body);
723 Expression* cond() const { return cond_; }
725 // Position where condition expression starts. We need it to make
726 // the loop's condition a breakable location.
727 int condition_position() { return condition_position_; }
728 void set_condition_position(int pos) { condition_position_ = pos; }
731 virtual int ContinueId() const { return continue_id_; }
732 virtual int StackCheckId() const { return back_edge_id_; }
733 int BackEdgeId() const { return back_edge_id_; }
736 template<class> friend class AstNodeFactory;
738 DoWhileStatement(Isolate* isolate, ZoneStringList* labels)
739 : IterationStatement(isolate, labels),
741 condition_position_(-1),
742 continue_id_(GetNextId(isolate)),
743 back_edge_id_(GetNextId(isolate)) {
748 int condition_position_;
754 class WhileStatement: public IterationStatement {
756 DECLARE_NODE_TYPE(WhileStatement)
758 void Initialize(Expression* cond, Statement* body) {
759 IterationStatement::Initialize(body);
763 Expression* cond() const { return cond_; }
764 bool may_have_function_literal() const {
765 return may_have_function_literal_;
767 void set_may_have_function_literal(bool value) {
768 may_have_function_literal_ = value;
772 virtual int ContinueId() const { return EntryId(); }
773 virtual int StackCheckId() const { return body_id_; }
774 int BodyId() const { return body_id_; }
777 template<class> friend class AstNodeFactory;
779 WhileStatement(Isolate* isolate, ZoneStringList* labels)
780 : IterationStatement(isolate, labels),
782 may_have_function_literal_(true),
783 body_id_(GetNextId(isolate)) {
788 // True if there is a function literal subexpression in the condition.
789 bool may_have_function_literal_;
794 class ForStatement: public IterationStatement {
796 DECLARE_NODE_TYPE(ForStatement)
798 void Initialize(Statement* init,
802 IterationStatement::Initialize(body);
808 Statement* init() const { return init_; }
809 Expression* cond() const { return cond_; }
810 Statement* next() const { return next_; }
812 bool may_have_function_literal() const {
813 return may_have_function_literal_;
815 void set_may_have_function_literal(bool value) {
816 may_have_function_literal_ = value;
820 virtual int ContinueId() const { return continue_id_; }
821 virtual int StackCheckId() const { return body_id_; }
822 int BodyId() const { return body_id_; }
824 bool is_fast_smi_loop() { return loop_variable_ != NULL; }
825 Variable* loop_variable() { return loop_variable_; }
826 void set_loop_variable(Variable* var) { loop_variable_ = var; }
829 template<class> friend class AstNodeFactory;
831 ForStatement(Isolate* isolate, ZoneStringList* labels)
832 : IterationStatement(isolate, labels),
836 may_have_function_literal_(true),
837 loop_variable_(NULL),
838 continue_id_(GetNextId(isolate)),
839 body_id_(GetNextId(isolate)) {
846 // True if there is a function literal subexpression in the condition.
847 bool may_have_function_literal_;
848 Variable* loop_variable_;
854 class ForInStatement: public IterationStatement {
856 DECLARE_NODE_TYPE(ForInStatement)
858 void Initialize(Expression* each, Expression* enumerable, Statement* body) {
859 IterationStatement::Initialize(body);
861 enumerable_ = enumerable;
864 Expression* each() const { return each_; }
865 Expression* enumerable() const { return enumerable_; }
867 virtual int ContinueId() const { return EntryId(); }
868 virtual int StackCheckId() const { return body_id_; }
869 int BodyId() const { return body_id_; }
870 int PrepareId() const { return prepare_id_; }
873 template<class> friend class AstNodeFactory;
875 ForInStatement(Isolate* isolate, ZoneStringList* labels)
876 : IterationStatement(isolate, labels),
879 body_id_(GetNextId(isolate)),
880 prepare_id_(GetNextId(isolate)) {
885 Expression* enumerable_;
891 class ExpressionStatement: public Statement {
893 DECLARE_NODE_TYPE(ExpressionStatement)
895 void set_expression(Expression* e) { expression_ = e; }
896 Expression* expression() const { return expression_; }
899 template<class> friend class AstNodeFactory;
901 explicit ExpressionStatement(Expression* expression)
902 : expression_(expression) { }
905 Expression* expression_;
909 class ContinueStatement: public Statement {
911 DECLARE_NODE_TYPE(ContinueStatement)
913 IterationStatement* target() const { return target_; }
916 template<class> friend class AstNodeFactory;
918 explicit ContinueStatement(IterationStatement* target)
919 : target_(target) { }
922 IterationStatement* target_;
926 class BreakStatement: public Statement {
928 DECLARE_NODE_TYPE(BreakStatement)
930 BreakableStatement* target() const { return target_; }
933 template<class> friend class AstNodeFactory;
935 explicit BreakStatement(BreakableStatement* target)
936 : target_(target) { }
939 BreakableStatement* target_;
943 class ReturnStatement: public Statement {
945 DECLARE_NODE_TYPE(ReturnStatement)
947 Expression* expression() const { return expression_; }
950 template<class> friend class AstNodeFactory;
952 explicit ReturnStatement(Expression* expression)
953 : expression_(expression) { }
956 Expression* expression_;
960 class WithStatement: public Statement {
962 DECLARE_NODE_TYPE(WithStatement)
964 Expression* expression() const { return expression_; }
965 Statement* statement() const { return statement_; }
968 template<class> friend class AstNodeFactory;
970 WithStatement(Expression* expression, Statement* statement)
971 : expression_(expression),
972 statement_(statement) { }
975 Expression* expression_;
976 Statement* statement_;
980 class CaseClause: public ZoneObject {
982 CaseClause(Isolate* isolate,
984 ZoneList<Statement*>* statements,
987 bool is_default() const { return label_ == NULL; }
988 Expression* label() const {
989 CHECK(!is_default());
992 Label* body_target() { return &body_target_; }
993 ZoneList<Statement*>* statements() const { return statements_; }
995 int position() const { return position_; }
996 void set_position(int pos) { position_ = pos; }
998 int EntryId() { return entry_id_; }
999 int CompareId() { return compare_id_; }
1001 // Type feedback information.
1002 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1003 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
1004 bool IsSymbolCompare() { return compare_type_ == SYMBOL_ONLY; }
1005 bool IsStringCompare() { return compare_type_ == STRING_ONLY; }
1006 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1011 ZoneList<Statement*>* statements_;
1013 enum CompareTypeFeedback {
1020 CompareTypeFeedback compare_type_;
1026 class SwitchStatement: public BreakableStatement {
1028 DECLARE_NODE_TYPE(SwitchStatement)
1030 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
1035 Expression* tag() const { return tag_; }
1036 ZoneList<CaseClause*>* cases() const { return cases_; }
1039 template<class> friend class AstNodeFactory;
1041 SwitchStatement(Isolate* isolate, ZoneStringList* labels)
1042 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
1048 ZoneList<CaseClause*>* cases_;
1052 // If-statements always have non-null references to their then- and
1053 // else-parts. When parsing if-statements with no explicit else-part,
1054 // the parser implicitly creates an empty statement. Use the
1055 // HasThenStatement() and HasElseStatement() functions to check if a
1056 // given if-statement has a then- or an else-part containing code.
1057 class IfStatement: public Statement {
1059 DECLARE_NODE_TYPE(IfStatement)
1061 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
1062 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
1064 Expression* condition() const { return condition_; }
1065 Statement* then_statement() const { return then_statement_; }
1066 Statement* else_statement() const { return else_statement_; }
1068 int IfId() const { return if_id_; }
1069 int ThenId() const { return then_id_; }
1070 int ElseId() const { return else_id_; }
1073 template<class> friend class AstNodeFactory;
1075 IfStatement(Isolate* isolate,
1076 Expression* condition,
1077 Statement* then_statement,
1078 Statement* else_statement)
1079 : condition_(condition),
1080 then_statement_(then_statement),
1081 else_statement_(else_statement),
1082 if_id_(GetNextId(isolate)),
1083 then_id_(GetNextId(isolate)),
1084 else_id_(GetNextId(isolate)) {
1088 Expression* condition_;
1089 Statement* then_statement_;
1090 Statement* else_statement_;
1097 // NOTE: TargetCollectors are represented as nodes to fit in the target
1098 // stack in the compiler; this should probably be reworked.
1099 class TargetCollector: public AstNode {
1101 TargetCollector() : targets_(0) { }
1103 // Adds a jump target to the collector. The collector stores a pointer not
1104 // a copy of the target to make binding work, so make sure not to pass in
1105 // references to something on the stack.
1106 void AddTarget(Label* target);
1108 // Virtual behaviour. TargetCollectors are never part of the AST.
1109 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
1110 virtual TargetCollector* AsTargetCollector() { return this; }
1112 ZoneList<Label*>* targets() { return &targets_; }
1115 ZoneList<Label*> targets_;
1119 class TryStatement: public Statement {
1121 void set_escaping_targets(ZoneList<Label*>* targets) {
1122 escaping_targets_ = targets;
1125 int index() const { return index_; }
1126 Block* try_block() const { return try_block_; }
1127 ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
1130 TryStatement(int index, Block* try_block)
1132 try_block_(try_block),
1133 escaping_targets_(NULL) { }
1136 // Unique (per-function) index of this handler. This is not an AST ID.
1140 ZoneList<Label*>* escaping_targets_;
1144 class TryCatchStatement: public TryStatement {
1146 DECLARE_NODE_TYPE(TryCatchStatement)
1148 Scope* scope() { return scope_; }
1149 Variable* variable() { return variable_; }
1150 Block* catch_block() const { return catch_block_; }
1153 template<class> friend class AstNodeFactory;
1155 TryCatchStatement(int index,
1160 : TryStatement(index, try_block),
1162 variable_(variable),
1163 catch_block_(catch_block) {
1168 Variable* variable_;
1169 Block* catch_block_;
1173 class TryFinallyStatement: public TryStatement {
1175 DECLARE_NODE_TYPE(TryFinallyStatement)
1177 Block* finally_block() const { return finally_block_; }
1180 template<class> friend class AstNodeFactory;
1182 TryFinallyStatement(int index, Block* try_block, Block* finally_block)
1183 : TryStatement(index, try_block),
1184 finally_block_(finally_block) { }
1187 Block* finally_block_;
1191 class DebuggerStatement: public Statement {
1193 DECLARE_NODE_TYPE(DebuggerStatement)
1196 template<class> friend class AstNodeFactory;
1198 DebuggerStatement() {}
1202 class EmptyStatement: public Statement {
1204 DECLARE_NODE_TYPE(EmptyStatement)
1207 template<class> friend class AstNodeFactory;
1213 class Literal: public Expression {
1215 DECLARE_NODE_TYPE(Literal)
1217 virtual bool IsPropertyName() {
1218 if (handle_->IsSymbol()) {
1220 return !String::cast(*handle_)->AsArrayIndex(&ignored);
1225 Handle<String> AsPropertyName() {
1226 ASSERT(IsPropertyName());
1227 return Handle<String>::cast(handle_);
1230 virtual bool ToBooleanIsTrue() { return handle_->ToBoolean()->IsTrue(); }
1231 virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
1233 // Identity testers.
1234 bool IsNull() const {
1235 ASSERT(!handle_.is_null());
1236 return handle_->IsNull();
1238 bool IsTrue() const {
1239 ASSERT(!handle_.is_null());
1240 return handle_->IsTrue();
1242 bool IsFalse() const {
1243 ASSERT(!handle_.is_null());
1244 return handle_->IsFalse();
1247 Handle<Object> handle() const { return handle_; }
1249 // Support for using Literal as a HashMap key. NOTE: Currently, this works
1250 // only for string and number literals!
1251 uint32_t Hash() { return ToString()->Hash(); }
1253 static bool Match(void* literal1, void* literal2) {
1254 Handle<String> s1 = static_cast<Literal*>(literal1)->ToString();
1255 Handle<String> s2 = static_cast<Literal*>(literal2)->ToString();
1256 return s1->Equals(*s2);
1260 template<class> friend class AstNodeFactory;
1262 Literal(Isolate* isolate, Handle<Object> handle)
1263 : Expression(isolate),
1267 Handle<String> ToString();
1269 Handle<Object> handle_;
1273 // Base class for literals that needs space in the corresponding JSFunction.
1274 class MaterializedLiteral: public Expression {
1276 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
1278 int literal_index() { return literal_index_; }
1280 // A materialized literal is simple if the values consist of only
1281 // constants and simple object and array literals.
1282 bool is_simple() const { return is_simple_; }
1284 int depth() const { return depth_; }
1287 MaterializedLiteral(Isolate* isolate,
1291 : Expression(isolate),
1292 literal_index_(literal_index),
1293 is_simple_(is_simple),
1303 // An object literal has a boilerplate object that is used
1304 // for minimizing the work when constructing it at runtime.
1305 class ObjectLiteral: public MaterializedLiteral {
1307 // Property is used for passing information
1308 // about an object literal's properties from the parser
1309 // to the code generator.
1310 class Property: public ZoneObject {
1313 CONSTANT, // Property with constant value (compile time).
1314 COMPUTED, // Property with computed value (execution time).
1315 MATERIALIZED_LITERAL, // Property value is a materialized literal.
1316 GETTER, SETTER, // Property is an accessor function.
1317 PROTOTYPE // Property is __proto__.
1320 Property(Literal* key, Expression* value, Isolate* isolate);
1322 Literal* key() { return key_; }
1323 Expression* value() { return value_; }
1324 Kind kind() { return kind_; }
1326 // Type feedback information.
1327 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1328 bool IsMonomorphic() { return !receiver_type_.is_null(); }
1329 Handle<Map> GetReceiverType() { return receiver_type_; }
1331 bool IsCompileTimeValue();
1333 void set_emit_store(bool emit_store);
1337 template<class> friend class AstNodeFactory;
1339 Property(bool is_getter, FunctionLiteral* value);
1340 void set_key(Literal* key) { key_ = key; }
1347 Handle<Map> receiver_type_;
1350 DECLARE_NODE_TYPE(ObjectLiteral)
1352 Handle<FixedArray> constant_properties() const {
1353 return constant_properties_;
1355 ZoneList<Property*>* properties() const { return properties_; }
1357 bool fast_elements() const { return fast_elements_; }
1359 bool has_function() { return has_function_; }
1361 // Mark all computed expressions that are bound to a key that
1362 // is shadowed by a later occurrence of the same key. For the
1363 // marked expressions, no store code is emitted.
1364 void CalculateEmitStore();
1369 kHasFunction = 1 << 1
1372 struct Accessors: public ZoneObject {
1373 Accessors() : getter(NULL), setter(NULL) { }
1379 template<class> friend class AstNodeFactory;
1381 ObjectLiteral(Isolate* isolate,
1382 Handle<FixedArray> constant_properties,
1383 ZoneList<Property*>* properties,
1389 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
1390 constant_properties_(constant_properties),
1391 properties_(properties),
1392 fast_elements_(fast_elements),
1393 has_function_(has_function) {}
1396 Handle<FixedArray> constant_properties_;
1397 ZoneList<Property*>* properties_;
1398 bool fast_elements_;
1403 // Node for capturing a regexp literal.
1404 class RegExpLiteral: public MaterializedLiteral {
1406 DECLARE_NODE_TYPE(RegExpLiteral)
1408 Handle<String> pattern() const { return pattern_; }
1409 Handle<String> flags() const { return flags_; }
1412 template<class> friend class AstNodeFactory;
1414 RegExpLiteral(Isolate* isolate,
1415 Handle<String> pattern,
1416 Handle<String> flags,
1418 : MaterializedLiteral(isolate, literal_index, false, 1),
1423 Handle<String> pattern_;
1424 Handle<String> flags_;
1427 // An array literal has a literals object that is used
1428 // for minimizing the work when constructing it at runtime.
1429 class ArrayLiteral: public MaterializedLiteral {
1431 DECLARE_NODE_TYPE(ArrayLiteral)
1433 Handle<FixedArray> constant_elements() const { return constant_elements_; }
1434 ZoneList<Expression*>* values() const { return values_; }
1436 // Return an AST id for an element that is used in simulate instructions.
1437 int GetIdForElement(int i) { return first_element_id_ + i; }
1440 template<class> friend class AstNodeFactory;
1442 ArrayLiteral(Isolate* isolate,
1443 Handle<FixedArray> constant_elements,
1444 ZoneList<Expression*>* values,
1448 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
1449 constant_elements_(constant_elements),
1451 first_element_id_(ReserveIdRange(isolate, values->length())) {}
1454 Handle<FixedArray> constant_elements_;
1455 ZoneList<Expression*>* values_;
1456 int first_element_id_;
1460 class VariableProxy: public Expression {
1462 DECLARE_NODE_TYPE(VariableProxy)
1464 virtual bool IsValidLeftHandSide() {
1465 return var_ == NULL ? true : var_->IsValidLeftHandSide();
1468 bool IsVariable(Handle<String> n) {
1469 return !is_this() && name().is_identical_to(n);
1472 bool IsArguments() { return var_ != NULL && var_->is_arguments(); }
1478 Handle<String> name() const { return name_; }
1479 Variable* var() const { return var_; }
1480 bool is_this() const { return is_this_; }
1481 int position() const { return position_; }
1482 Interface* interface() const { return interface_; }
1485 void MarkAsTrivial() { is_trivial_ = true; }
1486 void MarkAsLValue() { is_lvalue_ = true; }
1488 // Bind this proxy to the variable var.
1489 void BindTo(Variable* var);
1492 template<class> friend class AstNodeFactory;
1494 VariableProxy(Isolate* isolate, Variable* var);
1496 VariableProxy(Isolate* isolate,
1497 Handle<String> name,
1500 Interface* interface);
1502 Handle<String> name_;
1503 Variable* var_; // resolved variable, or NULL
1506 // True if this variable proxy is being used in an assignment
1507 // or with a increment/decrement operator.
1510 Interface* interface_;
1514 class Property: public Expression {
1516 DECLARE_NODE_TYPE(Property)
1518 virtual bool IsValidLeftHandSide() { return true; }
1520 Expression* obj() const { return obj_; }
1521 Expression* key() const { return key_; }
1522 virtual int position() const { return pos_; }
1524 bool IsStringLength() const { return is_string_length_; }
1525 bool IsStringAccess() const { return is_string_access_; }
1526 bool IsFunctionPrototype() const { return is_function_prototype_; }
1528 // Type feedback information.
1529 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1530 virtual bool IsMonomorphic() { return is_monomorphic_; }
1531 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1532 bool IsArrayLength() { return is_array_length_; }
1533 bool IsUninitialized() { return is_uninitialized_; }
1536 template<class> friend class AstNodeFactory;
1538 Property(Isolate* isolate,
1542 : Expression(isolate),
1546 is_monomorphic_(false),
1547 is_uninitialized_(false),
1548 is_array_length_(false),
1549 is_string_length_(false),
1550 is_string_access_(false),
1551 is_function_prototype_(false) { }
1558 SmallMapList receiver_types_;
1559 bool is_monomorphic_ : 1;
1560 bool is_uninitialized_ : 1;
1561 bool is_array_length_ : 1;
1562 bool is_string_length_ : 1;
1563 bool is_string_access_ : 1;
1564 bool is_function_prototype_ : 1;
1568 class Call: public Expression {
1570 DECLARE_NODE_TYPE(Call)
1572 Expression* expression() const { return expression_; }
1573 ZoneList<Expression*>* arguments() const { return arguments_; }
1574 virtual int position() const { return pos_; }
1576 void RecordTypeFeedback(TypeFeedbackOracle* oracle,
1577 CallKind call_kind);
1578 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1579 virtual bool IsMonomorphic() { return is_monomorphic_; }
1580 CheckType check_type() const { return check_type_; }
1581 Handle<JSFunction> target() { return target_; }
1582 Handle<JSObject> holder() { return holder_; }
1583 Handle<JSGlobalPropertyCell> cell() { return cell_; }
1585 bool ComputeTarget(Handle<Map> type, Handle<String> name);
1586 bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
1589 int ReturnId() const { return return_id_; }
1592 // Used to assert that the FullCodeGenerator records the return site.
1593 bool return_is_recorded_;
1597 template<class> friend class AstNodeFactory;
1599 Call(Isolate* isolate,
1600 Expression* expression,
1601 ZoneList<Expression*>* arguments,
1603 : Expression(isolate),
1604 expression_(expression),
1605 arguments_(arguments),
1607 is_monomorphic_(false),
1608 check_type_(RECEIVER_MAP_CHECK),
1609 return_id_(GetNextId(isolate)) { }
1612 Expression* expression_;
1613 ZoneList<Expression*>* arguments_;
1616 bool is_monomorphic_;
1617 CheckType check_type_;
1618 SmallMapList receiver_types_;
1619 Handle<JSFunction> target_;
1620 Handle<JSObject> holder_;
1621 Handle<JSGlobalPropertyCell> cell_;
1627 class CallNew: public Expression {
1629 DECLARE_NODE_TYPE(CallNew)
1631 Expression* expression() const { return expression_; }
1632 ZoneList<Expression*>* arguments() const { return arguments_; }
1633 virtual int position() const { return pos_; }
1635 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1636 virtual bool IsMonomorphic() { return is_monomorphic_; }
1637 Handle<JSFunction> target() { return target_; }
1640 int ReturnId() const { return return_id_; }
1643 template<class> friend class AstNodeFactory;
1645 CallNew(Isolate* isolate,
1646 Expression* expression,
1647 ZoneList<Expression*>* arguments,
1649 : Expression(isolate),
1650 expression_(expression),
1651 arguments_(arguments),
1653 is_monomorphic_(false),
1654 return_id_(GetNextId(isolate)) { }
1657 Expression* expression_;
1658 ZoneList<Expression*>* arguments_;
1661 bool is_monomorphic_;
1662 Handle<JSFunction> target_;
1668 // The CallRuntime class does not represent any official JavaScript
1669 // language construct. Instead it is used to call a C or JS function
1670 // with a set of arguments. This is used from the builtins that are
1671 // implemented in JavaScript (see "v8natives.js").
1672 class CallRuntime: public Expression {
1674 DECLARE_NODE_TYPE(CallRuntime)
1676 Handle<String> name() const { return name_; }
1677 const Runtime::Function* function() const { return function_; }
1678 ZoneList<Expression*>* arguments() const { return arguments_; }
1679 bool is_jsruntime() const { return function_ == NULL; }
1682 template<class> friend class AstNodeFactory;
1684 CallRuntime(Isolate* isolate,
1685 Handle<String> name,
1686 const Runtime::Function* function,
1687 ZoneList<Expression*>* arguments)
1688 : Expression(isolate),
1690 function_(function),
1691 arguments_(arguments) { }
1694 Handle<String> name_;
1695 const Runtime::Function* function_;
1696 ZoneList<Expression*>* arguments_;
1700 class UnaryOperation: public Expression {
1702 DECLARE_NODE_TYPE(UnaryOperation)
1704 virtual bool ResultOverwriteAllowed();
1706 Token::Value op() const { return op_; }
1707 Expression* expression() const { return expression_; }
1708 virtual int position() const { return pos_; }
1710 int MaterializeTrueId() { return materialize_true_id_; }
1711 int MaterializeFalseId() { return materialize_false_id_; }
1714 template<class> friend class AstNodeFactory;
1716 UnaryOperation(Isolate* isolate,
1718 Expression* expression,
1720 : Expression(isolate),
1722 expression_(expression),
1724 materialize_true_id_(AstNode::kNoNumber),
1725 materialize_false_id_(AstNode::kNoNumber) {
1726 ASSERT(Token::IsUnaryOp(op));
1727 if (op == Token::NOT) {
1728 materialize_true_id_ = GetNextId(isolate);
1729 materialize_false_id_ = GetNextId(isolate);
1735 Expression* expression_;
1738 // For unary not (Token::NOT), the AST ids where true and false will
1739 // actually be materialized, respectively.
1740 int materialize_true_id_;
1741 int materialize_false_id_;
1745 class BinaryOperation: public Expression {
1747 DECLARE_NODE_TYPE(BinaryOperation)
1749 virtual bool ResultOverwriteAllowed();
1751 Token::Value op() const { return op_; }
1752 Expression* left() const { return left_; }
1753 Expression* right() const { return right_; }
1754 virtual int position() const { return pos_; }
1757 int RightId() const { return right_id_; }
1760 template<class> friend class AstNodeFactory;
1762 BinaryOperation(Isolate* isolate,
1767 : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) {
1768 ASSERT(Token::IsBinaryOp(op));
1769 right_id_ = (op == Token::AND || op == Token::OR)
1770 ? GetNextId(isolate)
1771 : AstNode::kNoNumber;
1779 // The short-circuit logical operations have an AST ID for their
1780 // right-hand subexpression.
1785 class CountOperation: public Expression {
1787 DECLARE_NODE_TYPE(CountOperation)
1789 bool is_prefix() const { return is_prefix_; }
1790 bool is_postfix() const { return !is_prefix_; }
1792 Token::Value op() const { return op_; }
1793 Token::Value binary_op() {
1794 return (op() == Token::INC) ? Token::ADD : Token::SUB;
1797 Expression* expression() const { return expression_; }
1798 virtual int position() const { return pos_; }
1800 virtual void MarkAsStatement() { is_prefix_ = true; }
1802 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1803 virtual bool IsMonomorphic() { return is_monomorphic_; }
1804 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1807 int AssignmentId() const { return assignment_id_; }
1808 int CountId() const { return count_id_; }
1811 template<class> friend class AstNodeFactory;
1813 CountOperation(Isolate* isolate,
1818 : Expression(isolate),
1820 is_prefix_(is_prefix),
1823 assignment_id_(GetNextId(isolate)),
1824 count_id_(GetNextId(isolate)) {}
1829 bool is_monomorphic_;
1830 Expression* expression_;
1834 SmallMapList receiver_types_;
1838 class CompareOperation: public Expression {
1840 DECLARE_NODE_TYPE(CompareOperation)
1842 Token::Value op() const { return op_; }
1843 Expression* left() const { return left_; }
1844 Expression* right() const { return right_; }
1845 virtual int position() const { return pos_; }
1847 // Type feedback information.
1848 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1849 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
1850 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1852 // Match special cases.
1853 bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
1854 bool IsLiteralCompareUndefined(Expression** expr);
1855 bool IsLiteralCompareNull(Expression** expr);
1858 template<class> friend class AstNodeFactory;
1860 CompareOperation(Isolate* isolate,
1865 : Expression(isolate),
1870 compare_type_(NONE) {
1871 ASSERT(Token::IsCompareOp(op));
1880 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
1881 CompareTypeFeedback compare_type_;
1885 class Conditional: public Expression {
1887 DECLARE_NODE_TYPE(Conditional)
1889 Expression* condition() const { return condition_; }
1890 Expression* then_expression() const { return then_expression_; }
1891 Expression* else_expression() const { return else_expression_; }
1893 int then_expression_position() const { return then_expression_position_; }
1894 int else_expression_position() const { return else_expression_position_; }
1896 int ThenId() const { return then_id_; }
1897 int ElseId() const { return else_id_; }
1900 template<class> friend class AstNodeFactory;
1902 Conditional(Isolate* isolate,
1903 Expression* condition,
1904 Expression* then_expression,
1905 Expression* else_expression,
1906 int then_expression_position,
1907 int else_expression_position)
1908 : Expression(isolate),
1909 condition_(condition),
1910 then_expression_(then_expression),
1911 else_expression_(else_expression),
1912 then_expression_position_(then_expression_position),
1913 else_expression_position_(else_expression_position),
1914 then_id_(GetNextId(isolate)),
1915 else_id_(GetNextId(isolate)) { }
1918 Expression* condition_;
1919 Expression* then_expression_;
1920 Expression* else_expression_;
1921 int then_expression_position_;
1922 int else_expression_position_;
1928 class Assignment: public Expression {
1930 DECLARE_NODE_TYPE(Assignment)
1932 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1934 Token::Value binary_op() const;
1936 Token::Value op() const { return op_; }
1937 Expression* target() const { return target_; }
1938 Expression* value() const { return value_; }
1939 virtual int position() const { return pos_; }
1940 BinaryOperation* binary_operation() const { return binary_operation_; }
1942 // This check relies on the definition order of token in token.h.
1943 bool is_compound() const { return op() > Token::ASSIGN; }
1945 // An initialization block is a series of statments of the form
1946 // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1947 // ending of these blocks to allow for optimizations of initialization
1949 bool starts_initialization_block() { return block_start_; }
1950 bool ends_initialization_block() { return block_end_; }
1951 void mark_block_start() { block_start_ = true; }
1952 void mark_block_end() { block_end_ = true; }
1954 // Type feedback information.
1955 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1956 virtual bool IsMonomorphic() { return is_monomorphic_; }
1957 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1960 int CompoundLoadId() const { return compound_load_id_; }
1961 int AssignmentId() const { return assignment_id_; }
1964 template<class> friend class AstNodeFactory;
1966 Assignment(Isolate* isolate,
1972 template<class Visitor>
1973 void Init(Isolate* isolate, AstNodeFactory<Visitor>* factory) {
1974 ASSERT(Token::IsAssignmentOp(op_));
1975 if (is_compound()) {
1977 factory->NewBinaryOperation(binary_op(), target_, value_, pos_ + 1);
1978 compound_load_id_ = GetNextId(isolate);
1984 Expression* target_;
1987 BinaryOperation* binary_operation_;
1988 int compound_load_id_;
1994 bool is_monomorphic_;
1995 SmallMapList receiver_types_;
1999 class Throw: public Expression {
2001 DECLARE_NODE_TYPE(Throw)
2003 Expression* exception() const { return exception_; }
2004 virtual int position() const { return pos_; }
2007 template<class> friend class AstNodeFactory;
2009 Throw(Isolate* isolate, Expression* exception, int pos)
2010 : Expression(isolate), exception_(exception), pos_(pos) {}
2013 Expression* exception_;
2018 class FunctionLiteral: public Expression {
2021 ANONYMOUS_EXPRESSION,
2026 enum ParameterFlag {
2027 kNoDuplicateParameters = 0,
2028 kHasDuplicateParameters = 1
2031 enum IsFunctionFlag {
2036 DECLARE_NODE_TYPE(FunctionLiteral)
2038 Handle<String> name() const { return name_; }
2039 Scope* scope() const { return scope_; }
2040 ZoneList<Statement*>* body() const { return body_; }
2041 void set_function_token_position(int pos) { function_token_position_ = pos; }
2042 int function_token_position() const { return function_token_position_; }
2043 int start_position() const;
2044 int end_position() const;
2045 int SourceSize() const { return end_position() - start_position(); }
2046 bool is_expression() const { return IsExpression::decode(bitfield_); }
2047 bool is_anonymous() const { return IsAnonymous::decode(bitfield_); }
2048 bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; }
2049 LanguageMode language_mode() const;
2051 int materialized_literal_count() { return materialized_literal_count_; }
2052 int expected_property_count() { return expected_property_count_; }
2053 int handler_count() { return handler_count_; }
2054 bool has_only_simple_this_property_assignments() {
2055 return HasOnlySimpleThisPropertyAssignments::decode(bitfield_);
2057 Handle<FixedArray> this_property_assignments() {
2058 return this_property_assignments_;
2060 int parameter_count() { return parameter_count_; }
2062 bool AllowsLazyCompilation();
2064 Handle<String> debug_name() const {
2065 if (name_->length() > 0) return name_;
2066 return inferred_name();
2069 Handle<String> inferred_name() const { return inferred_name_; }
2070 void set_inferred_name(Handle<String> inferred_name) {
2071 inferred_name_ = inferred_name;
2074 bool pretenure() { return Pretenure::decode(bitfield_); }
2075 void set_pretenure() { bitfield_ |= Pretenure::encode(true); }
2077 bool has_duplicate_parameters() {
2078 return HasDuplicateParameters::decode(bitfield_);
2081 bool is_function() { return IsFunction::decode(bitfield_) == kIsFunction; }
2083 int ast_node_count() { return ast_properties_.node_count(); }
2084 AstProperties::Flags* flags() { return ast_properties_.flags(); }
2085 void set_ast_properties(AstProperties* ast_properties) {
2086 ast_properties_ = *ast_properties;
2090 template<class> friend class AstNodeFactory;
2092 FunctionLiteral(Isolate* isolate,
2093 Handle<String> name,
2095 ZoneList<Statement*>* body,
2096 int materialized_literal_count,
2097 int expected_property_count,
2099 bool has_only_simple_this_property_assignments,
2100 Handle<FixedArray> this_property_assignments,
2101 int parameter_count,
2103 ParameterFlag has_duplicate_parameters,
2104 IsFunctionFlag is_function)
2105 : Expression(isolate),
2109 this_property_assignments_(this_property_assignments),
2110 inferred_name_(isolate->factory()->empty_string()),
2111 materialized_literal_count_(materialized_literal_count),
2112 expected_property_count_(expected_property_count),
2113 handler_count_(handler_count),
2114 parameter_count_(parameter_count),
2115 function_token_position_(RelocInfo::kNoPosition) {
2117 HasOnlySimpleThisPropertyAssignments::encode(
2118 has_only_simple_this_property_assignments) |
2119 IsExpression::encode(type != DECLARATION) |
2120 IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) |
2121 Pretenure::encode(false) |
2122 HasDuplicateParameters::encode(has_duplicate_parameters) |
2123 IsFunction::encode(is_function);
2127 Handle<String> name_;
2129 ZoneList<Statement*>* body_;
2130 Handle<FixedArray> this_property_assignments_;
2131 Handle<String> inferred_name_;
2132 AstProperties ast_properties_;
2134 int materialized_literal_count_;
2135 int expected_property_count_;
2137 int parameter_count_;
2138 int function_token_position_;
2141 class HasOnlySimpleThisPropertyAssignments: public BitField<bool, 0, 1> {};
2142 class IsExpression: public BitField<bool, 1, 1> {};
2143 class IsAnonymous: public BitField<bool, 2, 1> {};
2144 class Pretenure: public BitField<bool, 3, 1> {};
2145 class HasDuplicateParameters: public BitField<ParameterFlag, 4, 1> {};
2146 class IsFunction: public BitField<IsFunctionFlag, 5, 1> {};
2150 class SharedFunctionInfoLiteral: public Expression {
2152 DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
2154 Handle<SharedFunctionInfo> shared_function_info() const {
2155 return shared_function_info_;
2159 template<class> friend class AstNodeFactory;
2161 SharedFunctionInfoLiteral(
2163 Handle<SharedFunctionInfo> shared_function_info)
2164 : Expression(isolate),
2165 shared_function_info_(shared_function_info) { }
2168 Handle<SharedFunctionInfo> shared_function_info_;
2172 class ThisFunction: public Expression {
2174 DECLARE_NODE_TYPE(ThisFunction)
2177 template<class> friend class AstNodeFactory;
2179 explicit ThisFunction(Isolate* isolate): Expression(isolate) {}
2182 #undef DECLARE_NODE_TYPE
2185 // ----------------------------------------------------------------------------
2186 // Regular expressions
2189 class RegExpVisitor BASE_EMBEDDED {
2191 virtual ~RegExpVisitor() { }
2192 #define MAKE_CASE(Name) \
2193 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
2194 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
2199 class RegExpTree: public ZoneObject {
2201 static const int kInfinity = kMaxInt;
2202 virtual ~RegExpTree() { }
2203 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
2204 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2205 RegExpNode* on_success) = 0;
2206 virtual bool IsTextElement() { return false; }
2207 virtual bool IsAnchoredAtStart() { return false; }
2208 virtual bool IsAnchoredAtEnd() { return false; }
2209 virtual int min_match() = 0;
2210 virtual int max_match() = 0;
2211 // Returns the interval of registers used for captures within this
2213 virtual Interval CaptureRegisters() { return Interval::Empty(); }
2214 virtual void AppendToText(RegExpText* text);
2215 SmartArrayPointer<const char> ToString();
2216 #define MAKE_ASTYPE(Name) \
2217 virtual RegExp##Name* As##Name(); \
2218 virtual bool Is##Name();
2219 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
2224 class RegExpDisjunction: public RegExpTree {
2226 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
2227 virtual void* Accept(RegExpVisitor* visitor, void* data);
2228 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2229 RegExpNode* on_success);
2230 virtual RegExpDisjunction* AsDisjunction();
2231 virtual Interval CaptureRegisters();
2232 virtual bool IsDisjunction();
2233 virtual bool IsAnchoredAtStart();
2234 virtual bool IsAnchoredAtEnd();
2235 virtual int min_match() { return min_match_; }
2236 virtual int max_match() { return max_match_; }
2237 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
2239 ZoneList<RegExpTree*>* alternatives_;
2245 class RegExpAlternative: public RegExpTree {
2247 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
2248 virtual void* Accept(RegExpVisitor* visitor, void* data);
2249 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2250 RegExpNode* on_success);
2251 virtual RegExpAlternative* AsAlternative();
2252 virtual Interval CaptureRegisters();
2253 virtual bool IsAlternative();
2254 virtual bool IsAnchoredAtStart();
2255 virtual bool IsAnchoredAtEnd();
2256 virtual int min_match() { return min_match_; }
2257 virtual int max_match() { return max_match_; }
2258 ZoneList<RegExpTree*>* nodes() { return nodes_; }
2260 ZoneList<RegExpTree*>* nodes_;
2266 class RegExpAssertion: public RegExpTree {
2276 explicit RegExpAssertion(Type type) : type_(type) { }
2277 virtual void* Accept(RegExpVisitor* visitor, void* data);
2278 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2279 RegExpNode* on_success);
2280 virtual RegExpAssertion* AsAssertion();
2281 virtual bool IsAssertion();
2282 virtual bool IsAnchoredAtStart();
2283 virtual bool IsAnchoredAtEnd();
2284 virtual int min_match() { return 0; }
2285 virtual int max_match() { return 0; }
2286 Type type() { return type_; }
2292 class CharacterSet BASE_EMBEDDED {
2294 explicit CharacterSet(uc16 standard_set_type)
2296 standard_set_type_(standard_set_type) {}
2297 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
2299 standard_set_type_(0) {}
2300 ZoneList<CharacterRange>* ranges();
2301 uc16 standard_set_type() { return standard_set_type_; }
2302 void set_standard_set_type(uc16 special_set_type) {
2303 standard_set_type_ = special_set_type;
2305 bool is_standard() { return standard_set_type_ != 0; }
2306 void Canonicalize();
2308 ZoneList<CharacterRange>* ranges_;
2309 // If non-zero, the value represents a standard set (e.g., all whitespace
2310 // characters) without having to expand the ranges.
2311 uc16 standard_set_type_;
2315 class RegExpCharacterClass: public RegExpTree {
2317 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
2319 is_negated_(is_negated) { }
2320 explicit RegExpCharacterClass(uc16 type)
2322 is_negated_(false) { }
2323 virtual void* Accept(RegExpVisitor* visitor, void* data);
2324 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2325 RegExpNode* on_success);
2326 virtual RegExpCharacterClass* AsCharacterClass();
2327 virtual bool IsCharacterClass();
2328 virtual bool IsTextElement() { return true; }
2329 virtual int min_match() { return 1; }
2330 virtual int max_match() { return 1; }
2331 virtual void AppendToText(RegExpText* text);
2332 CharacterSet character_set() { return set_; }
2333 // TODO(lrn): Remove need for complex version if is_standard that
2334 // recognizes a mangled standard set and just do { return set_.is_special(); }
2336 // Returns a value representing the standard character set if is_standard()
2338 // Currently used values are:
2339 // s : unicode whitespace
2340 // S : unicode non-whitespace
2341 // w : ASCII word character (digit, letter, underscore)
2342 // W : non-ASCII word character
2344 // D : non-ASCII digit
2345 // . : non-unicode non-newline
2346 // * : All characters
2347 uc16 standard_type() { return set_.standard_set_type(); }
2348 ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
2349 bool is_negated() { return is_negated_; }
2357 class RegExpAtom: public RegExpTree {
2359 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
2360 virtual void* Accept(RegExpVisitor* visitor, void* data);
2361 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2362 RegExpNode* on_success);
2363 virtual RegExpAtom* AsAtom();
2364 virtual bool IsAtom();
2365 virtual bool IsTextElement() { return true; }
2366 virtual int min_match() { return data_.length(); }
2367 virtual int max_match() { return data_.length(); }
2368 virtual void AppendToText(RegExpText* text);
2369 Vector<const uc16> data() { return data_; }
2370 int length() { return data_.length(); }
2372 Vector<const uc16> data_;
2376 class RegExpText: public RegExpTree {
2378 RegExpText() : elements_(2), length_(0) {}
2379 virtual void* Accept(RegExpVisitor* visitor, void* data);
2380 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2381 RegExpNode* on_success);
2382 virtual RegExpText* AsText();
2383 virtual bool IsText();
2384 virtual bool IsTextElement() { return true; }
2385 virtual int min_match() { return length_; }
2386 virtual int max_match() { return length_; }
2387 virtual void AppendToText(RegExpText* text);
2388 void AddElement(TextElement elm) {
2390 length_ += elm.length();
2392 ZoneList<TextElement>* elements() { return &elements_; }
2394 ZoneList<TextElement> elements_;
2399 class RegExpQuantifier: public RegExpTree {
2401 enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
2402 RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
2406 min_match_(min * body->min_match()),
2408 if (max > 0 && body->max_match() > kInfinity / max) {
2409 max_match_ = kInfinity;
2411 max_match_ = max * body->max_match();
2414 virtual void* Accept(RegExpVisitor* visitor, void* data);
2415 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2416 RegExpNode* on_success);
2417 static RegExpNode* ToNode(int min,
2421 RegExpCompiler* compiler,
2422 RegExpNode* on_success,
2423 bool not_at_start = false);
2424 virtual RegExpQuantifier* AsQuantifier();
2425 virtual Interval CaptureRegisters();
2426 virtual bool IsQuantifier();
2427 virtual int min_match() { return min_match_; }
2428 virtual int max_match() { return max_match_; }
2429 int min() { return min_; }
2430 int max() { return max_; }
2431 bool is_possessive() { return type_ == POSSESSIVE; }
2432 bool is_non_greedy() { return type_ == NON_GREEDY; }
2433 bool is_greedy() { return type_ == GREEDY; }
2434 RegExpTree* body() { return body_; }
2446 class RegExpCapture: public RegExpTree {
2448 explicit RegExpCapture(RegExpTree* body, int index)
2449 : body_(body), index_(index) { }
2450 virtual void* Accept(RegExpVisitor* visitor, void* data);
2451 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2452 RegExpNode* on_success);
2453 static RegExpNode* ToNode(RegExpTree* body,
2455 RegExpCompiler* compiler,
2456 RegExpNode* on_success);
2457 virtual RegExpCapture* AsCapture();
2458 virtual bool IsAnchoredAtStart();
2459 virtual bool IsAnchoredAtEnd();
2460 virtual Interval CaptureRegisters();
2461 virtual bool IsCapture();
2462 virtual int min_match() { return body_->min_match(); }
2463 virtual int max_match() { return body_->max_match(); }
2464 RegExpTree* body() { return body_; }
2465 int index() { return index_; }
2466 static int StartRegister(int index) { return index * 2; }
2467 static int EndRegister(int index) { return index * 2 + 1; }
2475 class RegExpLookahead: public RegExpTree {
2477 RegExpLookahead(RegExpTree* body,
2482 is_positive_(is_positive),
2483 capture_count_(capture_count),
2484 capture_from_(capture_from) { }
2486 virtual void* Accept(RegExpVisitor* visitor, void* data);
2487 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2488 RegExpNode* on_success);
2489 virtual RegExpLookahead* AsLookahead();
2490 virtual Interval CaptureRegisters();
2491 virtual bool IsLookahead();
2492 virtual bool IsAnchoredAtStart();
2493 virtual int min_match() { return 0; }
2494 virtual int max_match() { return 0; }
2495 RegExpTree* body() { return body_; }
2496 bool is_positive() { return is_positive_; }
2497 int capture_count() { return capture_count_; }
2498 int capture_from() { return capture_from_; }
2508 class RegExpBackReference: public RegExpTree {
2510 explicit RegExpBackReference(RegExpCapture* capture)
2511 : capture_(capture) { }
2512 virtual void* Accept(RegExpVisitor* visitor, void* data);
2513 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2514 RegExpNode* on_success);
2515 virtual RegExpBackReference* AsBackReference();
2516 virtual bool IsBackReference();
2517 virtual int min_match() { return 0; }
2518 virtual int max_match() { return capture_->max_match(); }
2519 int index() { return capture_->index(); }
2520 RegExpCapture* capture() { return capture_; }
2522 RegExpCapture* capture_;
2526 class RegExpEmpty: public RegExpTree {
2529 virtual void* Accept(RegExpVisitor* visitor, void* data);
2530 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2531 RegExpNode* on_success);
2532 virtual RegExpEmpty* AsEmpty();
2533 virtual bool IsEmpty();
2534 virtual int min_match() { return 0; }
2535 virtual int max_match() { return 0; }
2536 static RegExpEmpty* GetInstance() {
2537 static RegExpEmpty* instance = ::new RegExpEmpty();
2543 // ----------------------------------------------------------------------------
2544 // Out-of-line inline constructors (to side-step cyclic dependencies).
2546 inline ModuleVariable::ModuleVariable(VariableProxy* proxy)
2547 : Module(proxy->interface()),
2552 // ----------------------------------------------------------------------------
2554 // - leaf node visitors are abstract.
2556 class AstVisitor BASE_EMBEDDED {
2558 AstVisitor() : isolate_(Isolate::Current()), stack_overflow_(false) { }
2559 virtual ~AstVisitor() { }
2561 // Stack overflow check and dynamic dispatch.
2562 void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
2564 // Iteration left-to-right.
2565 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
2566 virtual void VisitStatements(ZoneList<Statement*>* statements);
2567 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
2569 // Stack overflow tracking support.
2570 bool HasStackOverflow() const { return stack_overflow_; }
2571 bool CheckStackOverflow();
2573 // If a stack-overflow exception is encountered when visiting a
2574 // node, calling SetStackOverflow will make sure that the visitor
2575 // bails out without visiting more nodes.
2576 void SetStackOverflow() { stack_overflow_ = true; }
2577 void ClearStackOverflow() { stack_overflow_ = false; }
2579 // Individual AST nodes.
2580 #define DEF_VISIT(type) \
2581 virtual void Visit##type(type* node) = 0;
2582 AST_NODE_LIST(DEF_VISIT)
2586 Isolate* isolate() { return isolate_; }
2590 bool stack_overflow_;
2594 // ----------------------------------------------------------------------------
2595 // Construction time visitor.
2597 class AstConstructionVisitor BASE_EMBEDDED {
2599 AstConstructionVisitor() { }
2601 AstProperties* ast_properties() { return &properties_; }
2604 template<class> friend class AstNodeFactory;
2607 #define DEF_VISIT(type) \
2608 void Visit##type(type* node);
2609 AST_NODE_LIST(DEF_VISIT)
2612 void increase_node_count() { properties_.add_node_count(1); }
2613 void add_flag(AstPropertiesFlag flag) { properties_.flags()->Add(flag); }
2615 AstProperties properties_;
2619 class AstNullVisitor BASE_EMBEDDED {
2622 #define DEF_VISIT(type) \
2623 void Visit##type(type* node) {}
2624 AST_NODE_LIST(DEF_VISIT)
2630 // ----------------------------------------------------------------------------
2633 template<class Visitor>
2634 class AstNodeFactory BASE_EMBEDDED {
2636 explicit AstNodeFactory(Isolate* isolate)
2637 : isolate_(isolate),
2638 zone_(isolate_->zone()) { }
2640 Visitor* visitor() { return &visitor_; }
2642 #define VISIT_AND_RETURN(NodeType, node) \
2643 visitor_.Visit##NodeType((node)); \
2646 VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
2649 VariableDeclaration* decl =
2650 new(zone_) VariableDeclaration(proxy, mode, scope);
2651 VISIT_AND_RETURN(VariableDeclaration, decl)
2654 FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy,
2656 FunctionLiteral* fun,
2658 FunctionDeclaration* decl =
2659 new(zone_) FunctionDeclaration(proxy, mode, fun, scope);
2660 VISIT_AND_RETURN(FunctionDeclaration, decl)
2663 ModuleDeclaration* NewModuleDeclaration(VariableProxy* proxy,
2666 ModuleDeclaration* decl =
2667 new(zone_) ModuleDeclaration(proxy, module, scope);
2668 VISIT_AND_RETURN(ModuleDeclaration, decl)
2671 ImportDeclaration* NewImportDeclaration(VariableProxy* proxy,
2674 ImportDeclaration* decl =
2675 new(zone_) ImportDeclaration(proxy, module, scope);
2676 VISIT_AND_RETURN(ImportDeclaration, decl)
2679 ExportDeclaration* NewExportDeclaration(VariableProxy* proxy,
2681 ExportDeclaration* decl =
2682 new(zone_) ExportDeclaration(proxy, scope);
2683 VISIT_AND_RETURN(ExportDeclaration, decl)
2686 ModuleLiteral* NewModuleLiteral(Block* body, Interface* interface) {
2687 ModuleLiteral* module = new(zone_) ModuleLiteral(body, interface);
2688 VISIT_AND_RETURN(ModuleLiteral, module)
2691 ModuleVariable* NewModuleVariable(VariableProxy* proxy) {
2692 ModuleVariable* module = new(zone_) ModuleVariable(proxy);
2693 VISIT_AND_RETURN(ModuleVariable, module)
2696 ModulePath* NewModulePath(Module* origin, Handle<String> name) {
2697 ModulePath* module = new(zone_) ModulePath(origin, name);
2698 VISIT_AND_RETURN(ModulePath, module)
2701 ModuleUrl* NewModuleUrl(Handle<String> url) {
2702 ModuleUrl* module = new(zone_) ModuleUrl(url);
2703 VISIT_AND_RETURN(ModuleUrl, module)
2706 Block* NewBlock(ZoneStringList* labels,
2708 bool is_initializer_block) {
2709 Block* block = new(zone_) Block(
2710 isolate_, labels, capacity, is_initializer_block);
2711 VISIT_AND_RETURN(Block, block)
2714 #define STATEMENT_WITH_LABELS(NodeType) \
2715 NodeType* New##NodeType(ZoneStringList* labels) { \
2716 NodeType* stmt = new(zone_) NodeType(isolate_, labels); \
2717 VISIT_AND_RETURN(NodeType, stmt); \
2719 STATEMENT_WITH_LABELS(DoWhileStatement)
2720 STATEMENT_WITH_LABELS(WhileStatement)
2721 STATEMENT_WITH_LABELS(ForStatement)
2722 STATEMENT_WITH_LABELS(ForInStatement)
2723 STATEMENT_WITH_LABELS(SwitchStatement)
2724 #undef STATEMENT_WITH_LABELS
2726 ExpressionStatement* NewExpressionStatement(Expression* expression) {
2727 ExpressionStatement* stmt = new(zone_) ExpressionStatement(expression);
2728 VISIT_AND_RETURN(ExpressionStatement, stmt)
2731 ContinueStatement* NewContinueStatement(IterationStatement* target) {
2732 ContinueStatement* stmt = new(zone_) ContinueStatement(target);
2733 VISIT_AND_RETURN(ContinueStatement, stmt)
2736 BreakStatement* NewBreakStatement(BreakableStatement* target) {
2737 BreakStatement* stmt = new(zone_) BreakStatement(target);
2738 VISIT_AND_RETURN(BreakStatement, stmt)
2741 ReturnStatement* NewReturnStatement(Expression* expression) {
2742 ReturnStatement* stmt = new(zone_) ReturnStatement(expression);
2743 VISIT_AND_RETURN(ReturnStatement, stmt)
2746 WithStatement* NewWithStatement(Expression* expression,
2747 Statement* statement) {
2748 WithStatement* stmt = new(zone_) WithStatement(expression, statement);
2749 VISIT_AND_RETURN(WithStatement, stmt)
2752 IfStatement* NewIfStatement(Expression* condition,
2753 Statement* then_statement,
2754 Statement* else_statement) {
2755 IfStatement* stmt = new(zone_) IfStatement(
2756 isolate_, condition, then_statement, else_statement);
2757 VISIT_AND_RETURN(IfStatement, stmt)
2760 TryCatchStatement* NewTryCatchStatement(int index,
2764 Block* catch_block) {
2765 TryCatchStatement* stmt = new(zone_) TryCatchStatement(
2766 index, try_block, scope, variable, catch_block);
2767 VISIT_AND_RETURN(TryCatchStatement, stmt)
2770 TryFinallyStatement* NewTryFinallyStatement(int index,
2772 Block* finally_block) {
2773 TryFinallyStatement* stmt =
2774 new(zone_) TryFinallyStatement(index, try_block, finally_block);
2775 VISIT_AND_RETURN(TryFinallyStatement, stmt)
2778 DebuggerStatement* NewDebuggerStatement() {
2779 DebuggerStatement* stmt = new(zone_) DebuggerStatement();
2780 VISIT_AND_RETURN(DebuggerStatement, stmt)
2783 EmptyStatement* NewEmptyStatement() {
2784 return new(zone_) EmptyStatement();
2787 Literal* NewLiteral(Handle<Object> handle) {
2788 Literal* lit = new(zone_) Literal(isolate_, handle);
2789 VISIT_AND_RETURN(Literal, lit)
2792 Literal* NewNumberLiteral(double number) {
2793 return NewLiteral(isolate_->factory()->NewNumber(number, TENURED));
2796 ObjectLiteral* NewObjectLiteral(
2797 Handle<FixedArray> constant_properties,
2798 ZoneList<ObjectLiteral::Property*>* properties,
2803 bool has_function) {
2804 ObjectLiteral* lit = new(zone_) ObjectLiteral(
2805 isolate_, constant_properties, properties, literal_index,
2806 is_simple, fast_elements, depth, has_function);
2807 VISIT_AND_RETURN(ObjectLiteral, lit)
2810 ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter,
2811 FunctionLiteral* value) {
2812 ObjectLiteral::Property* prop =
2813 new(zone_) ObjectLiteral::Property(is_getter, value);
2814 prop->set_key(NewLiteral(value->name()));
2815 return prop; // Not an AST node, will not be visited.
2818 RegExpLiteral* NewRegExpLiteral(Handle<String> pattern,
2819 Handle<String> flags,
2820 int literal_index) {
2821 RegExpLiteral* lit =
2822 new(zone_) RegExpLiteral(isolate_, pattern, flags, literal_index);
2823 VISIT_AND_RETURN(RegExpLiteral, lit);
2826 ArrayLiteral* NewArrayLiteral(Handle<FixedArray> constant_elements,
2827 ZoneList<Expression*>* values,
2831 ArrayLiteral* lit = new(zone_) ArrayLiteral(
2832 isolate_, constant_elements, values, literal_index, is_simple, depth);
2833 VISIT_AND_RETURN(ArrayLiteral, lit)
2836 VariableProxy* NewVariableProxy(Variable* var) {
2837 VariableProxy* proxy = new(zone_) VariableProxy(isolate_, var);
2838 VISIT_AND_RETURN(VariableProxy, proxy)
2841 VariableProxy* NewVariableProxy(Handle<String> name,
2843 int position = RelocInfo::kNoPosition,
2844 Interface* interface =
2845 Interface::NewValue()) {
2846 VariableProxy* proxy =
2847 new(zone_) VariableProxy(isolate_, name, is_this, position, interface);
2848 VISIT_AND_RETURN(VariableProxy, proxy)
2851 Property* NewProperty(Expression* obj, Expression* key, int pos) {
2852 Property* prop = new(zone_) Property(isolate_, obj, key, pos);
2853 VISIT_AND_RETURN(Property, prop)
2856 Call* NewCall(Expression* expression,
2857 ZoneList<Expression*>* arguments,
2859 Call* call = new(zone_) Call(isolate_, expression, arguments, pos);
2860 VISIT_AND_RETURN(Call, call)
2863 CallNew* NewCallNew(Expression* expression,
2864 ZoneList<Expression*>* arguments,
2866 CallNew* call = new(zone_) CallNew(isolate_, expression, arguments, pos);
2867 VISIT_AND_RETURN(CallNew, call)
2870 CallRuntime* NewCallRuntime(Handle<String> name,
2871 const Runtime::Function* function,
2872 ZoneList<Expression*>* arguments) {
2874 new(zone_) CallRuntime(isolate_, name, function, arguments);
2875 VISIT_AND_RETURN(CallRuntime, call)
2878 UnaryOperation* NewUnaryOperation(Token::Value op,
2879 Expression* expression,
2881 UnaryOperation* node =
2882 new(zone_) UnaryOperation(isolate_, op, expression, pos);
2883 VISIT_AND_RETURN(UnaryOperation, node)
2886 BinaryOperation* NewBinaryOperation(Token::Value op,
2890 BinaryOperation* node =
2891 new(zone_) BinaryOperation(isolate_, op, left, right, pos);
2892 VISIT_AND_RETURN(BinaryOperation, node)
2895 CountOperation* NewCountOperation(Token::Value op,
2899 CountOperation* node =
2900 new(zone_) CountOperation(isolate_, op, is_prefix, expr, pos);
2901 VISIT_AND_RETURN(CountOperation, node)
2904 CompareOperation* NewCompareOperation(Token::Value op,
2908 CompareOperation* node =
2909 new(zone_) CompareOperation(isolate_, op, left, right, pos);
2910 VISIT_AND_RETURN(CompareOperation, node)
2913 Conditional* NewConditional(Expression* condition,
2914 Expression* then_expression,
2915 Expression* else_expression,
2916 int then_expression_position,
2917 int else_expression_position) {
2918 Conditional* cond = new(zone_) Conditional(
2919 isolate_, condition, then_expression, else_expression,
2920 then_expression_position, else_expression_position);
2921 VISIT_AND_RETURN(Conditional, cond)
2924 Assignment* NewAssignment(Token::Value op,
2928 Assignment* assign =
2929 new(zone_) Assignment(isolate_, op, target, value, pos);
2930 assign->Init(isolate_, this);
2931 VISIT_AND_RETURN(Assignment, assign)
2934 Throw* NewThrow(Expression* exception, int pos) {
2935 Throw* t = new(zone_) Throw(isolate_, exception, pos);
2936 VISIT_AND_RETURN(Throw, t)
2939 FunctionLiteral* NewFunctionLiteral(
2940 Handle<String> name,
2942 ZoneList<Statement*>* body,
2943 int materialized_literal_count,
2944 int expected_property_count,
2946 bool has_only_simple_this_property_assignments,
2947 Handle<FixedArray> this_property_assignments,
2948 int parameter_count,
2949 FunctionLiteral::ParameterFlag has_duplicate_parameters,
2950 FunctionLiteral::Type type,
2951 FunctionLiteral::IsFunctionFlag is_function) {
2952 FunctionLiteral* lit = new(zone_) FunctionLiteral(
2953 isolate_, name, scope, body,
2954 materialized_literal_count, expected_property_count, handler_count,
2955 has_only_simple_this_property_assignments, this_property_assignments,
2956 parameter_count, type, has_duplicate_parameters, is_function);
2957 // Top-level literal doesn't count for the AST's properties.
2958 if (is_function == FunctionLiteral::kIsFunction) {
2959 visitor_.VisitFunctionLiteral(lit);
2964 SharedFunctionInfoLiteral* NewSharedFunctionInfoLiteral(
2965 Handle<SharedFunctionInfo> shared_function_info) {
2966 SharedFunctionInfoLiteral* lit =
2967 new(zone_) SharedFunctionInfoLiteral(isolate_, shared_function_info);
2968 VISIT_AND_RETURN(SharedFunctionInfoLiteral, lit)
2971 ThisFunction* NewThisFunction() {
2972 ThisFunction* fun = new(zone_) ThisFunction(isolate_);
2973 VISIT_AND_RETURN(ThisFunction, fun)
2976 #undef VISIT_AND_RETURN
2985 } } // namespace v8::internal