blob: b4705f6ab853e2373bb66be3e4bee5b3044a7701 [file] [log] [blame]
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001// Copyright 2011 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
lrn@chromium.org1c092762011-05-09 09:42:16 +000031#include "allocation.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000032#include "execution.h"
33#include "factory.h"
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +000034#include "jsregexp.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000035#include "runtime.h"
36#include "token.h"
37#include "variables.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000038
kasperl@chromium.org71affb52009-05-26 05:44:31 +000039namespace v8 {
40namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000041
42// The abstract syntax tree is an intermediate, light-weight
43// representation of the parsed JavaScript code suitable for
44// compilation to native code.
45
46// Nodes are allocated in a separate zone, which allows faster
47// allocation and constant-time deallocation of the entire syntax
48// tree.
49
50
51// ----------------------------------------------------------------------------
52// Nodes of the abstract syntax tree. Only concrete classes are
53// enumerated here.
54
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +000055#define STATEMENT_NODE_LIST(V) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000056 V(Block) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000057 V(ExpressionStatement) \
58 V(EmptyStatement) \
59 V(IfStatement) \
60 V(ContinueStatement) \
61 V(BreakStatement) \
62 V(ReturnStatement) \
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +000063 V(EnterWithContextStatement) \
64 V(ExitContextStatement) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000065 V(SwitchStatement) \
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +000066 V(DoWhileStatement) \
67 V(WhileStatement) \
68 V(ForStatement) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000069 V(ForInStatement) \
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +000070 V(TryCatchStatement) \
71 V(TryFinallyStatement) \
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +000072 V(DebuggerStatement)
73
74#define EXPRESSION_NODE_LIST(V) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000075 V(FunctionLiteral) \
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +000076 V(SharedFunctionInfoLiteral) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077 V(Conditional) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000078 V(VariableProxy) \
79 V(Literal) \
80 V(RegExpLiteral) \
81 V(ObjectLiteral) \
82 V(ArrayLiteral) \
83 V(Assignment) \
84 V(Throw) \
85 V(Property) \
86 V(Call) \
87 V(CallNew) \
88 V(CallRuntime) \
89 V(UnaryOperation) \
90 V(CountOperation) \
91 V(BinaryOperation) \
92 V(CompareOperation) \
ricow@chromium.org65fae842010-08-25 15:26:24 +000093 V(CompareToNull) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000094 V(ThisFunction)
95
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +000096#define AST_NODE_LIST(V) \
97 V(Declaration) \
98 STATEMENT_NODE_LIST(V) \
99 EXPRESSION_NODE_LIST(V)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000100
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000101// Forward declarations
fschneider@chromium.org086aac62010-03-17 13:18:24 +0000102class BitVector;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000103class DefinitionInfo;
104class MaterializedLiteral;
105class TargetCollector;
106class TypeFeedbackOracle;
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000107
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000108#define DEF_FORWARD_DECLARATION(type) class type;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000109AST_NODE_LIST(DEF_FORWARD_DECLARATION)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000110#undef DEF_FORWARD_DECLARATION
111
112
113// Typedef only introduced to avoid unreadable code.
114// Please do appreciate the required space in "> >".
115typedef ZoneList<Handle<String> > ZoneStringList;
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000116typedef ZoneList<Handle<Object> > ZoneObjectList;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000117
118
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000119#define DECLARE_NODE_TYPE(type) \
120 virtual void Accept(AstVisitor* v); \
121 virtual AstNode::Type node_type() const { return AstNode::k##type; } \
122 virtual type* As##type() { return this; }
123
124
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000125class AstNode: public ZoneObject {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000126 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000127#define DECLARE_TYPE_ENUM(type) k##type,
128 enum Type {
129 AST_NODE_LIST(DECLARE_TYPE_ENUM)
130 kInvalid = -1
131 };
132#undef DECLARE_TYPE_ENUM
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000133
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000134 static const int kNoNumber = -1;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000135 static const int kFunctionEntryId = 2; // Using 0 could disguise errors.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000136
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000137 // Override ZoneObject's new to count allocated AST nodes.
138 void* operator new(size_t size, Zone* zone) {
139 Isolate* isolate = zone->isolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000140 isolate->set_ast_node_count(isolate->ast_node_count() + 1);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000141 return zone->New(static_cast<int>(size));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000142 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000143
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000144 AstNode() {}
145
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000146 virtual ~AstNode() { }
147
148 virtual void Accept(AstVisitor* v) = 0;
149 virtual Type node_type() const { return kInvalid; }
150
151 // Type testing & conversion functions overridden by concrete subclasses.
152#define DECLARE_NODE_FUNCTIONS(type) \
153 virtual type* As##type() { return NULL; }
154 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
155#undef DECLARE_NODE_FUNCTIONS
156
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000157 virtual Statement* AsStatement() { return NULL; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000158 virtual Expression* AsExpression() { return NULL; }
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000159 virtual TargetCollector* AsTargetCollector() { return NULL; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000160 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
161 virtual IterationStatement* AsIterationStatement() { return NULL; }
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000162 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000163 virtual Slot* AsSlot() { return NULL; }
164
165 // True if the node is simple enough for us to inline calls containing it.
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000166 virtual bool IsInlineable() const = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000167
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000168 static int Count() { return Isolate::Current()->ast_node_count(); }
169 static void ResetIds() { Isolate::Current()->set_ast_node_id(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000170
171 protected:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000172 static unsigned GetNextId(Isolate* isolate) {
173 return ReserveIdRange(isolate, 1);
174 }
175
176 static unsigned ReserveIdRange(Isolate* isolate, int n) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000177 unsigned tmp = isolate->ast_node_id();
178 isolate->set_ast_node_id(tmp + n);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000179 return tmp;
180 }
181
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000182 private:
183 // Hidden to prevent accidental usage. It would have to load the
184 // current zone from the TLS.
185 void* operator new(size_t size);
186
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000187 friend class CaseClause; // Generates AST IDs.
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000188};
189
190
191class Statement: public AstNode {
192 public:
193 Statement() : statement_pos_(RelocInfo::kNoPosition) {}
194
195 virtual Statement* AsStatement() { return this; }
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000196
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000197 virtual Assignment* StatementAsSimpleAssignment() { return NULL; }
198 virtual CountOperation* StatementAsCountOperation() { return NULL; }
199
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000200 bool IsEmpty() { return AsEmptyStatement() != NULL; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000201
202 void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
203 int statement_pos() const { return statement_pos_; }
204
205 private:
206 int statement_pos_;
207};
208
209
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000210class Expression: public AstNode {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000211 public:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000212 enum Context {
213 // Not assigned a context yet, or else will not be visited during
214 // code generation.
215 kUninitialized,
216 // Evaluated for its side effects.
217 kEffect,
218 // Evaluated for its value (and side effects).
219 kValue,
220 // Evaluated for control flow (and side effects).
221 kTest
222 };
223
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000224 explicit Expression(Isolate* isolate)
225 : id_(GetNextId(isolate)),
226 test_id_(GetNextId(isolate)) {}
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000227
228 virtual int position() const {
229 UNREACHABLE();
230 return 0;
231 }
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000232
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000233 virtual Expression* AsExpression() { return this; }
234
ricow@chromium.org65fae842010-08-25 15:26:24 +0000235 virtual bool IsTrivial() { return false; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000236 virtual bool IsValidLeftHandSide() { return false; }
237
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000238 // Helpers for ToBoolean conversion.
239 virtual bool ToBooleanIsTrue() { return false; }
240 virtual bool ToBooleanIsFalse() { return false; }
241
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000242 // Symbols that cannot be parsed as array indices are considered property
243 // names. We do not treat symbols that can be array indexes as property
244 // names because [] for string objects is handled only by keyed ICs.
245 virtual bool IsPropertyName() { return false; }
246
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000247 // Mark the expression as being compiled as an expression
248 // statement. This is used to transform postfix increments to
249 // (faster) prefix increments.
250 virtual void MarkAsStatement() { /* do nothing */ }
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000251
ricow@chromium.org65fae842010-08-25 15:26:24 +0000252 // True iff the result can be safely overwritten (to avoid allocation).
253 // False for operations that can return one of their operands.
254 virtual bool ResultOverwriteAllowed() { return false; }
255
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000256 // True iff the expression is a literal represented as a smi.
257 virtual bool IsSmiLiteral() { return false; }
258
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000259 // Type feedback information for assignments and properties.
260 virtual bool IsMonomorphic() {
261 UNREACHABLE();
262 return false;
263 }
264 virtual bool IsArrayLength() {
265 UNREACHABLE();
266 return false;
267 }
268 virtual ZoneMapList* GetReceiverTypes() {
269 UNREACHABLE();
270 return NULL;
271 }
272 virtual Handle<Map> GetMonomorphicReceiverType() {
273 UNREACHABLE();
274 return Handle<Map>();
275 }
276
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000277 unsigned id() const { return id_; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000278 unsigned test_id() const { return test_id_; }
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000279
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000280 private:
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000281 unsigned id_;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000282 unsigned test_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000283};
284
285
286/**
287 * A sentinel used during pre parsing that represents some expression
288 * that is a valid left hand side without having to actually build
289 * the expression.
290 */
291class ValidLeftHandSideSentinel: public Expression {
292 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000293 explicit ValidLeftHandSideSentinel(Isolate* isolate) : Expression(isolate) {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000294 virtual bool IsValidLeftHandSide() { return true; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000295 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000296 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000297};
298
299
300class BreakableStatement: public Statement {
301 public:
302 enum Type {
303 TARGET_FOR_ANONYMOUS,
304 TARGET_FOR_NAMED_ONLY
305 };
306
307 // The labels associated with this statement. May be NULL;
308 // if it is != NULL, guaranteed to contain at least one entry.
309 ZoneStringList* labels() const { return labels_; }
310
311 // Type testing & conversion.
312 virtual BreakableStatement* AsBreakableStatement() { return this; }
313
314 // Code generation
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000315 Label* break_target() { return &break_target_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000316
317 // Testers.
318 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
319
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000320 // Bailout support.
321 int EntryId() const { return entry_id_; }
322 int ExitId() const { return exit_id_; }
323
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000324 protected:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000325 BreakableStatement(Isolate* isolate, ZoneStringList* labels, Type type);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000326
327 private:
328 ZoneStringList* labels_;
329 Type type_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000330 Label break_target_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000331 int entry_id_;
332 int exit_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000333};
334
335
336class Block: public BreakableStatement {
337 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000338 inline Block(Isolate* isolate,
339 ZoneStringList* labels,
340 int capacity,
341 bool is_initializer_block);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000342
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000343 DECLARE_NODE_TYPE(Block)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000344
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000345 virtual Assignment* StatementAsSimpleAssignment() {
346 if (statements_.length() != 1) return NULL;
347 return statements_[0]->StatementAsSimpleAssignment();
348 }
349
350 virtual CountOperation* StatementAsCountOperation() {
351 if (statements_.length() != 1) return NULL;
352 return statements_[0]->StatementAsCountOperation();
353 }
354
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000355 virtual bool IsInlineable() const;
356
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000357 void AddStatement(Statement* statement) { statements_.Add(statement); }
358
359 ZoneList<Statement*>* statements() { return &statements_; }
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000360 bool is_initializer_block() const { return is_initializer_block_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000361
362 private:
363 ZoneList<Statement*> statements_;
364 bool is_initializer_block_;
365};
366
367
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000368class Declaration: public AstNode {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000369 public:
370 Declaration(VariableProxy* proxy, Variable::Mode mode, FunctionLiteral* fun)
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000371 : proxy_(proxy),
372 mode_(mode),
373 fun_(fun) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000374 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
375 // At the moment there are no "const functions"'s in JavaScript...
376 ASSERT(fun == NULL || mode == Variable::VAR);
377 }
378
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000379 DECLARE_NODE_TYPE(Declaration)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000380
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000381 VariableProxy* proxy() const { return proxy_; }
382 Variable::Mode mode() const { return mode_; }
383 FunctionLiteral* fun() const { return fun_; } // may be NULL
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000384 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000385
386 private:
387 VariableProxy* proxy_;
388 Variable::Mode mode_;
389 FunctionLiteral* fun_;
390};
391
392
393class IterationStatement: public BreakableStatement {
394 public:
395 // Type testing & conversion.
396 virtual IterationStatement* AsIterationStatement() { return this; }
397
398 Statement* body() const { return body_; }
399
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000400 // Bailout support.
401 int OsrEntryId() const { return osr_entry_id_; }
402 virtual int ContinueId() const = 0;
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +0000403 virtual int StackCheckId() const = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000404
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000405 // Code generation
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000406 Label* continue_target() { return &continue_target_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000407
408 protected:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000409 inline IterationStatement(Isolate* isolate, ZoneStringList* labels);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000410
411 void Initialize(Statement* body) {
412 body_ = body;
413 }
414
415 private:
416 Statement* body_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000417 Label continue_target_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000418 int osr_entry_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000419};
420
421
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000422class DoWhileStatement: public IterationStatement {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000423 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000424 inline DoWhileStatement(Isolate* isolate, ZoneStringList* labels);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000425
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000426 DECLARE_NODE_TYPE(DoWhileStatement)
427
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000428 void Initialize(Expression* cond, Statement* body) {
429 IterationStatement::Initialize(body);
430 cond_ = cond;
431 }
432
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000433 Expression* cond() const { return cond_; }
434
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000435 // Position where condition expression starts. We need it to make
436 // the loop's condition a breakable location.
437 int condition_position() { return condition_position_; }
438 void set_condition_position(int pos) { condition_position_ = pos; }
439
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000440 // Bailout support.
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000441 virtual int ContinueId() const { return continue_id_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +0000442 virtual int StackCheckId() const { return back_edge_id_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000443 int BackEdgeId() const { return back_edge_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000444
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000445 virtual bool IsInlineable() const;
446
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000447 private:
448 Expression* cond_;
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000449 int condition_position_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000450 int continue_id_;
451 int back_edge_id_;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000452};
453
454
455class WhileStatement: public IterationStatement {
456 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000457 inline WhileStatement(Isolate* isolate, ZoneStringList* labels);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000458
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000459 DECLARE_NODE_TYPE(WhileStatement)
460
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000461 void Initialize(Expression* cond, Statement* body) {
462 IterationStatement::Initialize(body);
463 cond_ = cond;
464 }
465
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000466 Expression* cond() const { return cond_; }
467 bool may_have_function_literal() const {
468 return may_have_function_literal_;
469 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000470 void set_may_have_function_literal(bool value) {
471 may_have_function_literal_ = value;
472 }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000473 virtual bool IsInlineable() const;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000474
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000475 // Bailout support.
476 virtual int ContinueId() const { return EntryId(); }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +0000477 virtual int StackCheckId() const { return body_id_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000478 int BodyId() const { return body_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000479
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000480 private:
481 Expression* cond_;
482 // True if there is a function literal subexpression in the condition.
483 bool may_have_function_literal_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000484 int body_id_;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000485};
486
487
488class ForStatement: public IterationStatement {
489 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000490 inline ForStatement(Isolate* isolate, ZoneStringList* labels);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000491
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000492 DECLARE_NODE_TYPE(ForStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000493
494 void Initialize(Statement* init,
495 Expression* cond,
496 Statement* next,
497 Statement* body) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000498 IterationStatement::Initialize(body);
499 init_ = init;
500 cond_ = cond;
501 next_ = next;
502 }
503
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000504 Statement* init() const { return init_; }
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000505 Expression* cond() const { return cond_; }
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000506 Statement* next() const { return next_; }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000507
kasperl@chromium.orgf5aa8372009-03-24 14:47:14 +0000508 bool may_have_function_literal() const {
509 return may_have_function_literal_;
510 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000511 void set_may_have_function_literal(bool value) {
512 may_have_function_literal_ = value;
513 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000514
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000515 // Bailout support.
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000516 virtual int ContinueId() const { return continue_id_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +0000517 virtual int StackCheckId() const { return body_id_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000518 int BodyId() const { return body_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000519
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000520 bool is_fast_smi_loop() { return loop_variable_ != NULL; }
521 Variable* loop_variable() { return loop_variable_; }
522 void set_loop_variable(Variable* var) { loop_variable_ = var; }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000523 virtual bool IsInlineable() const;
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000524
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000525 private:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000526 Statement* init_;
527 Expression* cond_;
528 Statement* next_;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000529 // True if there is a function literal subexpression in the condition.
kasperl@chromium.orgf5aa8372009-03-24 14:47:14 +0000530 bool may_have_function_literal_;
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000531 Variable* loop_variable_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000532 int continue_id_;
533 int body_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000534};
535
536
537class ForInStatement: public IterationStatement {
538 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000539 inline ForInStatement(Isolate* isolate, ZoneStringList* labels);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000540
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000541 DECLARE_NODE_TYPE(ForInStatement)
542
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000543 void Initialize(Expression* each, Expression* enumerable, Statement* body) {
544 IterationStatement::Initialize(body);
545 each_ = each;
546 enumerable_ = enumerable;
547 }
548
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000549 Expression* each() const { return each_; }
550 Expression* enumerable() const { return enumerable_; }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000551 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000552
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000553 // Bailout support.
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000554 int AssignmentId() const { return assignment_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000555 virtual int ContinueId() const { return EntryId(); }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +0000556 virtual int StackCheckId() const { return EntryId(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000557
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000558 private:
559 Expression* each_;
560 Expression* enumerable_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000561 int assignment_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000562};
563
564
565class ExpressionStatement: public Statement {
566 public:
567 explicit ExpressionStatement(Expression* expression)
568 : expression_(expression) { }
569
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000570 DECLARE_NODE_TYPE(ExpressionStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000571
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000572 virtual bool IsInlineable() const;
573
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000574 virtual Assignment* StatementAsSimpleAssignment();
575 virtual CountOperation* StatementAsCountOperation();
576
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000577 void set_expression(Expression* e) { expression_ = e; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000578 Expression* expression() const { return expression_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000579
580 private:
581 Expression* expression_;
582};
583
584
585class ContinueStatement: public Statement {
586 public:
587 explicit ContinueStatement(IterationStatement* target)
588 : target_(target) { }
589
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000590 DECLARE_NODE_TYPE(ContinueStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000591
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000592 IterationStatement* target() const { return target_; }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000593 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000594
595 private:
596 IterationStatement* target_;
597};
598
599
600class BreakStatement: public Statement {
601 public:
602 explicit BreakStatement(BreakableStatement* target)
603 : target_(target) { }
604
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000605 DECLARE_NODE_TYPE(BreakStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000606
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000607 BreakableStatement* target() const { return target_; }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000608 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000609
610 private:
611 BreakableStatement* target_;
612};
613
614
615class ReturnStatement: public Statement {
616 public:
617 explicit ReturnStatement(Expression* expression)
618 : expression_(expression) { }
619
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000620 DECLARE_NODE_TYPE(ReturnStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000621
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000622 Expression* expression() const { return expression_; }
623 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000624
625 private:
626 Expression* expression_;
627};
628
629
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000630class EnterWithContextStatement: public Statement {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000631 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000632 explicit EnterWithContextStatement(Expression* expression)
633 : expression_(expression) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000634
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000635 DECLARE_NODE_TYPE(EnterWithContextStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000636
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000637 Expression* expression() const { return expression_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000638
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000639 virtual bool IsInlineable() const;
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000640
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000641 private:
642 Expression* expression_;
643};
644
645
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000646class ExitContextStatement: public Statement {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000647 public:
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000648 virtual bool IsInlineable() const;
649
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000650 DECLARE_NODE_TYPE(ExitContextStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000651};
652
653
654class CaseClause: public ZoneObject {
655 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000656 CaseClause(Isolate* isolate,
657 Expression* label,
658 ZoneList<Statement*>* statements,
659 int pos);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000660
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000661 bool is_default() const { return label_ == NULL; }
662 Expression* label() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000663 CHECK(!is_default());
664 return label_;
665 }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000666 Label* body_target() { return &body_target_; }
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000667 ZoneList<Statement*>* statements() const { return statements_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000668
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000669 int position() const { return position_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000670 void set_position(int pos) { position_ = pos; }
671
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000672 int EntryId() { return entry_id_; }
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000673 int CompareId() { return compare_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000674
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000675 // Type feedback information.
676 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
677 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
678 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
679
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000680 private:
681 Expression* label_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000682 Label body_target_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000683 ZoneList<Statement*>* statements_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000684 int position_;
685 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
686 CompareTypeFeedback compare_type_;
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000687 int compare_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000688 int entry_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000689};
690
691
692class SwitchStatement: public BreakableStatement {
693 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000694 inline SwitchStatement(Isolate* isolate, ZoneStringList* labels);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000695
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000696 DECLARE_NODE_TYPE(SwitchStatement)
697
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000698 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
699 tag_ = tag;
700 cases_ = cases;
701 }
702
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000703 Expression* tag() const { return tag_; }
704 ZoneList<CaseClause*>* cases() const { return cases_; }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000705 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000706
707 private:
708 Expression* tag_;
709 ZoneList<CaseClause*>* cases_;
710};
711
712
713// If-statements always have non-null references to their then- and
714// else-parts. When parsing if-statements with no explicit else-part,
715// the parser implicitly creates an empty statement. Use the
716// HasThenStatement() and HasElseStatement() functions to check if a
717// given if-statement has a then- or an else-part containing code.
718class IfStatement: public Statement {
719 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000720 IfStatement(Isolate* isolate,
721 Expression* condition,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000722 Statement* then_statement,
723 Statement* else_statement)
724 : condition_(condition),
725 then_statement_(then_statement),
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000726 else_statement_(else_statement),
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000727 if_id_(GetNextId(isolate)),
728 then_id_(GetNextId(isolate)),
729 else_id_(GetNextId(isolate)) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000730 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000731
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000732 DECLARE_NODE_TYPE(IfStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000733
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000734 virtual bool IsInlineable() const;
735
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000736 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
737 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
738
739 Expression* condition() const { return condition_; }
740 Statement* then_statement() const { return then_statement_; }
741 Statement* else_statement() const { return else_statement_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000742
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000743 int IfId() const { return if_id_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000744 int ThenId() const { return then_id_; }
745 int ElseId() const { return else_id_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000746
747 private:
748 Expression* condition_;
749 Statement* then_statement_;
750 Statement* else_statement_;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000751 int if_id_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000752 int then_id_;
753 int else_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000754};
755
756
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000757// NOTE: TargetCollectors are represented as nodes to fit in the target
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000758// stack in the compiler; this should probably be reworked.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000759class TargetCollector: public AstNode {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000760 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000761 TargetCollector(): targets_(0) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000762
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000763 // Adds a jump target to the collector. The collector stores a pointer not
764 // a copy of the target to make binding work, so make sure not to pass in
765 // references to something on the stack.
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000766 void AddTarget(Label* target);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000767
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000768 // Virtual behaviour. TargetCollectors are never part of the AST.
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000769 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000770 virtual TargetCollector* AsTargetCollector() { return this; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000771
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000772 ZoneList<Label*>* targets() { return &targets_; }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000773 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000774
775 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000776 ZoneList<Label*> targets_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777};
778
779
780class TryStatement: public Statement {
781 public:
782 explicit TryStatement(Block* try_block)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000783 : try_block_(try_block), escaping_targets_(NULL) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000784
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000785 void set_escaping_targets(ZoneList<Label*>* targets) {
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000786 escaping_targets_ = targets;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000787 }
788
789 Block* try_block() const { return try_block_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000790 ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000791 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000792
793 private:
794 Block* try_block_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000795 ZoneList<Label*>* escaping_targets_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000796};
797
798
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000799class TryCatchStatement: public TryStatement {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000800 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000801 TryCatchStatement(Block* try_block,
802 Scope* scope,
803 Variable* variable,
804 Block* catch_block)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000805 : TryStatement(try_block),
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000806 scope_(scope),
807 variable_(variable),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000808 catch_block_(catch_block) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000809 }
810
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000811 DECLARE_NODE_TYPE(TryCatchStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000812
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000813 Scope* scope() { return scope_; }
814 Variable* variable() { return variable_; }
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000815 Block* catch_block() const { return catch_block_; }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000816 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000817
818 private:
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000819 Scope* scope_;
820 Variable* variable_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000821 Block* catch_block_;
822};
823
824
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000825class TryFinallyStatement: public TryStatement {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000826 public:
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000827 TryFinallyStatement(Block* try_block, Block* finally_block)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000828 : TryStatement(try_block),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000829 finally_block_(finally_block) { }
830
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000831 DECLARE_NODE_TYPE(TryFinallyStatement)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000832
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000833 Block* finally_block() const { return finally_block_; }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000834 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000835
836 private:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000837 Block* finally_block_;
838};
839
840
841class DebuggerStatement: public Statement {
842 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000843 DECLARE_NODE_TYPE(DebuggerStatement)
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000844 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000845};
846
847
848class EmptyStatement: public Statement {
849 public:
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000850 DECLARE_NODE_TYPE(EmptyStatement)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000851
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000852 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000853};
854
855
856class Literal: public Expression {
857 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000858 Literal(Isolate* isolate, Handle<Object> handle)
859 : Expression(isolate), handle_(handle) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000860
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000861 DECLARE_NODE_TYPE(Literal)
862
ricow@chromium.org65fae842010-08-25 15:26:24 +0000863 virtual bool IsTrivial() { return true; }
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000864 virtual bool IsSmiLiteral() { return handle_->IsSmi(); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000865
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000866 // Check if this literal is identical to the other literal.
867 bool IsIdenticalTo(const Literal* other) const {
868 return handle_.is_identical_to(other->handle_);
869 }
870
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000871 virtual bool IsPropertyName() {
872 if (handle_->IsSymbol()) {
873 uint32_t ignored;
874 return !String::cast(*handle_)->AsArrayIndex(&ignored);
875 }
876 return false;
877 }
878
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000879 Handle<String> AsPropertyName() {
880 ASSERT(IsPropertyName());
881 return Handle<String>::cast(handle_);
882 }
883
884 virtual bool ToBooleanIsTrue() { return handle_->ToBoolean()->IsTrue(); }
885 virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
886
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000887 // Identity testers.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000888 bool IsNull() const {
889 ASSERT(!handle_.is_null());
890 return handle_->IsNull();
891 }
892 bool IsTrue() const {
893 ASSERT(!handle_.is_null());
894 return handle_->IsTrue();
895 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000896 bool IsFalse() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000897 ASSERT(!handle_.is_null());
898 return handle_->IsFalse();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000899 }
900
901 Handle<Object> handle() const { return handle_; }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000902 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000903
904 private:
905 Handle<Object> handle_;
906};
907
908
909// Base class for literals that needs space in the corresponding JSFunction.
910class MaterializedLiteral: public Expression {
911 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000912 MaterializedLiteral(Isolate* isolate,
913 int literal_index,
914 bool is_simple,
915 int depth)
916 : Expression(isolate),
917 literal_index_(literal_index),
918 is_simple_(is_simple),
919 depth_(depth) {}
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000920
921 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
922
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000923 int literal_index() { return literal_index_; }
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000924
925 // A materialized literal is simple if the values consist of only
926 // constants and simple object and array literals.
927 bool is_simple() const { return is_simple_; }
928
929 int depth() const { return depth_; }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000930 virtual bool IsInlineable() const;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000931
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000932 private:
933 int literal_index_;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000934 bool is_simple_;
935 int depth_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000936};
937
938
939// An object literal has a boilerplate object that is used
940// for minimizing the work when constructing it at runtime.
941class ObjectLiteral: public MaterializedLiteral {
942 public:
943 // Property is used for passing information
944 // about an object literal's properties from the parser
945 // to the code generator.
946 class Property: public ZoneObject {
947 public:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000948 enum Kind {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000949 CONSTANT, // Property with constant value (compile time).
950 COMPUTED, // Property with computed value (execution time).
951 MATERIALIZED_LITERAL, // Property value is a materialized literal.
952 GETTER, SETTER, // Property is an accessor function.
953 PROTOTYPE // Property is __proto__.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000954 };
955
956 Property(Literal* key, Expression* value);
957 Property(bool is_getter, FunctionLiteral* value);
958
959 Literal* key() { return key_; }
960 Expression* value() { return value_; }
961 Kind kind() { return kind_; }
962
ager@chromium.org3811b432009-10-28 14:53:37 +0000963 bool IsCompileTimeValue();
964
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000965 void set_emit_store(bool emit_store);
966 bool emit_store();
967
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000968 private:
969 Literal* key_;
970 Expression* value_;
971 Kind kind_;
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000972 bool emit_store_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000973 };
974
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000975 ObjectLiteral(Isolate* isolate,
976 Handle<FixedArray> constant_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000977 ZoneList<Property*>* properties,
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000978 int literal_index,
979 bool is_simple,
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000980 bool fast_elements,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000981 int depth,
982 bool has_function)
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000983 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000984 constant_properties_(constant_properties),
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000985 properties_(properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000986 fast_elements_(fast_elements),
987 has_function_(has_function) {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000988
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000989 DECLARE_NODE_TYPE(ObjectLiteral)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000990
991 Handle<FixedArray> constant_properties() const {
992 return constant_properties_;
993 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000994 ZoneList<Property*>* properties() const { return properties_; }
995
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000996 bool fast_elements() const { return fast_elements_; }
997
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000998 bool has_function() { return has_function_; }
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000999
1000 // Mark all computed expressions that are bound to a key that
1001 // is shadowed by a later occurrence of the same key. For the
1002 // marked expressions, no store code is emitted.
1003 void CalculateEmitStore();
1004
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001005 enum Flags {
1006 kNoFlags = 0,
1007 kFastElements = 1,
1008 kHasFunction = 1 << 1
1009 };
1010
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001011 private:
1012 Handle<FixedArray> constant_properties_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001013 ZoneList<Property*>* properties_;
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001014 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001015 bool has_function_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001016};
1017
1018
1019// Node for capturing a regexp literal.
1020class RegExpLiteral: public MaterializedLiteral {
1021 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001022 RegExpLiteral(Isolate* isolate,
1023 Handle<String> pattern,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001024 Handle<String> flags,
1025 int literal_index)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001026 : MaterializedLiteral(isolate, literal_index, false, 1),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001027 pattern_(pattern),
1028 flags_(flags) {}
1029
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001030 DECLARE_NODE_TYPE(RegExpLiteral)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001031
1032 Handle<String> pattern() const { return pattern_; }
1033 Handle<String> flags() const { return flags_; }
1034
1035 private:
1036 Handle<String> pattern_;
1037 Handle<String> flags_;
1038};
1039
1040// An array literal has a literals object that is used
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001041// for minimizing the work when constructing it at runtime.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001042class ArrayLiteral: public MaterializedLiteral {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001043 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001044 ArrayLiteral(Isolate* isolate,
1045 Handle<FixedArray> constant_elements,
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001046 ZoneList<Expression*>* values,
1047 int literal_index,
1048 bool is_simple,
1049 int depth)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001050 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001051 constant_elements_(constant_elements),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001052 values_(values),
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001053 first_element_id_(ReserveIdRange(isolate, values->length())) {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001054
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001055 DECLARE_NODE_TYPE(ArrayLiteral)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001056
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001057 Handle<FixedArray> constant_elements() const { return constant_elements_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001058 ZoneList<Expression*>* values() const { return values_; }
1059
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001060 // Return an AST id for an element that is used in simulate instructions.
1061 int GetIdForElement(int i) { return first_element_id_ + i; }
1062
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001063 private:
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001064 Handle<FixedArray> constant_elements_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001065 ZoneList<Expression*>* values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001066 int first_element_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001067};
1068
1069
1070class VariableProxy: public Expression {
1071 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001072 VariableProxy(Isolate* isolate, Variable* var);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001073
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001074 DECLARE_NODE_TYPE(VariableProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001075
1076 // Type testing & conversion
whesse@chromium.org7b260152011-06-20 15:33:18 +00001077 Variable* AsVariable() { return (this == NULL) ? NULL : var_; }
ager@chromium.org3e875802009-06-29 08:26:34 +00001078
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001079 virtual bool IsValidLeftHandSide() {
1080 return var_ == NULL ? true : var_->IsValidLeftHandSide();
1081 }
ager@chromium.org3e875802009-06-29 08:26:34 +00001082
ricow@chromium.org65fae842010-08-25 15:26:24 +00001083 virtual bool IsTrivial() {
1084 // Reading from a mutable variable is a side effect, but the
1085 // variable for 'this' is immutable.
1086 return is_this_ || is_trivial_;
ager@chromium.org5c838252010-02-19 08:53:10 +00001087 }
1088
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001089 virtual bool IsInlineable() const;
1090
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001091 bool IsVariable(Handle<String> n) {
1092 return !is_this() && name().is_identical_to(n);
1093 }
1094
ager@chromium.org3e875802009-06-29 08:26:34 +00001095 bool IsArguments() {
1096 Variable* variable = AsVariable();
1097 return (variable == NULL) ? false : variable->is_arguments();
1098 }
1099
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001100 Handle<String> name() const { return name_; }
1101 Variable* var() const { return var_; }
1102 bool is_this() const { return is_this_; }
1103 bool inside_with() const { return inside_with_; }
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001104 int position() const { return position_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001105
ricow@chromium.org65fae842010-08-25 15:26:24 +00001106 void MarkAsTrivial() { is_trivial_ = true; }
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001107
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001108 // Bind this proxy to the variable var.
1109 void BindTo(Variable* var);
1110
1111 protected:
1112 Handle<String> name_;
1113 Variable* var_; // resolved variable, or NULL
1114 bool is_this_;
1115 bool inside_with_;
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001116 bool is_trivial_;
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001117 int position_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001118
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001119 VariableProxy(Isolate* isolate,
1120 Handle<String> name,
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001121 bool is_this,
1122 bool inside_with,
1123 int position = RelocInfo::kNoPosition);
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001124 VariableProxy(Isolate* isolate, bool is_this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001125
1126 friend class Scope;
1127};
1128
1129
1130class VariableProxySentinel: public VariableProxy {
1131 public:
1132 virtual bool IsValidLeftHandSide() { return !is_this(); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001133
1134 private:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001135 VariableProxySentinel(Isolate* isolate, bool is_this)
1136 : VariableProxy(isolate, is_this) { }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001137
1138 friend class AstSentinels;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001139};
1140
1141
1142class Slot: public Expression {
1143 public:
1144 enum Type {
1145 // A slot in the parameter section on the stack. index() is
1146 // the parameter index, counting left-to-right, starting at 0.
1147 PARAMETER,
1148
1149 // A slot in the local section on the stack. index() is
1150 // the variable index in the stack frame, starting at 0.
1151 LOCAL,
1152
1153 // An indexed slot in a heap context. index() is the
1154 // variable index in the context object on the heap,
1155 // starting at 0. var()->scope() is the corresponding
1156 // scope.
1157 CONTEXT,
1158
1159 // A named slot in a heap context. var()->name() is the
1160 // variable name in the context object on the heap,
1161 // with lookup starting at the current context. index()
1162 // is invalid.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001163 LOOKUP
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001164 };
1165
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001166 Slot(Isolate* isolate, Variable* var, Type type, int index)
1167 : Expression(isolate), var_(var), type_(type), index_(index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001168 ASSERT(var != NULL);
1169 }
1170
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001171 virtual void Accept(AstVisitor* v);
1172
1173 virtual Slot* AsSlot() { return this; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001174
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001175 bool IsStackAllocated() { return type_ == PARAMETER || type_ == LOCAL; }
1176
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001177 // Accessors
ager@chromium.org3e875802009-06-29 08:26:34 +00001178 Variable* var() const { return var_; }
1179 Type type() const { return type_; }
1180 int index() const { return index_; }
1181 bool is_arguments() const { return var_->is_arguments(); }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00001182 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001183
1184 private:
1185 Variable* var_;
1186 Type type_;
1187 int index_;
1188};
1189
1190
1191class Property: public Expression {
1192 public:
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001193 // Synthetic properties are property lookups introduced by the system,
1194 // to objects that aren't visible to the user. Function calls to synthetic
1195 // properties should use the global object as receiver, not the base object
1196 // of the resolved Reference.
1197 enum Type { NORMAL, SYNTHETIC };
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001198 Property(Isolate* isolate,
1199 Expression* obj,
1200 Expression* key,
1201 int pos,
1202 Type type = NORMAL)
1203 : Expression(isolate),
1204 obj_(obj),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001205 key_(key),
1206 pos_(pos),
1207 type_(type),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001208 receiver_types_(NULL),
ager@chromium.org378b34e2011-01-28 08:04:38 +00001209 is_monomorphic_(false),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001210 is_array_length_(false),
ager@chromium.org378b34e2011-01-28 08:04:38 +00001211 is_string_length_(false),
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00001212 is_string_access_(false),
whesse@chromium.org7b260152011-06-20 15:33:18 +00001213 is_function_prototype_(false) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001214
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001215 DECLARE_NODE_TYPE(Property)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001216
1217 virtual bool IsValidLeftHandSide() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001218 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001219
1220 Expression* obj() const { return obj_; }
1221 Expression* key() const { return key_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001222 virtual int position() const { return pos_; }
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001223 bool is_synthetic() const { return type_ == SYNTHETIC; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001224
ager@chromium.org378b34e2011-01-28 08:04:38 +00001225 bool IsStringLength() const { return is_string_length_; }
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00001226 bool IsStringAccess() const { return is_string_access_; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001227 bool IsFunctionPrototype() const { return is_function_prototype_; }
1228
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001229 // Type feedback information.
1230 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1231 virtual bool IsMonomorphic() { return is_monomorphic_; }
1232 virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
1233 virtual bool IsArrayLength() { return is_array_length_; }
1234 virtual Handle<Map> GetMonomorphicReceiverType() {
1235 return monomorphic_receiver_type_;
1236 }
1237
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001238 private:
1239 Expression* obj_;
1240 Expression* key_;
1241 int pos_;
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001242 Type type_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001243
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001244 ZoneMapList* receiver_types_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00001245 bool is_monomorphic_ : 1;
1246 bool is_array_length_ : 1;
1247 bool is_string_length_ : 1;
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00001248 bool is_string_access_ : 1;
ager@chromium.org378b34e2011-01-28 08:04:38 +00001249 bool is_function_prototype_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001250 Handle<Map> monomorphic_receiver_type_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001251};
1252
1253
1254class Call: public Expression {
1255 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001256 Call(Isolate* isolate,
1257 Expression* expression,
1258 ZoneList<Expression*>* arguments,
1259 int pos)
1260 : Expression(isolate),
1261 expression_(expression),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001262 arguments_(arguments),
1263 pos_(pos),
1264 is_monomorphic_(false),
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001265 check_type_(RECEIVER_MAP_CHECK),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001266 receiver_types_(NULL),
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001267 return_id_(GetNextId(isolate)) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001268 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001269
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001270 DECLARE_NODE_TYPE(Call)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001271
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001272 virtual bool IsInlineable() const;
1273
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001274 Expression* expression() const { return expression_; }
1275 ZoneList<Expression*>* arguments() const { return arguments_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001276 virtual int position() const { return pos_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001277
danno@chromium.org40cb8782011-05-25 07:58:50 +00001278 void RecordTypeFeedback(TypeFeedbackOracle* oracle,
1279 CallKind call_kind);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001280 virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
1281 virtual bool IsMonomorphic() { return is_monomorphic_; }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001282 CheckType check_type() const { return check_type_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001283 Handle<JSFunction> target() { return target_; }
1284 Handle<JSObject> holder() { return holder_; }
1285 Handle<JSGlobalPropertyCell> cell() { return cell_; }
1286
1287 bool ComputeTarget(Handle<Map> type, Handle<String> name);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001288 bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001289
1290 // Bailout support.
1291 int ReturnId() const { return return_id_; }
1292
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001293#ifdef DEBUG
1294 // Used to assert that the FullCodeGenerator records the return site.
1295 bool return_is_recorded_;
1296#endif
1297
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001298 private:
1299 Expression* expression_;
1300 ZoneList<Expression*>* arguments_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001301 int pos_;
1302
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001303 bool is_monomorphic_;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001304 CheckType check_type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001305 ZoneMapList* receiver_types_;
1306 Handle<JSFunction> target_;
1307 Handle<JSObject> holder_;
1308 Handle<JSGlobalPropertyCell> cell_;
1309
1310 int return_id_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001311};
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001312
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001313
1314class AstSentinels {
1315 public:
1316 ~AstSentinels() { }
1317
1318 // Returns a property singleton property access on 'this'. Used
1319 // during preparsing.
1320 Property* this_property() { return &this_property_; }
1321 VariableProxySentinel* this_proxy() { return &this_proxy_; }
1322 VariableProxySentinel* identifier_proxy() { return &identifier_proxy_; }
1323 ValidLeftHandSideSentinel* valid_left_hand_side_sentinel() {
1324 return &valid_left_hand_side_sentinel_;
1325 }
1326 Call* call_sentinel() { return &call_sentinel_; }
1327 EmptyStatement* empty_statement() { return &empty_statement_; }
1328
1329 private:
1330 AstSentinels();
1331 VariableProxySentinel this_proxy_;
1332 VariableProxySentinel identifier_proxy_;
1333 ValidLeftHandSideSentinel valid_left_hand_side_sentinel_;
1334 Property this_property_;
1335 Call call_sentinel_;
1336 EmptyStatement empty_statement_;
1337
1338 friend class Isolate;
1339
1340 DISALLOW_COPY_AND_ASSIGN(AstSentinels);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001341};
1342
1343
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00001344class CallNew: public Expression {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001345 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001346 CallNew(Isolate* isolate,
1347 Expression* expression,
1348 ZoneList<Expression*>* arguments,
1349 int pos)
1350 : Expression(isolate),
1351 expression_(expression),
1352 arguments_(arguments),
1353 pos_(pos) { }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001354
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001355 DECLARE_NODE_TYPE(CallNew)
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001356
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001357 virtual bool IsInlineable() const;
1358
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00001359 Expression* expression() const { return expression_; }
1360 ZoneList<Expression*>* arguments() const { return arguments_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001361 virtual int position() const { return pos_; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001362
1363 private:
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00001364 Expression* expression_;
1365 ZoneList<Expression*>* arguments_;
1366 int pos_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001367};
1368
1369
1370// The CallRuntime class does not represent any official JavaScript
1371// language construct. Instead it is used to call a C or JS function
1372// with a set of arguments. This is used from the builtins that are
1373// implemented in JavaScript (see "v8natives.js").
1374class CallRuntime: public Expression {
1375 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001376 CallRuntime(Isolate* isolate,
1377 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001378 const Runtime::Function* function,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001379 ZoneList<Expression*>* arguments)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001380 : Expression(isolate),
1381 name_(name),
1382 function_(function),
1383 arguments_(arguments) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001384
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001385 DECLARE_NODE_TYPE(CallRuntime)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001386
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001387 virtual bool IsInlineable() const;
1388
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001389 Handle<String> name() const { return name_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001390 const Runtime::Function* function() const { return function_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001391 ZoneList<Expression*>* arguments() const { return arguments_; }
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001392 bool is_jsruntime() const { return function_ == NULL; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001393
1394 private:
1395 Handle<String> name_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001396 const Runtime::Function* function_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001397 ZoneList<Expression*>* arguments_;
1398};
1399
1400
1401class UnaryOperation: public Expression {
1402 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001403 UnaryOperation(Isolate* isolate,
1404 Token::Value op,
1405 Expression* expression,
1406 int pos)
1407 : Expression(isolate), op_(op), expression_(expression), pos_(pos) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001408 ASSERT(Token::IsUnaryOp(op));
1409 }
1410
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001411 DECLARE_NODE_TYPE(UnaryOperation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001412
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001413 virtual bool IsInlineable() const;
1414
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001415 virtual bool ResultOverwriteAllowed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001416
1417 Token::Value op() const { return op_; }
1418 Expression* expression() const { return expression_; }
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00001419 virtual int position() const { return pos_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001420
1421 private:
1422 Token::Value op_;
1423 Expression* expression_;
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00001424 int pos_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001425};
1426
1427
1428class BinaryOperation: public Expression {
1429 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001430 BinaryOperation(Isolate* isolate,
1431 Token::Value op,
ricow@chromium.org65fae842010-08-25 15:26:24 +00001432 Expression* left,
1433 Expression* right,
1434 int pos)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001435 : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001436 ASSERT(Token::IsBinaryOp(op));
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001437 right_id_ = (op == Token::AND || op == Token::OR)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001438 ? static_cast<int>(GetNextId(isolate))
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001439 : AstNode::kNoNumber;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001440 }
1441
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001442 DECLARE_NODE_TYPE(BinaryOperation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001443
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001444 virtual bool IsInlineable() const;
1445
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001446 virtual bool ResultOverwriteAllowed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001447
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001448 Token::Value op() const { return op_; }
1449 Expression* left() const { return left_; }
1450 Expression* right() const { return right_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001451 virtual int position() const { return pos_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001452
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001453 // Bailout support.
1454 int RightId() const { return right_id_; }
1455
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001456 private:
1457 Token::Value op_;
1458 Expression* left_;
1459 Expression* right_;
ricow@chromium.org65fae842010-08-25 15:26:24 +00001460 int pos_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001461 // The short-circuit logical operations have an AST ID for their
1462 // right-hand subexpression.
1463 int right_id_;
ricow@chromium.org65fae842010-08-25 15:26:24 +00001464};
1465
1466
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001467class CountOperation: public Expression {
1468 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001469 CountOperation(Isolate* isolate,
1470 Token::Value op,
1471 bool is_prefix,
1472 Expression* expr,
1473 int pos)
1474 : Expression(isolate),
1475 op_(op),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001476 is_prefix_(is_prefix),
1477 expression_(expr),
1478 pos_(pos),
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001479 assignment_id_(GetNextId(isolate)),
1480 count_id_(GetNextId(isolate)),
whesse@chromium.org7b260152011-06-20 15:33:18 +00001481 receiver_types_(NULL) { }
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001482
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001483 DECLARE_NODE_TYPE(CountOperation)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001484
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001485 bool is_prefix() const { return is_prefix_; }
1486 bool is_postfix() const { return !is_prefix_; }
ricow@chromium.org65fae842010-08-25 15:26:24 +00001487
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001488 Token::Value op() const { return op_; }
kasperl@chromium.org74e4e5e2010-01-25 10:15:52 +00001489 Token::Value binary_op() {
ricow@chromium.org65fae842010-08-25 15:26:24 +00001490 return (op() == Token::INC) ? Token::ADD : Token::SUB;
kasperl@chromium.org74e4e5e2010-01-25 10:15:52 +00001491 }
ricow@chromium.org65fae842010-08-25 15:26:24 +00001492
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001493 Expression* expression() const { return expression_; }
1494 virtual int position() const { return pos_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001495
1496 virtual void MarkAsStatement() { is_prefix_ = true; }
1497
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001498 virtual bool IsInlineable() const;
1499
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001500 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1501 virtual bool IsMonomorphic() { return is_monomorphic_; }
1502 virtual Handle<Map> GetMonomorphicReceiverType() {
1503 return monomorphic_receiver_type_;
1504 }
whesse@chromium.org7b260152011-06-20 15:33:18 +00001505 virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001506
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001507 // Bailout support.
1508 int AssignmentId() const { return assignment_id_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001509 int CountId() const { return count_id_; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001510
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001511 private:
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001512 Token::Value op_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001513 bool is_prefix_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001514 bool is_monomorphic_;
1515 Expression* expression_;
ricow@chromium.org65fae842010-08-25 15:26:24 +00001516 int pos_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001517 int assignment_id_;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001518 int count_id_;
1519 Handle<Map> monomorphic_receiver_type_;
whesse@chromium.org7b260152011-06-20 15:33:18 +00001520 ZoneMapList* receiver_types_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001521};
1522
1523
1524class CompareOperation: public Expression {
1525 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001526 CompareOperation(Isolate* isolate,
1527 Token::Value op,
ricow@chromium.org65fae842010-08-25 15:26:24 +00001528 Expression* left,
1529 Expression* right,
1530 int pos)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001531 : Expression(isolate),
1532 op_(op),
1533 left_(left),
1534 right_(right),
1535 pos_(pos),
1536 compare_type_(NONE) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001537 ASSERT(Token::IsCompareOp(op));
1538 }
1539
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001540 DECLARE_NODE_TYPE(CompareOperation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001541
1542 Token::Value op() const { return op_; }
1543 Expression* left() const { return left_; }
1544 Expression* right() const { return right_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001545 virtual int position() const { return pos_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001546
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001547 virtual bool IsInlineable() const;
1548
1549 // Type feedback information.
1550 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1551 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
1552 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1553
ager@chromium.org04921a82011-06-27 13:21:41 +00001554 // Match special cases.
1555 bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
1556 bool IsLiteralCompareUndefined(Expression** expr);
1557
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001558 private:
1559 Token::Value op_;
1560 Expression* left_;
1561 Expression* right_;
ricow@chromium.org65fae842010-08-25 15:26:24 +00001562 int pos_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001563
1564 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
1565 CompareTypeFeedback compare_type_;
ricow@chromium.org65fae842010-08-25 15:26:24 +00001566};
1567
1568
1569class CompareToNull: public Expression {
1570 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001571 CompareToNull(Isolate* isolate, bool is_strict, Expression* expression)
1572 : Expression(isolate), is_strict_(is_strict), expression_(expression) { }
ricow@chromium.org65fae842010-08-25 15:26:24 +00001573
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001574 DECLARE_NODE_TYPE(CompareToNull)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001575
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001576 virtual bool IsInlineable() const;
1577
ricow@chromium.org65fae842010-08-25 15:26:24 +00001578 bool is_strict() const { return is_strict_; }
1579 Token::Value op() const { return is_strict_ ? Token::EQ_STRICT : Token::EQ; }
1580 Expression* expression() const { return expression_; }
1581
1582 private:
1583 bool is_strict_;
1584 Expression* expression_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001585};
1586
1587
1588class Conditional: public Expression {
1589 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001590 Conditional(Isolate* isolate,
1591 Expression* condition,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001592 Expression* then_expression,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001593 Expression* else_expression,
1594 int then_expression_position,
1595 int else_expression_position)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001596 : Expression(isolate),
1597 condition_(condition),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001598 then_expression_(then_expression),
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001599 else_expression_(else_expression),
1600 then_expression_position_(then_expression_position),
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001601 else_expression_position_(else_expression_position),
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001602 then_id_(GetNextId(isolate)),
1603 else_id_(GetNextId(isolate)) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001604 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001605
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001606 DECLARE_NODE_TYPE(Conditional)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001607
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001608 virtual bool IsInlineable() const;
1609
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001610 Expression* condition() const { return condition_; }
1611 Expression* then_expression() const { return then_expression_; }
1612 Expression* else_expression() const { return else_expression_; }
1613
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001614 int then_expression_position() const { return then_expression_position_; }
1615 int else_expression_position() const { return else_expression_position_; }
1616
1617 int ThenId() const { return then_id_; }
1618 int ElseId() const { return else_id_; }
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001619
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001620 private:
1621 Expression* condition_;
1622 Expression* then_expression_;
1623 Expression* else_expression_;
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001624 int then_expression_position_;
1625 int else_expression_position_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001626 int then_id_;
1627 int else_id_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001628};
1629
1630
1631class Assignment: public Expression {
1632 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001633 Assignment(Isolate* isolate,
1634 Token::Value op,
1635 Expression* target,
1636 Expression* value,
1637 int pos);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001638
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001639 DECLARE_NODE_TYPE(Assignment)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001640
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001641 virtual bool IsInlineable() const;
1642
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001643 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1644
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001645 Token::Value binary_op() const;
1646
1647 Token::Value op() const { return op_; }
1648 Expression* target() const { return target_; }
1649 Expression* value() const { return value_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001650 virtual int position() const { return pos_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001651 BinaryOperation* binary_operation() const { return binary_operation_; }
1652
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +00001653 // This check relies on the definition order of token in token.h.
1654 bool is_compound() const { return op() > Token::ASSIGN; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001655
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001656 // An initialization block is a series of statments of the form
1657 // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1658 // ending of these blocks to allow for optimizations of initialization
1659 // blocks.
1660 bool starts_initialization_block() { return block_start_; }
1661 bool ends_initialization_block() { return block_end_; }
1662 void mark_block_start() { block_start_ = true; }
1663 void mark_block_end() { block_end_ = true; }
1664
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001665 // Type feedback information.
1666 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1667 virtual bool IsMonomorphic() { return is_monomorphic_; }
1668 virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
1669 virtual Handle<Map> GetMonomorphicReceiverType() {
1670 return monomorphic_receiver_type_;
1671 }
1672
1673 // Bailout support.
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001674 int CompoundLoadId() const { return compound_load_id_; }
1675 int AssignmentId() const { return assignment_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001676
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001677 private:
1678 Token::Value op_;
1679 Expression* target_;
1680 Expression* value_;
1681 int pos_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001682 BinaryOperation* binary_operation_;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001683 int compound_load_id_;
1684 int assignment_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001685
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001686 bool block_start_;
1687 bool block_end_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001688
1689 bool is_monomorphic_;
1690 ZoneMapList* receiver_types_;
1691 Handle<Map> monomorphic_receiver_type_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001692};
1693
1694
1695class Throw: public Expression {
1696 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001697 Throw(Isolate* isolate, Expression* exception, int pos)
1698 : Expression(isolate), exception_(exception), pos_(pos) {}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001699
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001700 DECLARE_NODE_TYPE(Throw)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001701
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001702 Expression* exception() const { return exception_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001703 virtual int position() const { return pos_; }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00001704 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001705
1706 private:
1707 Expression* exception_;
1708 int pos_;
1709};
1710
1711
1712class FunctionLiteral: public Expression {
1713 public:
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001714 enum Type {
1715 ANONYMOUS_EXPRESSION,
1716 NAMED_EXPRESSION,
1717 DECLARATION
1718 };
1719
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001720 FunctionLiteral(Isolate* isolate,
1721 Handle<String> name,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001722 Scope* scope,
1723 ZoneList<Statement*>* body,
1724 int materialized_literal_count,
1725 int expected_property_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001726 bool has_only_simple_this_property_assignments,
1727 Handle<FixedArray> this_property_assignments,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001728 int num_parameters,
1729 int start_position,
1730 int end_position,
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001731 Type type,
whesse@chromium.org7b260152011-06-20 15:33:18 +00001732 bool has_duplicate_parameters)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001733 : Expression(isolate),
1734 name_(name),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001735 scope_(scope),
1736 body_(body),
1737 materialized_literal_count_(materialized_literal_count),
1738 expected_property_count_(expected_property_count),
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001739 has_only_simple_this_property_assignments_(
1740 has_only_simple_this_property_assignments),
1741 this_property_assignments_(this_property_assignments),
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001742 num_parameters_(num_parameters),
1743 start_position_(start_position),
1744 end_position_(end_position),
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00001745 function_token_position_(RelocInfo::kNoPosition),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001746 inferred_name_(HEAP->empty_string()),
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001747 is_expression_(type != DECLARATION),
1748 is_anonymous_(type == ANONYMOUS_EXPRESSION),
whesse@chromium.org7b260152011-06-20 15:33:18 +00001749 pretenure_(false),
1750 has_duplicate_parameters_(has_duplicate_parameters) {
1751 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001752
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001753 DECLARE_NODE_TYPE(FunctionLiteral)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001754
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001755 Handle<String> name() const { return name_; }
1756 Scope* scope() const { return scope_; }
1757 ZoneList<Statement*>* body() const { return body_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001758 void set_function_token_position(int pos) { function_token_position_ = pos; }
1759 int function_token_position() const { return function_token_position_; }
1760 int start_position() const { return start_position_; }
1761 int end_position() const { return end_position_; }
1762 bool is_expression() const { return is_expression_; }
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001763 bool is_anonymous() const { return is_anonymous_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001764 bool strict_mode() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001765
1766 int materialized_literal_count() { return materialized_literal_count_; }
1767 int expected_property_count() { return expected_property_count_; }
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001768 bool has_only_simple_this_property_assignments() {
1769 return has_only_simple_this_property_assignments_;
1770 }
1771 Handle<FixedArray> this_property_assignments() {
1772 return this_property_assignments_;
1773 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001774 int num_parameters() { return num_parameters_; }
1775
1776 bool AllowsLazyCompilation();
1777
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00001778 Handle<String> debug_name() const {
1779 if (name_->length() > 0) return name_;
1780 return inferred_name();
1781 }
1782
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001783 Handle<String> inferred_name() const { return inferred_name_; }
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00001784 void set_inferred_name(Handle<String> inferred_name) {
1785 inferred_name_ = inferred_name;
1786 }
1787
vegorov@chromium.org21b5e952010-11-23 10:24:40 +00001788 bool pretenure() { return pretenure_; }
1789 void set_pretenure(bool value) { pretenure_ = value; }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00001790 virtual bool IsInlineable() const;
vegorov@chromium.org21b5e952010-11-23 10:24:40 +00001791
whesse@chromium.org7b260152011-06-20 15:33:18 +00001792 bool has_duplicate_parameters() { return has_duplicate_parameters_; }
1793
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001794 private:
1795 Handle<String> name_;
1796 Scope* scope_;
1797 ZoneList<Statement*>* body_;
1798 int materialized_literal_count_;
1799 int expected_property_count_;
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001800 bool has_only_simple_this_property_assignments_;
1801 Handle<FixedArray> this_property_assignments_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001802 int num_parameters_;
1803 int start_position_;
1804 int end_position_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001805 int function_token_position_;
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00001806 Handle<String> inferred_name_;
whesse@chromium.org7b260152011-06-20 15:33:18 +00001807 bool is_expression_;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001808 bool is_anonymous_;
vegorov@chromium.org21b5e952010-11-23 10:24:40 +00001809 bool pretenure_;
whesse@chromium.org7b260152011-06-20 15:33:18 +00001810 bool has_duplicate_parameters_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001811};
1812
1813
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001814class SharedFunctionInfoLiteral: public Expression {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001815 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001816 SharedFunctionInfoLiteral(
1817 Isolate* isolate,
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001818 Handle<SharedFunctionInfo> shared_function_info)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001819 : Expression(isolate), shared_function_info_(shared_function_info) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001820
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001821 DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
1822
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001823 Handle<SharedFunctionInfo> shared_function_info() const {
1824 return shared_function_info_;
1825 }
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00001826 virtual bool IsInlineable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001827
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001828 private:
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001829 Handle<SharedFunctionInfo> shared_function_info_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001830};
1831
1832
1833class ThisFunction: public Expression {
1834 public:
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001835 explicit ThisFunction(Isolate* isolate) : Expression(isolate) {}
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00001836 DECLARE_NODE_TYPE(ThisFunction)
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00001837 virtual bool IsInlineable() const;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001838};
1839
1840
1841// ----------------------------------------------------------------------------
1842// Regular expressions
1843
1844
ager@chromium.org32912102009-01-16 10:38:43 +00001845class RegExpVisitor BASE_EMBEDDED {
1846 public:
1847 virtual ~RegExpVisitor() { }
1848#define MAKE_CASE(Name) \
1849 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
1850 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
1851#undef MAKE_CASE
1852};
1853
1854
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001855class RegExpTree: public ZoneObject {
1856 public:
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001857 static const int kInfinity = kMaxInt;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001858 virtual ~RegExpTree() { }
1859 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
1860 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00001861 RegExpNode* on_success) = 0;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001862 virtual bool IsTextElement() { return false; }
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001863 virtual bool IsAnchoredAtStart() { return false; }
1864 virtual bool IsAnchoredAtEnd() { return false; }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001865 virtual int min_match() = 0;
1866 virtual int max_match() = 0;
ager@chromium.org32912102009-01-16 10:38:43 +00001867 // Returns the interval of registers used for captures within this
1868 // expression.
1869 virtual Interval CaptureRegisters() { return Interval::Empty(); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001870 virtual void AppendToText(RegExpText* text);
1871 SmartPointer<const char> ToString();
1872#define MAKE_ASTYPE(Name) \
1873 virtual RegExp##Name* As##Name(); \
1874 virtual bool Is##Name();
1875 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
1876#undef MAKE_ASTYPE
1877};
1878
1879
1880class RegExpDisjunction: public RegExpTree {
1881 public:
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001882 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001883 virtual void* Accept(RegExpVisitor* visitor, void* data);
1884 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00001885 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001886 virtual RegExpDisjunction* AsDisjunction();
ager@chromium.org32912102009-01-16 10:38:43 +00001887 virtual Interval CaptureRegisters();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001888 virtual bool IsDisjunction();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001889 virtual bool IsAnchoredAtStart();
1890 virtual bool IsAnchoredAtEnd();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001891 virtual int min_match() { return min_match_; }
1892 virtual int max_match() { return max_match_; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001893 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
1894 private:
1895 ZoneList<RegExpTree*>* alternatives_;
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001896 int min_match_;
1897 int max_match_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001898};
1899
1900
1901class RegExpAlternative: public RegExpTree {
1902 public:
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001903 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001904 virtual void* Accept(RegExpVisitor* visitor, void* data);
1905 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00001906 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001907 virtual RegExpAlternative* AsAlternative();
ager@chromium.org32912102009-01-16 10:38:43 +00001908 virtual Interval CaptureRegisters();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001909 virtual bool IsAlternative();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001910 virtual bool IsAnchoredAtStart();
1911 virtual bool IsAnchoredAtEnd();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001912 virtual int min_match() { return min_match_; }
1913 virtual int max_match() { return max_match_; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001914 ZoneList<RegExpTree*>* nodes() { return nodes_; }
1915 private:
1916 ZoneList<RegExpTree*>* nodes_;
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001917 int min_match_;
1918 int max_match_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001919};
1920
1921
1922class RegExpAssertion: public RegExpTree {
1923 public:
1924 enum Type {
1925 START_OF_LINE,
1926 START_OF_INPUT,
1927 END_OF_LINE,
1928 END_OF_INPUT,
1929 BOUNDARY,
1930 NON_BOUNDARY
1931 };
1932 explicit RegExpAssertion(Type type) : type_(type) { }
1933 virtual void* Accept(RegExpVisitor* visitor, void* data);
1934 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00001935 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001936 virtual RegExpAssertion* AsAssertion();
1937 virtual bool IsAssertion();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001938 virtual bool IsAnchoredAtStart();
1939 virtual bool IsAnchoredAtEnd();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001940 virtual int min_match() { return 0; }
1941 virtual int max_match() { return 0; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001942 Type type() { return type_; }
1943 private:
1944 Type type_;
1945};
1946
1947
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001948class CharacterSet BASE_EMBEDDED {
1949 public:
1950 explicit CharacterSet(uc16 standard_set_type)
1951 : ranges_(NULL),
1952 standard_set_type_(standard_set_type) {}
1953 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
1954 : ranges_(ranges),
1955 standard_set_type_(0) {}
1956 ZoneList<CharacterRange>* ranges();
1957 uc16 standard_set_type() { return standard_set_type_; }
1958 void set_standard_set_type(uc16 special_set_type) {
1959 standard_set_type_ = special_set_type;
1960 }
1961 bool is_standard() { return standard_set_type_ != 0; }
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001962 void Canonicalize();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001963 private:
1964 ZoneList<CharacterRange>* ranges_;
1965 // If non-zero, the value represents a standard set (e.g., all whitespace
1966 // characters) without having to expand the ranges.
1967 uc16 standard_set_type_;
1968};
1969
1970
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001971class RegExpCharacterClass: public RegExpTree {
1972 public:
1973 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001974 : set_(ranges),
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001975 is_negated_(is_negated) { }
1976 explicit RegExpCharacterClass(uc16 type)
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001977 : set_(type),
1978 is_negated_(false) { }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001979 virtual void* Accept(RegExpVisitor* visitor, void* data);
1980 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00001981 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001982 virtual RegExpCharacterClass* AsCharacterClass();
1983 virtual bool IsCharacterClass();
1984 virtual bool IsTextElement() { return true; }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001985 virtual int min_match() { return 1; }
1986 virtual int max_match() { return 1; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001987 virtual void AppendToText(RegExpText* text);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00001988 CharacterSet character_set() { return set_; }
1989 // TODO(lrn): Remove need for complex version if is_standard that
1990 // recognizes a mangled standard set and just do { return set_.is_special(); }
1991 bool is_standard();
1992 // Returns a value representing the standard character set if is_standard()
1993 // returns true.
1994 // Currently used values are:
1995 // s : unicode whitespace
1996 // S : unicode non-whitespace
1997 // w : ASCII word character (digit, letter, underscore)
1998 // W : non-ASCII word character
1999 // d : ASCII digit
2000 // D : non-ASCII digit
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002001 // . : non-unicode non-newline
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002002 // * : All characters
2003 uc16 standard_type() { return set_.standard_set_type(); }
2004 ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002005 bool is_negated() { return is_negated_; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002006
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002007 private:
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002008 CharacterSet set_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002009 bool is_negated_;
2010};
2011
2012
2013class RegExpAtom: public RegExpTree {
2014 public:
2015 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
2016 virtual void* Accept(RegExpVisitor* visitor, void* data);
2017 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002018 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002019 virtual RegExpAtom* AsAtom();
2020 virtual bool IsAtom();
2021 virtual bool IsTextElement() { return true; }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002022 virtual int min_match() { return data_.length(); }
2023 virtual int max_match() { return data_.length(); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002024 virtual void AppendToText(RegExpText* text);
2025 Vector<const uc16> data() { return data_; }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002026 int length() { return data_.length(); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002027 private:
2028 Vector<const uc16> data_;
2029};
2030
2031
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002032class RegExpText: public RegExpTree {
2033 public:
2034 RegExpText() : elements_(2), length_(0) {}
2035 virtual void* Accept(RegExpVisitor* visitor, void* data);
2036 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2037 RegExpNode* on_success);
2038 virtual RegExpText* AsText();
2039 virtual bool IsText();
2040 virtual bool IsTextElement() { return true; }
2041 virtual int min_match() { return length_; }
2042 virtual int max_match() { return length_; }
2043 virtual void AppendToText(RegExpText* text);
2044 void AddElement(TextElement elm) {
2045 elements_.Add(elm);
2046 length_ += elm.length();
kmillikin@chromium.org3cdd9e12010-09-06 11:39:48 +00002047 }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002048 ZoneList<TextElement>* elements() { return &elements_; }
2049 private:
2050 ZoneList<TextElement> elements_;
2051 int length_;
2052};
2053
2054
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002055class RegExpQuantifier: public RegExpTree {
2056 public:
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002057 enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
2058 RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
2059 : body_(body),
2060 min_(min),
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002061 max_(max),
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002062 min_match_(min * body->min_match()),
2063 type_(type) {
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002064 if (max > 0 && body->max_match() > kInfinity / max) {
2065 max_match_ = kInfinity;
2066 } else {
2067 max_match_ = max * body->max_match();
2068 }
2069 }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002070 virtual void* Accept(RegExpVisitor* visitor, void* data);
2071 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002072 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002073 static RegExpNode* ToNode(int min,
2074 int max,
2075 bool is_greedy,
2076 RegExpTree* body,
2077 RegExpCompiler* compiler,
iposva@chromium.org245aa852009-02-10 00:49:54 +00002078 RegExpNode* on_success,
2079 bool not_at_start = false);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002080 virtual RegExpQuantifier* AsQuantifier();
ager@chromium.org32912102009-01-16 10:38:43 +00002081 virtual Interval CaptureRegisters();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002082 virtual bool IsQuantifier();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002083 virtual int min_match() { return min_match_; }
2084 virtual int max_match() { return max_match_; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002085 int min() { return min_; }
2086 int max() { return max_; }
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002087 bool is_possessive() { return type_ == POSSESSIVE; }
2088 bool is_non_greedy() { return type_ == NON_GREEDY; }
2089 bool is_greedy() { return type_ == GREEDY; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002090 RegExpTree* body() { return body_; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002091
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002092 private:
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002093 RegExpTree* body_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002094 int min_;
2095 int max_;
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002096 int min_match_;
2097 int max_match_;
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002098 Type type_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002099};
2100
2101
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002102class RegExpCapture: public RegExpTree {
2103 public:
2104 explicit RegExpCapture(RegExpTree* body, int index)
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002105 : body_(body), index_(index) { }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002106 virtual void* Accept(RegExpVisitor* visitor, void* data);
2107 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002108 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002109 static RegExpNode* ToNode(RegExpTree* body,
2110 int index,
2111 RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002112 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002113 virtual RegExpCapture* AsCapture();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002114 virtual bool IsAnchoredAtStart();
2115 virtual bool IsAnchoredAtEnd();
ager@chromium.org32912102009-01-16 10:38:43 +00002116 virtual Interval CaptureRegisters();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002117 virtual bool IsCapture();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002118 virtual int min_match() { return body_->min_match(); }
2119 virtual int max_match() { return body_->max_match(); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002120 RegExpTree* body() { return body_; }
2121 int index() { return index_; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002122 static int StartRegister(int index) { return index * 2; }
2123 static int EndRegister(int index) { return index * 2 + 1; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002124
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002125 private:
2126 RegExpTree* body_;
2127 int index_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002128};
2129
2130
2131class RegExpLookahead: public RegExpTree {
2132 public:
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002133 RegExpLookahead(RegExpTree* body,
2134 bool is_positive,
2135 int capture_count,
2136 int capture_from)
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002137 : body_(body),
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002138 is_positive_(is_positive),
2139 capture_count_(capture_count),
2140 capture_from_(capture_from) { }
2141
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002142 virtual void* Accept(RegExpVisitor* visitor, void* data);
2143 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002144 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002145 virtual RegExpLookahead* AsLookahead();
ager@chromium.org32912102009-01-16 10:38:43 +00002146 virtual Interval CaptureRegisters();
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002147 virtual bool IsLookahead();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002148 virtual bool IsAnchoredAtStart();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002149 virtual int min_match() { return 0; }
2150 virtual int max_match() { return 0; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002151 RegExpTree* body() { return body_; }
2152 bool is_positive() { return is_positive_; }
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002153 int capture_count() { return capture_count_; }
2154 int capture_from() { return capture_from_; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002155
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002156 private:
2157 RegExpTree* body_;
2158 bool is_positive_;
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002159 int capture_count_;
2160 int capture_from_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002161};
2162
2163
2164class RegExpBackReference: public RegExpTree {
2165 public:
2166 explicit RegExpBackReference(RegExpCapture* capture)
2167 : capture_(capture) { }
2168 virtual void* Accept(RegExpVisitor* visitor, void* data);
2169 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002170 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002171 virtual RegExpBackReference* AsBackReference();
2172 virtual bool IsBackReference();
ager@chromium.org32912102009-01-16 10:38:43 +00002173 virtual int min_match() { return 0; }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002174 virtual int max_match() { return capture_->max_match(); }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002175 int index() { return capture_->index(); }
2176 RegExpCapture* capture() { return capture_; }
2177 private:
2178 RegExpCapture* capture_;
2179};
2180
2181
2182class RegExpEmpty: public RegExpTree {
2183 public:
2184 RegExpEmpty() { }
2185 virtual void* Accept(RegExpVisitor* visitor, void* data);
2186 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
ager@chromium.org8bb60582008-12-11 12:02:20 +00002187 RegExpNode* on_success);
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002188 virtual RegExpEmpty* AsEmpty();
2189 virtual bool IsEmpty();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +00002190 virtual int min_match() { return 0; }
2191 virtual int max_match() { return 0; }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002192 static RegExpEmpty* GetInstance() { return &kInstance; }
2193 private:
2194 static RegExpEmpty kInstance;
2195};
2196
2197
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002198// ----------------------------------------------------------------------------
2199// Basic visitor
2200// - leaf node visitors are abstract.
2201
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002202class AstVisitor BASE_EMBEDDED {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002203 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002204 AstVisitor() : isolate_(Isolate::Current()), stack_overflow_(false) { }
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002205 virtual ~AstVisitor() { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002206
lrn@chromium.org25156de2010-04-06 13:10:27 +00002207 // Stack overflow check and dynamic dispatch.
2208 void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002209
lrn@chromium.org25156de2010-04-06 13:10:27 +00002210 // Iteration left-to-right.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00002211 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002212 virtual void VisitStatements(ZoneList<Statement*>* statements);
2213 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
2214
2215 // Stack overflow tracking support.
2216 bool HasStackOverflow() const { return stack_overflow_; }
lrn@chromium.org25156de2010-04-06 13:10:27 +00002217 bool CheckStackOverflow();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002218
kasper.lund212ac232008-07-16 07:07:30 +00002219 // If a stack-overflow exception is encountered when visiting a
2220 // node, calling SetStackOverflow will make sure that the visitor
2221 // bails out without visiting more nodes.
2222 void SetStackOverflow() { stack_overflow_ = true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002223 void ClearStackOverflow() { stack_overflow_ = false; }
kasper.lund212ac232008-07-16 07:07:30 +00002224
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002225 // Nodes not appearing in the AST, including slots.
2226 virtual void VisitSlot(Slot* node) { UNREACHABLE(); }
2227
2228 // Individual AST nodes.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002229#define DEF_VISIT(type) \
2230 virtual void Visit##type(type* node) = 0;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002231 AST_NODE_LIST(DEF_VISIT)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002232#undef DEF_VISIT
2233
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002234 protected:
2235 Isolate* isolate() { return isolate_; }
2236
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002237 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002238 Isolate* isolate_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002239 bool stack_overflow_;
2240};
2241
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002242
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002243} } // namespace v8::internal
2244
2245#endif // V8_AST_H_