blob: 3acd121582a5e44150cc6c1cd01a321daa045f8e [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"
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000044#include "zone-inl.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
kasperl@chromium.org71affb52009-05-26 05:44:31 +000046namespace v8 {
47namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000048
49// The abstract syntax tree is an intermediate, light-weight
50// representation of the parsed JavaScript code suitable for
51// compilation to native code.
52
53// Nodes are allocated in a separate zone, which allows faster
54// allocation and constant-time deallocation of the entire syntax
55// tree.
56
57
58// ----------------------------------------------------------------------------
59// Nodes of the abstract syntax tree. Only concrete classes are
60// enumerated here.
61
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +000062#define DECLARATION_NODE_LIST(V) \
63 V(VariableDeclaration) \
64 V(ModuleDeclaration) \
65
66#define MODULE_NODE_LIST(V) \
67 V(ModuleLiteral) \
68 V(ModuleVariable) \
69 V(ModulePath) \
70 V(ModuleUrl)
71
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +000072#define STATEMENT_NODE_LIST(V) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000073 V(Block) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000074 V(ExpressionStatement) \
75 V(EmptyStatement) \
76 V(IfStatement) \
77 V(ContinueStatement) \
78 V(BreakStatement) \
79 V(ReturnStatement) \
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +000080 V(WithStatement) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000081 V(SwitchStatement) \
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +000082 V(DoWhileStatement) \
83 V(WhileStatement) \
84 V(ForStatement) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000085 V(ForInStatement) \
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +000086 V(TryCatchStatement) \
87 V(TryFinallyStatement) \
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +000088 V(DebuggerStatement)
89
90#define EXPRESSION_NODE_LIST(V) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000091 V(FunctionLiteral) \
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +000092 V(SharedFunctionInfoLiteral) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000093 V(Conditional) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000094 V(VariableProxy) \
95 V(Literal) \
96 V(RegExpLiteral) \
97 V(ObjectLiteral) \
98 V(ArrayLiteral) \
99 V(Assignment) \
100 V(Throw) \
101 V(Property) \
102 V(Call) \
103 V(CallNew) \
104 V(CallRuntime) \
105 V(UnaryOperation) \
106 V(CountOperation) \
107 V(BinaryOperation) \
108 V(CompareOperation) \
109 V(ThisFunction)
110
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000111#define AST_NODE_LIST(V) \
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000112 DECLARATION_NODE_LIST(V) \
113 MODULE_NODE_LIST(V) \
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000114 STATEMENT_NODE_LIST(V) \
115 EXPRESSION_NODE_LIST(V)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000116
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000117// Forward declarations
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000118class AstConstructionVisitor;
119template<class> class AstNodeFactory;
yangguo@chromium.org659ceec2012-01-26 07:37:54 +0000120class AstVisitor;
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000121class Declaration;
122class Module;
yangguo@chromium.org659ceec2012-01-26 07:37:54 +0000123class BreakableStatement;
124class Expression;
125class IterationStatement;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000126class MaterializedLiteral;
yangguo@chromium.org659ceec2012-01-26 07:37:54 +0000127class Statement;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000128class TargetCollector;
129class TypeFeedbackOracle;
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000130
yangguo@chromium.org659ceec2012-01-26 07:37:54 +0000131class RegExpAlternative;
132class RegExpAssertion;
133class RegExpAtom;
134class RegExpBackReference;
135class RegExpCapture;
136class RegExpCharacterClass;
137class RegExpCompiler;
138class RegExpDisjunction;
139class RegExpEmpty;
140class RegExpLookahead;
141class RegExpQuantifier;
142class RegExpText;
143
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000144#define DEF_FORWARD_DECLARATION(type) class type;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000145AST_NODE_LIST(DEF_FORWARD_DECLARATION)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000146#undef DEF_FORWARD_DECLARATION
147
148
149// Typedef only introduced to avoid unreadable code.
150// Please do appreciate the required space in "> >".
151typedef ZoneList<Handle<String> > ZoneStringList;
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000152typedef ZoneList<Handle<Object> > ZoneObjectList;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000153
154
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000155#define DECLARE_NODE_TYPE(type) \
156 virtual void Accept(AstVisitor* v); \
ulan@chromium.org65a89c22012-02-14 11:46:07 +0000157 virtual AstNode::Type node_type() const { return AstNode::k##type; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000158
159
160enum AstPropertiesFlag {
161 kDontInline,
162 kDontOptimize,
163 kDontSelfOptimize,
164 kDontSoftInline
165};
166
167
168class AstProperties BASE_EMBEDDED {
169 public:
170 class Flags : public EnumSet<AstPropertiesFlag, int> {};
171
172 AstProperties() : node_count_(0) { }
173
174 Flags* flags() { return &flags_; }
175 int node_count() { return node_count_; }
176 void add_node_count(int count) { node_count_ += count; }
177
178 private:
179 Flags flags_;
180 int node_count_;
181};
182
183
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000184class AstNode: public ZoneObject {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000185 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000186#define DECLARE_TYPE_ENUM(type) k##type,
187 enum Type {
188 AST_NODE_LIST(DECLARE_TYPE_ENUM)
189 kInvalid = -1
190 };
191#undef DECLARE_TYPE_ENUM
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000192
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000193 static const int kNoNumber = -1;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000194 static const int kFunctionEntryId = 2; // Using 0 could disguise errors.
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000195 // This AST id identifies the point after the declarations have been
196 // visited. We need it to capture the environment effects of declarations
197 // that emit code (function declarations).
198 static const int kDeclarationsId = 3;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000199
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000200 void* operator new(size_t size, Zone* zone) {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000201 return zone->New(static_cast<int>(size));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000202 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000203
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000204 AstNode() { }
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000205
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000206 virtual ~AstNode() { }
207
208 virtual void Accept(AstVisitor* v) = 0;
209 virtual Type node_type() const { return kInvalid; }
210
211 // Type testing & conversion functions overridden by concrete subclasses.
212#define DECLARE_NODE_FUNCTIONS(type) \
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000213 bool Is##type() { return node_type() == AstNode::k##type; } \
214 type* As##type() { return Is##type() ? reinterpret_cast<type*>(this) : NULL; }
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000215 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
216#undef DECLARE_NODE_FUNCTIONS
217
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000218 virtual Declaration* AsDeclaration() { return NULL; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000219 virtual Statement* AsStatement() { return NULL; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000220 virtual Expression* AsExpression() { return NULL; }
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000221 virtual TargetCollector* AsTargetCollector() { return NULL; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000222 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
223 virtual IterationStatement* AsIterationStatement() { return NULL; }
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000224 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000225
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000226 protected:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000227 static int GetNextId(Isolate* isolate) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000228 return ReserveIdRange(isolate, 1);
229 }
230
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000231 static int ReserveIdRange(Isolate* isolate, int n) {
232 int tmp = isolate->ast_node_id();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000233 isolate->set_ast_node_id(tmp + n);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000234 return tmp;
235 }
236
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000237 private:
238 // Hidden to prevent accidental usage. It would have to load the
239 // current zone from the TLS.
240 void* operator new(size_t size);
241
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000242 friend class CaseClause; // Generates AST IDs.
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000243};
244
245
246class Statement: public AstNode {
247 public:
248 Statement() : statement_pos_(RelocInfo::kNoPosition) {}
249
250 virtual Statement* AsStatement() { return this; }
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000251
252 bool IsEmpty() { return AsEmptyStatement() != NULL; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000253
254 void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
255 int statement_pos() const { return statement_pos_; }
256
257 private:
258 int statement_pos_;
259};
260
261
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000262class SmallMapList {
263 public:
264 SmallMapList() {}
265 explicit SmallMapList(int capacity) : list_(capacity) {}
266
267 void Reserve(int capacity) { list_.Reserve(capacity); }
268 void Clear() { list_.Clear(); }
269
270 bool is_empty() const { return list_.is_empty(); }
271 int length() const { return list_.length(); }
272
273 void Add(Handle<Map> handle) {
274 list_.Add(handle.location());
275 }
276
277 Handle<Map> at(int i) const {
278 return Handle<Map>(list_.at(i));
279 }
280
281 Handle<Map> first() const { return at(0); }
282 Handle<Map> last() const { return at(length() - 1); }
283
284 private:
285 // The list stores pointers to Map*, that is Map**, so it's GC safe.
286 SmallPointerList<Map*> list_;
287
288 DISALLOW_COPY_AND_ASSIGN(SmallMapList);
289};
290
291
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000292class Expression: public AstNode {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000293 public:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000294 enum Context {
295 // Not assigned a context yet, or else will not be visited during
296 // code generation.
297 kUninitialized,
298 // Evaluated for its side effects.
299 kEffect,
300 // Evaluated for its value (and side effects).
301 kValue,
302 // Evaluated for control flow (and side effects).
303 kTest
304 };
305
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000306 virtual int position() const {
307 UNREACHABLE();
308 return 0;
309 }
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000310
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000311 virtual Expression* AsExpression() { return this; }
312
313 virtual bool IsValidLeftHandSide() { return false; }
314
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000315 // Helpers for ToBoolean conversion.
316 virtual bool ToBooleanIsTrue() { return false; }
317 virtual bool ToBooleanIsFalse() { return false; }
318
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000319 // Symbols that cannot be parsed as array indices are considered property
320 // names. We do not treat symbols that can be array indexes as property
321 // names because [] for string objects is handled only by keyed ICs.
322 virtual bool IsPropertyName() { return false; }
323
ricow@chromium.org65fae842010-08-25 15:26:24 +0000324 // True iff the result can be safely overwritten (to avoid allocation).
325 // False for operations that can return one of their operands.
326 virtual bool ResultOverwriteAllowed() { return false; }
327
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000328 // True iff the expression is a literal represented as a smi.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000329 bool IsSmiLiteral();
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000330
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000331 // True iff the expression is a string literal.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000332 bool IsStringLiteral();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000333
334 // True iff the expression is the null literal.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000335 bool IsNullLiteral();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000336
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000337 // Type feedback information for assignments and properties.
338 virtual bool IsMonomorphic() {
339 UNREACHABLE();
340 return false;
341 }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000342 virtual SmallMapList* GetReceiverTypes() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000343 UNREACHABLE();
344 return NULL;
345 }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000346 Handle<Map> GetMonomorphicReceiverType() {
347 ASSERT(IsMonomorphic());
348 SmallMapList* types = GetReceiverTypes();
349 ASSERT(types != NULL && types->length() == 1);
350 return types->at(0);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000351 }
352
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000353 unsigned id() const { return id_; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000354 unsigned test_id() const { return test_id_; }
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000355
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000356 protected:
357 explicit Expression(Isolate* isolate)
358 : id_(GetNextId(isolate)),
359 test_id_(GetNextId(isolate)) {}
360
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000361 private:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000362 int id_;
363 int test_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000364};
365
366
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000367class BreakableStatement: public Statement {
368 public:
369 enum Type {
370 TARGET_FOR_ANONYMOUS,
371 TARGET_FOR_NAMED_ONLY
372 };
373
374 // The labels associated with this statement. May be NULL;
375 // if it is != NULL, guaranteed to contain at least one entry.
376 ZoneStringList* labels() const { return labels_; }
377
378 // Type testing & conversion.
379 virtual BreakableStatement* AsBreakableStatement() { return this; }
380
381 // Code generation
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000382 Label* break_target() { return &break_target_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000383
384 // Testers.
385 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
386
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000387 // Bailout support.
388 int EntryId() const { return entry_id_; }
389 int ExitId() const { return exit_id_; }
390
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000391 protected:
danno@chromium.orgc612e022011-11-10 11:38:15 +0000392 BreakableStatement(Isolate* isolate, ZoneStringList* labels, Type type)
393 : labels_(labels),
394 type_(type),
395 entry_id_(GetNextId(isolate)),
396 exit_id_(GetNextId(isolate)) {
397 ASSERT(labels == NULL || labels->length() > 0);
398 }
399
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000400
401 private:
402 ZoneStringList* labels_;
403 Type type_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000404 Label break_target_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000405 int entry_id_;
406 int exit_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000407};
408
409
410class Block: public BreakableStatement {
411 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000412 DECLARE_NODE_TYPE(Block)
413
414 void AddStatement(Statement* statement) { statements_.Add(statement); }
415
416 ZoneList<Statement*>* statements() { return &statements_; }
417 bool is_initializer_block() const { return is_initializer_block_; }
418
419 Scope* block_scope() const { return block_scope_; }
420 void set_block_scope(Scope* block_scope) { block_scope_ = block_scope; }
421
422 protected:
423 template<class> friend class AstNodeFactory;
424
danno@chromium.orgc612e022011-11-10 11:38:15 +0000425 Block(Isolate* isolate,
426 ZoneStringList* labels,
427 int capacity,
428 bool is_initializer_block)
429 : BreakableStatement(isolate, labels, TARGET_FOR_NAMED_ONLY),
430 statements_(capacity),
431 is_initializer_block_(is_initializer_block),
432 block_scope_(NULL) {
433 }
434
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000435 private:
436 ZoneList<Statement*> statements_;
437 bool is_initializer_block_;
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000438 Scope* block_scope_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000439};
440
441
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000442class Declaration: public AstNode {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000443 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000444 VariableProxy* proxy() const { return proxy_; }
445 VariableMode mode() const { return mode_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000446 Scope* scope() const { return scope_; }
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000447 virtual bool IsInlineable() const;
448
449 virtual Declaration* AsDeclaration() { return this; }
450 virtual VariableDeclaration* AsVariableDeclaration() { return NULL; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000451
452 protected:
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000453 Declaration(VariableProxy* proxy,
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +0000454 VariableMode mode,
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000455 Scope* scope)
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000456 : proxy_(proxy),
457 mode_(mode),
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000458 scope_(scope) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000459 ASSERT(mode == VAR ||
460 mode == CONST ||
461 mode == CONST_HARMONY ||
462 mode == LET);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000463 }
464
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000465 private:
466 VariableProxy* proxy_;
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +0000467 VariableMode mode_;
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000468
469 // Nested scope from which the declaration originated.
470 Scope* scope_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000471};
472
473
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000474class VariableDeclaration: public Declaration {
475 public:
476 DECLARE_NODE_TYPE(VariableDeclaration)
477
478 virtual VariableDeclaration* AsVariableDeclaration() { return this; }
479
480 FunctionLiteral* fun() const { return fun_; } // may be NULL
481 virtual bool IsInlineable() const;
482
483 protected:
484 template<class> friend class AstNodeFactory;
485
486 VariableDeclaration(VariableProxy* proxy,
487 VariableMode mode,
488 FunctionLiteral* fun,
489 Scope* scope)
490 : Declaration(proxy, mode, scope),
491 fun_(fun) {
492 // At the moment there are no "const functions"'s in JavaScript...
493 ASSERT(fun == NULL || mode == VAR || mode == LET);
494 }
495
496 private:
497 FunctionLiteral* fun_;
498};
499
500
501class ModuleDeclaration: public Declaration {
502 public:
503 DECLARE_NODE_TYPE(ModuleDeclaration)
504
505 Module* module() const { return module_; }
506
507 protected:
508 template<class> friend class AstNodeFactory;
509
510 ModuleDeclaration(VariableProxy* proxy,
511 Module* module,
512 Scope* scope)
513 : Declaration(proxy, LET, scope),
514 module_(module) {
515 }
516
517 private:
518 Module* module_;
519};
520
521
522class Module: public AstNode {
523 // TODO(rossberg): stuff to come...
524 protected:
525 Module() {}
526};
527
528
529class ModuleLiteral: public Module {
530 public:
531 DECLARE_NODE_TYPE(ModuleLiteral)
532
533 Block* body() const { return body_; }
534
535 protected:
536 template<class> friend class AstNodeFactory;
537
538 explicit ModuleLiteral(Block* body)
539 : body_(body) {
540 }
541
542 private:
543 Block* body_;
544};
545
546
547class ModuleVariable: public Module {
548 public:
549 DECLARE_NODE_TYPE(ModuleVariable)
550
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000551 VariableProxy* proxy() const { return proxy_; }
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000552
553 protected:
554 template<class> friend class AstNodeFactory;
555
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000556 explicit ModuleVariable(VariableProxy* proxy)
557 : proxy_(proxy) {
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000558 }
559
560 private:
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000561 VariableProxy* proxy_;
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000562};
563
564
565class ModulePath: public Module {
566 public:
567 DECLARE_NODE_TYPE(ModulePath)
568
569 Module* module() const { return module_; }
570 Handle<String> name() const { return name_; }
571
572 protected:
573 template<class> friend class AstNodeFactory;
574
575 ModulePath(Module* module, Handle<String> name)
576 : module_(module),
577 name_(name) {
578 }
579
580 private:
581 Module* module_;
582 Handle<String> name_;
583};
584
585
586class ModuleUrl: public Module {
587 public:
588 DECLARE_NODE_TYPE(ModuleUrl)
589
590 Handle<String> url() const { return url_; }
591
592 protected:
593 template<class> friend class AstNodeFactory;
594
595 explicit ModuleUrl(Handle<String> url) : url_(url) {
596 }
597
598 private:
599 Handle<String> url_;
600};
601
602
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000603class IterationStatement: public BreakableStatement {
604 public:
605 // Type testing & conversion.
606 virtual IterationStatement* AsIterationStatement() { return this; }
607
608 Statement* body() const { return body_; }
609
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000610 // Bailout support.
611 int OsrEntryId() const { return osr_entry_id_; }
612 virtual int ContinueId() const = 0;
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +0000613 virtual int StackCheckId() const = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000614
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000615 // Code generation
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000616 Label* continue_target() { return &continue_target_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000617
618 protected:
danno@chromium.orgc612e022011-11-10 11:38:15 +0000619 IterationStatement(Isolate* isolate, ZoneStringList* labels)
620 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
621 body_(NULL),
622 osr_entry_id_(GetNextId(isolate)) {
623 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000624
625 void Initialize(Statement* body) {
626 body_ = body;
627 }
628
629 private:
630 Statement* body_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000631 Label continue_target_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000632 int osr_entry_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000633};
634
635
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000636class DoWhileStatement: public IterationStatement {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000637 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000638 DECLARE_NODE_TYPE(DoWhileStatement)
639
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000640 void Initialize(Expression* cond, Statement* body) {
641 IterationStatement::Initialize(body);
642 cond_ = cond;
643 }
644
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000645 Expression* cond() const { return cond_; }
646
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000647 // Position where condition expression starts. We need it to make
648 // the loop's condition a breakable location.
649 int condition_position() { return condition_position_; }
650 void set_condition_position(int pos) { condition_position_ = pos; }
651
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000652 // Bailout support.
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000653 virtual int ContinueId() const { return continue_id_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +0000654 virtual int StackCheckId() const { return back_edge_id_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000655 int BackEdgeId() const { return back_edge_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000656
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000657 protected:
658 template<class> friend class AstNodeFactory;
659
660 DoWhileStatement(Isolate* isolate, ZoneStringList* labels)
661 : IterationStatement(isolate, labels),
662 cond_(NULL),
663 condition_position_(-1),
664 continue_id_(GetNextId(isolate)),
665 back_edge_id_(GetNextId(isolate)) {
666 }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000667
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000668 private:
669 Expression* cond_;
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000670 int condition_position_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000671 int continue_id_;
672 int back_edge_id_;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000673};
674
675
676class WhileStatement: public IterationStatement {
677 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000678 DECLARE_NODE_TYPE(WhileStatement)
679
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000680 void Initialize(Expression* cond, Statement* body) {
681 IterationStatement::Initialize(body);
682 cond_ = cond;
683 }
684
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000685 Expression* cond() const { return cond_; }
686 bool may_have_function_literal() const {
687 return may_have_function_literal_;
688 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000689 void set_may_have_function_literal(bool value) {
690 may_have_function_literal_ = value;
691 }
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000692
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000693 // Bailout support.
694 virtual int ContinueId() const { return EntryId(); }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +0000695 virtual int StackCheckId() const { return body_id_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000696 int BodyId() const { return body_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000697
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000698 protected:
699 template<class> friend class AstNodeFactory;
700
701 WhileStatement(Isolate* isolate, ZoneStringList* labels)
702 : IterationStatement(isolate, labels),
703 cond_(NULL),
704 may_have_function_literal_(true),
705 body_id_(GetNextId(isolate)) {
706 }
707
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000708 private:
709 Expression* cond_;
710 // True if there is a function literal subexpression in the condition.
711 bool may_have_function_literal_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000712 int body_id_;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000713};
714
715
716class ForStatement: public IterationStatement {
717 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000718 DECLARE_NODE_TYPE(ForStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000719
720 void Initialize(Statement* init,
721 Expression* cond,
722 Statement* next,
723 Statement* body) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000724 IterationStatement::Initialize(body);
725 init_ = init;
726 cond_ = cond;
727 next_ = next;
728 }
729
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000730 Statement* init() const { return init_; }
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000731 Expression* cond() const { return cond_; }
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000732 Statement* next() const { return next_; }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000733
kasperl@chromium.orgf5aa8372009-03-24 14:47:14 +0000734 bool may_have_function_literal() const {
735 return may_have_function_literal_;
736 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000737 void set_may_have_function_literal(bool value) {
738 may_have_function_literal_ = value;
739 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000740
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000741 // Bailout support.
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000742 virtual int ContinueId() const { return continue_id_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +0000743 virtual int StackCheckId() const { return body_id_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000744 int BodyId() const { return body_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000745
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000746 bool is_fast_smi_loop() { return loop_variable_ != NULL; }
747 Variable* loop_variable() { return loop_variable_; }
748 void set_loop_variable(Variable* var) { loop_variable_ = var; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000749
750 protected:
751 template<class> friend class AstNodeFactory;
752
753 ForStatement(Isolate* isolate, ZoneStringList* labels)
754 : IterationStatement(isolate, labels),
755 init_(NULL),
756 cond_(NULL),
757 next_(NULL),
758 may_have_function_literal_(true),
759 loop_variable_(NULL),
760 continue_id_(GetNextId(isolate)),
761 body_id_(GetNextId(isolate)) {
762 }
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000763
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000764 private:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000765 Statement* init_;
766 Expression* cond_;
767 Statement* next_;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000768 // True if there is a function literal subexpression in the condition.
kasperl@chromium.orgf5aa8372009-03-24 14:47:14 +0000769 bool may_have_function_literal_;
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000770 Variable* loop_variable_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000771 int continue_id_;
772 int body_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000773};
774
775
776class ForInStatement: public IterationStatement {
777 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000778 DECLARE_NODE_TYPE(ForInStatement)
779
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000780 void Initialize(Expression* each, Expression* enumerable, Statement* body) {
781 IterationStatement::Initialize(body);
782 each_ = each;
783 enumerable_ = enumerable;
784 }
785
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000786 Expression* each() const { return each_; }
787 Expression* enumerable() const { return enumerable_; }
788
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000789 virtual int ContinueId() const { return EntryId(); }
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +0000790 virtual int StackCheckId() const { return body_id_; }
791 int BodyId() const { return body_id_; }
792 int PrepareId() const { return prepare_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000793
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000794 protected:
795 template<class> friend class AstNodeFactory;
796
797 ForInStatement(Isolate* isolate, ZoneStringList* labels)
798 : IterationStatement(isolate, labels),
799 each_(NULL),
800 enumerable_(NULL),
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +0000801 body_id_(GetNextId(isolate)),
802 prepare_id_(GetNextId(isolate)) {
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000803 }
804
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000805 private:
806 Expression* each_;
807 Expression* enumerable_;
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +0000808 int body_id_;
809 int prepare_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000810};
811
812
813class ExpressionStatement: public Statement {
814 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000815 DECLARE_NODE_TYPE(ExpressionStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000816
817 void set_expression(Expression* e) { expression_ = e; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000818 Expression* expression() const { return expression_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000819
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000820 protected:
821 template<class> friend class AstNodeFactory;
822
823 explicit ExpressionStatement(Expression* expression)
824 : expression_(expression) { }
825
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000826 private:
827 Expression* expression_;
828};
829
830
831class ContinueStatement: public Statement {
832 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000833 DECLARE_NODE_TYPE(ContinueStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000834
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000835 IterationStatement* target() const { return target_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000836
837 protected:
838 template<class> friend class AstNodeFactory;
839
840 explicit ContinueStatement(IterationStatement* target)
841 : target_(target) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000842
843 private:
844 IterationStatement* target_;
845};
846
847
848class BreakStatement: public Statement {
849 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000850 DECLARE_NODE_TYPE(BreakStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000851
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000852 BreakableStatement* target() const { return target_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000853
854 protected:
855 template<class> friend class AstNodeFactory;
856
857 explicit BreakStatement(BreakableStatement* target)
858 : target_(target) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000859
860 private:
861 BreakableStatement* target_;
862};
863
864
865class ReturnStatement: public Statement {
866 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000867 DECLARE_NODE_TYPE(ReturnStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000868
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000869 Expression* expression() const { return expression_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000870
871 protected:
872 template<class> friend class AstNodeFactory;
873
874 explicit ReturnStatement(Expression* expression)
875 : expression_(expression) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000876
877 private:
878 Expression* expression_;
879};
880
881
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000882class WithStatement: public Statement {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000883 public:
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000884 DECLARE_NODE_TYPE(WithStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000885
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000886 Expression* expression() const { return expression_; }
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000887 Statement* statement() const { return statement_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000888
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000889 protected:
890 template<class> friend class AstNodeFactory;
891
892 WithStatement(Expression* expression, Statement* statement)
893 : expression_(expression),
894 statement_(statement) { }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000895
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000896 private:
897 Expression* expression_;
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000898 Statement* statement_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000899};
900
901
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000902class CaseClause: public ZoneObject {
903 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000904 CaseClause(Isolate* isolate,
905 Expression* label,
906 ZoneList<Statement*>* statements,
907 int pos);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000908
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000909 bool is_default() const { return label_ == NULL; }
910 Expression* label() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000911 CHECK(!is_default());
912 return label_;
913 }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000914 Label* body_target() { return &body_target_; }
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000915 ZoneList<Statement*>* statements() const { return statements_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000916
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000917 int position() const { return position_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000918 void set_position(int pos) { position_ = pos; }
919
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000920 int EntryId() { return entry_id_; }
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000921 int CompareId() { return compare_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000922
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000923 // Type feedback information.
924 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
925 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
erikcorry0ad885c2011-11-21 13:51:57 +0000926 bool IsSymbolCompare() { return compare_type_ == SYMBOL_ONLY; }
927 bool IsStringCompare() { return compare_type_ == STRING_ONLY; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000928 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
929
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000930 private:
931 Expression* label_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000932 Label body_target_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000933 ZoneList<Statement*>* statements_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000934 int position_;
erikcorry0ad885c2011-11-21 13:51:57 +0000935 enum CompareTypeFeedback {
936 NONE,
937 SMI_ONLY,
938 SYMBOL_ONLY,
939 STRING_ONLY,
940 OBJECT_ONLY
941 };
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000942 CompareTypeFeedback compare_type_;
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000943 int compare_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000944 int entry_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000945};
946
947
948class SwitchStatement: public BreakableStatement {
949 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000950 DECLARE_NODE_TYPE(SwitchStatement)
951
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000952 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
953 tag_ = tag;
954 cases_ = cases;
955 }
956
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000957 Expression* tag() const { return tag_; }
958 ZoneList<CaseClause*>* cases() const { return cases_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000959
960 protected:
961 template<class> friend class AstNodeFactory;
962
963 SwitchStatement(Isolate* isolate, ZoneStringList* labels)
964 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
965 tag_(NULL),
966 cases_(NULL) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000967
968 private:
969 Expression* tag_;
970 ZoneList<CaseClause*>* cases_;
971};
972
973
974// If-statements always have non-null references to their then- and
975// else-parts. When parsing if-statements with no explicit else-part,
976// the parser implicitly creates an empty statement. Use the
977// HasThenStatement() and HasElseStatement() functions to check if a
978// given if-statement has a then- or an else-part containing code.
979class IfStatement: public Statement {
980 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000981 DECLARE_NODE_TYPE(IfStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000982
983 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
984 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
985
986 Expression* condition() const { return condition_; }
987 Statement* then_statement() const { return then_statement_; }
988 Statement* else_statement() const { return else_statement_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000989
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000990 int IfId() const { return if_id_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000991 int ThenId() const { return then_id_; }
992 int ElseId() const { return else_id_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000993
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000994 protected:
995 template<class> friend class AstNodeFactory;
996
997 IfStatement(Isolate* isolate,
998 Expression* condition,
999 Statement* then_statement,
1000 Statement* else_statement)
1001 : condition_(condition),
1002 then_statement_(then_statement),
1003 else_statement_(else_statement),
1004 if_id_(GetNextId(isolate)),
1005 then_id_(GetNextId(isolate)),
1006 else_id_(GetNextId(isolate)) {
1007 }
1008
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001009 private:
1010 Expression* condition_;
1011 Statement* then_statement_;
1012 Statement* else_statement_;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001013 int if_id_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001014 int then_id_;
1015 int else_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001016};
1017
1018
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001019// NOTE: TargetCollectors are represented as nodes to fit in the target
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001020// stack in the compiler; this should probably be reworked.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001021class TargetCollector: public AstNode {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001022 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001023 TargetCollector() : targets_(0) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001024
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001025 // Adds a jump target to the collector. The collector stores a pointer not
1026 // a copy of the target to make binding work, so make sure not to pass in
1027 // references to something on the stack.
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001028 void AddTarget(Label* target);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001029
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001030 // Virtual behaviour. TargetCollectors are never part of the AST.
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001031 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001032 virtual TargetCollector* AsTargetCollector() { return this; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001033
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001034 ZoneList<Label*>* targets() { return &targets_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001035
1036 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001037 ZoneList<Label*> targets_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001038};
1039
1040
1041class TryStatement: public Statement {
1042 public:
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001043 void set_escaping_targets(ZoneList<Label*>* targets) {
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001044 escaping_targets_ = targets;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001045 }
1046
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00001047 int index() const { return index_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001048 Block* try_block() const { return try_block_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001049 ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001050
1051 protected:
1052 TryStatement(int index, Block* try_block)
1053 : index_(index),
1054 try_block_(try_block),
1055 escaping_targets_(NULL) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001056
1057 private:
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00001058 // Unique (per-function) index of this handler. This is not an AST ID.
1059 int index_;
1060
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001061 Block* try_block_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001062 ZoneList<Label*>* escaping_targets_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001063};
1064
1065
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001066class TryCatchStatement: public TryStatement {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001067 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001068 DECLARE_NODE_TYPE(TryCatchStatement)
1069
1070 Scope* scope() { return scope_; }
1071 Variable* variable() { return variable_; }
1072 Block* catch_block() const { return catch_block_; }
1073
1074 protected:
1075 template<class> friend class AstNodeFactory;
1076
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00001077 TryCatchStatement(int index,
1078 Block* try_block,
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001079 Scope* scope,
1080 Variable* variable,
1081 Block* catch_block)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00001082 : TryStatement(index, try_block),
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001083 scope_(scope),
1084 variable_(variable),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001085 catch_block_(catch_block) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001086 }
1087
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001088 private:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001089 Scope* scope_;
1090 Variable* variable_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001091 Block* catch_block_;
1092};
1093
1094
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001095class TryFinallyStatement: public TryStatement {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001096 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001097 DECLARE_NODE_TYPE(TryFinallyStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001098
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001099 Block* finally_block() const { return finally_block_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001100
1101 protected:
1102 template<class> friend class AstNodeFactory;
1103
1104 TryFinallyStatement(int index, Block* try_block, Block* finally_block)
1105 : TryStatement(index, try_block),
1106 finally_block_(finally_block) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001107
1108 private:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001109 Block* finally_block_;
1110};
1111
1112
1113class DebuggerStatement: public Statement {
1114 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001115 DECLARE_NODE_TYPE(DebuggerStatement)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001116
1117 protected:
1118 template<class> friend class AstNodeFactory;
1119
1120 DebuggerStatement() {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001121};
1122
1123
1124class EmptyStatement: public Statement {
1125 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001126 DECLARE_NODE_TYPE(EmptyStatement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001127
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001128 protected:
1129 template<class> friend class AstNodeFactory;
1130
1131 EmptyStatement() {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001132};
1133
1134
1135class Literal: public Expression {
1136 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001137 DECLARE_NODE_TYPE(Literal)
1138
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001139 // Check if this literal is identical to the other literal.
1140 bool IsIdenticalTo(const Literal* other) const {
1141 return handle_.is_identical_to(other->handle_);
1142 }
1143
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001144 virtual bool IsPropertyName() {
1145 if (handle_->IsSymbol()) {
1146 uint32_t ignored;
1147 return !String::cast(*handle_)->AsArrayIndex(&ignored);
1148 }
1149 return false;
1150 }
1151
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001152 Handle<String> AsPropertyName() {
1153 ASSERT(IsPropertyName());
1154 return Handle<String>::cast(handle_);
1155 }
1156
1157 virtual bool ToBooleanIsTrue() { return handle_->ToBoolean()->IsTrue(); }
1158 virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
1159
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001160 // Identity testers.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001161 bool IsNull() const {
1162 ASSERT(!handle_.is_null());
1163 return handle_->IsNull();
1164 }
1165 bool IsTrue() const {
1166 ASSERT(!handle_.is_null());
1167 return handle_->IsTrue();
1168 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001169 bool IsFalse() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001170 ASSERT(!handle_.is_null());
1171 return handle_->IsFalse();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001172 }
1173
1174 Handle<Object> handle() const { return handle_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001175
1176 protected:
1177 template<class> friend class AstNodeFactory;
1178
1179 Literal(Isolate* isolate, Handle<Object> handle)
1180 : Expression(isolate),
1181 handle_(handle) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001182
1183 private:
1184 Handle<Object> handle_;
1185};
1186
1187
1188// Base class for literals that needs space in the corresponding JSFunction.
1189class MaterializedLiteral: public Expression {
1190 public:
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001191 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
1192
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001193 int literal_index() { return literal_index_; }
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001194
1195 // A materialized literal is simple if the values consist of only
1196 // constants and simple object and array literals.
1197 bool is_simple() const { return is_simple_; }
1198
1199 int depth() const { return depth_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001200
1201 protected:
1202 MaterializedLiteral(Isolate* isolate,
1203 int literal_index,
1204 bool is_simple,
1205 int depth)
1206 : Expression(isolate),
1207 literal_index_(literal_index),
1208 is_simple_(is_simple),
1209 depth_(depth) {}
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001210
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001211 private:
1212 int literal_index_;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001213 bool is_simple_;
1214 int depth_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001215};
1216
1217
1218// An object literal has a boilerplate object that is used
1219// for minimizing the work when constructing it at runtime.
1220class ObjectLiteral: public MaterializedLiteral {
1221 public:
1222 // Property is used for passing information
1223 // about an object literal's properties from the parser
1224 // to the code generator.
1225 class Property: public ZoneObject {
1226 public:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001227 enum Kind {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001228 CONSTANT, // Property with constant value (compile time).
1229 COMPUTED, // Property with computed value (execution time).
1230 MATERIALIZED_LITERAL, // Property value is a materialized literal.
1231 GETTER, SETTER, // Property is an accessor function.
1232 PROTOTYPE // Property is __proto__.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001233 };
1234
1235 Property(Literal* key, Expression* value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001236
1237 Literal* key() { return key_; }
1238 Expression* value() { return value_; }
1239 Kind kind() { return kind_; }
1240
ager@chromium.org3811b432009-10-28 14:53:37 +00001241 bool IsCompileTimeValue();
1242
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00001243 void set_emit_store(bool emit_store);
1244 bool emit_store();
1245
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001246 protected:
1247 template<class> friend class AstNodeFactory;
1248
1249 Property(bool is_getter, FunctionLiteral* value);
1250 void set_key(Literal* key) { key_ = key; }
1251
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001252 private:
1253 Literal* key_;
1254 Expression* value_;
1255 Kind kind_;
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00001256 bool emit_store_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001257 };
1258
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001259 DECLARE_NODE_TYPE(ObjectLiteral)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001260
1261 Handle<FixedArray> constant_properties() const {
1262 return constant_properties_;
1263 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001264 ZoneList<Property*>* properties() const { return properties_; }
1265
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001266 bool fast_elements() const { return fast_elements_; }
1267
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001268 bool has_function() { return has_function_; }
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00001269
1270 // Mark all computed expressions that are bound to a key that
1271 // is shadowed by a later occurrence of the same key. For the
1272 // marked expressions, no store code is emitted.
1273 void CalculateEmitStore();
1274
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001275 enum Flags {
1276 kNoFlags = 0,
1277 kFastElements = 1,
1278 kHasFunction = 1 << 1
1279 };
1280
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001281 protected:
1282 template<class> friend class AstNodeFactory;
1283
1284 ObjectLiteral(Isolate* isolate,
1285 Handle<FixedArray> constant_properties,
1286 ZoneList<Property*>* properties,
1287 int literal_index,
1288 bool is_simple,
1289 bool fast_elements,
1290 int depth,
1291 bool has_function)
1292 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
1293 constant_properties_(constant_properties),
1294 properties_(properties),
1295 fast_elements_(fast_elements),
1296 has_function_(has_function) {}
1297
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001298 private:
1299 Handle<FixedArray> constant_properties_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001300 ZoneList<Property*>* properties_;
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001301 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001302 bool has_function_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001303};
1304
1305
1306// Node for capturing a regexp literal.
1307class RegExpLiteral: public MaterializedLiteral {
1308 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001309 DECLARE_NODE_TYPE(RegExpLiteral)
1310
1311 Handle<String> pattern() const { return pattern_; }
1312 Handle<String> flags() const { return flags_; }
1313
1314 protected:
1315 template<class> friend class AstNodeFactory;
1316
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001317 RegExpLiteral(Isolate* isolate,
1318 Handle<String> pattern,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001319 Handle<String> flags,
1320 int literal_index)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001321 : MaterializedLiteral(isolate, literal_index, false, 1),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001322 pattern_(pattern),
1323 flags_(flags) {}
1324
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001325 private:
1326 Handle<String> pattern_;
1327 Handle<String> flags_;
1328};
1329
1330// An array literal has a literals object that is used
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001331// for minimizing the work when constructing it at runtime.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001332class ArrayLiteral: public MaterializedLiteral {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001333 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001334 DECLARE_NODE_TYPE(ArrayLiteral)
1335
1336 Handle<FixedArray> constant_elements() const { return constant_elements_; }
1337 ZoneList<Expression*>* values() const { return values_; }
1338
1339 // Return an AST id for an element that is used in simulate instructions.
1340 int GetIdForElement(int i) { return first_element_id_ + i; }
1341
1342 protected:
1343 template<class> friend class AstNodeFactory;
1344
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001345 ArrayLiteral(Isolate* isolate,
1346 Handle<FixedArray> constant_elements,
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001347 ZoneList<Expression*>* values,
1348 int literal_index,
1349 bool is_simple,
1350 int depth)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001351 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001352 constant_elements_(constant_elements),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001353 values_(values),
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001354 first_element_id_(ReserveIdRange(isolate, values->length())) {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001355
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001356 private:
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001357 Handle<FixedArray> constant_elements_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001358 ZoneList<Expression*>* values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001359 int first_element_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001360};
1361
1362
1363class VariableProxy: public Expression {
1364 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001365 DECLARE_NODE_TYPE(VariableProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001366
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001367 virtual bool IsValidLeftHandSide() {
1368 return var_ == NULL ? true : var_->IsValidLeftHandSide();
1369 }
ager@chromium.org3e875802009-06-29 08:26:34 +00001370
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001371 bool IsVariable(Handle<String> n) {
1372 return !is_this() && name().is_identical_to(n);
1373 }
1374
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001375 bool IsArguments() { return var_ != NULL && var_->is_arguments(); }
ager@chromium.org3e875802009-06-29 08:26:34 +00001376
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001377 bool IsLValue() {
1378 return is_lvalue_;
1379 }
1380
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001381 Handle<String> name() const { return name_; }
1382 Variable* var() const { return var_; }
1383 bool is_this() const { return is_this_; }
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001384 int position() const { return position_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001385
ricow@chromium.org65fae842010-08-25 15:26:24 +00001386 void MarkAsTrivial() { is_trivial_ = true; }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001387 void MarkAsLValue() { is_lvalue_ = true; }
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001388
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001389 // Bind this proxy to the variable var.
1390 void BindTo(Variable* var);
1391
1392 protected:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001393 template<class> friend class AstNodeFactory;
1394
1395 VariableProxy(Isolate* isolate, Variable* var);
1396
1397 VariableProxy(Isolate* isolate,
1398 Handle<String> name,
1399 bool is_this,
1400 int position);
1401
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001402 Handle<String> name_;
1403 Variable* var_; // resolved variable, or NULL
1404 bool is_this_;
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001405 bool is_trivial_;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001406 // True if this variable proxy is being used in an assignment
1407 // or with a increment/decrement operator.
1408 bool is_lvalue_;
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001409 int position_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001410};
1411
1412
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001413class Property: public Expression {
1414 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001415 DECLARE_NODE_TYPE(Property)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001416
1417 virtual bool IsValidLeftHandSide() { return true; }
1418
1419 Expression* obj() const { return obj_; }
1420 Expression* key() const { return key_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001421 virtual int position() const { return pos_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001422
ager@chromium.org378b34e2011-01-28 08:04:38 +00001423 bool IsStringLength() const { return is_string_length_; }
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00001424 bool IsStringAccess() const { return is_string_access_; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001425 bool IsFunctionPrototype() const { return is_function_prototype_; }
1426
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001427 // Type feedback information.
1428 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1429 virtual bool IsMonomorphic() { return is_monomorphic_; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001430 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001431 bool IsArrayLength() { return is_array_length_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001432
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001433 protected:
1434 template<class> friend class AstNodeFactory;
1435
1436 Property(Isolate* isolate,
1437 Expression* obj,
1438 Expression* key,
1439 int pos)
1440 : Expression(isolate),
1441 obj_(obj),
1442 key_(key),
1443 pos_(pos),
1444 is_monomorphic_(false),
1445 is_array_length_(false),
1446 is_string_length_(false),
1447 is_string_access_(false),
1448 is_function_prototype_(false) { }
1449
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001450 private:
1451 Expression* obj_;
1452 Expression* key_;
1453 int pos_;
1454
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001455 SmallMapList receiver_types_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00001456 bool is_monomorphic_ : 1;
1457 bool is_array_length_ : 1;
1458 bool is_string_length_ : 1;
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00001459 bool is_string_access_ : 1;
ager@chromium.org378b34e2011-01-28 08:04:38 +00001460 bool is_function_prototype_ : 1;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001461};
1462
1463
1464class Call: public Expression {
1465 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001466 DECLARE_NODE_TYPE(Call)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001467
1468 Expression* expression() const { return expression_; }
1469 ZoneList<Expression*>* arguments() const { return arguments_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001470 virtual int position() const { return pos_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001471
danno@chromium.org40cb8782011-05-25 07:58:50 +00001472 void RecordTypeFeedback(TypeFeedbackOracle* oracle,
1473 CallKind call_kind);
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001474 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001475 virtual bool IsMonomorphic() { return is_monomorphic_; }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001476 CheckType check_type() const { return check_type_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001477 Handle<JSFunction> target() { return target_; }
1478 Handle<JSObject> holder() { return holder_; }
1479 Handle<JSGlobalPropertyCell> cell() { return cell_; }
1480
1481 bool ComputeTarget(Handle<Map> type, Handle<String> name);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001482 bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001483
1484 // Bailout support.
1485 int ReturnId() const { return return_id_; }
1486
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001487#ifdef DEBUG
1488 // Used to assert that the FullCodeGenerator records the return site.
1489 bool return_is_recorded_;
1490#endif
1491
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001492 protected:
1493 template<class> friend class AstNodeFactory;
1494
1495 Call(Isolate* isolate,
1496 Expression* expression,
1497 ZoneList<Expression*>* arguments,
1498 int pos)
1499 : Expression(isolate),
1500 expression_(expression),
1501 arguments_(arguments),
1502 pos_(pos),
1503 is_monomorphic_(false),
1504 check_type_(RECEIVER_MAP_CHECK),
1505 return_id_(GetNextId(isolate)) { }
1506
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001507 private:
1508 Expression* expression_;
1509 ZoneList<Expression*>* arguments_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001510 int pos_;
1511
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001512 bool is_monomorphic_;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001513 CheckType check_type_;
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001514 SmallMapList receiver_types_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001515 Handle<JSFunction> target_;
1516 Handle<JSObject> holder_;
1517 Handle<JSGlobalPropertyCell> cell_;
1518
1519 int return_id_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001520};
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001521
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001522
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00001523class CallNew: public Expression {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001524 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001525 DECLARE_NODE_TYPE(CallNew)
1526
1527 Expression* expression() const { return expression_; }
1528 ZoneList<Expression*>* arguments() const { return arguments_; }
1529 virtual int position() const { return pos_; }
1530
1531 protected:
1532 template<class> friend class AstNodeFactory;
1533
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001534 CallNew(Isolate* isolate,
1535 Expression* expression,
1536 ZoneList<Expression*>* arguments,
1537 int pos)
1538 : Expression(isolate),
1539 expression_(expression),
1540 arguments_(arguments),
1541 pos_(pos) { }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001542
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001543 private:
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00001544 Expression* expression_;
1545 ZoneList<Expression*>* arguments_;
1546 int pos_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001547};
1548
1549
1550// The CallRuntime class does not represent any official JavaScript
1551// language construct. Instead it is used to call a C or JS function
1552// with a set of arguments. This is used from the builtins that are
1553// implemented in JavaScript (see "v8natives.js").
1554class CallRuntime: public Expression {
1555 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001556 DECLARE_NODE_TYPE(CallRuntime)
1557
1558 Handle<String> name() const { return name_; }
1559 const Runtime::Function* function() const { return function_; }
1560 ZoneList<Expression*>* arguments() const { return arguments_; }
1561 bool is_jsruntime() const { return function_ == NULL; }
1562
1563 protected:
1564 template<class> friend class AstNodeFactory;
1565
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001566 CallRuntime(Isolate* isolate,
1567 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001568 const Runtime::Function* function,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001569 ZoneList<Expression*>* arguments)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001570 : Expression(isolate),
1571 name_(name),
1572 function_(function),
1573 arguments_(arguments) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001574
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001575 private:
1576 Handle<String> name_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001577 const Runtime::Function* function_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001578 ZoneList<Expression*>* arguments_;
1579};
1580
1581
1582class UnaryOperation: public Expression {
1583 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001584 DECLARE_NODE_TYPE(UnaryOperation)
1585
1586 virtual bool ResultOverwriteAllowed();
1587
1588 Token::Value op() const { return op_; }
1589 Expression* expression() const { return expression_; }
1590 virtual int position() const { return pos_; }
1591
1592 int MaterializeTrueId() { return materialize_true_id_; }
1593 int MaterializeFalseId() { return materialize_false_id_; }
1594
1595 protected:
1596 template<class> friend class AstNodeFactory;
1597
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001598 UnaryOperation(Isolate* isolate,
1599 Token::Value op,
1600 Expression* expression,
1601 int pos)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001602 : Expression(isolate),
1603 op_(op),
1604 expression_(expression),
1605 pos_(pos),
1606 materialize_true_id_(AstNode::kNoNumber),
1607 materialize_false_id_(AstNode::kNoNumber) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001608 ASSERT(Token::IsUnaryOp(op));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001609 if (op == Token::NOT) {
1610 materialize_true_id_ = GetNextId(isolate);
1611 materialize_false_id_ = GetNextId(isolate);
1612 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001613 }
1614
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001615 private:
1616 Token::Value op_;
1617 Expression* expression_;
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00001618 int pos_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001619
1620 // For unary not (Token::NOT), the AST ids where true and false will
1621 // actually be materialized, respectively.
1622 int materialize_true_id_;
1623 int materialize_false_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001624};
1625
1626
1627class BinaryOperation: public Expression {
1628 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001629 DECLARE_NODE_TYPE(BinaryOperation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001630
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001631 virtual bool ResultOverwriteAllowed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001632
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001633 Token::Value op() const { return op_; }
1634 Expression* left() const { return left_; }
1635 Expression* right() const { return right_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001636 virtual int position() const { return pos_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001637
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001638 // Bailout support.
1639 int RightId() const { return right_id_; }
1640
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001641 protected:
1642 template<class> friend class AstNodeFactory;
1643
1644 BinaryOperation(Isolate* isolate,
1645 Token::Value op,
1646 Expression* left,
1647 Expression* right,
1648 int pos)
1649 : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) {
1650 ASSERT(Token::IsBinaryOp(op));
1651 right_id_ = (op == Token::AND || op == Token::OR)
1652 ? GetNextId(isolate)
1653 : AstNode::kNoNumber;
1654 }
1655
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001656 private:
1657 Token::Value op_;
1658 Expression* left_;
1659 Expression* right_;
ricow@chromium.org65fae842010-08-25 15:26:24 +00001660 int pos_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001661 // The short-circuit logical operations have an AST ID for their
1662 // right-hand subexpression.
1663 int right_id_;
ricow@chromium.org65fae842010-08-25 15:26:24 +00001664};
1665
1666
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001667class CountOperation: public Expression {
1668 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001669 DECLARE_NODE_TYPE(CountOperation)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001670
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001671 bool is_prefix() const { return is_prefix_; }
1672 bool is_postfix() const { return !is_prefix_; }
ricow@chromium.org65fae842010-08-25 15:26:24 +00001673
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001674 Token::Value op() const { return op_; }
kasperl@chromium.org74e4e5e2010-01-25 10:15:52 +00001675 Token::Value binary_op() {
ricow@chromium.org65fae842010-08-25 15:26:24 +00001676 return (op() == Token::INC) ? Token::ADD : Token::SUB;
kasperl@chromium.org74e4e5e2010-01-25 10:15:52 +00001677 }
ricow@chromium.org65fae842010-08-25 15:26:24 +00001678
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001679 Expression* expression() const { return expression_; }
1680 virtual int position() const { return pos_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001681
1682 virtual void MarkAsStatement() { is_prefix_ = true; }
1683
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001684 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1685 virtual bool IsMonomorphic() { return is_monomorphic_; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001686 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001687
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001688 // Bailout support.
1689 int AssignmentId() const { return assignment_id_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001690 int CountId() const { return count_id_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001691
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001692 protected:
1693 template<class> friend class AstNodeFactory;
1694
1695 CountOperation(Isolate* isolate,
1696 Token::Value op,
1697 bool is_prefix,
1698 Expression* expr,
1699 int pos)
1700 : Expression(isolate),
1701 op_(op),
1702 is_prefix_(is_prefix),
1703 expression_(expr),
1704 pos_(pos),
1705 assignment_id_(GetNextId(isolate)),
1706 count_id_(GetNextId(isolate)) {}
1707
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001708 private:
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001709 Token::Value op_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001710 bool is_prefix_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001711 bool is_monomorphic_;
1712 Expression* expression_;
ricow@chromium.org65fae842010-08-25 15:26:24 +00001713 int pos_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001714 int assignment_id_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001715 int count_id_;
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001716 SmallMapList receiver_types_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001717};
1718
1719
1720class CompareOperation: public Expression {
1721 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001722 DECLARE_NODE_TYPE(CompareOperation)
1723
1724 Token::Value op() const { return op_; }
1725 Expression* left() const { return left_; }
1726 Expression* right() const { return right_; }
1727 virtual int position() const { return pos_; }
1728
1729 // Type feedback information.
1730 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1731 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
1732 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1733
1734 // Match special cases.
1735 bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
1736 bool IsLiteralCompareUndefined(Expression** expr);
1737 bool IsLiteralCompareNull(Expression** expr);
1738
1739 protected:
1740 template<class> friend class AstNodeFactory;
1741
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001742 CompareOperation(Isolate* isolate,
1743 Token::Value op,
ricow@chromium.org65fae842010-08-25 15:26:24 +00001744 Expression* left,
1745 Expression* right,
1746 int pos)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001747 : Expression(isolate),
1748 op_(op),
1749 left_(left),
1750 right_(right),
1751 pos_(pos),
1752 compare_type_(NONE) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001753 ASSERT(Token::IsCompareOp(op));
1754 }
1755
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001756 private:
1757 Token::Value op_;
1758 Expression* left_;
1759 Expression* right_;
ricow@chromium.org65fae842010-08-25 15:26:24 +00001760 int pos_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001761
1762 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
1763 CompareTypeFeedback compare_type_;
ricow@chromium.org65fae842010-08-25 15:26:24 +00001764};
1765
1766
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001767class Conditional: public Expression {
1768 public:
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001769 DECLARE_NODE_TYPE(Conditional)
1770
1771 Expression* condition() const { return condition_; }
1772 Expression* then_expression() const { return then_expression_; }
1773 Expression* else_expression() const { return else_expression_; }
1774
1775 int then_expression_position() const { return then_expression_position_; }
1776 int else_expression_position() const { return else_expression_position_; }
1777
1778 int ThenId() const { return then_id_; }
1779 int ElseId() const { return else_id_; }
1780
1781 protected:
1782 template<class> friend class AstNodeFactory;
1783
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001784 Conditional(Isolate* isolate,
1785 Expression* condition,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001786 Expression* then_expression,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001787 Expression* else_expression,
1788 int then_expression_position,
1789 int else_expression_position)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001790 : Expression(isolate),
1791 condition_(condition),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001792 then_expression_(then_expression),
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001793 else_expression_(else_expression),
1794 then_expression_position_(then_expression_position),
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001795 else_expression_position_(else_expression_position),
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001796 then_id_(GetNextId(isolate)),
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001797 else_id_(GetNextId(isolate)) { }
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001798
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001799 private:
1800 Expression* condition_;
1801 Expression* then_expression_;
1802 Expression* else_expression_;
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001803 int then_expression_position_;
1804 int else_expression_position_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001805 int then_id_;
1806 int else_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001807};
1808
1809
1810class Assignment: public Expression {
1811 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001812 DECLARE_NODE_TYPE(Assignment)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001813
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001814 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1815
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001816 Token::Value binary_op() const;
1817
1818 Token::Value op() const { return op_; }
1819 Expression* target() const { return target_; }
1820 Expression* value() const { return value_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001821 virtual int position() const { return pos_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001822 BinaryOperation* binary_operation() const { return binary_operation_; }
1823
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +00001824 // This check relies on the definition order of token in token.h.
1825 bool is_compound() const { return op() > Token::ASSIGN; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001826
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001827 // An initialization block is a series of statments of the form
1828 // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1829 // ending of these blocks to allow for optimizations of initialization
1830 // blocks.
1831 bool starts_initialization_block() { return block_start_; }
1832 bool ends_initialization_block() { return block_end_; }
1833 void mark_block_start() { block_start_ = true; }
1834 void mark_block_end() { block_end_ = true; }
1835
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001836 // Type feedback information.
1837 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1838 virtual bool IsMonomorphic() { return is_monomorphic_; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001839 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001840
1841 // Bailout support.
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001842 int CompoundLoadId() const { return compound_load_id_; }
1843 int AssignmentId() const { return assignment_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001844
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001845 protected:
1846 template<class> friend class AstNodeFactory;
1847
1848 Assignment(Isolate* isolate,
1849 Token::Value op,
1850 Expression* target,
1851 Expression* value,
1852 int pos);
1853
1854 template<class Visitor>
1855 void Init(Isolate* isolate, AstNodeFactory<Visitor>* factory) {
1856 ASSERT(Token::IsAssignmentOp(op_));
1857 if (is_compound()) {
1858 binary_operation_ =
1859 factory->NewBinaryOperation(binary_op(), target_, value_, pos_ + 1);
1860 compound_load_id_ = GetNextId(isolate);
1861 }
1862 }
1863
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001864 private:
1865 Token::Value op_;
1866 Expression* target_;
1867 Expression* value_;
1868 int pos_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001869 BinaryOperation* binary_operation_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001870 int compound_load_id_;
1871 int assignment_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001872
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001873 bool block_start_;
1874 bool block_end_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001875
1876 bool is_monomorphic_;
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001877 SmallMapList receiver_types_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001878};
1879
1880
1881class Throw: public Expression {
1882 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001883 DECLARE_NODE_TYPE(Throw)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001884
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001885 Expression* exception() const { return exception_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001886 virtual int position() const { return pos_; }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001887
1888 protected:
1889 template<class> friend class AstNodeFactory;
1890
1891 Throw(Isolate* isolate, Expression* exception, int pos)
1892 : Expression(isolate), exception_(exception), pos_(pos) {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001893
1894 private:
1895 Expression* exception_;
1896 int pos_;
1897};
1898
1899
1900class FunctionLiteral: public Expression {
1901 public:
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001902 enum Type {
1903 ANONYMOUS_EXPRESSION,
1904 NAMED_EXPRESSION,
1905 DECLARATION
1906 };
1907
yangguo@chromium.org56454712012-02-16 15:33:53 +00001908 enum ParameterFlag {
1909 kNoDuplicateParameters = 0,
1910 kHasDuplicateParameters = 1
1911 };
1912
1913 enum IsFunctionFlag {
1914 kGlobalOrEval,
1915 kIsFunction
1916 };
1917
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001918 DECLARE_NODE_TYPE(FunctionLiteral)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001919
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001920 Handle<String> name() const { return name_; }
1921 Scope* scope() const { return scope_; }
1922 ZoneList<Statement*>* body() const { return body_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001923 void set_function_token_position(int pos) { function_token_position_ = pos; }
1924 int function_token_position() const { return function_token_position_; }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001925 int start_position() const;
1926 int end_position() const;
yangguo@chromium.org56454712012-02-16 15:33:53 +00001927 int SourceSize() const { return end_position() - start_position(); }
danno@chromium.orgc612e022011-11-10 11:38:15 +00001928 bool is_expression() const { return IsExpression::decode(bitfield_); }
1929 bool is_anonymous() const { return IsAnonymous::decode(bitfield_); }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001930 bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; }
1931 LanguageMode language_mode() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001932
1933 int materialized_literal_count() { return materialized_literal_count_; }
1934 int expected_property_count() { return expected_property_count_; }
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00001935 int handler_count() { return handler_count_; }
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001936 bool has_only_simple_this_property_assignments() {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001937 return HasOnlySimpleThisPropertyAssignments::decode(bitfield_);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001938 }
1939 Handle<FixedArray> this_property_assignments() {
1940 return this_property_assignments_;
1941 }
danno@chromium.orgc612e022011-11-10 11:38:15 +00001942 int parameter_count() { return parameter_count_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001943
1944 bool AllowsLazyCompilation();
1945
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00001946 Handle<String> debug_name() const {
1947 if (name_->length() > 0) return name_;
1948 return inferred_name();
1949 }
1950
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001951 Handle<String> inferred_name() const { return inferred_name_; }
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00001952 void set_inferred_name(Handle<String> inferred_name) {
1953 inferred_name_ = inferred_name;
1954 }
1955
danno@chromium.orgc612e022011-11-10 11:38:15 +00001956 bool pretenure() { return Pretenure::decode(bitfield_); }
1957 void set_pretenure() { bitfield_ |= Pretenure::encode(true); }
vegorov@chromium.org21b5e952010-11-23 10:24:40 +00001958
danno@chromium.orgc612e022011-11-10 11:38:15 +00001959 bool has_duplicate_parameters() {
1960 return HasDuplicateParameters::decode(bitfield_);
1961 }
whesse@chromium.org7b260152011-06-20 15:33:18 +00001962
yangguo@chromium.org56454712012-02-16 15:33:53 +00001963 bool is_function() { return IsFunction::decode(bitfield_) == kIsFunction; }
1964
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001965 int ast_node_count() { return ast_properties_.node_count(); }
1966 AstProperties::Flags* flags() { return ast_properties_.flags(); }
1967 void set_ast_properties(AstProperties* ast_properties) {
1968 ast_properties_ = *ast_properties;
1969 }
1970
1971 protected:
1972 template<class> friend class AstNodeFactory;
1973
1974 FunctionLiteral(Isolate* isolate,
1975 Handle<String> name,
1976 Scope* scope,
1977 ZoneList<Statement*>* body,
1978 int materialized_literal_count,
1979 int expected_property_count,
1980 int handler_count,
1981 bool has_only_simple_this_property_assignments,
1982 Handle<FixedArray> this_property_assignments,
1983 int parameter_count,
1984 Type type,
yangguo@chromium.org56454712012-02-16 15:33:53 +00001985 ParameterFlag has_duplicate_parameters,
1986 IsFunctionFlag is_function)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001987 : Expression(isolate),
1988 name_(name),
1989 scope_(scope),
1990 body_(body),
1991 this_property_assignments_(this_property_assignments),
1992 inferred_name_(isolate->factory()->empty_string()),
1993 materialized_literal_count_(materialized_literal_count),
1994 expected_property_count_(expected_property_count),
1995 handler_count_(handler_count),
1996 parameter_count_(parameter_count),
1997 function_token_position_(RelocInfo::kNoPosition) {
1998 bitfield_ =
1999 HasOnlySimpleThisPropertyAssignments::encode(
2000 has_only_simple_this_property_assignments) |
2001 IsExpression::encode(type != DECLARATION) |
2002 IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) |
2003 Pretenure::encode(false) |
yangguo@chromium.org56454712012-02-16 15:33:53 +00002004 HasDuplicateParameters::encode(has_duplicate_parameters) |
2005 IsFunction::encode(is_function);
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002006 }
2007
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002008 private:
2009 Handle<String> name_;
2010 Scope* scope_;
2011 ZoneList<Statement*>* body_;
danno@chromium.orgc612e022011-11-10 11:38:15 +00002012 Handle<FixedArray> this_property_assignments_;
2013 Handle<String> inferred_name_;
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002014 AstProperties ast_properties_;
danno@chromium.orgc612e022011-11-10 11:38:15 +00002015
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002016 int materialized_literal_count_;
2017 int expected_property_count_;
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00002018 int handler_count_;
danno@chromium.orgc612e022011-11-10 11:38:15 +00002019 int parameter_count_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002020 int function_token_position_;
danno@chromium.orgc612e022011-11-10 11:38:15 +00002021
2022 unsigned bitfield_;
2023 class HasOnlySimpleThisPropertyAssignments: public BitField<bool, 0, 1> {};
2024 class IsExpression: public BitField<bool, 1, 1> {};
2025 class IsAnonymous: public BitField<bool, 2, 1> {};
2026 class Pretenure: public BitField<bool, 3, 1> {};
yangguo@chromium.org56454712012-02-16 15:33:53 +00002027 class HasDuplicateParameters: public BitField<ParameterFlag, 4, 1> {};
2028 class IsFunction: public BitField<IsFunctionFlag, 5, 1> {};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002029};
2030
2031
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002032class SharedFunctionInfoLiteral: public Expression {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002033 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00002034 DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
2035
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002036 Handle<SharedFunctionInfo> shared_function_info() const {
2037 return shared_function_info_;
2038 }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002039
2040 protected:
2041 template<class> friend class AstNodeFactory;
2042
2043 SharedFunctionInfoLiteral(
2044 Isolate* isolate,
2045 Handle<SharedFunctionInfo> shared_function_info)
2046 : Expression(isolate),
2047 shared_function_info_(shared_function_info) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002048
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002049 private:
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002050 Handle<SharedFunctionInfo> shared_function_info_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002051};
2052
2053
2054class ThisFunction: public Expression {
2055 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00002056 DECLARE_NODE_TYPE(ThisFunction)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002057
2058 protected:
2059 template<class> friend class AstNodeFactory;
2060
2061 explicit ThisFunction(Isolate* isolate): Expression(isolate) {}
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002062};
2063
ulan@chromium.org65a89c22012-02-14 11:46:07 +00002064#undef DECLARE_NODE_TYPE
2065
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002066
2067// ----------------------------------------------------------------------------
2068// Regular expressions
2069
2070
ager@chromium.org32912102009-01-16 10:38:43 +00002071class RegExpVisitor BASE_EMBEDDED {
2072 public:
2073 virtual ~RegExpVisitor() { }
2074#define MAKE_CASE(Name) \
2075 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
2076 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
2077#undef MAKE_CASE
2078};
2079
2080
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002081class RegExpTree: public ZoneObject {
2082 public:
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002083 static const int kInfinity = kMaxInt;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002084 virtual ~RegExpTree() { }
2085 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
2086 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002087 RegExpNode* on_success) = 0;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002088 virtual bool IsTextElement() { return false; }
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002089 virtual bool IsAnchoredAtStart() { return false; }
2090 virtual bool IsAnchoredAtEnd() { return false; }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002091 virtual int min_match() = 0;
2092 virtual int max_match() = 0;
ager@chromium.org32912102009-01-16 10:38:43 +00002093 // Returns the interval of registers used for captures within this
2094 // expression.
2095 virtual Interval CaptureRegisters() { return Interval::Empty(); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002096 virtual void AppendToText(RegExpText* text);
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002097 SmartArrayPointer<const char> ToString();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002098#define MAKE_ASTYPE(Name) \
2099 virtual RegExp##Name* As##Name(); \
2100 virtual bool Is##Name();
2101 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
2102#undef MAKE_ASTYPE
2103};
2104
2105
2106class RegExpDisjunction: public RegExpTree {
2107 public:
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002108 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002109 virtual void* Accept(RegExpVisitor* visitor, void* data);
2110 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002111 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002112 virtual RegExpDisjunction* AsDisjunction();
ager@chromium.org32912102009-01-16 10:38:43 +00002113 virtual Interval CaptureRegisters();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002114 virtual bool IsDisjunction();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002115 virtual bool IsAnchoredAtStart();
2116 virtual bool IsAnchoredAtEnd();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002117 virtual int min_match() { return min_match_; }
2118 virtual int max_match() { return max_match_; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002119 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
2120 private:
2121 ZoneList<RegExpTree*>* alternatives_;
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002122 int min_match_;
2123 int max_match_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002124};
2125
2126
2127class RegExpAlternative: public RegExpTree {
2128 public:
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002129 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002130 virtual void* Accept(RegExpVisitor* visitor, void* data);
2131 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002132 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002133 virtual RegExpAlternative* AsAlternative();
ager@chromium.org32912102009-01-16 10:38:43 +00002134 virtual Interval CaptureRegisters();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002135 virtual bool IsAlternative();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002136 virtual bool IsAnchoredAtStart();
2137 virtual bool IsAnchoredAtEnd();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002138 virtual int min_match() { return min_match_; }
2139 virtual int max_match() { return max_match_; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002140 ZoneList<RegExpTree*>* nodes() { return nodes_; }
2141 private:
2142 ZoneList<RegExpTree*>* nodes_;
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002143 int min_match_;
2144 int max_match_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002145};
2146
2147
2148class RegExpAssertion: public RegExpTree {
2149 public:
2150 enum Type {
2151 START_OF_LINE,
2152 START_OF_INPUT,
2153 END_OF_LINE,
2154 END_OF_INPUT,
2155 BOUNDARY,
2156 NON_BOUNDARY
2157 };
2158 explicit RegExpAssertion(Type type) : type_(type) { }
2159 virtual void* Accept(RegExpVisitor* visitor, void* data);
2160 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002161 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002162 virtual RegExpAssertion* AsAssertion();
2163 virtual bool IsAssertion();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002164 virtual bool IsAnchoredAtStart();
2165 virtual bool IsAnchoredAtEnd();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002166 virtual int min_match() { return 0; }
2167 virtual int max_match() { return 0; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002168 Type type() { return type_; }
2169 private:
2170 Type type_;
2171};
2172
2173
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002174class CharacterSet BASE_EMBEDDED {
2175 public:
2176 explicit CharacterSet(uc16 standard_set_type)
2177 : ranges_(NULL),
2178 standard_set_type_(standard_set_type) {}
2179 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
2180 : ranges_(ranges),
2181 standard_set_type_(0) {}
2182 ZoneList<CharacterRange>* ranges();
2183 uc16 standard_set_type() { return standard_set_type_; }
2184 void set_standard_set_type(uc16 special_set_type) {
2185 standard_set_type_ = special_set_type;
2186 }
2187 bool is_standard() { return standard_set_type_ != 0; }
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002188 void Canonicalize();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002189 private:
2190 ZoneList<CharacterRange>* ranges_;
2191 // If non-zero, the value represents a standard set (e.g., all whitespace
2192 // characters) without having to expand the ranges.
2193 uc16 standard_set_type_;
2194};
2195
2196
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002197class RegExpCharacterClass: public RegExpTree {
2198 public:
2199 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002200 : set_(ranges),
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002201 is_negated_(is_negated) { }
2202 explicit RegExpCharacterClass(uc16 type)
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002203 : set_(type),
2204 is_negated_(false) { }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002205 virtual void* Accept(RegExpVisitor* visitor, void* data);
2206 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002207 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002208 virtual RegExpCharacterClass* AsCharacterClass();
2209 virtual bool IsCharacterClass();
2210 virtual bool IsTextElement() { return true; }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002211 virtual int min_match() { return 1; }
2212 virtual int max_match() { return 1; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002213 virtual void AppendToText(RegExpText* text);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002214 CharacterSet character_set() { return set_; }
2215 // TODO(lrn): Remove need for complex version if is_standard that
2216 // recognizes a mangled standard set and just do { return set_.is_special(); }
2217 bool is_standard();
2218 // Returns a value representing the standard character set if is_standard()
2219 // returns true.
2220 // Currently used values are:
2221 // s : unicode whitespace
2222 // S : unicode non-whitespace
2223 // w : ASCII word character (digit, letter, underscore)
2224 // W : non-ASCII word character
2225 // d : ASCII digit
2226 // D : non-ASCII digit
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002227 // . : non-unicode non-newline
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002228 // * : All characters
2229 uc16 standard_type() { return set_.standard_set_type(); }
2230 ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002231 bool is_negated() { return is_negated_; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002232
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002233 private:
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002234 CharacterSet set_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002235 bool is_negated_;
2236};
2237
2238
2239class RegExpAtom: public RegExpTree {
2240 public:
2241 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
2242 virtual void* Accept(RegExpVisitor* visitor, void* data);
2243 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002244 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002245 virtual RegExpAtom* AsAtom();
2246 virtual bool IsAtom();
2247 virtual bool IsTextElement() { return true; }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002248 virtual int min_match() { return data_.length(); }
2249 virtual int max_match() { return data_.length(); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002250 virtual void AppendToText(RegExpText* text);
2251 Vector<const uc16> data() { return data_; }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002252 int length() { return data_.length(); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002253 private:
2254 Vector<const uc16> data_;
2255};
2256
2257
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002258class RegExpText: public RegExpTree {
2259 public:
2260 RegExpText() : elements_(2), length_(0) {}
2261 virtual void* Accept(RegExpVisitor* visitor, void* data);
2262 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2263 RegExpNode* on_success);
2264 virtual RegExpText* AsText();
2265 virtual bool IsText();
2266 virtual bool IsTextElement() { return true; }
2267 virtual int min_match() { return length_; }
2268 virtual int max_match() { return length_; }
2269 virtual void AppendToText(RegExpText* text);
2270 void AddElement(TextElement elm) {
2271 elements_.Add(elm);
2272 length_ += elm.length();
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +00002273 }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002274 ZoneList<TextElement>* elements() { return &elements_; }
2275 private:
2276 ZoneList<TextElement> elements_;
2277 int length_;
2278};
2279
2280
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002281class RegExpQuantifier: public RegExpTree {
2282 public:
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002283 enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
2284 RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
2285 : body_(body),
2286 min_(min),
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002287 max_(max),
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002288 min_match_(min * body->min_match()),
2289 type_(type) {
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002290 if (max > 0 && body->max_match() > kInfinity / max) {
2291 max_match_ = kInfinity;
2292 } else {
2293 max_match_ = max * body->max_match();
2294 }
2295 }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002296 virtual void* Accept(RegExpVisitor* visitor, void* data);
2297 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002298 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002299 static RegExpNode* ToNode(int min,
2300 int max,
2301 bool is_greedy,
2302 RegExpTree* body,
2303 RegExpCompiler* compiler,
iposva@chromium.org245aa852009-02-10 00:49:54 +00002304 RegExpNode* on_success,
2305 bool not_at_start = false);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002306 virtual RegExpQuantifier* AsQuantifier();
ager@chromium.org32912102009-01-16 10:38:43 +00002307 virtual Interval CaptureRegisters();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002308 virtual bool IsQuantifier();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002309 virtual int min_match() { return min_match_; }
2310 virtual int max_match() { return max_match_; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002311 int min() { return min_; }
2312 int max() { return max_; }
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002313 bool is_possessive() { return type_ == POSSESSIVE; }
2314 bool is_non_greedy() { return type_ == NON_GREEDY; }
2315 bool is_greedy() { return type_ == GREEDY; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002316 RegExpTree* body() { return body_; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002317
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002318 private:
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002319 RegExpTree* body_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002320 int min_;
2321 int max_;
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002322 int min_match_;
2323 int max_match_;
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002324 Type type_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002325};
2326
2327
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002328class RegExpCapture: public RegExpTree {
2329 public:
2330 explicit RegExpCapture(RegExpTree* body, int index)
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002331 : body_(body), index_(index) { }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002332 virtual void* Accept(RegExpVisitor* visitor, void* data);
2333 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002334 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002335 static RegExpNode* ToNode(RegExpTree* body,
2336 int index,
2337 RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002338 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002339 virtual RegExpCapture* AsCapture();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002340 virtual bool IsAnchoredAtStart();
2341 virtual bool IsAnchoredAtEnd();
ager@chromium.org32912102009-01-16 10:38:43 +00002342 virtual Interval CaptureRegisters();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002343 virtual bool IsCapture();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002344 virtual int min_match() { return body_->min_match(); }
2345 virtual int max_match() { return body_->max_match(); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002346 RegExpTree* body() { return body_; }
2347 int index() { return index_; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002348 static int StartRegister(int index) { return index * 2; }
2349 static int EndRegister(int index) { return index * 2 + 1; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002350
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002351 private:
2352 RegExpTree* body_;
2353 int index_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002354};
2355
2356
2357class RegExpLookahead: public RegExpTree {
2358 public:
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002359 RegExpLookahead(RegExpTree* body,
2360 bool is_positive,
2361 int capture_count,
2362 int capture_from)
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002363 : body_(body),
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002364 is_positive_(is_positive),
2365 capture_count_(capture_count),
2366 capture_from_(capture_from) { }
2367
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002368 virtual void* Accept(RegExpVisitor* visitor, void* data);
2369 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002370 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002371 virtual RegExpLookahead* AsLookahead();
ager@chromium.org32912102009-01-16 10:38:43 +00002372 virtual Interval CaptureRegisters();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002373 virtual bool IsLookahead();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002374 virtual bool IsAnchoredAtStart();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002375 virtual int min_match() { return 0; }
2376 virtual int max_match() { return 0; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002377 RegExpTree* body() { return body_; }
2378 bool is_positive() { return is_positive_; }
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002379 int capture_count() { return capture_count_; }
2380 int capture_from() { return capture_from_; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002381
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002382 private:
2383 RegExpTree* body_;
2384 bool is_positive_;
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002385 int capture_count_;
2386 int capture_from_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002387};
2388
2389
2390class RegExpBackReference: public RegExpTree {
2391 public:
2392 explicit RegExpBackReference(RegExpCapture* capture)
2393 : capture_(capture) { }
2394 virtual void* Accept(RegExpVisitor* visitor, void* data);
2395 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002396 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002397 virtual RegExpBackReference* AsBackReference();
2398 virtual bool IsBackReference();
ager@chromium.org32912102009-01-16 10:38:43 +00002399 virtual int min_match() { return 0; }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002400 virtual int max_match() { return capture_->max_match(); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002401 int index() { return capture_->index(); }
2402 RegExpCapture* capture() { return capture_; }
2403 private:
2404 RegExpCapture* capture_;
2405};
2406
2407
2408class RegExpEmpty: public RegExpTree {
2409 public:
2410 RegExpEmpty() { }
2411 virtual void* Accept(RegExpVisitor* visitor, void* data);
2412 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002413 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002414 virtual RegExpEmpty* AsEmpty();
2415 virtual bool IsEmpty();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002416 virtual int min_match() { return 0; }
2417 virtual int max_match() { return 0; }
erikcorry0ad885c2011-11-21 13:51:57 +00002418 static RegExpEmpty* GetInstance() {
2419 static RegExpEmpty* instance = ::new RegExpEmpty();
2420 return instance;
2421 }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002422};
2423
2424
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002425// ----------------------------------------------------------------------------
2426// Basic visitor
2427// - leaf node visitors are abstract.
2428
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002429class AstVisitor BASE_EMBEDDED {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002430 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002431 AstVisitor() : isolate_(Isolate::Current()), stack_overflow_(false) { }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002432 virtual ~AstVisitor() { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002433
lrn@chromium.org25156de2010-04-06 13:10:27 +00002434 // Stack overflow check and dynamic dispatch.
2435 void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002436
lrn@chromium.org25156de2010-04-06 13:10:27 +00002437 // Iteration left-to-right.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00002438 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002439 virtual void VisitStatements(ZoneList<Statement*>* statements);
2440 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
2441
2442 // Stack overflow tracking support.
2443 bool HasStackOverflow() const { return stack_overflow_; }
lrn@chromium.org25156de2010-04-06 13:10:27 +00002444 bool CheckStackOverflow();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002445
kasper.lund212ac232008-07-16 07:07:30 +00002446 // If a stack-overflow exception is encountered when visiting a
2447 // node, calling SetStackOverflow will make sure that the visitor
2448 // bails out without visiting more nodes.
2449 void SetStackOverflow() { stack_overflow_ = true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002450 void ClearStackOverflow() { stack_overflow_ = false; }
kasper.lund212ac232008-07-16 07:07:30 +00002451
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002452 // Individual AST nodes.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002453#define DEF_VISIT(type) \
2454 virtual void Visit##type(type* node) = 0;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002455 AST_NODE_LIST(DEF_VISIT)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002456#undef DEF_VISIT
2457
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002458 protected:
2459 Isolate* isolate() { return isolate_; }
2460
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002461 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002462 Isolate* isolate_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002463 bool stack_overflow_;
2464};
2465
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002466
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002467// ----------------------------------------------------------------------------
2468// Construction time visitor.
2469
2470class AstConstructionVisitor BASE_EMBEDDED {
2471 public:
2472 AstConstructionVisitor() { }
2473
2474 AstProperties* ast_properties() { return &properties_; }
2475
2476 private:
2477 template<class> friend class AstNodeFactory;
2478
2479 // Node visitors.
2480#define DEF_VISIT(type) \
2481 void Visit##type(type* node);
2482 AST_NODE_LIST(DEF_VISIT)
2483#undef DEF_VISIT
2484
2485 void increase_node_count() { properties_.add_node_count(1); }
2486 void add_flag(AstPropertiesFlag flag) { properties_.flags()->Add(flag); }
2487
2488 AstProperties properties_;
2489};
2490
2491
2492class AstNullVisitor BASE_EMBEDDED {
2493 public:
2494 // Node visitors.
2495#define DEF_VISIT(type) \
2496 void Visit##type(type* node) {}
2497 AST_NODE_LIST(DEF_VISIT)
2498#undef DEF_VISIT
2499};
2500
2501
2502
2503// ----------------------------------------------------------------------------
2504// AstNode factory
2505
2506template<class Visitor>
2507class AstNodeFactory BASE_EMBEDDED {
2508 public:
2509 explicit AstNodeFactory(Isolate* isolate)
2510 : isolate_(isolate),
2511 zone_(isolate_->zone()) { }
2512
2513 Visitor* visitor() { return &visitor_; }
2514
2515#define VISIT_AND_RETURN(NodeType, node) \
2516 visitor_.Visit##NodeType((node)); \
2517 return node;
2518
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002519 VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
2520 VariableMode mode,
2521 FunctionLiteral* fun,
2522 Scope* scope) {
2523 VariableDeclaration* decl =
2524 new(zone_) VariableDeclaration(proxy, mode, fun, scope);
2525 VISIT_AND_RETURN(VariableDeclaration, decl)
2526 }
2527
2528 ModuleDeclaration* NewModuleDeclaration(VariableProxy* proxy,
2529 Module* module,
2530 Scope* scope) {
2531 ModuleDeclaration* decl =
2532 new(zone_) ModuleDeclaration(proxy, module, scope);
2533 VISIT_AND_RETURN(ModuleDeclaration, decl)
2534 }
2535
2536 ModuleLiteral* NewModuleLiteral(Block* body) {
2537 ModuleLiteral* module = new(zone_) ModuleLiteral(body);
2538 VISIT_AND_RETURN(ModuleLiteral, module)
2539 }
2540
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00002541 ModuleVariable* NewModuleVariable(VariableProxy* proxy) {
2542 ModuleVariable* module = new(zone_) ModuleVariable(proxy);
2543 VISIT_AND_RETURN(ModuleVariable, module)
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002544 }
2545
2546 ModulePath* NewModulePath(Module* origin, Handle<String> name) {
2547 ModulePath* module = new(zone_) ModulePath(origin, name);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00002548 VISIT_AND_RETURN(ModulePath, module)
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002549 }
2550
2551 ModuleUrl* NewModuleUrl(Handle<String> url) {
2552 ModuleUrl* module = new(zone_) ModuleUrl(url);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00002553 VISIT_AND_RETURN(ModuleUrl, module)
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002554 }
2555
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002556 Block* NewBlock(ZoneStringList* labels,
2557 int capacity,
2558 bool is_initializer_block) {
2559 Block* block = new(zone_) Block(
2560 isolate_, labels, capacity, is_initializer_block);
2561 VISIT_AND_RETURN(Block, block)
2562 }
2563
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002564#define STATEMENT_WITH_LABELS(NodeType) \
2565 NodeType* New##NodeType(ZoneStringList* labels) { \
2566 NodeType* stmt = new(zone_) NodeType(isolate_, labels); \
2567 VISIT_AND_RETURN(NodeType, stmt); \
2568 }
2569 STATEMENT_WITH_LABELS(DoWhileStatement)
2570 STATEMENT_WITH_LABELS(WhileStatement)
2571 STATEMENT_WITH_LABELS(ForStatement)
2572 STATEMENT_WITH_LABELS(ForInStatement)
2573 STATEMENT_WITH_LABELS(SwitchStatement)
2574#undef STATEMENT_WITH_LABELS
2575
2576 ExpressionStatement* NewExpressionStatement(Expression* expression) {
2577 ExpressionStatement* stmt = new(zone_) ExpressionStatement(expression);
2578 VISIT_AND_RETURN(ExpressionStatement, stmt)
2579 }
2580
2581 ContinueStatement* NewContinueStatement(IterationStatement* target) {
2582 ContinueStatement* stmt = new(zone_) ContinueStatement(target);
2583 VISIT_AND_RETURN(ContinueStatement, stmt)
2584 }
2585
2586 BreakStatement* NewBreakStatement(BreakableStatement* target) {
2587 BreakStatement* stmt = new(zone_) BreakStatement(target);
2588 VISIT_AND_RETURN(BreakStatement, stmt)
2589 }
2590
2591 ReturnStatement* NewReturnStatement(Expression* expression) {
2592 ReturnStatement* stmt = new(zone_) ReturnStatement(expression);
2593 VISIT_AND_RETURN(ReturnStatement, stmt)
2594 }
2595
2596 WithStatement* NewWithStatement(Expression* expression,
2597 Statement* statement) {
2598 WithStatement* stmt = new(zone_) WithStatement(expression, statement);
2599 VISIT_AND_RETURN(WithStatement, stmt)
2600 }
2601
2602 IfStatement* NewIfStatement(Expression* condition,
2603 Statement* then_statement,
2604 Statement* else_statement) {
2605 IfStatement* stmt = new(zone_) IfStatement(
2606 isolate_, condition, then_statement, else_statement);
2607 VISIT_AND_RETURN(IfStatement, stmt)
2608 }
2609
2610 TryCatchStatement* NewTryCatchStatement(int index,
2611 Block* try_block,
2612 Scope* scope,
2613 Variable* variable,
2614 Block* catch_block) {
2615 TryCatchStatement* stmt = new(zone_) TryCatchStatement(
2616 index, try_block, scope, variable, catch_block);
2617 VISIT_AND_RETURN(TryCatchStatement, stmt)
2618 }
2619
2620 TryFinallyStatement* NewTryFinallyStatement(int index,
2621 Block* try_block,
2622 Block* finally_block) {
2623 TryFinallyStatement* stmt =
2624 new(zone_) TryFinallyStatement(index, try_block, finally_block);
2625 VISIT_AND_RETURN(TryFinallyStatement, stmt)
2626 }
2627
2628 DebuggerStatement* NewDebuggerStatement() {
2629 DebuggerStatement* stmt = new(zone_) DebuggerStatement();
2630 VISIT_AND_RETURN(DebuggerStatement, stmt)
2631 }
2632
2633 EmptyStatement* NewEmptyStatement() {
2634 return new(zone_) EmptyStatement();
2635 }
2636
2637 Literal* NewLiteral(Handle<Object> handle) {
2638 Literal* lit = new(zone_) Literal(isolate_, handle);
2639 VISIT_AND_RETURN(Literal, lit)
2640 }
2641
2642 Literal* NewNumberLiteral(double number) {
2643 return NewLiteral(isolate_->factory()->NewNumber(number, TENURED));
2644 }
2645
2646 ObjectLiteral* NewObjectLiteral(
2647 Handle<FixedArray> constant_properties,
2648 ZoneList<ObjectLiteral::Property*>* properties,
2649 int literal_index,
2650 bool is_simple,
2651 bool fast_elements,
2652 int depth,
2653 bool has_function) {
2654 ObjectLiteral* lit = new(zone_) ObjectLiteral(
2655 isolate_, constant_properties, properties, literal_index,
2656 is_simple, fast_elements, depth, has_function);
2657 VISIT_AND_RETURN(ObjectLiteral, lit)
2658 }
2659
2660 ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter,
2661 FunctionLiteral* value) {
2662 ObjectLiteral::Property* prop =
2663 new(zone_) ObjectLiteral::Property(is_getter, value);
2664 prop->set_key(NewLiteral(value->name()));
2665 return prop; // Not an AST node, will not be visited.
2666 }
2667
2668 RegExpLiteral* NewRegExpLiteral(Handle<String> pattern,
2669 Handle<String> flags,
2670 int literal_index) {
2671 RegExpLiteral* lit =
2672 new(zone_) RegExpLiteral(isolate_, pattern, flags, literal_index);
2673 VISIT_AND_RETURN(RegExpLiteral, lit);
2674 }
2675
2676 ArrayLiteral* NewArrayLiteral(Handle<FixedArray> constant_elements,
2677 ZoneList<Expression*>* values,
2678 int literal_index,
2679 bool is_simple,
2680 int depth) {
2681 ArrayLiteral* lit = new(zone_) ArrayLiteral(
2682 isolate_, constant_elements, values, literal_index, is_simple, depth);
2683 VISIT_AND_RETURN(ArrayLiteral, lit)
2684 }
2685
2686 VariableProxy* NewVariableProxy(Variable* var) {
2687 VariableProxy* proxy = new(zone_) VariableProxy(isolate_, var);
2688 VISIT_AND_RETURN(VariableProxy, proxy)
2689 }
2690
2691 VariableProxy* NewVariableProxy(Handle<String> name,
2692 bool is_this,
2693 int position = RelocInfo::kNoPosition) {
2694 VariableProxy* proxy =
2695 new(zone_) VariableProxy(isolate_, name, is_this, position);
2696 VISIT_AND_RETURN(VariableProxy, proxy)
2697 }
2698
2699 Property* NewProperty(Expression* obj, Expression* key, int pos) {
2700 Property* prop = new(zone_) Property(isolate_, obj, key, pos);
2701 VISIT_AND_RETURN(Property, prop)
2702 }
2703
2704 Call* NewCall(Expression* expression,
2705 ZoneList<Expression*>* arguments,
2706 int pos) {
2707 Call* call = new(zone_) Call(isolate_, expression, arguments, pos);
2708 VISIT_AND_RETURN(Call, call)
2709 }
2710
2711 CallNew* NewCallNew(Expression* expression,
2712 ZoneList<Expression*>* arguments,
2713 int pos) {
2714 CallNew* call = new(zone_) CallNew(isolate_, expression, arguments, pos);
2715 VISIT_AND_RETURN(CallNew, call)
2716 }
2717
2718 CallRuntime* NewCallRuntime(Handle<String> name,
2719 const Runtime::Function* function,
2720 ZoneList<Expression*>* arguments) {
2721 CallRuntime* call =
2722 new(zone_) CallRuntime(isolate_, name, function, arguments);
2723 VISIT_AND_RETURN(CallRuntime, call)
2724 }
2725
2726 UnaryOperation* NewUnaryOperation(Token::Value op,
2727 Expression* expression,
2728 int pos) {
2729 UnaryOperation* node =
2730 new(zone_) UnaryOperation(isolate_, op, expression, pos);
2731 VISIT_AND_RETURN(UnaryOperation, node)
2732 }
2733
2734 BinaryOperation* NewBinaryOperation(Token::Value op,
2735 Expression* left,
2736 Expression* right,
2737 int pos) {
2738 BinaryOperation* node =
2739 new(zone_) BinaryOperation(isolate_, op, left, right, pos);
2740 VISIT_AND_RETURN(BinaryOperation, node)
2741 }
2742
2743 CountOperation* NewCountOperation(Token::Value op,
2744 bool is_prefix,
2745 Expression* expr,
2746 int pos) {
2747 CountOperation* node =
2748 new(zone_) CountOperation(isolate_, op, is_prefix, expr, pos);
2749 VISIT_AND_RETURN(CountOperation, node)
2750 }
2751
2752 CompareOperation* NewCompareOperation(Token::Value op,
2753 Expression* left,
2754 Expression* right,
2755 int pos) {
2756 CompareOperation* node =
2757 new(zone_) CompareOperation(isolate_, op, left, right, pos);
2758 VISIT_AND_RETURN(CompareOperation, node)
2759 }
2760
2761 Conditional* NewConditional(Expression* condition,
2762 Expression* then_expression,
2763 Expression* else_expression,
2764 int then_expression_position,
2765 int else_expression_position) {
2766 Conditional* cond = new(zone_) Conditional(
2767 isolate_, condition, then_expression, else_expression,
2768 then_expression_position, else_expression_position);
2769 VISIT_AND_RETURN(Conditional, cond)
2770 }
2771
2772 Assignment* NewAssignment(Token::Value op,
2773 Expression* target,
2774 Expression* value,
2775 int pos) {
2776 Assignment* assign =
2777 new(zone_) Assignment(isolate_, op, target, value, pos);
2778 assign->Init(isolate_, this);
2779 VISIT_AND_RETURN(Assignment, assign)
2780 }
2781
2782 Throw* NewThrow(Expression* exception, int pos) {
2783 Throw* t = new(zone_) Throw(isolate_, exception, pos);
2784 VISIT_AND_RETURN(Throw, t)
2785 }
2786
2787 FunctionLiteral* NewFunctionLiteral(
2788 Handle<String> name,
2789 Scope* scope,
2790 ZoneList<Statement*>* body,
2791 int materialized_literal_count,
2792 int expected_property_count,
2793 int handler_count,
2794 bool has_only_simple_this_property_assignments,
2795 Handle<FixedArray> this_property_assignments,
2796 int parameter_count,
yangguo@chromium.org56454712012-02-16 15:33:53 +00002797 FunctionLiteral::ParameterFlag has_duplicate_parameters,
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002798 FunctionLiteral::Type type,
yangguo@chromium.org56454712012-02-16 15:33:53 +00002799 FunctionLiteral::IsFunctionFlag is_function) {
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002800 FunctionLiteral* lit = new(zone_) FunctionLiteral(
2801 isolate_, name, scope, body,
2802 materialized_literal_count, expected_property_count, handler_count,
2803 has_only_simple_this_property_assignments, this_property_assignments,
yangguo@chromium.org56454712012-02-16 15:33:53 +00002804 parameter_count, type, has_duplicate_parameters, is_function);
2805 // Top-level literal doesn't count for the AST's properties.
2806 if (is_function == FunctionLiteral::kIsFunction) {
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00002807 visitor_.VisitFunctionLiteral(lit);
2808 }
2809 return lit;
2810 }
2811
2812 SharedFunctionInfoLiteral* NewSharedFunctionInfoLiteral(
2813 Handle<SharedFunctionInfo> shared_function_info) {
2814 SharedFunctionInfoLiteral* lit =
2815 new(zone_) SharedFunctionInfoLiteral(isolate_, shared_function_info);
2816 VISIT_AND_RETURN(SharedFunctionInfoLiteral, lit)
2817 }
2818
2819 ThisFunction* NewThisFunction() {
2820 ThisFunction* fun = new(zone_) ThisFunction(isolate_);
2821 VISIT_AND_RETURN(ThisFunction, fun)
2822 }
2823
2824#undef VISIT_AND_RETURN
2825
2826 private:
2827 Isolate* isolate_;
2828 Zone* zone_;
2829 Visitor visitor_;
2830};
2831
2832
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002833} } // namespace v8::internal
2834
2835#endif // V8_AST_H_