blob: e38def8dc8a8602ae8065b6076ef7d389ae2504d [file] [log] [blame]
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_AST_H_
29#define V8_AST_H_
30
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000031#include "v8.h"
32
33#include "assembler.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000034#include "factory.h"
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000035#include "isolate.h"
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +000036#include "jsregexp.h"
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000037#include "list-inl.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000038#include "runtime.h"
ricow@chromium.orgddd545c2011-08-24 12:02:41 +000039#include "small-pointer-list.h"
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000040#include "smart-array-pointer.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000041#include "token.h"
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +000042#include "utils.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000043#include "variables.h"
erik.corry@gmail.combbceb572012-03-09 10:52:05 +000044#include "interface.h"
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000045#include "zone-inl.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000046
kasperl@chromium.org71affb52009-05-26 05:44:31 +000047namespace v8 {
48namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000049
50// The abstract syntax tree is an intermediate, light-weight
51// representation of the parsed JavaScript code suitable for
52// compilation to native code.
53
54// Nodes are allocated in a separate zone, which allows faster
55// allocation and constant-time deallocation of the entire syntax
56// tree.
57
58
59// ----------------------------------------------------------------------------
60// Nodes of the abstract syntax tree. Only concrete classes are
61// enumerated here.
62
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +000063#define DECLARATION_NODE_LIST(V) \
64 V(VariableDeclaration) \
ulan@chromium.org812308e2012-02-29 15:58:45 +000065 V(FunctionDeclaration) \
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +000066 V(ModuleDeclaration) \
ulan@chromium.org812308e2012-02-29 15:58:45 +000067 V(ImportDeclaration) \
68 V(ExportDeclaration) \
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +000069
70#define MODULE_NODE_LIST(V) \
71 V(ModuleLiteral) \
72 V(ModuleVariable) \
73 V(ModulePath) \
74 V(ModuleUrl)
75
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +000076#define STATEMENT_NODE_LIST(V) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077 V(Block) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000078 V(ExpressionStatement) \
79 V(EmptyStatement) \
80 V(IfStatement) \
81 V(ContinueStatement) \
82 V(BreakStatement) \
83 V(ReturnStatement) \
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +000084 V(WithStatement) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000085 V(SwitchStatement) \
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +000086 V(DoWhileStatement) \
87 V(WhileStatement) \
88 V(ForStatement) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000089 V(ForInStatement) \
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +000090 V(TryCatchStatement) \
91 V(TryFinallyStatement) \
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +000092 V(DebuggerStatement)
93
94#define EXPRESSION_NODE_LIST(V) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000095 V(FunctionLiteral) \
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +000096 V(SharedFunctionInfoLiteral) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000097 V(Conditional) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000098 V(VariableProxy) \
99 V(Literal) \
100 V(RegExpLiteral) \
101 V(ObjectLiteral) \
102 V(ArrayLiteral) \
103 V(Assignment) \
104 V(Throw) \
105 V(Property) \
106 V(Call) \
107 V(CallNew) \
108 V(CallRuntime) \
109 V(UnaryOperation) \
110 V(CountOperation) \
111 V(BinaryOperation) \
112 V(CompareOperation) \
113 V(ThisFunction)
114
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000115#define AST_NODE_LIST(V) \
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000116 DECLARATION_NODE_LIST(V) \
117 MODULE_NODE_LIST(V) \
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000118 STATEMENT_NODE_LIST(V) \
119 EXPRESSION_NODE_LIST(V)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000120
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000121// Forward declarations
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000122class AstConstructionVisitor;
123template<class> class AstNodeFactory;
yangguo@chromium.org659ceec2012-01-26 07:37:54 +0000124class AstVisitor;
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000125class Declaration;
126class Module;
yangguo@chromium.org659ceec2012-01-26 07:37:54 +0000127class BreakableStatement;
128class Expression;
129class IterationStatement;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000130class MaterializedLiteral;
yangguo@chromium.org659ceec2012-01-26 07:37:54 +0000131class Statement;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000132class TargetCollector;
133class TypeFeedbackOracle;
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000134
yangguo@chromium.org659ceec2012-01-26 07:37:54 +0000135class RegExpAlternative;
136class RegExpAssertion;
137class RegExpAtom;
138class RegExpBackReference;
139class RegExpCapture;
140class RegExpCharacterClass;
141class RegExpCompiler;
142class RegExpDisjunction;
143class RegExpEmpty;
144class RegExpLookahead;
145class RegExpQuantifier;
146class RegExpText;
147
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000148#define DEF_FORWARD_DECLARATION(type) class type;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000149AST_NODE_LIST(DEF_FORWARD_DECLARATION)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000150#undef DEF_FORWARD_DECLARATION
151
152
153// Typedef only introduced to avoid unreadable code.
154// Please do appreciate the required space in "> >".
155typedef ZoneList<Handle<String> > ZoneStringList;
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000156typedef ZoneList<Handle<Object> > ZoneObjectList;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000157
158
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000159#define DECLARE_NODE_TYPE(type) \
160 virtual void Accept(AstVisitor* v); \
ulan@chromium.org65a89c22012-02-14 11:46:07 +0000161 virtual AstNode::Type node_type() const { return AstNode::k##type; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000162
163
164enum AstPropertiesFlag {
165 kDontInline,
166 kDontOptimize,
167 kDontSelfOptimize,
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000168 kDontSoftInline,
169 kDontCache
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000170};
171
172
173class AstProperties BASE_EMBEDDED {
174 public:
175 class Flags : public EnumSet<AstPropertiesFlag, int> {};
176
177 AstProperties() : node_count_(0) { }
178
179 Flags* flags() { return &flags_; }
180 int node_count() { return node_count_; }
181 void add_node_count(int count) { node_count_ += count; }
182
183 private:
184 Flags flags_;
185 int node_count_;
186};
187
188
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000189class AstNode: public ZoneObject {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000190 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000191#define DECLARE_TYPE_ENUM(type) k##type,
192 enum Type {
193 AST_NODE_LIST(DECLARE_TYPE_ENUM)
194 kInvalid = -1
195 };
196#undef DECLARE_TYPE_ENUM
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000197
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000198 static const int kNoNumber = -1;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000199 static const int kFunctionEntryId = 2; // Using 0 could disguise errors.
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000200 // This AST id identifies the point after the declarations have been
201 // visited. We need it to capture the environment effects of declarations
202 // that emit code (function declarations).
203 static const int kDeclarationsId = 3;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000204
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000205 void* operator new(size_t size, Zone* zone) {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000206 return zone->New(static_cast<int>(size));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000207 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000208
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000209 AstNode() { }
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000210
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000211 virtual ~AstNode() { }
212
213 virtual void Accept(AstVisitor* v) = 0;
214 virtual Type node_type() const { return kInvalid; }
215
216 // Type testing & conversion functions overridden by concrete subclasses.
217#define DECLARE_NODE_FUNCTIONS(type) \
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000218 bool Is##type() { return node_type() == AstNode::k##type; } \
219 type* As##type() { return Is##type() ? reinterpret_cast<type*>(this) : NULL; }
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000220 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
221#undef DECLARE_NODE_FUNCTIONS
222
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000223 virtual Declaration* AsDeclaration() { return NULL; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000224 virtual Statement* AsStatement() { return NULL; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000225 virtual Expression* AsExpression() { return NULL; }
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000226 virtual TargetCollector* AsTargetCollector() { return NULL; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000227 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
228 virtual IterationStatement* AsIterationStatement() { return NULL; }
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000229 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000230
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000231 protected:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000232 static int GetNextId(Isolate* isolate) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000233 return ReserveIdRange(isolate, 1);
234 }
235
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000236 static int ReserveIdRange(Isolate* isolate, int n) {
237 int tmp = isolate->ast_node_id();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000238 isolate->set_ast_node_id(tmp + n);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000239 return tmp;
240 }
241
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000242 private:
243 // Hidden to prevent accidental usage. It would have to load the
244 // current zone from the TLS.
245 void* operator new(size_t size);
246
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000247 friend class CaseClause; // Generates AST IDs.
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000248};
249
250
251class Statement: public AstNode {
252 public:
253 Statement() : statement_pos_(RelocInfo::kNoPosition) {}
254
255 virtual Statement* AsStatement() { return this; }
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000256
257 bool IsEmpty() { return AsEmptyStatement() != NULL; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000258
259 void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
260 int statement_pos() const { return statement_pos_; }
261
262 private:
263 int statement_pos_;
264};
265
266
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000267class SmallMapList {
268 public:
269 SmallMapList() {}
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000270 SmallMapList(int capacity, Zone* zone) : list_(capacity, zone) {}
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000271
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000272 void Reserve(int capacity, Zone* zone) { list_.Reserve(capacity, zone); }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000273 void Clear() { list_.Clear(); }
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000274 void Sort() { list_.Sort(); }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000275
276 bool is_empty() const { return list_.is_empty(); }
277 int length() const { return list_.length(); }
278
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000279 void Add(Handle<Map> handle, Zone* zone) {
280 list_.Add(handle.location(), zone);
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000281 }
282
283 Handle<Map> at(int i) const {
284 return Handle<Map>(list_.at(i));
285 }
286
287 Handle<Map> first() const { return at(0); }
288 Handle<Map> last() const { return at(length() - 1); }
289
290 private:
291 // The list stores pointers to Map*, that is Map**, so it's GC safe.
292 SmallPointerList<Map*> list_;
293
294 DISALLOW_COPY_AND_ASSIGN(SmallMapList);
295};
296
297
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000298class Expression: public AstNode {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000299 public:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000300 enum Context {
301 // Not assigned a context yet, or else will not be visited during
302 // code generation.
303 kUninitialized,
304 // Evaluated for its side effects.
305 kEffect,
306 // Evaluated for its value (and side effects).
307 kValue,
308 // Evaluated for control flow (and side effects).
309 kTest
310 };
311
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000312 virtual int position() const {
313 UNREACHABLE();
314 return 0;
315 }
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000316
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000317 virtual Expression* AsExpression() { return this; }
318
319 virtual bool IsValidLeftHandSide() { return false; }
320
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000321 // Helpers for ToBoolean conversion.
322 virtual bool ToBooleanIsTrue() { return false; }
323 virtual bool ToBooleanIsFalse() { return false; }
324
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000325 // Symbols that cannot be parsed as array indices are considered property
326 // names. We do not treat symbols that can be array indexes as property
327 // names because [] for string objects is handled only by keyed ICs.
328 virtual bool IsPropertyName() { return false; }
329
ricow@chromium.org65fae842010-08-25 15:26:24 +0000330 // True iff the result can be safely overwritten (to avoid allocation).
331 // False for operations that can return one of their operands.
332 virtual bool ResultOverwriteAllowed() { return false; }
333
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000334 // True iff the expression is a literal represented as a smi.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000335 bool IsSmiLiteral();
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000336
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000337 // True iff the expression is a string literal.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000338 bool IsStringLiteral();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000339
340 // True iff the expression is the null literal.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000341 bool IsNullLiteral();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000342
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000343 // Type feedback information for assignments and properties.
344 virtual bool IsMonomorphic() {
345 UNREACHABLE();
346 return false;
347 }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000348 virtual SmallMapList* GetReceiverTypes() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000349 UNREACHABLE();
350 return NULL;
351 }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000352 Handle<Map> GetMonomorphicReceiverType() {
353 ASSERT(IsMonomorphic());
354 SmallMapList* types = GetReceiverTypes();
355 ASSERT(types != NULL && types->length() == 1);
356 return types->at(0);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000357 }
358
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000359 unsigned id() const { return id_; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000360 unsigned test_id() const { return test_id_; }
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000361
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000362 protected:
363 explicit Expression(Isolate* isolate)
364 : id_(GetNextId(isolate)),
365 test_id_(GetNextId(isolate)) {}
366
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000367 private:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000368 int id_;
369 int test_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000370};
371
372
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000373class BreakableStatement: public Statement {
374 public:
375 enum Type {
376 TARGET_FOR_ANONYMOUS,
377 TARGET_FOR_NAMED_ONLY
378 };
379
380 // The labels associated with this statement. May be NULL;
381 // if it is != NULL, guaranteed to contain at least one entry.
382 ZoneStringList* labels() const { return labels_; }
383
384 // Type testing & conversion.
385 virtual BreakableStatement* AsBreakableStatement() { return this; }
386
387 // Code generation
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000388 Label* break_target() { return &break_target_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000389
390 // Testers.
391 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
392
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000393 // Bailout support.
394 int EntryId() const { return entry_id_; }
395 int ExitId() const { return exit_id_; }
396
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000397 protected:
danno@chromium.orgc612e022011-11-10 11:38:15 +0000398 BreakableStatement(Isolate* isolate, ZoneStringList* labels, Type type)
399 : labels_(labels),
400 type_(type),
401 entry_id_(GetNextId(isolate)),
402 exit_id_(GetNextId(isolate)) {
403 ASSERT(labels == NULL || labels->length() > 0);
404 }
405
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000406
407 private:
408 ZoneStringList* labels_;
409 Type type_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000410 Label break_target_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000411 int entry_id_;
412 int exit_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000413};
414
415
416class Block: public BreakableStatement {
417 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000418 DECLARE_NODE_TYPE(Block)
419
rossberg@chromium.org400388e2012-06-06 09:29:22 +0000420 void AddStatement(Statement* statement, Zone* zone) {
421 statements_.Add(statement, zone);
422 }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000423
424 ZoneList<Statement*>* statements() { return &statements_; }
425 bool is_initializer_block() const { return is_initializer_block_; }
426
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000427 Scope* scope() const { return scope_; }
428 void set_scope(Scope* scope) { scope_ = scope; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000429
430 protected:
431 template<class> friend class AstNodeFactory;
432
danno@chromium.orgc612e022011-11-10 11:38:15 +0000433 Block(Isolate* isolate,
434 ZoneStringList* labels,
435 int capacity,
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000436 bool is_initializer_block,
437 Zone* zone)
danno@chromium.orgc612e022011-11-10 11:38:15 +0000438 : BreakableStatement(isolate, labels, TARGET_FOR_NAMED_ONLY),
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000439 statements_(capacity, zone),
danno@chromium.orgc612e022011-11-10 11:38:15 +0000440 is_initializer_block_(is_initializer_block),
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000441 scope_(NULL) {
danno@chromium.orgc612e022011-11-10 11:38:15 +0000442 }
443
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000444 private:
445 ZoneList<Statement*> statements_;
446 bool is_initializer_block_;
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000447 Scope* scope_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000448};
449
450
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000451class Declaration: public AstNode {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000452 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000453 VariableProxy* proxy() const { return proxy_; }
454 VariableMode mode() const { return mode_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000455 Scope* scope() const { return scope_; }
ulan@chromium.org812308e2012-02-29 15:58:45 +0000456 virtual InitializationFlag initialization() const = 0;
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000457 virtual bool IsInlineable() const;
458
459 virtual Declaration* AsDeclaration() { return this; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000460
461 protected:
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000462 Declaration(VariableProxy* proxy,
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +0000463 VariableMode mode,
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000464 Scope* scope)
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000465 : proxy_(proxy),
466 mode_(mode),
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000467 scope_(scope) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000468 ASSERT(mode == VAR ||
469 mode == CONST ||
470 mode == CONST_HARMONY ||
471 mode == LET);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000472 }
473
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000474 private:
475 VariableProxy* proxy_;
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +0000476 VariableMode mode_;
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000477
478 // Nested scope from which the declaration originated.
479 Scope* scope_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000480};
481
482
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000483class VariableDeclaration: public Declaration {
484 public:
485 DECLARE_NODE_TYPE(VariableDeclaration)
486
ulan@chromium.org812308e2012-02-29 15:58:45 +0000487 virtual InitializationFlag initialization() const {
488 return mode() == VAR ? kCreatedInitialized : kNeedsInitialization;
489 }
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000490
491 protected:
492 template<class> friend class AstNodeFactory;
493
494 VariableDeclaration(VariableProxy* proxy,
495 VariableMode mode,
ulan@chromium.org812308e2012-02-29 15:58:45 +0000496 Scope* scope)
497 : Declaration(proxy, mode, scope) {
498 }
499};
500
501
502class FunctionDeclaration: public Declaration {
503 public:
504 DECLARE_NODE_TYPE(FunctionDeclaration)
505
506 FunctionLiteral* fun() const { return fun_; }
507 virtual InitializationFlag initialization() const {
508 return kCreatedInitialized;
509 }
510 virtual bool IsInlineable() const;
511
512 protected:
513 template<class> friend class AstNodeFactory;
514
515 FunctionDeclaration(VariableProxy* proxy,
516 VariableMode mode,
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000517 FunctionLiteral* fun,
518 Scope* scope)
519 : Declaration(proxy, mode, scope),
520 fun_(fun) {
ulan@chromium.org812308e2012-02-29 15:58:45 +0000521 // At the moment there are no "const functions" in JavaScript...
522 ASSERT(mode == VAR || mode == LET);
523 ASSERT(fun != NULL);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000524 }
525
526 private:
527 FunctionLiteral* fun_;
528};
529
530
531class ModuleDeclaration: public Declaration {
532 public:
533 DECLARE_NODE_TYPE(ModuleDeclaration)
534
535 Module* module() const { return module_; }
ulan@chromium.org812308e2012-02-29 15:58:45 +0000536 virtual InitializationFlag initialization() const {
537 return kCreatedInitialized;
538 }
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000539
540 protected:
541 template<class> friend class AstNodeFactory;
542
543 ModuleDeclaration(VariableProxy* proxy,
544 Module* module,
545 Scope* scope)
546 : Declaration(proxy, LET, scope),
547 module_(module) {
548 }
549
550 private:
551 Module* module_;
552};
553
554
ulan@chromium.org812308e2012-02-29 15:58:45 +0000555class ImportDeclaration: public Declaration {
556 public:
557 DECLARE_NODE_TYPE(ImportDeclaration)
558
559 Module* module() const { return module_; }
560 virtual InitializationFlag initialization() const {
561 return kCreatedInitialized;
562 }
563
564 protected:
565 template<class> friend class AstNodeFactory;
566
567 ImportDeclaration(VariableProxy* proxy,
568 Module* module,
569 Scope* scope)
570 : Declaration(proxy, LET, scope),
571 module_(module) {
572 }
573
574 private:
575 Module* module_;
576};
577
578
579class ExportDeclaration: public Declaration {
580 public:
581 DECLARE_NODE_TYPE(ExportDeclaration)
582
583 virtual InitializationFlag initialization() const {
584 return kCreatedInitialized;
585 }
586
587 protected:
588 template<class> friend class AstNodeFactory;
589
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000590 ExportDeclaration(VariableProxy* proxy, Scope* scope)
591 : Declaration(proxy, LET, scope) {}
ulan@chromium.org812308e2012-02-29 15:58:45 +0000592};
593
594
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000595class Module: public AstNode {
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000596 public:
597 Interface* interface() const { return interface_; }
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000598 Block* body() const { return body_; }
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000599
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000600 protected:
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000601 explicit Module(Zone* zone)
602 : interface_(Interface::NewModule(zone)),
603 body_(NULL) {}
604 explicit Module(Interface* interface, Block* body = NULL)
605 : interface_(interface),
606 body_(body) {}
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000607
608 private:
609 Interface* interface_;
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000610 Block* body_;
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000611};
612
613
614class ModuleLiteral: public Module {
615 public:
616 DECLARE_NODE_TYPE(ModuleLiteral)
617
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000618 protected:
619 template<class> friend class AstNodeFactory;
620
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000621 ModuleLiteral(Block* body, Interface* interface) : Module(interface, body) {}
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000622};
623
624
625class ModuleVariable: public Module {
626 public:
627 DECLARE_NODE_TYPE(ModuleVariable)
628
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000629 VariableProxy* proxy() const { return proxy_; }
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000630
631 protected:
632 template<class> friend class AstNodeFactory;
633
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000634 inline explicit ModuleVariable(VariableProxy* proxy);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000635
636 private:
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000637 VariableProxy* proxy_;
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000638};
639
640
641class ModulePath: public Module {
642 public:
643 DECLARE_NODE_TYPE(ModulePath)
644
645 Module* module() const { return module_; }
646 Handle<String> name() const { return name_; }
647
648 protected:
649 template<class> friend class AstNodeFactory;
650
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000651 ModulePath(Module* module, Handle<String> name, Zone* zone)
652 : Module(zone),
653 module_(module),
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000654 name_(name) {
655 }
656
657 private:
658 Module* module_;
659 Handle<String> name_;
660};
661
662
663class ModuleUrl: public Module {
664 public:
665 DECLARE_NODE_TYPE(ModuleUrl)
666
667 Handle<String> url() const { return url_; }
668
669 protected:
670 template<class> friend class AstNodeFactory;
671
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000672 ModuleUrl(Handle<String> url, Zone* zone)
673 : Module(zone), url_(url) {
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000674 }
675
676 private:
677 Handle<String> url_;
678};
679
680
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000681class IterationStatement: public BreakableStatement {
682 public:
683 // Type testing & conversion.
684 virtual IterationStatement* AsIterationStatement() { return this; }
685
686 Statement* body() const { return body_; }
687
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000688 // Bailout support.
689 int OsrEntryId() const { return osr_entry_id_; }
690 virtual int ContinueId() const = 0;
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +0000691 virtual int StackCheckId() const = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000692
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000693 // Code generation
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000694 Label* continue_target() { return &continue_target_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000695
696 protected:
danno@chromium.orgc612e022011-11-10 11:38:15 +0000697 IterationStatement(Isolate* isolate, ZoneStringList* labels)
698 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
699 body_(NULL),
700 osr_entry_id_(GetNextId(isolate)) {
701 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000702
703 void Initialize(Statement* body) {
704 body_ = body;
705 }
706
707 private:
708 Statement* body_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000709 Label continue_target_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000710 int osr_entry_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000711};
712
713
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000714class DoWhileStatement: public IterationStatement {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000715 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000716 DECLARE_NODE_TYPE(DoWhileStatement)
717
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000718 void Initialize(Expression* cond, Statement* body) {
719 IterationStatement::Initialize(body);
720 cond_ = cond;
721 }
722
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000723 Expression* cond() const { return cond_; }
724
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000725 // 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; }
729
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000730 // Bailout support.
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000731 virtual int ContinueId() const { return continue_id_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +0000732 virtual int StackCheckId() const { return back_edge_id_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000733 int BackEdgeId() const { return back_edge_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000734
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000735 protected:
736 template<class> friend class AstNodeFactory;
737
738 DoWhileStatement(Isolate* isolate, ZoneStringList* labels)
739 : IterationStatement(isolate, labels),
740 cond_(NULL),
741 condition_position_(-1),
742 continue_id_(GetNextId(isolate)),
743 back_edge_id_(GetNextId(isolate)) {
744 }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000745
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000746 private:
747 Expression* cond_;
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000748 int condition_position_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000749 int continue_id_;
750 int back_edge_id_;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000751};
752
753
754class WhileStatement: public IterationStatement {
755 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000756 DECLARE_NODE_TYPE(WhileStatement)
757
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000758 void Initialize(Expression* cond, Statement* body) {
759 IterationStatement::Initialize(body);
760 cond_ = cond;
761 }
762
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000763 Expression* cond() const { return cond_; }
764 bool may_have_function_literal() const {
765 return may_have_function_literal_;
766 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000767 void set_may_have_function_literal(bool value) {
768 may_have_function_literal_ = value;
769 }
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000770
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000771 // Bailout support.
772 virtual int ContinueId() const { return EntryId(); }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +0000773 virtual int StackCheckId() const { return body_id_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000774 int BodyId() const { return body_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000775
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000776 protected:
777 template<class> friend class AstNodeFactory;
778
779 WhileStatement(Isolate* isolate, ZoneStringList* labels)
780 : IterationStatement(isolate, labels),
781 cond_(NULL),
782 may_have_function_literal_(true),
783 body_id_(GetNextId(isolate)) {
784 }
785
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000786 private:
787 Expression* cond_;
788 // True if there is a function literal subexpression in the condition.
789 bool may_have_function_literal_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000790 int body_id_;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000791};
792
793
794class ForStatement: public IterationStatement {
795 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000796 DECLARE_NODE_TYPE(ForStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000797
798 void Initialize(Statement* init,
799 Expression* cond,
800 Statement* next,
801 Statement* body) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000802 IterationStatement::Initialize(body);
803 init_ = init;
804 cond_ = cond;
805 next_ = next;
806 }
807
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000808 Statement* init() const { return init_; }
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000809 Expression* cond() const { return cond_; }
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000810 Statement* next() const { return next_; }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000811
kasperl@chromium.orgf5aa8372009-03-24 14:47:14 +0000812 bool may_have_function_literal() const {
813 return may_have_function_literal_;
814 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000815 void set_may_have_function_literal(bool value) {
816 may_have_function_literal_ = value;
817 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000818
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000819 // Bailout support.
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000820 virtual int ContinueId() const { return continue_id_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +0000821 virtual int StackCheckId() const { return body_id_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000822 int BodyId() const { return body_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000823
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000824 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; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000827
828 protected:
829 template<class> friend class AstNodeFactory;
830
831 ForStatement(Isolate* isolate, ZoneStringList* labels)
832 : IterationStatement(isolate, labels),
833 init_(NULL),
834 cond_(NULL),
835 next_(NULL),
836 may_have_function_literal_(true),
837 loop_variable_(NULL),
838 continue_id_(GetNextId(isolate)),
839 body_id_(GetNextId(isolate)) {
840 }
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000841
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000842 private:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000843 Statement* init_;
844 Expression* cond_;
845 Statement* next_;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000846 // True if there is a function literal subexpression in the condition.
kasperl@chromium.orgf5aa8372009-03-24 14:47:14 +0000847 bool may_have_function_literal_;
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000848 Variable* loop_variable_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000849 int continue_id_;
850 int body_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000851};
852
853
854class ForInStatement: public IterationStatement {
855 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000856 DECLARE_NODE_TYPE(ForInStatement)
857
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000858 void Initialize(Expression* each, Expression* enumerable, Statement* body) {
859 IterationStatement::Initialize(body);
860 each_ = each;
861 enumerable_ = enumerable;
862 }
863
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000864 Expression* each() const { return each_; }
865 Expression* enumerable() const { return enumerable_; }
866
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000867 virtual int ContinueId() const { return EntryId(); }
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +0000868 virtual int StackCheckId() const { return body_id_; }
869 int BodyId() const { return body_id_; }
870 int PrepareId() const { return prepare_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000871
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000872 protected:
873 template<class> friend class AstNodeFactory;
874
875 ForInStatement(Isolate* isolate, ZoneStringList* labels)
876 : IterationStatement(isolate, labels),
877 each_(NULL),
878 enumerable_(NULL),
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +0000879 body_id_(GetNextId(isolate)),
880 prepare_id_(GetNextId(isolate)) {
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000881 }
882
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000883 private:
884 Expression* each_;
885 Expression* enumerable_;
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +0000886 int body_id_;
887 int prepare_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000888};
889
890
891class ExpressionStatement: public Statement {
892 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000893 DECLARE_NODE_TYPE(ExpressionStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000894
895 void set_expression(Expression* e) { expression_ = e; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000896 Expression* expression() const { return expression_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000897
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000898 protected:
899 template<class> friend class AstNodeFactory;
900
901 explicit ExpressionStatement(Expression* expression)
902 : expression_(expression) { }
903
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000904 private:
905 Expression* expression_;
906};
907
908
909class ContinueStatement: public Statement {
910 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000911 DECLARE_NODE_TYPE(ContinueStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000912
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000913 IterationStatement* target() const { return target_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000914
915 protected:
916 template<class> friend class AstNodeFactory;
917
918 explicit ContinueStatement(IterationStatement* target)
919 : target_(target) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000920
921 private:
922 IterationStatement* target_;
923};
924
925
926class BreakStatement: public Statement {
927 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000928 DECLARE_NODE_TYPE(BreakStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000929
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000930 BreakableStatement* target() const { return target_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000931
932 protected:
933 template<class> friend class AstNodeFactory;
934
935 explicit BreakStatement(BreakableStatement* target)
936 : target_(target) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000937
938 private:
939 BreakableStatement* target_;
940};
941
942
943class ReturnStatement: public Statement {
944 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000945 DECLARE_NODE_TYPE(ReturnStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000946
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000947 Expression* expression() const { return expression_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000948
949 protected:
950 template<class> friend class AstNodeFactory;
951
952 explicit ReturnStatement(Expression* expression)
953 : expression_(expression) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000954
955 private:
956 Expression* expression_;
957};
958
959
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000960class WithStatement: public Statement {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000961 public:
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000962 DECLARE_NODE_TYPE(WithStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000963
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000964 Expression* expression() const { return expression_; }
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000965 Statement* statement() const { return statement_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000966
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000967 protected:
968 template<class> friend class AstNodeFactory;
969
970 WithStatement(Expression* expression, Statement* statement)
971 : expression_(expression),
972 statement_(statement) { }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000973
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000974 private:
975 Expression* expression_;
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000976 Statement* statement_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000977};
978
979
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000980class CaseClause: public ZoneObject {
981 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000982 CaseClause(Isolate* isolate,
983 Expression* label,
984 ZoneList<Statement*>* statements,
985 int pos);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000986
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000987 bool is_default() const { return label_ == NULL; }
988 Expression* label() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000989 CHECK(!is_default());
990 return label_;
991 }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000992 Label* body_target() { return &body_target_; }
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000993 ZoneList<Statement*>* statements() const { return statements_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000994
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000995 int position() const { return position_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000996 void set_position(int pos) { position_ = pos; }
997
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000998 int EntryId() { return entry_id_; }
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000999 int CompareId() { return compare_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001000
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001001 // Type feedback information.
1002 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1003 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
erikcorry0ad885c2011-11-21 13:51:57 +00001004 bool IsSymbolCompare() { return compare_type_ == SYMBOL_ONLY; }
1005 bool IsStringCompare() { return compare_type_ == STRING_ONLY; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001006 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1007
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001008 private:
1009 Expression* label_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001010 Label body_target_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001011 ZoneList<Statement*>* statements_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001012 int position_;
erikcorry0ad885c2011-11-21 13:51:57 +00001013 enum CompareTypeFeedback {
1014 NONE,
1015 SMI_ONLY,
1016 SYMBOL_ONLY,
1017 STRING_ONLY,
1018 OBJECT_ONLY
1019 };
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001020 CompareTypeFeedback compare_type_;
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00001021 int compare_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001022 int entry_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001023};
1024
1025
1026class SwitchStatement: public BreakableStatement {
1027 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001028 DECLARE_NODE_TYPE(SwitchStatement)
1029
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001030 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
1031 tag_ = tag;
1032 cases_ = cases;
1033 }
1034
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001035 Expression* tag() const { return tag_; }
1036 ZoneList<CaseClause*>* cases() const { return cases_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001037
1038 protected:
1039 template<class> friend class AstNodeFactory;
1040
1041 SwitchStatement(Isolate* isolate, ZoneStringList* labels)
1042 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
1043 tag_(NULL),
1044 cases_(NULL) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001045
1046 private:
1047 Expression* tag_;
1048 ZoneList<CaseClause*>* cases_;
1049};
1050
1051
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.
1057class IfStatement: public Statement {
1058 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001059 DECLARE_NODE_TYPE(IfStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001060
1061 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
1062 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
1063
1064 Expression* condition() const { return condition_; }
1065 Statement* then_statement() const { return then_statement_; }
1066 Statement* else_statement() const { return else_statement_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001067
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001068 int IfId() const { return if_id_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001069 int ThenId() const { return then_id_; }
1070 int ElseId() const { return else_id_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001071
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001072 protected:
1073 template<class> friend class AstNodeFactory;
1074
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)) {
1085 }
1086
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001087 private:
1088 Expression* condition_;
1089 Statement* then_statement_;
1090 Statement* else_statement_;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001091 int if_id_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001092 int then_id_;
1093 int else_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001094};
1095
1096
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001097// NOTE: TargetCollectors are represented as nodes to fit in the target
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001098// stack in the compiler; this should probably be reworked.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001099class TargetCollector: public AstNode {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001100 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001101 explicit TargetCollector(Zone* zone) : targets_(0, zone) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001102
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001103 // 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.
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001106 void AddTarget(Label* target, Zone* zone);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001107
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001108 // Virtual behaviour. TargetCollectors are never part of the AST.
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001109 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001110 virtual TargetCollector* AsTargetCollector() { return this; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001111
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001112 ZoneList<Label*>* targets() { return &targets_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001113
1114 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001115 ZoneList<Label*> targets_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001116};
1117
1118
1119class TryStatement: public Statement {
1120 public:
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001121 void set_escaping_targets(ZoneList<Label*>* targets) {
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001122 escaping_targets_ = targets;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001123 }
1124
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00001125 int index() const { return index_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001126 Block* try_block() const { return try_block_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001127 ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001128
1129 protected:
1130 TryStatement(int index, Block* try_block)
1131 : index_(index),
1132 try_block_(try_block),
1133 escaping_targets_(NULL) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001134
1135 private:
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00001136 // Unique (per-function) index of this handler. This is not an AST ID.
1137 int index_;
1138
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001139 Block* try_block_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001140 ZoneList<Label*>* escaping_targets_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001141};
1142
1143
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001144class TryCatchStatement: public TryStatement {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001145 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001146 DECLARE_NODE_TYPE(TryCatchStatement)
1147
1148 Scope* scope() { return scope_; }
1149 Variable* variable() { return variable_; }
1150 Block* catch_block() const { return catch_block_; }
1151
1152 protected:
1153 template<class> friend class AstNodeFactory;
1154
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00001155 TryCatchStatement(int index,
1156 Block* try_block,
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001157 Scope* scope,
1158 Variable* variable,
1159 Block* catch_block)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00001160 : TryStatement(index, try_block),
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001161 scope_(scope),
1162 variable_(variable),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001163 catch_block_(catch_block) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001164 }
1165
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001166 private:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001167 Scope* scope_;
1168 Variable* variable_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001169 Block* catch_block_;
1170};
1171
1172
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001173class TryFinallyStatement: public TryStatement {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001174 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001175 DECLARE_NODE_TYPE(TryFinallyStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001176
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001177 Block* finally_block() const { return finally_block_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001178
1179 protected:
1180 template<class> friend class AstNodeFactory;
1181
1182 TryFinallyStatement(int index, Block* try_block, Block* finally_block)
1183 : TryStatement(index, try_block),
1184 finally_block_(finally_block) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001185
1186 private:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001187 Block* finally_block_;
1188};
1189
1190
1191class DebuggerStatement: public Statement {
1192 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001193 DECLARE_NODE_TYPE(DebuggerStatement)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001194
1195 protected:
1196 template<class> friend class AstNodeFactory;
1197
1198 DebuggerStatement() {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001199};
1200
1201
1202class EmptyStatement: public Statement {
1203 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001204 DECLARE_NODE_TYPE(EmptyStatement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001205
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001206 protected:
1207 template<class> friend class AstNodeFactory;
1208
1209 EmptyStatement() {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001210};
1211
1212
1213class Literal: public Expression {
1214 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001215 DECLARE_NODE_TYPE(Literal)
1216
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001217 virtual bool IsPropertyName() {
1218 if (handle_->IsSymbol()) {
1219 uint32_t ignored;
1220 return !String::cast(*handle_)->AsArrayIndex(&ignored);
1221 }
1222 return false;
1223 }
1224
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001225 Handle<String> AsPropertyName() {
1226 ASSERT(IsPropertyName());
1227 return Handle<String>::cast(handle_);
1228 }
1229
1230 virtual bool ToBooleanIsTrue() { return handle_->ToBoolean()->IsTrue(); }
1231 virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
1232
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001233 // Identity testers.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001234 bool IsNull() const {
1235 ASSERT(!handle_.is_null());
1236 return handle_->IsNull();
1237 }
1238 bool IsTrue() const {
1239 ASSERT(!handle_.is_null());
1240 return handle_->IsTrue();
1241 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001242 bool IsFalse() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001243 ASSERT(!handle_.is_null());
1244 return handle_->IsFalse();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001245 }
1246
1247 Handle<Object> handle() const { return handle_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001248
erik.corry@gmail.combbceb572012-03-09 10:52:05 +00001249 // 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(); }
1252
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);
1257 }
1258
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001259 protected:
1260 template<class> friend class AstNodeFactory;
1261
1262 Literal(Isolate* isolate, Handle<Object> handle)
1263 : Expression(isolate),
1264 handle_(handle) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001265
1266 private:
erik.corry@gmail.combbceb572012-03-09 10:52:05 +00001267 Handle<String> ToString();
1268
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001269 Handle<Object> handle_;
1270};
1271
1272
1273// Base class for literals that needs space in the corresponding JSFunction.
1274class MaterializedLiteral: public Expression {
1275 public:
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001276 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
1277
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001278 int literal_index() { return literal_index_; }
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001279
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_; }
1283
1284 int depth() const { return depth_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001285
1286 protected:
1287 MaterializedLiteral(Isolate* isolate,
1288 int literal_index,
1289 bool is_simple,
1290 int depth)
1291 : Expression(isolate),
1292 literal_index_(literal_index),
1293 is_simple_(is_simple),
1294 depth_(depth) {}
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001295
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001296 private:
1297 int literal_index_;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001298 bool is_simple_;
1299 int depth_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001300};
1301
1302
1303// An object literal has a boilerplate object that is used
1304// for minimizing the work when constructing it at runtime.
1305class ObjectLiteral: public MaterializedLiteral {
1306 public:
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 {
1311 public:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001312 enum Kind {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001313 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__.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001318 };
1319
ulan@chromium.org812308e2012-02-29 15:58:45 +00001320 Property(Literal* key, Expression* value, Isolate* isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001321
1322 Literal* key() { return key_; }
1323 Expression* value() { return value_; }
1324 Kind kind() { return kind_; }
1325
mstarzinger@chromium.org3233d2f2012-03-14 11:16:03 +00001326 // Type feedback information.
1327 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1328 bool IsMonomorphic() { return !receiver_type_.is_null(); }
1329 Handle<Map> GetReceiverType() { return receiver_type_; }
1330
ager@chromium.org3811b432009-10-28 14:53:37 +00001331 bool IsCompileTimeValue();
1332
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00001333 void set_emit_store(bool emit_store);
1334 bool emit_store();
1335
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001336 protected:
1337 template<class> friend class AstNodeFactory;
1338
1339 Property(bool is_getter, FunctionLiteral* value);
1340 void set_key(Literal* key) { key_ = key; }
1341
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001342 private:
1343 Literal* key_;
1344 Expression* value_;
1345 Kind kind_;
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00001346 bool emit_store_;
mstarzinger@chromium.org3233d2f2012-03-14 11:16:03 +00001347 Handle<Map> receiver_type_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001348 };
1349
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001350 DECLARE_NODE_TYPE(ObjectLiteral)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001351
1352 Handle<FixedArray> constant_properties() const {
1353 return constant_properties_;
1354 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001355 ZoneList<Property*>* properties() const { return properties_; }
1356
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001357 bool fast_elements() const { return fast_elements_; }
1358
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001359 bool has_function() { return has_function_; }
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00001360
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.
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001364 void CalculateEmitStore(Zone* zone);
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00001365
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001366 enum Flags {
1367 kNoFlags = 0,
1368 kFastElements = 1,
1369 kHasFunction = 1 << 1
1370 };
1371
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00001372 struct Accessors: public ZoneObject {
1373 Accessors() : getter(NULL), setter(NULL) { }
1374 Expression* getter;
1375 Expression* setter;
1376 };
1377
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001378 protected:
1379 template<class> friend class AstNodeFactory;
1380
1381 ObjectLiteral(Isolate* isolate,
1382 Handle<FixedArray> constant_properties,
1383 ZoneList<Property*>* properties,
1384 int literal_index,
1385 bool is_simple,
1386 bool fast_elements,
1387 int depth,
1388 bool has_function)
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) {}
1394
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001395 private:
1396 Handle<FixedArray> constant_properties_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001397 ZoneList<Property*>* properties_;
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001398 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001399 bool has_function_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001400};
1401
1402
1403// Node for capturing a regexp literal.
1404class RegExpLiteral: public MaterializedLiteral {
1405 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001406 DECLARE_NODE_TYPE(RegExpLiteral)
1407
1408 Handle<String> pattern() const { return pattern_; }
1409 Handle<String> flags() const { return flags_; }
1410
1411 protected:
1412 template<class> friend class AstNodeFactory;
1413
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001414 RegExpLiteral(Isolate* isolate,
1415 Handle<String> pattern,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001416 Handle<String> flags,
1417 int literal_index)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001418 : MaterializedLiteral(isolate, literal_index, false, 1),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001419 pattern_(pattern),
1420 flags_(flags) {}
1421
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001422 private:
1423 Handle<String> pattern_;
1424 Handle<String> flags_;
1425};
1426
1427// An array literal has a literals object that is used
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001428// for minimizing the work when constructing it at runtime.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001429class ArrayLiteral: public MaterializedLiteral {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001430 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001431 DECLARE_NODE_TYPE(ArrayLiteral)
1432
1433 Handle<FixedArray> constant_elements() const { return constant_elements_; }
1434 ZoneList<Expression*>* values() const { return values_; }
1435
1436 // Return an AST id for an element that is used in simulate instructions.
1437 int GetIdForElement(int i) { return first_element_id_ + i; }
1438
1439 protected:
1440 template<class> friend class AstNodeFactory;
1441
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001442 ArrayLiteral(Isolate* isolate,
1443 Handle<FixedArray> constant_elements,
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001444 ZoneList<Expression*>* values,
1445 int literal_index,
1446 bool is_simple,
1447 int depth)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001448 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001449 constant_elements_(constant_elements),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001450 values_(values),
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001451 first_element_id_(ReserveIdRange(isolate, values->length())) {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001452
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001453 private:
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001454 Handle<FixedArray> constant_elements_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001455 ZoneList<Expression*>* values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001456 int first_element_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001457};
1458
1459
1460class VariableProxy: public Expression {
1461 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001462 DECLARE_NODE_TYPE(VariableProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001463
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001464 virtual bool IsValidLeftHandSide() {
1465 return var_ == NULL ? true : var_->IsValidLeftHandSide();
1466 }
ager@chromium.org3e875802009-06-29 08:26:34 +00001467
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001468 bool IsVariable(Handle<String> n) {
1469 return !is_this() && name().is_identical_to(n);
1470 }
1471
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001472 bool IsArguments() { return var_ != NULL && var_->is_arguments(); }
ager@chromium.org3e875802009-06-29 08:26:34 +00001473
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001474 bool IsLValue() {
1475 return is_lvalue_;
1476 }
1477
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001478 Handle<String> name() const { return name_; }
1479 Variable* var() const { return var_; }
1480 bool is_this() const { return is_this_; }
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001481 int position() const { return position_; }
erik.corry@gmail.combbceb572012-03-09 10:52:05 +00001482 Interface* interface() const { return interface_; }
1483
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001484
ricow@chromium.org65fae842010-08-25 15:26:24 +00001485 void MarkAsTrivial() { is_trivial_ = true; }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001486 void MarkAsLValue() { is_lvalue_ = true; }
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001487
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001488 // Bind this proxy to the variable var.
1489 void BindTo(Variable* var);
1490
1491 protected:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001492 template<class> friend class AstNodeFactory;
1493
1494 VariableProxy(Isolate* isolate, Variable* var);
1495
1496 VariableProxy(Isolate* isolate,
1497 Handle<String> name,
1498 bool is_this,
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00001499 Interface* interface,
1500 int position);
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001501
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001502 Handle<String> name_;
1503 Variable* var_; // resolved variable, or NULL
1504 bool is_this_;
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001505 bool is_trivial_;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001506 // True if this variable proxy is being used in an assignment
1507 // or with a increment/decrement operator.
1508 bool is_lvalue_;
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001509 int position_;
erik.corry@gmail.combbceb572012-03-09 10:52:05 +00001510 Interface* interface_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001511};
1512
1513
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001514class Property: public Expression {
1515 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001516 DECLARE_NODE_TYPE(Property)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001517
1518 virtual bool IsValidLeftHandSide() { return true; }
1519
1520 Expression* obj() const { return obj_; }
1521 Expression* key() const { return key_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001522 virtual int position() const { return pos_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001523
ager@chromium.org378b34e2011-01-28 08:04:38 +00001524 bool IsStringLength() const { return is_string_length_; }
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00001525 bool IsStringAccess() const { return is_string_access_; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001526 bool IsFunctionPrototype() const { return is_function_prototype_; }
1527
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001528 // Type feedback information.
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001529 void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001530 virtual bool IsMonomorphic() { return is_monomorphic_; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001531 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001532 bool IsArrayLength() { return is_array_length_; }
jkummerow@chromium.org531dfe82012-03-20 13:01:16 +00001533 bool IsUninitialized() { return is_uninitialized_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001534
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001535 protected:
1536 template<class> friend class AstNodeFactory;
1537
1538 Property(Isolate* isolate,
1539 Expression* obj,
1540 Expression* key,
1541 int pos)
1542 : Expression(isolate),
1543 obj_(obj),
1544 key_(key),
1545 pos_(pos),
1546 is_monomorphic_(false),
jkummerow@chromium.org531dfe82012-03-20 13:01:16 +00001547 is_uninitialized_(false),
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001548 is_array_length_(false),
1549 is_string_length_(false),
1550 is_string_access_(false),
1551 is_function_prototype_(false) { }
1552
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001553 private:
1554 Expression* obj_;
1555 Expression* key_;
1556 int pos_;
1557
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001558 SmallMapList receiver_types_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00001559 bool is_monomorphic_ : 1;
jkummerow@chromium.org531dfe82012-03-20 13:01:16 +00001560 bool is_uninitialized_ : 1;
ager@chromium.org378b34e2011-01-28 08:04:38 +00001561 bool is_array_length_ : 1;
1562 bool is_string_length_ : 1;
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00001563 bool is_string_access_ : 1;
ager@chromium.org378b34e2011-01-28 08:04:38 +00001564 bool is_function_prototype_ : 1;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001565};
1566
1567
1568class Call: public Expression {
1569 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001570 DECLARE_NODE_TYPE(Call)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001571
1572 Expression* expression() const { return expression_; }
1573 ZoneList<Expression*>* arguments() const { return arguments_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001574 virtual int position() const { return pos_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001575
danno@chromium.org40cb8782011-05-25 07:58:50 +00001576 void RecordTypeFeedback(TypeFeedbackOracle* oracle,
1577 CallKind call_kind);
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001578 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001579 virtual bool IsMonomorphic() { return is_monomorphic_; }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001580 CheckType check_type() const { return check_type_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001581 Handle<JSFunction> target() { return target_; }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001582
1583 // A cache for the holder, set as a side effect of computing the target of the
1584 // call. Note that it contains the null handle when the receiver is the same
1585 // as the holder!
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001586 Handle<JSObject> holder() { return holder_; }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001587
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001588 Handle<JSGlobalPropertyCell> cell() { return cell_; }
1589
1590 bool ComputeTarget(Handle<Map> type, Handle<String> name);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001591 bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001592
1593 // Bailout support.
1594 int ReturnId() const { return return_id_; }
1595
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001596#ifdef DEBUG
1597 // Used to assert that the FullCodeGenerator records the return site.
1598 bool return_is_recorded_;
1599#endif
1600
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001601 protected:
1602 template<class> friend class AstNodeFactory;
1603
1604 Call(Isolate* isolate,
1605 Expression* expression,
1606 ZoneList<Expression*>* arguments,
1607 int pos)
1608 : Expression(isolate),
1609 expression_(expression),
1610 arguments_(arguments),
1611 pos_(pos),
1612 is_monomorphic_(false),
1613 check_type_(RECEIVER_MAP_CHECK),
1614 return_id_(GetNextId(isolate)) { }
1615
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001616 private:
1617 Expression* expression_;
1618 ZoneList<Expression*>* arguments_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001619 int pos_;
1620
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001621 bool is_monomorphic_;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001622 CheckType check_type_;
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001623 SmallMapList receiver_types_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001624 Handle<JSFunction> target_;
1625 Handle<JSObject> holder_;
1626 Handle<JSGlobalPropertyCell> cell_;
1627
1628 int return_id_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001629};
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001630
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001631
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00001632class CallNew: public Expression {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001633 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001634 DECLARE_NODE_TYPE(CallNew)
1635
1636 Expression* expression() const { return expression_; }
1637 ZoneList<Expression*>* arguments() const { return arguments_; }
1638 virtual int position() const { return pos_; }
1639
ulan@chromium.org967e2702012-02-28 09:49:15 +00001640 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1641 virtual bool IsMonomorphic() { return is_monomorphic_; }
1642 Handle<JSFunction> target() { return target_; }
1643
1644 // Bailout support.
1645 int ReturnId() const { return return_id_; }
1646
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001647 protected:
1648 template<class> friend class AstNodeFactory;
1649
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001650 CallNew(Isolate* isolate,
1651 Expression* expression,
1652 ZoneList<Expression*>* arguments,
1653 int pos)
1654 : Expression(isolate),
1655 expression_(expression),
1656 arguments_(arguments),
ulan@chromium.org967e2702012-02-28 09:49:15 +00001657 pos_(pos),
1658 is_monomorphic_(false),
1659 return_id_(GetNextId(isolate)) { }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001660
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001661 private:
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00001662 Expression* expression_;
1663 ZoneList<Expression*>* arguments_;
1664 int pos_;
ulan@chromium.org967e2702012-02-28 09:49:15 +00001665
1666 bool is_monomorphic_;
1667 Handle<JSFunction> target_;
1668
1669 int return_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001670};
1671
1672
1673// The CallRuntime class does not represent any official JavaScript
1674// language construct. Instead it is used to call a C or JS function
1675// with a set of arguments. This is used from the builtins that are
1676// implemented in JavaScript (see "v8natives.js").
1677class CallRuntime: public Expression {
1678 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001679 DECLARE_NODE_TYPE(CallRuntime)
1680
1681 Handle<String> name() const { return name_; }
1682 const Runtime::Function* function() const { return function_; }
1683 ZoneList<Expression*>* arguments() const { return arguments_; }
1684 bool is_jsruntime() const { return function_ == NULL; }
1685
1686 protected:
1687 template<class> friend class AstNodeFactory;
1688
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001689 CallRuntime(Isolate* isolate,
1690 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001691 const Runtime::Function* function,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001692 ZoneList<Expression*>* arguments)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001693 : Expression(isolate),
1694 name_(name),
1695 function_(function),
1696 arguments_(arguments) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001697
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001698 private:
1699 Handle<String> name_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001700 const Runtime::Function* function_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001701 ZoneList<Expression*>* arguments_;
1702};
1703
1704
1705class UnaryOperation: public Expression {
1706 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001707 DECLARE_NODE_TYPE(UnaryOperation)
1708
1709 virtual bool ResultOverwriteAllowed();
1710
1711 Token::Value op() const { return op_; }
1712 Expression* expression() const { return expression_; }
1713 virtual int position() const { return pos_; }
1714
1715 int MaterializeTrueId() { return materialize_true_id_; }
1716 int MaterializeFalseId() { return materialize_false_id_; }
1717
1718 protected:
1719 template<class> friend class AstNodeFactory;
1720
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001721 UnaryOperation(Isolate* isolate,
1722 Token::Value op,
1723 Expression* expression,
1724 int pos)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001725 : Expression(isolate),
1726 op_(op),
1727 expression_(expression),
1728 pos_(pos),
1729 materialize_true_id_(AstNode::kNoNumber),
1730 materialize_false_id_(AstNode::kNoNumber) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001731 ASSERT(Token::IsUnaryOp(op));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001732 if (op == Token::NOT) {
1733 materialize_true_id_ = GetNextId(isolate);
1734 materialize_false_id_ = GetNextId(isolate);
1735 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001736 }
1737
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001738 private:
1739 Token::Value op_;
1740 Expression* expression_;
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00001741 int pos_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001742
1743 // For unary not (Token::NOT), the AST ids where true and false will
1744 // actually be materialized, respectively.
1745 int materialize_true_id_;
1746 int materialize_false_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001747};
1748
1749
1750class BinaryOperation: public Expression {
1751 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001752 DECLARE_NODE_TYPE(BinaryOperation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001753
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001754 virtual bool ResultOverwriteAllowed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001755
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001756 Token::Value op() const { return op_; }
1757 Expression* left() const { return left_; }
1758 Expression* right() const { return right_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001759 virtual int position() const { return pos_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001760
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001761 // Bailout support.
1762 int RightId() const { return right_id_; }
1763
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001764 protected:
1765 template<class> friend class AstNodeFactory;
1766
1767 BinaryOperation(Isolate* isolate,
1768 Token::Value op,
1769 Expression* left,
1770 Expression* right,
1771 int pos)
1772 : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) {
1773 ASSERT(Token::IsBinaryOp(op));
1774 right_id_ = (op == Token::AND || op == Token::OR)
1775 ? GetNextId(isolate)
1776 : AstNode::kNoNumber;
1777 }
1778
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001779 private:
1780 Token::Value op_;
1781 Expression* left_;
1782 Expression* right_;
ricow@chromium.org65fae842010-08-25 15:26:24 +00001783 int pos_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001784 // The short-circuit logical operations have an AST ID for their
1785 // right-hand subexpression.
1786 int right_id_;
ricow@chromium.org65fae842010-08-25 15:26:24 +00001787};
1788
1789
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001790class CountOperation: public Expression {
1791 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001792 DECLARE_NODE_TYPE(CountOperation)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001793
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001794 bool is_prefix() const { return is_prefix_; }
1795 bool is_postfix() const { return !is_prefix_; }
ricow@chromium.org65fae842010-08-25 15:26:24 +00001796
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001797 Token::Value op() const { return op_; }
kasperl@chromium.org74e4e5e2010-01-25 10:15:52 +00001798 Token::Value binary_op() {
ricow@chromium.org65fae842010-08-25 15:26:24 +00001799 return (op() == Token::INC) ? Token::ADD : Token::SUB;
kasperl@chromium.org74e4e5e2010-01-25 10:15:52 +00001800 }
ricow@chromium.org65fae842010-08-25 15:26:24 +00001801
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001802 Expression* expression() const { return expression_; }
1803 virtual int position() const { return pos_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001804
1805 virtual void MarkAsStatement() { is_prefix_ = true; }
1806
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001807 void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* znoe);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001808 virtual bool IsMonomorphic() { return is_monomorphic_; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001809 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001810
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001811 // Bailout support.
1812 int AssignmentId() const { return assignment_id_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001813 int CountId() const { return count_id_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001814
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001815 protected:
1816 template<class> friend class AstNodeFactory;
1817
1818 CountOperation(Isolate* isolate,
1819 Token::Value op,
1820 bool is_prefix,
1821 Expression* expr,
1822 int pos)
1823 : Expression(isolate),
1824 op_(op),
1825 is_prefix_(is_prefix),
1826 expression_(expr),
1827 pos_(pos),
1828 assignment_id_(GetNextId(isolate)),
1829 count_id_(GetNextId(isolate)) {}
1830
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001831 private:
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001832 Token::Value op_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001833 bool is_prefix_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001834 bool is_monomorphic_;
1835 Expression* expression_;
ricow@chromium.org65fae842010-08-25 15:26:24 +00001836 int pos_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001837 int assignment_id_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001838 int count_id_;
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001839 SmallMapList receiver_types_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001840};
1841
1842
1843class CompareOperation: public Expression {
1844 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001845 DECLARE_NODE_TYPE(CompareOperation)
1846
1847 Token::Value op() const { return op_; }
1848 Expression* left() const { return left_; }
1849 Expression* right() const { return right_; }
1850 virtual int position() const { return pos_; }
1851
1852 // Type feedback information.
1853 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1854 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
1855 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1856
1857 // Match special cases.
1858 bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
1859 bool IsLiteralCompareUndefined(Expression** expr);
1860 bool IsLiteralCompareNull(Expression** expr);
1861
1862 protected:
1863 template<class> friend class AstNodeFactory;
1864
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001865 CompareOperation(Isolate* isolate,
1866 Token::Value op,
ricow@chromium.org65fae842010-08-25 15:26:24 +00001867 Expression* left,
1868 Expression* right,
1869 int pos)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001870 : Expression(isolate),
1871 op_(op),
1872 left_(left),
1873 right_(right),
1874 pos_(pos),
1875 compare_type_(NONE) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001876 ASSERT(Token::IsCompareOp(op));
1877 }
1878
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001879 private:
1880 Token::Value op_;
1881 Expression* left_;
1882 Expression* right_;
ricow@chromium.org65fae842010-08-25 15:26:24 +00001883 int pos_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001884
1885 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
1886 CompareTypeFeedback compare_type_;
ricow@chromium.org65fae842010-08-25 15:26:24 +00001887};
1888
1889
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001890class Conditional: public Expression {
1891 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001892 DECLARE_NODE_TYPE(Conditional)
1893
1894 Expression* condition() const { return condition_; }
1895 Expression* then_expression() const { return then_expression_; }
1896 Expression* else_expression() const { return else_expression_; }
1897
1898 int then_expression_position() const { return then_expression_position_; }
1899 int else_expression_position() const { return else_expression_position_; }
1900
1901 int ThenId() const { return then_id_; }
1902 int ElseId() const { return else_id_; }
1903
1904 protected:
1905 template<class> friend class AstNodeFactory;
1906
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001907 Conditional(Isolate* isolate,
1908 Expression* condition,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001909 Expression* then_expression,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001910 Expression* else_expression,
1911 int then_expression_position,
1912 int else_expression_position)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001913 : Expression(isolate),
1914 condition_(condition),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001915 then_expression_(then_expression),
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001916 else_expression_(else_expression),
1917 then_expression_position_(then_expression_position),
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001918 else_expression_position_(else_expression_position),
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001919 then_id_(GetNextId(isolate)),
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001920 else_id_(GetNextId(isolate)) { }
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001921
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001922 private:
1923 Expression* condition_;
1924 Expression* then_expression_;
1925 Expression* else_expression_;
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001926 int then_expression_position_;
1927 int else_expression_position_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001928 int then_id_;
1929 int else_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001930};
1931
1932
1933class Assignment: public Expression {
1934 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001935 DECLARE_NODE_TYPE(Assignment)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001936
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001937 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1938
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001939 Token::Value binary_op() const;
1940
1941 Token::Value op() const { return op_; }
1942 Expression* target() const { return target_; }
1943 Expression* value() const { return value_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001944 virtual int position() const { return pos_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001945 BinaryOperation* binary_operation() const { return binary_operation_; }
1946
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +00001947 // This check relies on the definition order of token in token.h.
1948 bool is_compound() const { return op() > Token::ASSIGN; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001949
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001950 // An initialization block is a series of statments of the form
1951 // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1952 // ending of these blocks to allow for optimizations of initialization
1953 // blocks.
1954 bool starts_initialization_block() { return block_start_; }
1955 bool ends_initialization_block() { return block_end_; }
1956 void mark_block_start() { block_start_ = true; }
1957 void mark_block_end() { block_end_ = true; }
1958
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001959 // Type feedback information.
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001960 void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001961 virtual bool IsMonomorphic() { return is_monomorphic_; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001962 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001963
1964 // Bailout support.
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001965 int CompoundLoadId() const { return compound_load_id_; }
1966 int AssignmentId() const { return assignment_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001967
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001968 protected:
1969 template<class> friend class AstNodeFactory;
1970
1971 Assignment(Isolate* isolate,
1972 Token::Value op,
1973 Expression* target,
1974 Expression* value,
1975 int pos);
1976
1977 template<class Visitor>
1978 void Init(Isolate* isolate, AstNodeFactory<Visitor>* factory) {
1979 ASSERT(Token::IsAssignmentOp(op_));
1980 if (is_compound()) {
1981 binary_operation_ =
1982 factory->NewBinaryOperation(binary_op(), target_, value_, pos_ + 1);
1983 compound_load_id_ = GetNextId(isolate);
1984 }
1985 }
1986
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001987 private:
1988 Token::Value op_;
1989 Expression* target_;
1990 Expression* value_;
1991 int pos_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001992 BinaryOperation* binary_operation_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001993 int compound_load_id_;
1994 int assignment_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001995
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001996 bool block_start_;
1997 bool block_end_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001998
1999 bool is_monomorphic_;
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00002000 SmallMapList receiver_types_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002001};
2002
2003
2004class Throw: public Expression {
2005 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00002006 DECLARE_NODE_TYPE(Throw)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002007
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002008 Expression* exception() const { return exception_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002009 virtual int position() const { return pos_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002010
2011 protected:
2012 template<class> friend class AstNodeFactory;
2013
2014 Throw(Isolate* isolate, Expression* exception, int pos)
2015 : Expression(isolate), exception_(exception), pos_(pos) {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002016
2017 private:
2018 Expression* exception_;
2019 int pos_;
2020};
2021
2022
2023class FunctionLiteral: public Expression {
2024 public:
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002025 enum Type {
2026 ANONYMOUS_EXPRESSION,
2027 NAMED_EXPRESSION,
2028 DECLARATION
2029 };
2030
yangguo@chromium.org56454712012-02-16 15:33:53 +00002031 enum ParameterFlag {
2032 kNoDuplicateParameters = 0,
2033 kHasDuplicateParameters = 1
2034 };
2035
2036 enum IsFunctionFlag {
2037 kGlobalOrEval,
2038 kIsFunction
2039 };
2040
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00002041 DECLARE_NODE_TYPE(FunctionLiteral)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002042
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002043 Handle<String> name() const { return name_; }
2044 Scope* scope() const { return scope_; }
2045 ZoneList<Statement*>* body() const { return body_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002046 void set_function_token_position(int pos) { function_token_position_ = pos; }
2047 int function_token_position() const { return function_token_position_; }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002048 int start_position() const;
2049 int end_position() const;
yangguo@chromium.org56454712012-02-16 15:33:53 +00002050 int SourceSize() const { return end_position() - start_position(); }
danno@chromium.orgc612e022011-11-10 11:38:15 +00002051 bool is_expression() const { return IsExpression::decode(bitfield_); }
2052 bool is_anonymous() const { return IsAnonymous::decode(bitfield_); }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002053 bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; }
2054 LanguageMode language_mode() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002055
2056 int materialized_literal_count() { return materialized_literal_count_; }
2057 int expected_property_count() { return expected_property_count_; }
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00002058 int handler_count() { return handler_count_; }
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002059 bool has_only_simple_this_property_assignments() {
danno@chromium.orgc612e022011-11-10 11:38:15 +00002060 return HasOnlySimpleThisPropertyAssignments::decode(bitfield_);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002061 }
2062 Handle<FixedArray> this_property_assignments() {
2063 return this_property_assignments_;
2064 }
danno@chromium.orgc612e022011-11-10 11:38:15 +00002065 int parameter_count() { return parameter_count_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002066
2067 bool AllowsLazyCompilation();
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00002068 bool AllowsLazyCompilationWithoutContext();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002069
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00002070 Handle<String> debug_name() const {
2071 if (name_->length() > 0) return name_;
2072 return inferred_name();
2073 }
2074
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002075 Handle<String> inferred_name() const { return inferred_name_; }
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002076 void set_inferred_name(Handle<String> inferred_name) {
2077 inferred_name_ = inferred_name;
2078 }
2079
danno@chromium.orgc612e022011-11-10 11:38:15 +00002080 bool pretenure() { return Pretenure::decode(bitfield_); }
2081 void set_pretenure() { bitfield_ |= Pretenure::encode(true); }
vegorov@chromium.org21b5e952010-11-23 10:24:40 +00002082
danno@chromium.orgc612e022011-11-10 11:38:15 +00002083 bool has_duplicate_parameters() {
2084 return HasDuplicateParameters::decode(bitfield_);
2085 }
whesse@chromium.org7b260152011-06-20 15:33:18 +00002086
yangguo@chromium.org56454712012-02-16 15:33:53 +00002087 bool is_function() { return IsFunction::decode(bitfield_) == kIsFunction; }
2088
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002089 int ast_node_count() { return ast_properties_.node_count(); }
2090 AstProperties::Flags* flags() { return ast_properties_.flags(); }
2091 void set_ast_properties(AstProperties* ast_properties) {
2092 ast_properties_ = *ast_properties;
2093 }
2094
2095 protected:
2096 template<class> friend class AstNodeFactory;
2097
2098 FunctionLiteral(Isolate* isolate,
2099 Handle<String> name,
2100 Scope* scope,
2101 ZoneList<Statement*>* body,
2102 int materialized_literal_count,
2103 int expected_property_count,
2104 int handler_count,
2105 bool has_only_simple_this_property_assignments,
2106 Handle<FixedArray> this_property_assignments,
2107 int parameter_count,
2108 Type type,
yangguo@chromium.org56454712012-02-16 15:33:53 +00002109 ParameterFlag has_duplicate_parameters,
2110 IsFunctionFlag is_function)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002111 : Expression(isolate),
2112 name_(name),
2113 scope_(scope),
2114 body_(body),
2115 this_property_assignments_(this_property_assignments),
2116 inferred_name_(isolate->factory()->empty_string()),
2117 materialized_literal_count_(materialized_literal_count),
2118 expected_property_count_(expected_property_count),
2119 handler_count_(handler_count),
2120 parameter_count_(parameter_count),
2121 function_token_position_(RelocInfo::kNoPosition) {
2122 bitfield_ =
2123 HasOnlySimpleThisPropertyAssignments::encode(
2124 has_only_simple_this_property_assignments) |
2125 IsExpression::encode(type != DECLARATION) |
2126 IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) |
2127 Pretenure::encode(false) |
yangguo@chromium.org56454712012-02-16 15:33:53 +00002128 HasDuplicateParameters::encode(has_duplicate_parameters) |
2129 IsFunction::encode(is_function);
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002130 }
2131
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002132 private:
2133 Handle<String> name_;
2134 Scope* scope_;
2135 ZoneList<Statement*>* body_;
danno@chromium.orgc612e022011-11-10 11:38:15 +00002136 Handle<FixedArray> this_property_assignments_;
2137 Handle<String> inferred_name_;
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002138 AstProperties ast_properties_;
danno@chromium.orgc612e022011-11-10 11:38:15 +00002139
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002140 int materialized_literal_count_;
2141 int expected_property_count_;
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00002142 int handler_count_;
danno@chromium.orgc612e022011-11-10 11:38:15 +00002143 int parameter_count_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002144 int function_token_position_;
danno@chromium.orgc612e022011-11-10 11:38:15 +00002145
2146 unsigned bitfield_;
2147 class HasOnlySimpleThisPropertyAssignments: public BitField<bool, 0, 1> {};
2148 class IsExpression: public BitField<bool, 1, 1> {};
2149 class IsAnonymous: public BitField<bool, 2, 1> {};
2150 class Pretenure: public BitField<bool, 3, 1> {};
yangguo@chromium.org56454712012-02-16 15:33:53 +00002151 class HasDuplicateParameters: public BitField<ParameterFlag, 4, 1> {};
2152 class IsFunction: public BitField<IsFunctionFlag, 5, 1> {};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002153};
2154
2155
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002156class SharedFunctionInfoLiteral: public Expression {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002157 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00002158 DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
2159
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002160 Handle<SharedFunctionInfo> shared_function_info() const {
2161 return shared_function_info_;
2162 }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002163
2164 protected:
2165 template<class> friend class AstNodeFactory;
2166
2167 SharedFunctionInfoLiteral(
2168 Isolate* isolate,
2169 Handle<SharedFunctionInfo> shared_function_info)
2170 : Expression(isolate),
2171 shared_function_info_(shared_function_info) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002172
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002173 private:
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002174 Handle<SharedFunctionInfo> shared_function_info_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002175};
2176
2177
2178class ThisFunction: public Expression {
2179 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00002180 DECLARE_NODE_TYPE(ThisFunction)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002181
2182 protected:
2183 template<class> friend class AstNodeFactory;
2184
2185 explicit ThisFunction(Isolate* isolate): Expression(isolate) {}
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002186};
2187
ulan@chromium.org65a89c22012-02-14 11:46:07 +00002188#undef DECLARE_NODE_TYPE
2189
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002190
2191// ----------------------------------------------------------------------------
2192// Regular expressions
2193
2194
ager@chromium.org32912102009-01-16 10:38:43 +00002195class RegExpVisitor BASE_EMBEDDED {
2196 public:
2197 virtual ~RegExpVisitor() { }
2198#define MAKE_CASE(Name) \
2199 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
2200 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
2201#undef MAKE_CASE
2202};
2203
2204
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002205class RegExpTree: public ZoneObject {
2206 public:
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002207 static const int kInfinity = kMaxInt;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002208 virtual ~RegExpTree() { }
2209 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
2210 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002211 RegExpNode* on_success) = 0;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002212 virtual bool IsTextElement() { return false; }
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002213 virtual bool IsAnchoredAtStart() { return false; }
2214 virtual bool IsAnchoredAtEnd() { return false; }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002215 virtual int min_match() = 0;
2216 virtual int max_match() = 0;
ager@chromium.org32912102009-01-16 10:38:43 +00002217 // Returns the interval of registers used for captures within this
2218 // expression.
2219 virtual Interval CaptureRegisters() { return Interval::Empty(); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002220 virtual void AppendToText(RegExpText* text, Zone* zone);
2221 SmartArrayPointer<const char> ToString(Zone* zone);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002222#define MAKE_ASTYPE(Name) \
2223 virtual RegExp##Name* As##Name(); \
2224 virtual bool Is##Name();
2225 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
2226#undef MAKE_ASTYPE
2227};
2228
2229
2230class RegExpDisjunction: public RegExpTree {
2231 public:
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002232 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002233 virtual void* Accept(RegExpVisitor* visitor, void* data);
2234 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002235 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002236 virtual RegExpDisjunction* AsDisjunction();
ager@chromium.org32912102009-01-16 10:38:43 +00002237 virtual Interval CaptureRegisters();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002238 virtual bool IsDisjunction();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002239 virtual bool IsAnchoredAtStart();
2240 virtual bool IsAnchoredAtEnd();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002241 virtual int min_match() { return min_match_; }
2242 virtual int max_match() { return max_match_; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002243 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
2244 private:
2245 ZoneList<RegExpTree*>* alternatives_;
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002246 int min_match_;
2247 int max_match_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002248};
2249
2250
2251class RegExpAlternative: public RegExpTree {
2252 public:
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002253 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002254 virtual void* Accept(RegExpVisitor* visitor, void* data);
2255 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002256 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002257 virtual RegExpAlternative* AsAlternative();
ager@chromium.org32912102009-01-16 10:38:43 +00002258 virtual Interval CaptureRegisters();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002259 virtual bool IsAlternative();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002260 virtual bool IsAnchoredAtStart();
2261 virtual bool IsAnchoredAtEnd();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002262 virtual int min_match() { return min_match_; }
2263 virtual int max_match() { return max_match_; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002264 ZoneList<RegExpTree*>* nodes() { return nodes_; }
2265 private:
2266 ZoneList<RegExpTree*>* nodes_;
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002267 int min_match_;
2268 int max_match_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002269};
2270
2271
2272class RegExpAssertion: public RegExpTree {
2273 public:
2274 enum Type {
2275 START_OF_LINE,
2276 START_OF_INPUT,
2277 END_OF_LINE,
2278 END_OF_INPUT,
2279 BOUNDARY,
2280 NON_BOUNDARY
2281 };
2282 explicit RegExpAssertion(Type type) : type_(type) { }
2283 virtual void* Accept(RegExpVisitor* visitor, void* data);
2284 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002285 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002286 virtual RegExpAssertion* AsAssertion();
2287 virtual bool IsAssertion();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002288 virtual bool IsAnchoredAtStart();
2289 virtual bool IsAnchoredAtEnd();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002290 virtual int min_match() { return 0; }
2291 virtual int max_match() { return 0; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002292 Type type() { return type_; }
2293 private:
2294 Type type_;
2295};
2296
2297
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002298class CharacterSet BASE_EMBEDDED {
2299 public:
2300 explicit CharacterSet(uc16 standard_set_type)
2301 : ranges_(NULL),
2302 standard_set_type_(standard_set_type) {}
2303 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
2304 : ranges_(ranges),
2305 standard_set_type_(0) {}
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002306 ZoneList<CharacterRange>* ranges(Zone* zone);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002307 uc16 standard_set_type() { return standard_set_type_; }
2308 void set_standard_set_type(uc16 special_set_type) {
2309 standard_set_type_ = special_set_type;
2310 }
2311 bool is_standard() { return standard_set_type_ != 0; }
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002312 void Canonicalize();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002313 private:
2314 ZoneList<CharacterRange>* ranges_;
2315 // If non-zero, the value represents a standard set (e.g., all whitespace
2316 // characters) without having to expand the ranges.
2317 uc16 standard_set_type_;
2318};
2319
2320
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002321class RegExpCharacterClass: public RegExpTree {
2322 public:
2323 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002324 : set_(ranges),
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002325 is_negated_(is_negated) { }
2326 explicit RegExpCharacterClass(uc16 type)
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002327 : set_(type),
2328 is_negated_(false) { }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002329 virtual void* Accept(RegExpVisitor* visitor, void* data);
2330 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002331 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002332 virtual RegExpCharacterClass* AsCharacterClass();
2333 virtual bool IsCharacterClass();
2334 virtual bool IsTextElement() { return true; }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002335 virtual int min_match() { return 1; }
2336 virtual int max_match() { return 1; }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002337 virtual void AppendToText(RegExpText* text, Zone* zone);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002338 CharacterSet character_set() { return set_; }
2339 // TODO(lrn): Remove need for complex version if is_standard that
2340 // recognizes a mangled standard set and just do { return set_.is_special(); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002341 bool is_standard(Zone* zone);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002342 // Returns a value representing the standard character set if is_standard()
2343 // returns true.
2344 // Currently used values are:
2345 // s : unicode whitespace
2346 // S : unicode non-whitespace
2347 // w : ASCII word character (digit, letter, underscore)
2348 // W : non-ASCII word character
2349 // d : ASCII digit
2350 // D : non-ASCII digit
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002351 // . : non-unicode non-newline
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002352 // * : All characters
2353 uc16 standard_type() { return set_.standard_set_type(); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002354 ZoneList<CharacterRange>* ranges(Zone* zone) { return set_.ranges(zone); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002355 bool is_negated() { return is_negated_; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002356
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002357 private:
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002358 CharacterSet set_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002359 bool is_negated_;
2360};
2361
2362
2363class RegExpAtom: public RegExpTree {
2364 public:
2365 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
2366 virtual void* Accept(RegExpVisitor* visitor, void* data);
2367 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002368 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002369 virtual RegExpAtom* AsAtom();
2370 virtual bool IsAtom();
2371 virtual bool IsTextElement() { return true; }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002372 virtual int min_match() { return data_.length(); }
2373 virtual int max_match() { return data_.length(); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002374 virtual void AppendToText(RegExpText* text, Zone* zone);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002375 Vector<const uc16> data() { return data_; }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002376 int length() { return data_.length(); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002377 private:
2378 Vector<const uc16> data_;
2379};
2380
2381
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002382class RegExpText: public RegExpTree {
2383 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002384 explicit RegExpText(Zone* zone) : elements_(2, zone), length_(0) {}
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002385 virtual void* Accept(RegExpVisitor* visitor, void* data);
2386 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2387 RegExpNode* on_success);
2388 virtual RegExpText* AsText();
2389 virtual bool IsText();
2390 virtual bool IsTextElement() { return true; }
2391 virtual int min_match() { return length_; }
2392 virtual int max_match() { return length_; }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002393 virtual void AppendToText(RegExpText* text, Zone* zone);
2394 void AddElement(TextElement elm, Zone* zone) {
2395 elements_.Add(elm, zone);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002396 length_ += elm.length();
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +00002397 }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002398 ZoneList<TextElement>* elements() { return &elements_; }
2399 private:
2400 ZoneList<TextElement> elements_;
2401 int length_;
2402};
2403
2404
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002405class RegExpQuantifier: public RegExpTree {
2406 public:
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002407 enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
2408 RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
2409 : body_(body),
2410 min_(min),
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002411 max_(max),
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002412 min_match_(min * body->min_match()),
2413 type_(type) {
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002414 if (max > 0 && body->max_match() > kInfinity / max) {
2415 max_match_ = kInfinity;
2416 } else {
2417 max_match_ = max * body->max_match();
2418 }
2419 }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002420 virtual void* Accept(RegExpVisitor* visitor, void* data);
2421 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002422 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002423 static RegExpNode* ToNode(int min,
2424 int max,
2425 bool is_greedy,
2426 RegExpTree* body,
2427 RegExpCompiler* compiler,
iposva@chromium.org245aa852009-02-10 00:49:54 +00002428 RegExpNode* on_success,
2429 bool not_at_start = false);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002430 virtual RegExpQuantifier* AsQuantifier();
ager@chromium.org32912102009-01-16 10:38:43 +00002431 virtual Interval CaptureRegisters();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002432 virtual bool IsQuantifier();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002433 virtual int min_match() { return min_match_; }
2434 virtual int max_match() { return max_match_; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002435 int min() { return min_; }
2436 int max() { return max_; }
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002437 bool is_possessive() { return type_ == POSSESSIVE; }
2438 bool is_non_greedy() { return type_ == NON_GREEDY; }
2439 bool is_greedy() { return type_ == GREEDY; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002440 RegExpTree* body() { return body_; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002441
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002442 private:
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002443 RegExpTree* body_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002444 int min_;
2445 int max_;
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002446 int min_match_;
2447 int max_match_;
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002448 Type type_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002449};
2450
2451
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002452class RegExpCapture: public RegExpTree {
2453 public:
2454 explicit RegExpCapture(RegExpTree* body, int index)
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002455 : body_(body), index_(index) { }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002456 virtual void* Accept(RegExpVisitor* visitor, void* data);
2457 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002458 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002459 static RegExpNode* ToNode(RegExpTree* body,
2460 int index,
2461 RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002462 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002463 virtual RegExpCapture* AsCapture();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002464 virtual bool IsAnchoredAtStart();
2465 virtual bool IsAnchoredAtEnd();
ager@chromium.org32912102009-01-16 10:38:43 +00002466 virtual Interval CaptureRegisters();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002467 virtual bool IsCapture();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002468 virtual int min_match() { return body_->min_match(); }
2469 virtual int max_match() { return body_->max_match(); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002470 RegExpTree* body() { return body_; }
2471 int index() { return index_; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002472 static int StartRegister(int index) { return index * 2; }
2473 static int EndRegister(int index) { return index * 2 + 1; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002474
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002475 private:
2476 RegExpTree* body_;
2477 int index_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002478};
2479
2480
2481class RegExpLookahead: public RegExpTree {
2482 public:
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002483 RegExpLookahead(RegExpTree* body,
2484 bool is_positive,
2485 int capture_count,
2486 int capture_from)
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002487 : body_(body),
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002488 is_positive_(is_positive),
2489 capture_count_(capture_count),
2490 capture_from_(capture_from) { }
2491
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002492 virtual void* Accept(RegExpVisitor* visitor, void* data);
2493 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002494 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002495 virtual RegExpLookahead* AsLookahead();
ager@chromium.org32912102009-01-16 10:38:43 +00002496 virtual Interval CaptureRegisters();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002497 virtual bool IsLookahead();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002498 virtual bool IsAnchoredAtStart();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002499 virtual int min_match() { return 0; }
2500 virtual int max_match() { return 0; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002501 RegExpTree* body() { return body_; }
2502 bool is_positive() { return is_positive_; }
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002503 int capture_count() { return capture_count_; }
2504 int capture_from() { return capture_from_; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002505
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002506 private:
2507 RegExpTree* body_;
2508 bool is_positive_;
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002509 int capture_count_;
2510 int capture_from_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002511};
2512
2513
2514class RegExpBackReference: public RegExpTree {
2515 public:
2516 explicit RegExpBackReference(RegExpCapture* capture)
2517 : capture_(capture) { }
2518 virtual void* Accept(RegExpVisitor* visitor, void* data);
2519 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002520 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002521 virtual RegExpBackReference* AsBackReference();
2522 virtual bool IsBackReference();
ager@chromium.org32912102009-01-16 10:38:43 +00002523 virtual int min_match() { return 0; }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002524 virtual int max_match() { return capture_->max_match(); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002525 int index() { return capture_->index(); }
2526 RegExpCapture* capture() { return capture_; }
2527 private:
2528 RegExpCapture* capture_;
2529};
2530
2531
2532class RegExpEmpty: public RegExpTree {
2533 public:
2534 RegExpEmpty() { }
2535 virtual void* Accept(RegExpVisitor* visitor, void* data);
2536 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002537 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002538 virtual RegExpEmpty* AsEmpty();
2539 virtual bool IsEmpty();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002540 virtual int min_match() { return 0; }
2541 virtual int max_match() { return 0; }
erikcorry0ad885c2011-11-21 13:51:57 +00002542 static RegExpEmpty* GetInstance() {
2543 static RegExpEmpty* instance = ::new RegExpEmpty();
2544 return instance;
2545 }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002546};
2547
2548
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002549// ----------------------------------------------------------------------------
erik.corry@gmail.combbceb572012-03-09 10:52:05 +00002550// Out-of-line inline constructors (to side-step cyclic dependencies).
2551
2552inline ModuleVariable::ModuleVariable(VariableProxy* proxy)
2553 : Module(proxy->interface()),
2554 proxy_(proxy) {
2555}
2556
2557
2558// ----------------------------------------------------------------------------
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002559// Basic visitor
2560// - leaf node visitors are abstract.
2561
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002562class AstVisitor BASE_EMBEDDED {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002563 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002564 AstVisitor() : isolate_(Isolate::Current()), stack_overflow_(false) { }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002565 virtual ~AstVisitor() { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002566
lrn@chromium.org25156de2010-04-06 13:10:27 +00002567 // Stack overflow check and dynamic dispatch.
2568 void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002569
lrn@chromium.org25156de2010-04-06 13:10:27 +00002570 // Iteration left-to-right.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00002571 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002572 virtual void VisitStatements(ZoneList<Statement*>* statements);
2573 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
2574
2575 // Stack overflow tracking support.
2576 bool HasStackOverflow() const { return stack_overflow_; }
lrn@chromium.org25156de2010-04-06 13:10:27 +00002577 bool CheckStackOverflow();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002578
kasper.lund212ac232008-07-16 07:07:30 +00002579 // If a stack-overflow exception is encountered when visiting a
2580 // node, calling SetStackOverflow will make sure that the visitor
2581 // bails out without visiting more nodes.
2582 void SetStackOverflow() { stack_overflow_ = true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002583 void ClearStackOverflow() { stack_overflow_ = false; }
kasper.lund212ac232008-07-16 07:07:30 +00002584
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002585 // Individual AST nodes.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002586#define DEF_VISIT(type) \
2587 virtual void Visit##type(type* node) = 0;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002588 AST_NODE_LIST(DEF_VISIT)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002589#undef DEF_VISIT
2590
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002591 protected:
2592 Isolate* isolate() { return isolate_; }
2593
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002594 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002595 Isolate* isolate_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002596 bool stack_overflow_;
2597};
2598
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002599
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002600// ----------------------------------------------------------------------------
2601// Construction time visitor.
2602
2603class AstConstructionVisitor BASE_EMBEDDED {
2604 public:
2605 AstConstructionVisitor() { }
2606
2607 AstProperties* ast_properties() { return &properties_; }
2608
2609 private:
2610 template<class> friend class AstNodeFactory;
2611
2612 // Node visitors.
2613#define DEF_VISIT(type) \
2614 void Visit##type(type* node);
2615 AST_NODE_LIST(DEF_VISIT)
2616#undef DEF_VISIT
2617
2618 void increase_node_count() { properties_.add_node_count(1); }
2619 void add_flag(AstPropertiesFlag flag) { properties_.flags()->Add(flag); }
2620
2621 AstProperties properties_;
2622};
2623
2624
2625class AstNullVisitor BASE_EMBEDDED {
2626 public:
2627 // Node visitors.
2628#define DEF_VISIT(type) \
2629 void Visit##type(type* node) {}
2630 AST_NODE_LIST(DEF_VISIT)
2631#undef DEF_VISIT
2632};
2633
2634
2635
2636// ----------------------------------------------------------------------------
2637// AstNode factory
2638
2639template<class Visitor>
2640class AstNodeFactory BASE_EMBEDDED {
2641 public:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00002642 AstNodeFactory(Isolate* isolate, Zone* zone)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002643 : isolate_(isolate),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00002644 zone_(zone) { }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002645
2646 Visitor* visitor() { return &visitor_; }
2647
2648#define VISIT_AND_RETURN(NodeType, node) \
2649 visitor_.Visit##NodeType((node)); \
2650 return node;
2651
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002652 VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
2653 VariableMode mode,
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002654 Scope* scope) {
2655 VariableDeclaration* decl =
ulan@chromium.org812308e2012-02-29 15:58:45 +00002656 new(zone_) VariableDeclaration(proxy, mode, scope);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002657 VISIT_AND_RETURN(VariableDeclaration, decl)
2658 }
2659
ulan@chromium.org812308e2012-02-29 15:58:45 +00002660 FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy,
2661 VariableMode mode,
2662 FunctionLiteral* fun,
2663 Scope* scope) {
2664 FunctionDeclaration* decl =
2665 new(zone_) FunctionDeclaration(proxy, mode, fun, scope);
2666 VISIT_AND_RETURN(FunctionDeclaration, decl)
2667 }
2668
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002669 ModuleDeclaration* NewModuleDeclaration(VariableProxy* proxy,
2670 Module* module,
2671 Scope* scope) {
2672 ModuleDeclaration* decl =
2673 new(zone_) ModuleDeclaration(proxy, module, scope);
2674 VISIT_AND_RETURN(ModuleDeclaration, decl)
2675 }
2676
ulan@chromium.org812308e2012-02-29 15:58:45 +00002677 ImportDeclaration* NewImportDeclaration(VariableProxy* proxy,
2678 Module* module,
2679 Scope* scope) {
2680 ImportDeclaration* decl =
2681 new(zone_) ImportDeclaration(proxy, module, scope);
2682 VISIT_AND_RETURN(ImportDeclaration, decl)
2683 }
2684
2685 ExportDeclaration* NewExportDeclaration(VariableProxy* proxy,
2686 Scope* scope) {
2687 ExportDeclaration* decl =
2688 new(zone_) ExportDeclaration(proxy, scope);
2689 VISIT_AND_RETURN(ExportDeclaration, decl)
2690 }
2691
erik.corry@gmail.combbceb572012-03-09 10:52:05 +00002692 ModuleLiteral* NewModuleLiteral(Block* body, Interface* interface) {
2693 ModuleLiteral* module = new(zone_) ModuleLiteral(body, interface);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002694 VISIT_AND_RETURN(ModuleLiteral, module)
2695 }
2696
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00002697 ModuleVariable* NewModuleVariable(VariableProxy* proxy) {
2698 ModuleVariable* module = new(zone_) ModuleVariable(proxy);
2699 VISIT_AND_RETURN(ModuleVariable, module)
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002700 }
2701
2702 ModulePath* NewModulePath(Module* origin, Handle<String> name) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002703 ModulePath* module = new(zone_) ModulePath(origin, name, zone_);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00002704 VISIT_AND_RETURN(ModulePath, module)
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002705 }
2706
2707 ModuleUrl* NewModuleUrl(Handle<String> url) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002708 ModuleUrl* module = new(zone_) ModuleUrl(url, zone_);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00002709 VISIT_AND_RETURN(ModuleUrl, module)
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002710 }
2711
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002712 Block* NewBlock(ZoneStringList* labels,
2713 int capacity,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00002714 bool is_initializer_block) {
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002715 Block* block = new(zone_) Block(
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00002716 isolate_, labels, capacity, is_initializer_block, zone_);
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002717 VISIT_AND_RETURN(Block, block)
2718 }
2719
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002720#define STATEMENT_WITH_LABELS(NodeType) \
2721 NodeType* New##NodeType(ZoneStringList* labels) { \
2722 NodeType* stmt = new(zone_) NodeType(isolate_, labels); \
2723 VISIT_AND_RETURN(NodeType, stmt); \
2724 }
2725 STATEMENT_WITH_LABELS(DoWhileStatement)
2726 STATEMENT_WITH_LABELS(WhileStatement)
2727 STATEMENT_WITH_LABELS(ForStatement)
2728 STATEMENT_WITH_LABELS(ForInStatement)
2729 STATEMENT_WITH_LABELS(SwitchStatement)
2730#undef STATEMENT_WITH_LABELS
2731
2732 ExpressionStatement* NewExpressionStatement(Expression* expression) {
2733 ExpressionStatement* stmt = new(zone_) ExpressionStatement(expression);
2734 VISIT_AND_RETURN(ExpressionStatement, stmt)
2735 }
2736
2737 ContinueStatement* NewContinueStatement(IterationStatement* target) {
2738 ContinueStatement* stmt = new(zone_) ContinueStatement(target);
2739 VISIT_AND_RETURN(ContinueStatement, stmt)
2740 }
2741
2742 BreakStatement* NewBreakStatement(BreakableStatement* target) {
2743 BreakStatement* stmt = new(zone_) BreakStatement(target);
2744 VISIT_AND_RETURN(BreakStatement, stmt)
2745 }
2746
2747 ReturnStatement* NewReturnStatement(Expression* expression) {
2748 ReturnStatement* stmt = new(zone_) ReturnStatement(expression);
2749 VISIT_AND_RETURN(ReturnStatement, stmt)
2750 }
2751
2752 WithStatement* NewWithStatement(Expression* expression,
2753 Statement* statement) {
2754 WithStatement* stmt = new(zone_) WithStatement(expression, statement);
2755 VISIT_AND_RETURN(WithStatement, stmt)
2756 }
2757
2758 IfStatement* NewIfStatement(Expression* condition,
2759 Statement* then_statement,
2760 Statement* else_statement) {
2761 IfStatement* stmt = new(zone_) IfStatement(
2762 isolate_, condition, then_statement, else_statement);
2763 VISIT_AND_RETURN(IfStatement, stmt)
2764 }
2765
2766 TryCatchStatement* NewTryCatchStatement(int index,
2767 Block* try_block,
2768 Scope* scope,
2769 Variable* variable,
2770 Block* catch_block) {
2771 TryCatchStatement* stmt = new(zone_) TryCatchStatement(
2772 index, try_block, scope, variable, catch_block);
2773 VISIT_AND_RETURN(TryCatchStatement, stmt)
2774 }
2775
2776 TryFinallyStatement* NewTryFinallyStatement(int index,
2777 Block* try_block,
2778 Block* finally_block) {
2779 TryFinallyStatement* stmt =
2780 new(zone_) TryFinallyStatement(index, try_block, finally_block);
2781 VISIT_AND_RETURN(TryFinallyStatement, stmt)
2782 }
2783
2784 DebuggerStatement* NewDebuggerStatement() {
2785 DebuggerStatement* stmt = new(zone_) DebuggerStatement();
2786 VISIT_AND_RETURN(DebuggerStatement, stmt)
2787 }
2788
2789 EmptyStatement* NewEmptyStatement() {
2790 return new(zone_) EmptyStatement();
2791 }
2792
2793 Literal* NewLiteral(Handle<Object> handle) {
2794 Literal* lit = new(zone_) Literal(isolate_, handle);
2795 VISIT_AND_RETURN(Literal, lit)
2796 }
2797
2798 Literal* NewNumberLiteral(double number) {
2799 return NewLiteral(isolate_->factory()->NewNumber(number, TENURED));
2800 }
2801
2802 ObjectLiteral* NewObjectLiteral(
2803 Handle<FixedArray> constant_properties,
2804 ZoneList<ObjectLiteral::Property*>* properties,
2805 int literal_index,
2806 bool is_simple,
2807 bool fast_elements,
2808 int depth,
2809 bool has_function) {
2810 ObjectLiteral* lit = new(zone_) ObjectLiteral(
2811 isolate_, constant_properties, properties, literal_index,
2812 is_simple, fast_elements, depth, has_function);
2813 VISIT_AND_RETURN(ObjectLiteral, lit)
2814 }
2815
2816 ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter,
2817 FunctionLiteral* value) {
2818 ObjectLiteral::Property* prop =
2819 new(zone_) ObjectLiteral::Property(is_getter, value);
2820 prop->set_key(NewLiteral(value->name()));
2821 return prop; // Not an AST node, will not be visited.
2822 }
2823
2824 RegExpLiteral* NewRegExpLiteral(Handle<String> pattern,
2825 Handle<String> flags,
2826 int literal_index) {
2827 RegExpLiteral* lit =
2828 new(zone_) RegExpLiteral(isolate_, pattern, flags, literal_index);
2829 VISIT_AND_RETURN(RegExpLiteral, lit);
2830 }
2831
2832 ArrayLiteral* NewArrayLiteral(Handle<FixedArray> constant_elements,
2833 ZoneList<Expression*>* values,
2834 int literal_index,
2835 bool is_simple,
2836 int depth) {
2837 ArrayLiteral* lit = new(zone_) ArrayLiteral(
2838 isolate_, constant_elements, values, literal_index, is_simple, depth);
2839 VISIT_AND_RETURN(ArrayLiteral, lit)
2840 }
2841
2842 VariableProxy* NewVariableProxy(Variable* var) {
2843 VariableProxy* proxy = new(zone_) VariableProxy(isolate_, var);
2844 VISIT_AND_RETURN(VariableProxy, proxy)
2845 }
2846
2847 VariableProxy* NewVariableProxy(Handle<String> name,
2848 bool is_this,
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00002849 Interface* interface = Interface::NewValue(),
2850 int position = RelocInfo::kNoPosition) {
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002851 VariableProxy* proxy =
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00002852 new(zone_) VariableProxy(isolate_, name, is_this, interface, position);
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002853 VISIT_AND_RETURN(VariableProxy, proxy)
2854 }
2855
2856 Property* NewProperty(Expression* obj, Expression* key, int pos) {
2857 Property* prop = new(zone_) Property(isolate_, obj, key, pos);
2858 VISIT_AND_RETURN(Property, prop)
2859 }
2860
2861 Call* NewCall(Expression* expression,
2862 ZoneList<Expression*>* arguments,
2863 int pos) {
2864 Call* call = new(zone_) Call(isolate_, expression, arguments, pos);
2865 VISIT_AND_RETURN(Call, call)
2866 }
2867
2868 CallNew* NewCallNew(Expression* expression,
2869 ZoneList<Expression*>* arguments,
2870 int pos) {
2871 CallNew* call = new(zone_) CallNew(isolate_, expression, arguments, pos);
2872 VISIT_AND_RETURN(CallNew, call)
2873 }
2874
2875 CallRuntime* NewCallRuntime(Handle<String> name,
2876 const Runtime::Function* function,
2877 ZoneList<Expression*>* arguments) {
2878 CallRuntime* call =
2879 new(zone_) CallRuntime(isolate_, name, function, arguments);
2880 VISIT_AND_RETURN(CallRuntime, call)
2881 }
2882
2883 UnaryOperation* NewUnaryOperation(Token::Value op,
2884 Expression* expression,
2885 int pos) {
2886 UnaryOperation* node =
2887 new(zone_) UnaryOperation(isolate_, op, expression, pos);
2888 VISIT_AND_RETURN(UnaryOperation, node)
2889 }
2890
2891 BinaryOperation* NewBinaryOperation(Token::Value op,
2892 Expression* left,
2893 Expression* right,
2894 int pos) {
2895 BinaryOperation* node =
2896 new(zone_) BinaryOperation(isolate_, op, left, right, pos);
2897 VISIT_AND_RETURN(BinaryOperation, node)
2898 }
2899
2900 CountOperation* NewCountOperation(Token::Value op,
2901 bool is_prefix,
2902 Expression* expr,
2903 int pos) {
2904 CountOperation* node =
2905 new(zone_) CountOperation(isolate_, op, is_prefix, expr, pos);
2906 VISIT_AND_RETURN(CountOperation, node)
2907 }
2908
2909 CompareOperation* NewCompareOperation(Token::Value op,
2910 Expression* left,
2911 Expression* right,
2912 int pos) {
2913 CompareOperation* node =
2914 new(zone_) CompareOperation(isolate_, op, left, right, pos);
2915 VISIT_AND_RETURN(CompareOperation, node)
2916 }
2917
2918 Conditional* NewConditional(Expression* condition,
2919 Expression* then_expression,
2920 Expression* else_expression,
2921 int then_expression_position,
2922 int else_expression_position) {
2923 Conditional* cond = new(zone_) Conditional(
2924 isolate_, condition, then_expression, else_expression,
2925 then_expression_position, else_expression_position);
2926 VISIT_AND_RETURN(Conditional, cond)
2927 }
2928
2929 Assignment* NewAssignment(Token::Value op,
2930 Expression* target,
2931 Expression* value,
2932 int pos) {
2933 Assignment* assign =
2934 new(zone_) Assignment(isolate_, op, target, value, pos);
2935 assign->Init(isolate_, this);
2936 VISIT_AND_RETURN(Assignment, assign)
2937 }
2938
2939 Throw* NewThrow(Expression* exception, int pos) {
2940 Throw* t = new(zone_) Throw(isolate_, exception, pos);
2941 VISIT_AND_RETURN(Throw, t)
2942 }
2943
2944 FunctionLiteral* NewFunctionLiteral(
2945 Handle<String> name,
2946 Scope* scope,
2947 ZoneList<Statement*>* body,
2948 int materialized_literal_count,
2949 int expected_property_count,
2950 int handler_count,
2951 bool has_only_simple_this_property_assignments,
2952 Handle<FixedArray> this_property_assignments,
2953 int parameter_count,
yangguo@chromium.org56454712012-02-16 15:33:53 +00002954 FunctionLiteral::ParameterFlag has_duplicate_parameters,
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002955 FunctionLiteral::Type type,
yangguo@chromium.org56454712012-02-16 15:33:53 +00002956 FunctionLiteral::IsFunctionFlag is_function) {
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002957 FunctionLiteral* lit = new(zone_) FunctionLiteral(
2958 isolate_, name, scope, body,
2959 materialized_literal_count, expected_property_count, handler_count,
2960 has_only_simple_this_property_assignments, this_property_assignments,
yangguo@chromium.org56454712012-02-16 15:33:53 +00002961 parameter_count, type, has_duplicate_parameters, is_function);
2962 // Top-level literal doesn't count for the AST's properties.
2963 if (is_function == FunctionLiteral::kIsFunction) {
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002964 visitor_.VisitFunctionLiteral(lit);
2965 }
2966 return lit;
2967 }
2968
2969 SharedFunctionInfoLiteral* NewSharedFunctionInfoLiteral(
2970 Handle<SharedFunctionInfo> shared_function_info) {
2971 SharedFunctionInfoLiteral* lit =
2972 new(zone_) SharedFunctionInfoLiteral(isolate_, shared_function_info);
2973 VISIT_AND_RETURN(SharedFunctionInfoLiteral, lit)
2974 }
2975
2976 ThisFunction* NewThisFunction() {
2977 ThisFunction* fun = new(zone_) ThisFunction(isolate_);
2978 VISIT_AND_RETURN(ThisFunction, fun)
2979 }
2980
2981#undef VISIT_AND_RETURN
2982
2983 private:
2984 Isolate* isolate_;
2985 Zone* zone_;
2986 Visitor visitor_;
2987};
2988
2989
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002990} } // namespace v8::internal
2991
2992#endif // V8_AST_H_