blob: 0ac1644f4b42ab20f36471489297004f58a83ad2 [file] [log] [blame]
Ben Murdoch8b112d22011-06-08 16:22:53 +01001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +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
Ben Murdoch257744e2011-11-30 15:57:28 +000031#include "allocation.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000032#include "execution.h"
33#include "factory.h"
Steve Block3ce2e202009-11-05 08:53:23 +000034#include "jsregexp.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000035#include "runtime.h"
36#include "token.h"
37#include "variables.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000038
39namespace v8 {
40namespace internal {
41
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
55#define STATEMENT_NODE_LIST(V) \
56 V(Block) \
57 V(ExpressionStatement) \
58 V(EmptyStatement) \
59 V(IfStatement) \
60 V(ContinueStatement) \
61 V(BreakStatement) \
62 V(ReturnStatement) \
63 V(WithEnterStatement) \
64 V(WithExitStatement) \
65 V(SwitchStatement) \
Steve Block3ce2e202009-11-05 08:53:23 +000066 V(DoWhileStatement) \
67 V(WhileStatement) \
68 V(ForStatement) \
Steve Blocka7e24c12009-10-30 11:49:00 +000069 V(ForInStatement) \
Steve Block3ce2e202009-11-05 08:53:23 +000070 V(TryCatchStatement) \
71 V(TryFinallyStatement) \
Steve Blocka7e24c12009-10-30 11:49:00 +000072 V(DebuggerStatement)
73
74#define EXPRESSION_NODE_LIST(V) \
75 V(FunctionLiteral) \
Steve Block6ded16b2010-05-10 14:33:55 +010076 V(SharedFunctionInfoLiteral) \
Steve Blocka7e24c12009-10-30 11:49:00 +000077 V(Conditional) \
Steve Blocka7e24c12009-10-30 11:49:00 +000078 V(VariableProxy) \
79 V(Literal) \
80 V(RegExpLiteral) \
81 V(ObjectLiteral) \
82 V(ArrayLiteral) \
83 V(CatchExtensionObject) \
84 V(Assignment) \
85 V(Throw) \
86 V(Property) \
87 V(Call) \
88 V(CallNew) \
89 V(CallRuntime) \
90 V(UnaryOperation) \
91 V(CountOperation) \
92 V(BinaryOperation) \
93 V(CompareOperation) \
Kristian Monsen80d68ea2010-09-08 11:05:35 +010094 V(CompareToNull) \
Steve Blocka7e24c12009-10-30 11:49:00 +000095 V(ThisFunction)
96
97#define AST_NODE_LIST(V) \
98 V(Declaration) \
99 STATEMENT_NODE_LIST(V) \
100 EXPRESSION_NODE_LIST(V)
101
102// Forward declarations
Steve Block6ded16b2010-05-10 14:33:55 +0100103class BitVector;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100104class DefinitionInfo;
105class MaterializedLiteral;
106class TargetCollector;
107class TypeFeedbackOracle;
Steve Blocka7e24c12009-10-30 11:49:00 +0000108
109#define DEF_FORWARD_DECLARATION(type) class type;
110AST_NODE_LIST(DEF_FORWARD_DECLARATION)
111#undef DEF_FORWARD_DECLARATION
112
113
114// Typedef only introduced to avoid unreadable code.
115// Please do appreciate the required space in "> >".
116typedef ZoneList<Handle<String> > ZoneStringList;
117typedef ZoneList<Handle<Object> > ZoneObjectList;
118
119
Ben Murdochf87a2032010-10-22 12:50:53 +0100120#define DECLARE_NODE_TYPE(type) \
121 virtual void Accept(AstVisitor* v); \
122 virtual AstNode::Type node_type() const { return AstNode::k##type; } \
123 virtual type* As##type() { return this; }
124
125
Steve Blocka7e24c12009-10-30 11:49:00 +0000126class AstNode: public ZoneObject {
127 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100128#define DECLARE_TYPE_ENUM(type) k##type,
129 enum Type {
130 AST_NODE_LIST(DECLARE_TYPE_ENUM)
131 kInvalid = -1
132 };
133#undef DECLARE_TYPE_ENUM
Steve Blocka7e24c12009-10-30 11:49:00 +0000134
Ben Murdochb0fe1622011-05-05 13:52:32 +0100135 static const int kNoNumber = -1;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100136 static const int kFunctionEntryId = 2; // Using 0 could disguise errors.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100137
Steve Block44f0eee2011-05-26 01:26:41 +0100138 AstNode() : id_(GetNextId()) {
139 Isolate* isolate = Isolate::Current();
140 isolate->set_ast_node_count(isolate->ast_node_count() + 1);
141 }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100142
Ben Murdochf87a2032010-10-22 12:50:53 +0100143 virtual ~AstNode() { }
144
145 virtual void Accept(AstVisitor* v) = 0;
146 virtual Type node_type() const { return kInvalid; }
147
148 // Type testing & conversion functions overridden by concrete subclasses.
149#define DECLARE_NODE_FUNCTIONS(type) \
150 virtual type* As##type() { return NULL; }
151 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
152#undef DECLARE_NODE_FUNCTIONS
153
Steve Blocka7e24c12009-10-30 11:49:00 +0000154 virtual Statement* AsStatement() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000155 virtual Expression* AsExpression() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000156 virtual TargetCollector* AsTargetCollector() { return NULL; }
157 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
158 virtual IterationStatement* AsIterationStatement() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000159 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100160 virtual Slot* AsSlot() { return NULL; }
161
162 // True if the node is simple enough for us to inline calls containing it.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100163 virtual bool IsInlineable() const = 0;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100164
Steve Block44f0eee2011-05-26 01:26:41 +0100165 static int Count() { return Isolate::Current()->ast_node_count(); }
166 static void ResetIds() { Isolate::Current()->set_ast_node_id(0); }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100167 unsigned id() const { return id_; }
168
169 protected:
Steve Block44f0eee2011-05-26 01:26:41 +0100170 static unsigned GetNextId() {
171 Isolate* isolate = Isolate::Current();
172 unsigned tmp = isolate->ast_node_id();
173 isolate->set_ast_node_id(tmp + 1);
174 return tmp;
175 }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100176 static unsigned ReserveIdRange(int n) {
Steve Block44f0eee2011-05-26 01:26:41 +0100177 Isolate* isolate = Isolate::Current();
178 unsigned tmp = isolate->ast_node_id();
179 isolate->set_ast_node_id(tmp + n);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100180 return tmp;
181 }
182
183 private:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100184 unsigned id_;
Steve Block44f0eee2011-05-26 01:26:41 +0100185
186 friend class CaseClause; // Generates AST IDs.
Steve Blocka7e24c12009-10-30 11:49:00 +0000187};
188
189
190class Statement: public AstNode {
191 public:
192 Statement() : statement_pos_(RelocInfo::kNoPosition) {}
193
194 virtual Statement* AsStatement() { return this; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000195
Steve Block6ded16b2010-05-10 14:33:55 +0100196 virtual Assignment* StatementAsSimpleAssignment() { return NULL; }
197 virtual CountOperation* StatementAsCountOperation() { return NULL; }
198
Steve Blocka7e24c12009-10-30 11:49:00 +0000199 bool IsEmpty() { return AsEmptyStatement() != NULL; }
200
201 void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
202 int statement_pos() const { return statement_pos_; }
203
204 private:
205 int statement_pos_;
206};
207
208
209class Expression: public AstNode {
210 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100211 enum Context {
212 // Not assigned a context yet, or else will not be visited during
213 // code generation.
214 kUninitialized,
215 // Evaluated for its side effects.
216 kEffect,
217 // Evaluated for its value (and side effects).
218 kValue,
219 // Evaluated for control flow (and side effects).
220 kTest
221 };
222
Ben Murdoch8b112d22011-06-08 16:22:53 +0100223 Expression() {}
224
225 virtual int position() const {
226 UNREACHABLE();
227 return 0;
228 }
Leon Clarke4515c472010-02-03 11:58:03 +0000229
Steve Blocka7e24c12009-10-30 11:49:00 +0000230 virtual Expression* AsExpression() { return this; }
231
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100232 virtual bool IsTrivial() { return false; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000233 virtual bool IsValidLeftHandSide() { return false; }
234
Ben Murdochb0fe1622011-05-05 13:52:32 +0100235 // Helpers for ToBoolean conversion.
236 virtual bool ToBooleanIsTrue() { return false; }
237 virtual bool ToBooleanIsFalse() { return false; }
238
Leon Clarkee46be812010-01-19 14:06:41 +0000239 // Symbols that cannot be parsed as array indices are considered property
240 // names. We do not treat symbols that can be array indexes as property
241 // names because [] for string objects is handled only by keyed ICs.
242 virtual bool IsPropertyName() { return false; }
243
Steve Blocka7e24c12009-10-30 11:49:00 +0000244 // Mark the expression as being compiled as an expression
245 // statement. This is used to transform postfix increments to
246 // (faster) prefix increments.
247 virtual void MarkAsStatement() { /* do nothing */ }
248
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100249 // True iff the result can be safely overwritten (to avoid allocation).
250 // False for operations that can return one of their operands.
251 virtual bool ResultOverwriteAllowed() { return false; }
252
253 // True iff the expression is a literal represented as a smi.
254 virtual bool IsSmiLiteral() { return false; }
255
Ben Murdochb0fe1622011-05-05 13:52:32 +0100256 // Type feedback information for assignments and properties.
257 virtual bool IsMonomorphic() {
258 UNREACHABLE();
259 return false;
260 }
261 virtual bool IsArrayLength() {
262 UNREACHABLE();
263 return false;
264 }
265 virtual ZoneMapList* GetReceiverTypes() {
266 UNREACHABLE();
267 return NULL;
268 }
269 virtual Handle<Map> GetMonomorphicReceiverType() {
270 UNREACHABLE();
271 return Handle<Map>();
272 }
273
Ben Murdoch8b112d22011-06-08 16:22:53 +0100274 ExternalArrayType external_array_type() const {
275 return external_array_type_;
Steve Block6ded16b2010-05-10 14:33:55 +0100276 }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100277 void set_external_array_type(ExternalArrayType array_type) {
278 external_array_type_ = array_type;
Andrei Popescu402d9372010-02-26 13:31:12 +0000279 }
280
Steve Blocka7e24c12009-10-30 11:49:00 +0000281 private:
Ben Murdoch8b112d22011-06-08 16:22:53 +0100282 ExternalArrayType external_array_type_;
Steve Blocka7e24c12009-10-30 11:49:00 +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:
293 virtual bool IsValidLeftHandSide() { return true; }
294 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100295 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000296};
297
298
299class BreakableStatement: public Statement {
300 public:
301 enum Type {
302 TARGET_FOR_ANONYMOUS,
303 TARGET_FOR_NAMED_ONLY
304 };
305
306 // The labels associated with this statement. May be NULL;
307 // if it is != NULL, guaranteed to contain at least one entry.
308 ZoneStringList* labels() const { return labels_; }
309
310 // Type testing & conversion.
311 virtual BreakableStatement* AsBreakableStatement() { return this; }
312
313 // Code generation
Ben Murdoch8b112d22011-06-08 16:22:53 +0100314 Label* break_target() { return &break_target_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000315
316 // Testers.
317 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
318
Ben Murdochb0fe1622011-05-05 13:52:32 +0100319 // Bailout support.
320 int EntryId() const { return entry_id_; }
321 int ExitId() const { return exit_id_; }
322
Steve Blocka7e24c12009-10-30 11:49:00 +0000323 protected:
Kristian Monsen25f61362010-05-21 11:50:48 +0100324 inline BreakableStatement(ZoneStringList* labels, Type type);
Steve Blocka7e24c12009-10-30 11:49:00 +0000325
326 private:
327 ZoneStringList* labels_;
328 Type type_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100329 Label break_target_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100330 int entry_id_;
331 int exit_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000332};
333
334
335class Block: public BreakableStatement {
336 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100337 inline Block(ZoneStringList* labels, int capacity, bool is_initializer_block);
Steve Blocka7e24c12009-10-30 11:49:00 +0000338
Ben Murdochf87a2032010-10-22 12:50:53 +0100339 DECLARE_NODE_TYPE(Block)
Steve Block6ded16b2010-05-10 14:33:55 +0100340
341 virtual Assignment* StatementAsSimpleAssignment() {
342 if (statements_.length() != 1) return NULL;
343 return statements_[0]->StatementAsSimpleAssignment();
344 }
345
346 virtual CountOperation* StatementAsCountOperation() {
347 if (statements_.length() != 1) return NULL;
348 return statements_[0]->StatementAsCountOperation();
349 }
350
Ben Murdochb0fe1622011-05-05 13:52:32 +0100351 virtual bool IsInlineable() const;
352
Steve Blocka7e24c12009-10-30 11:49:00 +0000353 void AddStatement(Statement* statement) { statements_.Add(statement); }
354
355 ZoneList<Statement*>* statements() { return &statements_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100356 bool is_initializer_block() const { return is_initializer_block_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000357
358 private:
359 ZoneList<Statement*> statements_;
360 bool is_initializer_block_;
361};
362
363
364class Declaration: public AstNode {
365 public:
366 Declaration(VariableProxy* proxy, Variable::Mode mode, FunctionLiteral* fun)
367 : proxy_(proxy),
368 mode_(mode),
369 fun_(fun) {
370 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
371 // At the moment there are no "const functions"'s in JavaScript...
372 ASSERT(fun == NULL || mode == Variable::VAR);
373 }
374
Ben Murdochf87a2032010-10-22 12:50:53 +0100375 DECLARE_NODE_TYPE(Declaration)
Steve Blocka7e24c12009-10-30 11:49:00 +0000376
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100377 VariableProxy* proxy() const { return proxy_; }
378 Variable::Mode mode() const { return mode_; }
379 FunctionLiteral* fun() const { return fun_; } // may be NULL
Ben Murdoch8b112d22011-06-08 16:22:53 +0100380 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000381
382 private:
383 VariableProxy* proxy_;
384 Variable::Mode mode_;
385 FunctionLiteral* fun_;
386};
387
388
389class IterationStatement: public BreakableStatement {
390 public:
391 // Type testing & conversion.
392 virtual IterationStatement* AsIterationStatement() { return this; }
393
394 Statement* body() const { return body_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100395
396 // Bailout support.
397 int OsrEntryId() const { return osr_entry_id_; }
398 virtual int ContinueId() const = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000399
400 // Code generation
Ben Murdoch8b112d22011-06-08 16:22:53 +0100401 Label* continue_target() { return &continue_target_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000402
403 protected:
Kristian Monsen25f61362010-05-21 11:50:48 +0100404 explicit inline IterationStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000405
406 void Initialize(Statement* body) {
407 body_ = body;
408 }
409
410 private:
411 Statement* body_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100412 Label continue_target_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100413 int osr_entry_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000414};
415
416
Steve Block3ce2e202009-11-05 08:53:23 +0000417class DoWhileStatement: public IterationStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000418 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100419 explicit inline DoWhileStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000420
Ben Murdochf87a2032010-10-22 12:50:53 +0100421 DECLARE_NODE_TYPE(DoWhileStatement)
422
Steve Block3ce2e202009-11-05 08:53:23 +0000423 void Initialize(Expression* cond, Statement* body) {
424 IterationStatement::Initialize(body);
425 cond_ = cond;
426 }
427
Steve Block3ce2e202009-11-05 08:53:23 +0000428 Expression* cond() const { return cond_; }
429
Steve Blockd0582a62009-12-15 09:54:21 +0000430 // Position where condition expression starts. We need it to make
431 // the loop's condition a breakable location.
432 int condition_position() { return condition_position_; }
433 void set_condition_position(int pos) { condition_position_ = pos; }
434
Ben Murdochb0fe1622011-05-05 13:52:32 +0100435 // Bailout support.
436 virtual int ContinueId() const { return continue_id_; }
437 int BackEdgeId() const { return back_edge_id_; }
438
Ben Murdoch8b112d22011-06-08 16:22:53 +0100439 virtual bool IsInlineable() const;
440
Steve Block3ce2e202009-11-05 08:53:23 +0000441 private:
442 Expression* cond_;
Steve Blockd0582a62009-12-15 09:54:21 +0000443 int condition_position_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100444 int continue_id_;
445 int back_edge_id_;
Steve Block3ce2e202009-11-05 08:53:23 +0000446};
447
448
449class WhileStatement: public IterationStatement {
450 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100451 explicit inline WhileStatement(ZoneStringList* labels);
Steve Block3ce2e202009-11-05 08:53:23 +0000452
Ben Murdochf87a2032010-10-22 12:50:53 +0100453 DECLARE_NODE_TYPE(WhileStatement)
454
Steve Block3ce2e202009-11-05 08:53:23 +0000455 void Initialize(Expression* cond, Statement* body) {
456 IterationStatement::Initialize(body);
457 cond_ = cond;
458 }
459
Steve Block3ce2e202009-11-05 08:53:23 +0000460 Expression* cond() const { return cond_; }
461 bool may_have_function_literal() const {
462 return may_have_function_literal_;
463 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100464 void set_may_have_function_literal(bool value) {
465 may_have_function_literal_ = value;
466 }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100467 virtual bool IsInlineable() const;
Steve Block3ce2e202009-11-05 08:53:23 +0000468
Ben Murdochb0fe1622011-05-05 13:52:32 +0100469 // Bailout support.
470 virtual int ContinueId() const { return EntryId(); }
471 int BodyId() const { return body_id_; }
472
Steve Block3ce2e202009-11-05 08:53:23 +0000473 private:
474 Expression* cond_;
475 // True if there is a function literal subexpression in the condition.
476 bool may_have_function_literal_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100477 int body_id_;
Steve Block3ce2e202009-11-05 08:53:23 +0000478};
479
480
481class ForStatement: public IterationStatement {
482 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100483 explicit inline ForStatement(ZoneStringList* labels);
Steve Block6ded16b2010-05-10 14:33:55 +0100484
Ben Murdochf87a2032010-10-22 12:50:53 +0100485 DECLARE_NODE_TYPE(ForStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000486
487 void Initialize(Statement* init,
488 Expression* cond,
489 Statement* next,
490 Statement* body) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000491 IterationStatement::Initialize(body);
492 init_ = init;
493 cond_ = cond;
494 next_ = next;
495 }
496
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100497 Statement* init() const { return init_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100498 Expression* cond() const { return cond_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100499 Statement* next() const { return next_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100500
Steve Blocka7e24c12009-10-30 11:49:00 +0000501 bool may_have_function_literal() const {
502 return may_have_function_literal_;
503 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100504 void set_may_have_function_literal(bool value) {
505 may_have_function_literal_ = value;
506 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000507
Ben Murdochb0fe1622011-05-05 13:52:32 +0100508 // Bailout support.
509 virtual int ContinueId() const { return continue_id_; }
510 int BodyId() const { return body_id_; }
511
Steve Block6ded16b2010-05-10 14:33:55 +0100512 bool is_fast_smi_loop() { return loop_variable_ != NULL; }
513 Variable* loop_variable() { return loop_variable_; }
514 void set_loop_variable(Variable* var) { loop_variable_ = var; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100515 virtual bool IsInlineable() const;
Steve Block6ded16b2010-05-10 14:33:55 +0100516
Steve Blocka7e24c12009-10-30 11:49:00 +0000517 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000518 Statement* init_;
519 Expression* cond_;
520 Statement* next_;
521 // True if there is a function literal subexpression in the condition.
522 bool may_have_function_literal_;
Steve Block6ded16b2010-05-10 14:33:55 +0100523 Variable* loop_variable_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100524 int continue_id_;
525 int body_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000526};
527
528
529class ForInStatement: public IterationStatement {
530 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100531 explicit inline ForInStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000532
Ben Murdochf87a2032010-10-22 12:50:53 +0100533 DECLARE_NODE_TYPE(ForInStatement)
534
Steve Blocka7e24c12009-10-30 11:49:00 +0000535 void Initialize(Expression* each, Expression* enumerable, Statement* body) {
536 IterationStatement::Initialize(body);
537 each_ = each;
538 enumerable_ = enumerable;
539 }
540
Steve Blocka7e24c12009-10-30 11:49:00 +0000541 Expression* each() const { return each_; }
542 Expression* enumerable() const { return enumerable_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100543 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000544
Ben Murdochb0fe1622011-05-05 13:52:32 +0100545 // Bailout support.
546 int AssignmentId() const { return assignment_id_; }
547 virtual int ContinueId() const { return EntryId(); }
548
Steve Blocka7e24c12009-10-30 11:49:00 +0000549 private:
550 Expression* each_;
551 Expression* enumerable_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100552 int assignment_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000553};
554
555
556class ExpressionStatement: public Statement {
557 public:
558 explicit ExpressionStatement(Expression* expression)
559 : expression_(expression) { }
560
Ben Murdochf87a2032010-10-22 12:50:53 +0100561 DECLARE_NODE_TYPE(ExpressionStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000562
Ben Murdochb0fe1622011-05-05 13:52:32 +0100563 virtual bool IsInlineable() const;
564
Steve Block6ded16b2010-05-10 14:33:55 +0100565 virtual Assignment* StatementAsSimpleAssignment();
566 virtual CountOperation* StatementAsCountOperation();
567
Steve Blocka7e24c12009-10-30 11:49:00 +0000568 void set_expression(Expression* e) { expression_ = e; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100569 Expression* expression() const { return expression_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000570
571 private:
572 Expression* expression_;
573};
574
575
576class ContinueStatement: public Statement {
577 public:
578 explicit ContinueStatement(IterationStatement* target)
579 : target_(target) { }
580
Ben Murdochf87a2032010-10-22 12:50:53 +0100581 DECLARE_NODE_TYPE(ContinueStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000582
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100583 IterationStatement* target() const { return target_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100584 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000585
586 private:
587 IterationStatement* target_;
588};
589
590
591class BreakStatement: public Statement {
592 public:
593 explicit BreakStatement(BreakableStatement* target)
594 : target_(target) { }
595
Ben Murdochf87a2032010-10-22 12:50:53 +0100596 DECLARE_NODE_TYPE(BreakStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000597
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100598 BreakableStatement* target() const { return target_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100599 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000600
601 private:
602 BreakableStatement* target_;
603};
604
605
606class ReturnStatement: public Statement {
607 public:
608 explicit ReturnStatement(Expression* expression)
609 : expression_(expression) { }
610
Ben Murdochf87a2032010-10-22 12:50:53 +0100611 DECLARE_NODE_TYPE(ReturnStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000612
Ben Murdochb0fe1622011-05-05 13:52:32 +0100613 Expression* expression() const { return expression_; }
614 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000615
616 private:
617 Expression* expression_;
618};
619
620
621class WithEnterStatement: public Statement {
622 public:
623 explicit WithEnterStatement(Expression* expression, bool is_catch_block)
624 : expression_(expression), is_catch_block_(is_catch_block) { }
625
Ben Murdochf87a2032010-10-22 12:50:53 +0100626 DECLARE_NODE_TYPE(WithEnterStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000627
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100628 Expression* expression() const { return expression_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000629
630 bool is_catch_block() const { return is_catch_block_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100631 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000632
633 private:
634 Expression* expression_;
635 bool is_catch_block_;
636};
637
638
639class WithExitStatement: public Statement {
640 public:
641 WithExitStatement() { }
642
Ben Murdoch8b112d22011-06-08 16:22:53 +0100643 virtual bool IsInlineable() const;
644
Ben Murdochf87a2032010-10-22 12:50:53 +0100645 DECLARE_NODE_TYPE(WithExitStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000646};
647
648
649class CaseClause: public ZoneObject {
650 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100651 CaseClause(Expression* label, ZoneList<Statement*>* statements, int pos);
Steve Blocka7e24c12009-10-30 11:49:00 +0000652
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100653 bool is_default() const { return label_ == NULL; }
654 Expression* label() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000655 CHECK(!is_default());
656 return label_;
657 }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100658 Label* body_target() { return &body_target_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100659 ZoneList<Statement*>* statements() const { return statements_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000660
Ben Murdoch8b112d22011-06-08 16:22:53 +0100661 int position() const { return position_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100662 void set_position(int pos) { position_ = pos; }
663
Steve Block44f0eee2011-05-26 01:26:41 +0100664 int EntryId() { return entry_id_; }
Ben Murdoch257744e2011-11-30 15:57:28 +0000665 int CompareId() { return compare_id_; }
Steve Block44f0eee2011-05-26 01:26:41 +0100666
Ben Murdochb0fe1622011-05-05 13:52:32 +0100667 // Type feedback information.
668 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
669 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
670 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
671
Steve Blocka7e24c12009-10-30 11:49:00 +0000672 private:
673 Expression* label_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100674 Label body_target_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000675 ZoneList<Statement*>* statements_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100676 int position_;
677 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
678 CompareTypeFeedback compare_type_;
Ben Murdoch257744e2011-11-30 15:57:28 +0000679 int compare_id_;
Steve Block44f0eee2011-05-26 01:26:41 +0100680 int entry_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000681};
682
683
684class SwitchStatement: public BreakableStatement {
685 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100686 explicit inline SwitchStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000687
Ben Murdochf87a2032010-10-22 12:50:53 +0100688 DECLARE_NODE_TYPE(SwitchStatement)
689
Steve Blocka7e24c12009-10-30 11:49:00 +0000690 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
691 tag_ = tag;
692 cases_ = cases;
693 }
694
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100695 Expression* tag() const { return tag_; }
696 ZoneList<CaseClause*>* cases() const { return cases_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100697 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000698
699 private:
700 Expression* tag_;
701 ZoneList<CaseClause*>* cases_;
702};
703
704
705// If-statements always have non-null references to their then- and
706// else-parts. When parsing if-statements with no explicit else-part,
707// the parser implicitly creates an empty statement. Use the
708// HasThenStatement() and HasElseStatement() functions to check if a
709// given if-statement has a then- or an else-part containing code.
710class IfStatement: public Statement {
711 public:
712 IfStatement(Expression* condition,
713 Statement* then_statement,
714 Statement* else_statement)
715 : condition_(condition),
716 then_statement_(then_statement),
Ben Murdochb0fe1622011-05-05 13:52:32 +0100717 else_statement_(else_statement),
718 then_id_(GetNextId()),
719 else_id_(GetNextId()) {
720 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000721
Ben Murdochf87a2032010-10-22 12:50:53 +0100722 DECLARE_NODE_TYPE(IfStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000723
Ben Murdochb0fe1622011-05-05 13:52:32 +0100724 virtual bool IsInlineable() const;
725
Steve Blocka7e24c12009-10-30 11:49:00 +0000726 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
727 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
728
729 Expression* condition() const { return condition_; }
730 Statement* then_statement() const { return then_statement_; }
731 Statement* else_statement() const { return else_statement_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100732
733 int ThenId() const { return then_id_; }
734 int ElseId() const { return else_id_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000735
736 private:
737 Expression* condition_;
738 Statement* then_statement_;
739 Statement* else_statement_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100740 int then_id_;
741 int else_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000742};
743
744
745// NOTE: TargetCollectors are represented as nodes to fit in the target
746// stack in the compiler; this should probably be reworked.
747class TargetCollector: public AstNode {
748 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +0100749 explicit TargetCollector(ZoneList<Label*>* targets)
Steve Blocka7e24c12009-10-30 11:49:00 +0000750 : targets_(targets) {
751 }
752
753 // Adds a jump target to the collector. The collector stores a pointer not
754 // a copy of the target to make binding work, so make sure not to pass in
755 // references to something on the stack.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100756 void AddTarget(Label* target);
Steve Blocka7e24c12009-10-30 11:49:00 +0000757
758 // Virtual behaviour. TargetCollectors are never part of the AST.
759 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
760 virtual TargetCollector* AsTargetCollector() { return this; }
761
Ben Murdoch8b112d22011-06-08 16:22:53 +0100762 ZoneList<Label*>* targets() { return targets_; }
763 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000764
765 private:
Ben Murdoch8b112d22011-06-08 16:22:53 +0100766 ZoneList<Label*>* targets_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000767};
768
769
770class TryStatement: public Statement {
771 public:
772 explicit TryStatement(Block* try_block)
773 : try_block_(try_block), escaping_targets_(NULL) { }
774
Ben Murdoch8b112d22011-06-08 16:22:53 +0100775 void set_escaping_targets(ZoneList<Label*>* targets) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000776 escaping_targets_ = targets;
777 }
778
779 Block* try_block() const { return try_block_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100780 ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
781 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000782
783 private:
784 Block* try_block_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100785 ZoneList<Label*>* escaping_targets_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000786};
787
788
Steve Block3ce2e202009-11-05 08:53:23 +0000789class TryCatchStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000790 public:
Steve Block3ce2e202009-11-05 08:53:23 +0000791 TryCatchStatement(Block* try_block,
Leon Clarkee46be812010-01-19 14:06:41 +0000792 VariableProxy* catch_var,
Steve Block3ce2e202009-11-05 08:53:23 +0000793 Block* catch_block)
Steve Blocka7e24c12009-10-30 11:49:00 +0000794 : TryStatement(try_block),
795 catch_var_(catch_var),
796 catch_block_(catch_block) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000797 }
798
Ben Murdochf87a2032010-10-22 12:50:53 +0100799 DECLARE_NODE_TYPE(TryCatchStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000800
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100801 VariableProxy* catch_var() const { return catch_var_; }
802 Block* catch_block() const { return catch_block_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100803 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000804
805 private:
Leon Clarkee46be812010-01-19 14:06:41 +0000806 VariableProxy* catch_var_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000807 Block* catch_block_;
808};
809
810
Steve Block3ce2e202009-11-05 08:53:23 +0000811class TryFinallyStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000812 public:
Steve Block3ce2e202009-11-05 08:53:23 +0000813 TryFinallyStatement(Block* try_block, Block* finally_block)
Steve Blocka7e24c12009-10-30 11:49:00 +0000814 : TryStatement(try_block),
815 finally_block_(finally_block) { }
816
Ben Murdochf87a2032010-10-22 12:50:53 +0100817 DECLARE_NODE_TYPE(TryFinallyStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000818
819 Block* finally_block() const { return finally_block_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100820 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000821
822 private:
823 Block* finally_block_;
824};
825
826
827class DebuggerStatement: public Statement {
828 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100829 DECLARE_NODE_TYPE(DebuggerStatement)
Ben Murdoch8b112d22011-06-08 16:22:53 +0100830 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000831};
832
833
834class EmptyStatement: public Statement {
835 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100836 DECLARE_NODE_TYPE(EmptyStatement)
Ben Murdochb0fe1622011-05-05 13:52:32 +0100837
Ben Murdoch8b112d22011-06-08 16:22:53 +0100838 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000839};
840
841
842class Literal: public Expression {
843 public:
844 explicit Literal(Handle<Object> handle) : handle_(handle) { }
845
Ben Murdochf87a2032010-10-22 12:50:53 +0100846 DECLARE_NODE_TYPE(Literal)
847
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100848 virtual bool IsTrivial() { return true; }
849 virtual bool IsSmiLiteral() { return handle_->IsSmi(); }
Steve Blocka7e24c12009-10-30 11:49:00 +0000850
Steve Blocka7e24c12009-10-30 11:49:00 +0000851 // Check if this literal is identical to the other literal.
852 bool IsIdenticalTo(const Literal* other) const {
853 return handle_.is_identical_to(other->handle_);
854 }
855
Leon Clarkee46be812010-01-19 14:06:41 +0000856 virtual bool IsPropertyName() {
857 if (handle_->IsSymbol()) {
858 uint32_t ignored;
859 return !String::cast(*handle_)->AsArrayIndex(&ignored);
860 }
861 return false;
862 }
863
Ben Murdochb0fe1622011-05-05 13:52:32 +0100864 Handle<String> AsPropertyName() {
865 ASSERT(IsPropertyName());
866 return Handle<String>::cast(handle_);
867 }
868
869 virtual bool ToBooleanIsTrue() { return handle_->ToBoolean()->IsTrue(); }
870 virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
871
Steve Blocka7e24c12009-10-30 11:49:00 +0000872 // Identity testers.
Steve Block44f0eee2011-05-26 01:26:41 +0100873 bool IsNull() const {
874 ASSERT(!handle_.is_null());
875 return handle_->IsNull();
876 }
877 bool IsTrue() const {
878 ASSERT(!handle_.is_null());
879 return handle_->IsTrue();
880 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000881 bool IsFalse() const {
Steve Block44f0eee2011-05-26 01:26:41 +0100882 ASSERT(!handle_.is_null());
883 return handle_->IsFalse();
Steve Blocka7e24c12009-10-30 11:49:00 +0000884 }
885
886 Handle<Object> handle() const { return handle_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100887 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000888
889 private:
890 Handle<Object> handle_;
891};
892
893
894// Base class for literals that needs space in the corresponding JSFunction.
895class MaterializedLiteral: public Expression {
896 public:
897 explicit MaterializedLiteral(int literal_index, bool is_simple, int depth)
898 : literal_index_(literal_index), is_simple_(is_simple), depth_(depth) {}
899
900 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
901
902 int literal_index() { return literal_index_; }
903
904 // A materialized literal is simple if the values consist of only
905 // constants and simple object and array literals.
906 bool is_simple() const { return is_simple_; }
907
Steve Blocka7e24c12009-10-30 11:49:00 +0000908 int depth() const { return depth_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100909 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000910
911 private:
912 int literal_index_;
913 bool is_simple_;
914 int depth_;
915};
916
917
918// An object literal has a boilerplate object that is used
919// for minimizing the work when constructing it at runtime.
920class ObjectLiteral: public MaterializedLiteral {
921 public:
922 // Property is used for passing information
923 // about an object literal's properties from the parser
924 // to the code generator.
925 class Property: public ZoneObject {
926 public:
Steve Blocka7e24c12009-10-30 11:49:00 +0000927 enum Kind {
928 CONSTANT, // Property with constant value (compile time).
929 COMPUTED, // Property with computed value (execution time).
930 MATERIALIZED_LITERAL, // Property value is a materialized literal.
931 GETTER, SETTER, // Property is an accessor function.
932 PROTOTYPE // Property is __proto__.
933 };
934
935 Property(Literal* key, Expression* value);
936 Property(bool is_getter, FunctionLiteral* value);
937
938 Literal* key() { return key_; }
939 Expression* value() { return value_; }
940 Kind kind() { return kind_; }
941
Steve Blockd0582a62009-12-15 09:54:21 +0000942 bool IsCompileTimeValue();
943
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800944 void set_emit_store(bool emit_store);
945 bool emit_store();
946
Steve Blocka7e24c12009-10-30 11:49:00 +0000947 private:
948 Literal* key_;
949 Expression* value_;
950 Kind kind_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800951 bool emit_store_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000952 };
953
954 ObjectLiteral(Handle<FixedArray> constant_properties,
955 ZoneList<Property*>* properties,
956 int literal_index,
957 bool is_simple,
Steve Block6ded16b2010-05-10 14:33:55 +0100958 bool fast_elements,
Steve Block44f0eee2011-05-26 01:26:41 +0100959 int depth,
960 bool has_function)
Steve Blocka7e24c12009-10-30 11:49:00 +0000961 : MaterializedLiteral(literal_index, is_simple, depth),
962 constant_properties_(constant_properties),
Steve Block6ded16b2010-05-10 14:33:55 +0100963 properties_(properties),
Steve Block44f0eee2011-05-26 01:26:41 +0100964 fast_elements_(fast_elements),
965 has_function_(has_function) {}
Steve Blocka7e24c12009-10-30 11:49:00 +0000966
Ben Murdochf87a2032010-10-22 12:50:53 +0100967 DECLARE_NODE_TYPE(ObjectLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +0000968
969 Handle<FixedArray> constant_properties() const {
970 return constant_properties_;
971 }
972 ZoneList<Property*>* properties() const { return properties_; }
973
Steve Block6ded16b2010-05-10 14:33:55 +0100974 bool fast_elements() const { return fast_elements_; }
975
Steve Block44f0eee2011-05-26 01:26:41 +0100976 bool has_function() { return has_function_; }
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800977
978 // Mark all computed expressions that are bound to a key that
979 // is shadowed by a later occurrence of the same key. For the
980 // marked expressions, no store code is emitted.
981 void CalculateEmitStore();
982
Steve Block44f0eee2011-05-26 01:26:41 +0100983 enum Flags {
984 kNoFlags = 0,
985 kFastElements = 1,
986 kHasFunction = 1 << 1
987 };
988
Steve Blocka7e24c12009-10-30 11:49:00 +0000989 private:
990 Handle<FixedArray> constant_properties_;
991 ZoneList<Property*>* properties_;
Steve Block6ded16b2010-05-10 14:33:55 +0100992 bool fast_elements_;
Steve Block44f0eee2011-05-26 01:26:41 +0100993 bool has_function_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000994};
995
996
997// Node for capturing a regexp literal.
998class RegExpLiteral: public MaterializedLiteral {
999 public:
1000 RegExpLiteral(Handle<String> pattern,
1001 Handle<String> flags,
1002 int literal_index)
1003 : MaterializedLiteral(literal_index, false, 1),
1004 pattern_(pattern),
1005 flags_(flags) {}
1006
Ben Murdochf87a2032010-10-22 12:50:53 +01001007 DECLARE_NODE_TYPE(RegExpLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00001008
1009 Handle<String> pattern() const { return pattern_; }
1010 Handle<String> flags() const { return flags_; }
1011
1012 private:
1013 Handle<String> pattern_;
1014 Handle<String> flags_;
1015};
1016
1017// An array literal has a literals object that is used
1018// for minimizing the work when constructing it at runtime.
1019class ArrayLiteral: public MaterializedLiteral {
1020 public:
Leon Clarkee46be812010-01-19 14:06:41 +00001021 ArrayLiteral(Handle<FixedArray> constant_elements,
Steve Blocka7e24c12009-10-30 11:49:00 +00001022 ZoneList<Expression*>* values,
1023 int literal_index,
1024 bool is_simple,
1025 int depth)
1026 : MaterializedLiteral(literal_index, is_simple, depth),
Leon Clarkee46be812010-01-19 14:06:41 +00001027 constant_elements_(constant_elements),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001028 values_(values),
1029 first_element_id_(ReserveIdRange(values->length())) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00001030
Ben Murdochf87a2032010-10-22 12:50:53 +01001031 DECLARE_NODE_TYPE(ArrayLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00001032
Leon Clarkee46be812010-01-19 14:06:41 +00001033 Handle<FixedArray> constant_elements() const { return constant_elements_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001034 ZoneList<Expression*>* values() const { return values_; }
1035
Ben Murdochb0fe1622011-05-05 13:52:32 +01001036 // Return an AST id for an element that is used in simulate instructions.
1037 int GetIdForElement(int i) { return first_element_id_ + i; }
1038
Steve Blocka7e24c12009-10-30 11:49:00 +00001039 private:
Leon Clarkee46be812010-01-19 14:06:41 +00001040 Handle<FixedArray> constant_elements_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001041 ZoneList<Expression*>* values_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001042 int first_element_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001043};
1044
1045
1046// Node for constructing a context extension object for a catch block.
1047// The catch context extension object has one property, the catch
1048// variable, which should be DontDelete.
1049class CatchExtensionObject: public Expression {
1050 public:
1051 CatchExtensionObject(Literal* key, VariableProxy* value)
1052 : key_(key), value_(value) {
1053 }
1054
Ben Murdochf87a2032010-10-22 12:50:53 +01001055 DECLARE_NODE_TYPE(CatchExtensionObject)
Steve Blocka7e24c12009-10-30 11:49:00 +00001056
1057 Literal* key() const { return key_; }
1058 VariableProxy* value() const { return value_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001059 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001060
1061 private:
1062 Literal* key_;
1063 VariableProxy* value_;
1064};
1065
1066
1067class VariableProxy: public Expression {
1068 public:
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001069 explicit VariableProxy(Variable* var);
1070
Ben Murdochf87a2032010-10-22 12:50:53 +01001071 DECLARE_NODE_TYPE(VariableProxy)
Steve Blocka7e24c12009-10-30 11:49:00 +00001072
1073 // Type testing & conversion
1074 virtual Property* AsProperty() {
1075 return var_ == NULL ? NULL : var_->AsProperty();
1076 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001077
Steve Blocka7e24c12009-10-30 11:49:00 +00001078 Variable* AsVariable() {
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001079 if (this == NULL || var_ == NULL) return NULL;
1080 Expression* rewrite = var_->rewrite();
1081 if (rewrite == NULL || rewrite->AsSlot() != NULL) return var_;
1082 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00001083 }
1084
1085 virtual bool IsValidLeftHandSide() {
1086 return var_ == NULL ? true : var_->IsValidLeftHandSide();
1087 }
1088
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001089 virtual bool IsTrivial() {
1090 // Reading from a mutable variable is a side effect, but the
1091 // variable for 'this' is immutable.
1092 return is_this_ || is_trivial_;
Andrei Popescu402d9372010-02-26 13:31:12 +00001093 }
1094
Ben Murdochb0fe1622011-05-05 13:52:32 +01001095 virtual bool IsInlineable() const;
1096
Steve Blocka7e24c12009-10-30 11:49:00 +00001097 bool IsVariable(Handle<String> n) {
1098 return !is_this() && name().is_identical_to(n);
1099 }
1100
1101 bool IsArguments() {
1102 Variable* variable = AsVariable();
1103 return (variable == NULL) ? false : variable->is_arguments();
1104 }
1105
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001106 Handle<String> name() const { return name_; }
1107 Variable* var() const { return var_; }
1108 bool is_this() const { return is_this_; }
1109 bool inside_with() const { return inside_with_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001110 int position() const { return position_; }
Steve Block6ded16b2010-05-10 14:33:55 +01001111
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001112 void MarkAsTrivial() { is_trivial_ = true; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001113
1114 // Bind this proxy to the variable var.
1115 void BindTo(Variable* var);
1116
1117 protected:
1118 Handle<String> name_;
1119 Variable* var_; // resolved variable, or NULL
1120 bool is_this_;
1121 bool inside_with_;
Steve Block6ded16b2010-05-10 14:33:55 +01001122 bool is_trivial_;
Ben Murdoch8b112d22011-06-08 16:22:53 +01001123 int position_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001124
Ben Murdoch8b112d22011-06-08 16:22:53 +01001125 VariableProxy(Handle<String> name,
1126 bool is_this,
1127 bool inside_with,
1128 int position = RelocInfo::kNoPosition);
Steve Blocka7e24c12009-10-30 11:49:00 +00001129 explicit VariableProxy(bool is_this);
1130
1131 friend class Scope;
1132};
1133
1134
1135class VariableProxySentinel: public VariableProxy {
1136 public:
1137 virtual bool IsValidLeftHandSide() { return !is_this(); }
Steve Blocka7e24c12009-10-30 11:49:00 +00001138
1139 private:
1140 explicit VariableProxySentinel(bool is_this) : VariableProxy(is_this) { }
Steve Block44f0eee2011-05-26 01:26:41 +01001141
1142 friend class AstSentinels;
Steve Blocka7e24c12009-10-30 11:49:00 +00001143};
1144
1145
1146class Slot: public Expression {
1147 public:
1148 enum Type {
1149 // A slot in the parameter section on the stack. index() is
1150 // the parameter index, counting left-to-right, starting at 0.
1151 PARAMETER,
1152
1153 // A slot in the local section on the stack. index() is
1154 // the variable index in the stack frame, starting at 0.
1155 LOCAL,
1156
1157 // An indexed slot in a heap context. index() is the
1158 // variable index in the context object on the heap,
1159 // starting at 0. var()->scope() is the corresponding
1160 // scope.
1161 CONTEXT,
1162
1163 // A named slot in a heap context. var()->name() is the
1164 // variable name in the context object on the heap,
1165 // with lookup starting at the current context. index()
1166 // is invalid.
Steve Blockd0582a62009-12-15 09:54:21 +00001167 LOOKUP
Steve Blocka7e24c12009-10-30 11:49:00 +00001168 };
1169
1170 Slot(Variable* var, Type type, int index)
1171 : var_(var), type_(type), index_(index) {
1172 ASSERT(var != NULL);
1173 }
1174
Ben Murdochb0fe1622011-05-05 13:52:32 +01001175 virtual void Accept(AstVisitor* v);
1176
1177 virtual Slot* AsSlot() { return this; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001178
Steve Block6ded16b2010-05-10 14:33:55 +01001179 bool IsStackAllocated() { return type_ == PARAMETER || type_ == LOCAL; }
1180
Steve Blocka7e24c12009-10-30 11:49:00 +00001181 // Accessors
1182 Variable* var() const { return var_; }
1183 Type type() const { return type_; }
1184 int index() const { return index_; }
1185 bool is_arguments() const { return var_->is_arguments(); }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001186 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001187
1188 private:
1189 Variable* var_;
1190 Type type_;
1191 int index_;
1192};
1193
1194
1195class Property: public Expression {
1196 public:
1197 // Synthetic properties are property lookups introduced by the system,
1198 // to objects that aren't visible to the user. Function calls to synthetic
1199 // properties should use the global object as receiver, not the base object
1200 // of the resolved Reference.
1201 enum Type { NORMAL, SYNTHETIC };
1202 Property(Expression* obj, Expression* key, int pos, Type type = NORMAL)
Ben Murdochb0fe1622011-05-05 13:52:32 +01001203 : obj_(obj),
1204 key_(key),
1205 pos_(pos),
1206 type_(type),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001207 receiver_types_(NULL),
Steve Block1e0659c2011-05-24 12:43:12 +01001208 is_monomorphic_(false),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001209 is_array_length_(false),
Steve Block1e0659c2011-05-24 12:43:12 +01001210 is_string_length_(false),
Steve Block44f0eee2011-05-26 01:26:41 +01001211 is_string_access_(false),
Steve Block9fac8402011-05-12 15:51:54 +01001212 is_function_prototype_(false),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001213 is_arguments_access_(false) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001214
Ben Murdochf87a2032010-10-22 12:50:53 +01001215 DECLARE_NODE_TYPE(Property)
Steve Blocka7e24c12009-10-30 11:49:00 +00001216
1217 virtual bool IsValidLeftHandSide() { return true; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001218 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001219
1220 Expression* obj() const { return obj_; }
1221 Expression* key() const { return key_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001222 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001223 bool is_synthetic() const { return type_ == SYNTHETIC; }
1224
Steve Block1e0659c2011-05-24 12:43:12 +01001225 bool IsStringLength() const { return is_string_length_; }
Steve Block44f0eee2011-05-26 01:26:41 +01001226 bool IsStringAccess() const { return is_string_access_; }
Steve Block9fac8402011-05-12 15:51:54 +01001227 bool IsFunctionPrototype() const { return is_function_prototype_; }
1228
Ben Murdochb0fe1622011-05-05 13:52:32 +01001229 // Marks that this is actually an argument rewritten to a keyed property
1230 // accessing the argument through the arguments shadow object.
1231 void set_is_arguments_access(bool is_arguments_access) {
1232 is_arguments_access_ = is_arguments_access;
1233 }
1234 bool is_arguments_access() const { return is_arguments_access_; }
1235
1236 // Type feedback information.
1237 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1238 virtual bool IsMonomorphic() { return is_monomorphic_; }
1239 virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
1240 virtual bool IsArrayLength() { return is_array_length_; }
1241 virtual Handle<Map> GetMonomorphicReceiverType() {
1242 return monomorphic_receiver_type_;
1243 }
1244
Steve Blocka7e24c12009-10-30 11:49:00 +00001245 private:
1246 Expression* obj_;
1247 Expression* key_;
1248 int pos_;
1249 Type type_;
1250
Ben Murdochb0fe1622011-05-05 13:52:32 +01001251 ZoneMapList* receiver_types_;
Steve Block1e0659c2011-05-24 12:43:12 +01001252 bool is_monomorphic_ : 1;
1253 bool is_array_length_ : 1;
1254 bool is_string_length_ : 1;
Steve Block44f0eee2011-05-26 01:26:41 +01001255 bool is_string_access_ : 1;
Steve Block1e0659c2011-05-24 12:43:12 +01001256 bool is_function_prototype_ : 1;
1257 bool is_arguments_access_ : 1;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001258 Handle<Map> monomorphic_receiver_type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001259};
1260
1261
1262class Call: public Expression {
1263 public:
1264 Call(Expression* expression, ZoneList<Expression*>* arguments, int pos)
Ben Murdochb0fe1622011-05-05 13:52:32 +01001265 : expression_(expression),
1266 arguments_(arguments),
1267 pos_(pos),
1268 is_monomorphic_(false),
Ben Murdochb8e0da22011-05-16 14:20:40 +01001269 check_type_(RECEIVER_MAP_CHECK),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001270 receiver_types_(NULL),
1271 return_id_(GetNextId()) {
1272 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001273
Ben Murdochf87a2032010-10-22 12:50:53 +01001274 DECLARE_NODE_TYPE(Call)
Steve Blocka7e24c12009-10-30 11:49:00 +00001275
Ben Murdochb0fe1622011-05-05 13:52:32 +01001276 virtual bool IsInlineable() const;
1277
Steve Blocka7e24c12009-10-30 11:49:00 +00001278 Expression* expression() const { return expression_; }
1279 ZoneList<Expression*>* arguments() const { return arguments_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001280 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001281
Ben Murdoch257744e2011-11-30 15:57:28 +00001282 void RecordTypeFeedback(TypeFeedbackOracle* oracle,
1283 CallKind call_kind);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001284 virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
1285 virtual bool IsMonomorphic() { return is_monomorphic_; }
Ben Murdochb8e0da22011-05-16 14:20:40 +01001286 CheckType check_type() const { return check_type_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001287 Handle<JSFunction> target() { return target_; }
1288 Handle<JSObject> holder() { return holder_; }
1289 Handle<JSGlobalPropertyCell> cell() { return cell_; }
1290
1291 bool ComputeTarget(Handle<Map> type, Handle<String> name);
Ben Murdoch8b112d22011-06-08 16:22:53 +01001292 bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001293
1294 // Bailout support.
1295 int ReturnId() const { return return_id_; }
1296
Ben Murdochb0fe1622011-05-05 13:52:32 +01001297#ifdef DEBUG
1298 // Used to assert that the FullCodeGenerator records the return site.
1299 bool return_is_recorded_;
1300#endif
1301
Steve Blocka7e24c12009-10-30 11:49:00 +00001302 private:
1303 Expression* expression_;
1304 ZoneList<Expression*>* arguments_;
1305 int pos_;
1306
Ben Murdochb0fe1622011-05-05 13:52:32 +01001307 bool is_monomorphic_;
Ben Murdochb8e0da22011-05-16 14:20:40 +01001308 CheckType check_type_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001309 ZoneMapList* receiver_types_;
1310 Handle<JSFunction> target_;
1311 Handle<JSObject> holder_;
1312 Handle<JSGlobalPropertyCell> cell_;
1313
1314 int return_id_;
Steve Block44f0eee2011-05-26 01:26:41 +01001315};
Ben Murdochb0fe1622011-05-05 13:52:32 +01001316
Steve Block44f0eee2011-05-26 01:26:41 +01001317
1318class AstSentinels {
1319 public:
1320 ~AstSentinels() { }
1321
1322 // Returns a property singleton property access on 'this'. Used
1323 // during preparsing.
1324 Property* this_property() { return &this_property_; }
1325 VariableProxySentinel* this_proxy() { return &this_proxy_; }
1326 VariableProxySentinel* identifier_proxy() { return &identifier_proxy_; }
1327 ValidLeftHandSideSentinel* valid_left_hand_side_sentinel() {
1328 return &valid_left_hand_side_sentinel_;
1329 }
1330 Call* call_sentinel() { return &call_sentinel_; }
1331 EmptyStatement* empty_statement() { return &empty_statement_; }
1332
1333 private:
1334 AstSentinels();
1335 VariableProxySentinel this_proxy_;
1336 VariableProxySentinel identifier_proxy_;
1337 ValidLeftHandSideSentinel valid_left_hand_side_sentinel_;
1338 Property this_property_;
1339 Call call_sentinel_;
1340 EmptyStatement empty_statement_;
1341
1342 friend class Isolate;
1343
1344 DISALLOW_COPY_AND_ASSIGN(AstSentinels);
Steve Blocka7e24c12009-10-30 11:49:00 +00001345};
1346
1347
1348class CallNew: public Expression {
1349 public:
1350 CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1351 : expression_(expression), arguments_(arguments), pos_(pos) { }
1352
Ben Murdochf87a2032010-10-22 12:50:53 +01001353 DECLARE_NODE_TYPE(CallNew)
Steve Blocka7e24c12009-10-30 11:49:00 +00001354
Ben Murdochb0fe1622011-05-05 13:52:32 +01001355 virtual bool IsInlineable() const;
1356
Steve Blocka7e24c12009-10-30 11:49:00 +00001357 Expression* expression() const { return expression_; }
1358 ZoneList<Expression*>* arguments() const { return arguments_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001359 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001360
1361 private:
1362 Expression* expression_;
1363 ZoneList<Expression*>* arguments_;
1364 int pos_;
1365};
1366
1367
1368// The CallRuntime class does not represent any official JavaScript
1369// language construct. Instead it is used to call a C or JS function
1370// with a set of arguments. This is used from the builtins that are
1371// implemented in JavaScript (see "v8natives.js").
1372class CallRuntime: public Expression {
1373 public:
1374 CallRuntime(Handle<String> name,
Steve Block44f0eee2011-05-26 01:26:41 +01001375 const Runtime::Function* function,
Steve Blocka7e24c12009-10-30 11:49:00 +00001376 ZoneList<Expression*>* arguments)
1377 : name_(name), function_(function), arguments_(arguments) { }
1378
Ben Murdochf87a2032010-10-22 12:50:53 +01001379 DECLARE_NODE_TYPE(CallRuntime)
Steve Blocka7e24c12009-10-30 11:49:00 +00001380
Ben Murdochb0fe1622011-05-05 13:52:32 +01001381 virtual bool IsInlineable() const;
1382
Steve Blocka7e24c12009-10-30 11:49:00 +00001383 Handle<String> name() const { return name_; }
Steve Block44f0eee2011-05-26 01:26:41 +01001384 const Runtime::Function* function() const { return function_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001385 ZoneList<Expression*>* arguments() const { return arguments_; }
Steve Blockd0582a62009-12-15 09:54:21 +00001386 bool is_jsruntime() const { return function_ == NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001387
1388 private:
1389 Handle<String> name_;
Steve Block44f0eee2011-05-26 01:26:41 +01001390 const Runtime::Function* function_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001391 ZoneList<Expression*>* arguments_;
1392};
1393
1394
1395class UnaryOperation: public Expression {
1396 public:
Ben Murdoch257744e2011-11-30 15:57:28 +00001397 UnaryOperation(Token::Value op, Expression* expression, int pos)
1398 : op_(op), expression_(expression), pos_(pos) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001399 ASSERT(Token::IsUnaryOp(op));
1400 }
1401
Ben Murdochf87a2032010-10-22 12:50:53 +01001402 DECLARE_NODE_TYPE(UnaryOperation)
Steve Blocka7e24c12009-10-30 11:49:00 +00001403
Ben Murdochb0fe1622011-05-05 13:52:32 +01001404 virtual bool IsInlineable() const;
1405
Ben Murdochf87a2032010-10-22 12:50:53 +01001406 virtual bool ResultOverwriteAllowed();
Steve Blocka7e24c12009-10-30 11:49:00 +00001407
1408 Token::Value op() const { return op_; }
1409 Expression* expression() const { return expression_; }
Ben Murdoch257744e2011-11-30 15:57:28 +00001410 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001411
1412 private:
1413 Token::Value op_;
1414 Expression* expression_;
Ben Murdoch257744e2011-11-30 15:57:28 +00001415 int pos_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001416};
1417
1418
1419class BinaryOperation: public Expression {
1420 public:
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001421 BinaryOperation(Token::Value op,
1422 Expression* left,
1423 Expression* right,
1424 int pos)
Steve Block1e0659c2011-05-24 12:43:12 +01001425 : op_(op), left_(left), right_(right), pos_(pos) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001426 ASSERT(Token::IsBinaryOp(op));
Ben Murdochb0fe1622011-05-05 13:52:32 +01001427 right_id_ = (op == Token::AND || op == Token::OR)
Steve Block9fac8402011-05-12 15:51:54 +01001428 ? static_cast<int>(GetNextId())
Ben Murdochb0fe1622011-05-05 13:52:32 +01001429 : AstNode::kNoNumber;
Steve Blocka7e24c12009-10-30 11:49:00 +00001430 }
1431
Ben Murdochf87a2032010-10-22 12:50:53 +01001432 DECLARE_NODE_TYPE(BinaryOperation)
Steve Blocka7e24c12009-10-30 11:49:00 +00001433
Ben Murdochb0fe1622011-05-05 13:52:32 +01001434 virtual bool IsInlineable() const;
1435
Ben Murdochf87a2032010-10-22 12:50:53 +01001436 virtual bool ResultOverwriteAllowed();
Steve Blocka7e24c12009-10-30 11:49:00 +00001437
Steve Blocka7e24c12009-10-30 11:49:00 +00001438 Token::Value op() const { return op_; }
1439 Expression* left() const { return left_; }
1440 Expression* right() const { return right_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001441 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001442
Ben Murdochb0fe1622011-05-05 13:52:32 +01001443 // Bailout support.
1444 int RightId() const { return right_id_; }
1445
Steve Blocka7e24c12009-10-30 11:49:00 +00001446 private:
1447 Token::Value op_;
1448 Expression* left_;
1449 Expression* right_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001450 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001451 // The short-circuit logical operations have an AST ID for their
1452 // right-hand subexpression.
1453 int right_id_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001454};
1455
1456
Steve Blocka7e24c12009-10-30 11:49:00 +00001457class CountOperation: public Expression {
1458 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +01001459 CountOperation(Token::Value op, bool is_prefix, Expression* expr, int pos)
1460 : op_(op),
1461 is_prefix_(is_prefix),
1462 expression_(expr),
1463 pos_(pos),
1464 assignment_id_(GetNextId()),
1465 count_id_(GetNextId()) { }
Steve Block6ded16b2010-05-10 14:33:55 +01001466
Ben Murdochf87a2032010-10-22 12:50:53 +01001467 DECLARE_NODE_TYPE(CountOperation)
Steve Block6ded16b2010-05-10 14:33:55 +01001468
Steve Blocka7e24c12009-10-30 11:49:00 +00001469 bool is_prefix() const { return is_prefix_; }
1470 bool is_postfix() const { return !is_prefix_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001471
Ben Murdoch8b112d22011-06-08 16:22:53 +01001472 Token::Value op() const { return op_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001473 Token::Value binary_op() {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001474 return (op() == Token::INC) ? Token::ADD : Token::SUB;
Leon Clarkee46be812010-01-19 14:06:41 +00001475 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001476
Ben Murdoch8b112d22011-06-08 16:22:53 +01001477 Expression* expression() const { return expression_; }
1478 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001479
1480 virtual void MarkAsStatement() { is_prefix_ = true; }
1481
Ben Murdochb0fe1622011-05-05 13:52:32 +01001482 virtual bool IsInlineable() const;
1483
Ben Murdoch8b112d22011-06-08 16:22:53 +01001484 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1485 virtual bool IsMonomorphic() { return is_monomorphic_; }
1486 virtual Handle<Map> GetMonomorphicReceiverType() {
1487 return monomorphic_receiver_type_;
1488 }
1489
Ben Murdochb0fe1622011-05-05 13:52:32 +01001490 // Bailout support.
1491 int AssignmentId() const { return assignment_id_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001492 int CountId() const { return count_id_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001493
Steve Blocka7e24c12009-10-30 11:49:00 +00001494 private:
Ben Murdoch8b112d22011-06-08 16:22:53 +01001495 Token::Value op_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001496 bool is_prefix_;
Ben Murdoch8b112d22011-06-08 16:22:53 +01001497 bool is_monomorphic_;
1498 Expression* expression_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001499 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001500 int assignment_id_;
Ben Murdoch8b112d22011-06-08 16:22:53 +01001501 int count_id_;
1502 Handle<Map> monomorphic_receiver_type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001503};
1504
1505
1506class CompareOperation: public Expression {
1507 public:
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001508 CompareOperation(Token::Value op,
1509 Expression* left,
1510 Expression* right,
1511 int pos)
Ben Murdochb0fe1622011-05-05 13:52:32 +01001512 : op_(op), left_(left), right_(right), pos_(pos), compare_type_(NONE) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001513 ASSERT(Token::IsCompareOp(op));
1514 }
1515
Ben Murdochf87a2032010-10-22 12:50:53 +01001516 DECLARE_NODE_TYPE(CompareOperation)
Steve Blocka7e24c12009-10-30 11:49:00 +00001517
1518 Token::Value op() const { return op_; }
1519 Expression* left() const { return left_; }
1520 Expression* right() const { return right_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001521 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001522
Ben Murdochb0fe1622011-05-05 13:52:32 +01001523 virtual bool IsInlineable() const;
1524
1525 // Type feedback information.
1526 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1527 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
1528 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1529
Steve Blocka7e24c12009-10-30 11:49:00 +00001530 private:
1531 Token::Value op_;
1532 Expression* left_;
1533 Expression* right_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001534 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001535
1536 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
1537 CompareTypeFeedback compare_type_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001538};
1539
1540
1541class CompareToNull: public Expression {
1542 public:
1543 CompareToNull(bool is_strict, Expression* expression)
1544 : is_strict_(is_strict), expression_(expression) { }
1545
Ben Murdochf87a2032010-10-22 12:50:53 +01001546 DECLARE_NODE_TYPE(CompareToNull)
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001547
Ben Murdochb0fe1622011-05-05 13:52:32 +01001548 virtual bool IsInlineable() const;
1549
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001550 bool is_strict() const { return is_strict_; }
1551 Token::Value op() const { return is_strict_ ? Token::EQ_STRICT : Token::EQ; }
1552 Expression* expression() const { return expression_; }
1553
1554 private:
1555 bool is_strict_;
1556 Expression* expression_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001557};
1558
1559
1560class Conditional: public Expression {
1561 public:
1562 Conditional(Expression* condition,
1563 Expression* then_expression,
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001564 Expression* else_expression,
1565 int then_expression_position,
1566 int else_expression_position)
Steve Blocka7e24c12009-10-30 11:49:00 +00001567 : condition_(condition),
1568 then_expression_(then_expression),
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001569 else_expression_(else_expression),
1570 then_expression_position_(then_expression_position),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001571 else_expression_position_(else_expression_position),
1572 then_id_(GetNextId()),
1573 else_id_(GetNextId()) {
1574 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001575
Ben Murdochf87a2032010-10-22 12:50:53 +01001576 DECLARE_NODE_TYPE(Conditional)
Steve Blocka7e24c12009-10-30 11:49:00 +00001577
Ben Murdochb0fe1622011-05-05 13:52:32 +01001578 virtual bool IsInlineable() const;
1579
Steve Blocka7e24c12009-10-30 11:49:00 +00001580 Expression* condition() const { return condition_; }
1581 Expression* then_expression() const { return then_expression_; }
1582 Expression* else_expression() const { return else_expression_; }
1583
Ben Murdochb0fe1622011-05-05 13:52:32 +01001584 int then_expression_position() const { return then_expression_position_; }
1585 int else_expression_position() const { return else_expression_position_; }
1586
1587 int ThenId() const { return then_id_; }
1588 int ElseId() const { return else_id_; }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001589
Steve Blocka7e24c12009-10-30 11:49:00 +00001590 private:
1591 Expression* condition_;
1592 Expression* then_expression_;
1593 Expression* else_expression_;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001594 int then_expression_position_;
1595 int else_expression_position_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001596 int then_id_;
1597 int else_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001598};
1599
1600
1601class Assignment: public Expression {
1602 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +01001603 Assignment(Token::Value op, Expression* target, Expression* value, int pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00001604
Ben Murdochf87a2032010-10-22 12:50:53 +01001605 DECLARE_NODE_TYPE(Assignment)
Steve Blocka7e24c12009-10-30 11:49:00 +00001606
Ben Murdochb0fe1622011-05-05 13:52:32 +01001607 virtual bool IsInlineable() const;
1608
Steve Block6ded16b2010-05-10 14:33:55 +01001609 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1610
Steve Blocka7e24c12009-10-30 11:49:00 +00001611 Token::Value binary_op() const;
1612
1613 Token::Value op() const { return op_; }
1614 Expression* target() const { return target_; }
1615 Expression* value() const { return value_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001616 virtual int position() const { return pos_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001617 BinaryOperation* binary_operation() const { return binary_operation_; }
1618
Leon Clarkee46be812010-01-19 14:06:41 +00001619 // This check relies on the definition order of token in token.h.
1620 bool is_compound() const { return op() > Token::ASSIGN; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001621
1622 // An initialization block is a series of statments of the form
1623 // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1624 // ending of these blocks to allow for optimizations of initialization
1625 // blocks.
1626 bool starts_initialization_block() { return block_start_; }
1627 bool ends_initialization_block() { return block_end_; }
1628 void mark_block_start() { block_start_ = true; }
1629 void mark_block_end() { block_end_ = true; }
1630
Ben Murdochb0fe1622011-05-05 13:52:32 +01001631 // Type feedback information.
1632 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1633 virtual bool IsMonomorphic() { return is_monomorphic_; }
1634 virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
1635 virtual Handle<Map> GetMonomorphicReceiverType() {
1636 return monomorphic_receiver_type_;
1637 }
1638
1639 // Bailout support.
1640 int CompoundLoadId() const { return compound_load_id_; }
1641 int AssignmentId() const { return assignment_id_; }
1642
Steve Blocka7e24c12009-10-30 11:49:00 +00001643 private:
1644 Token::Value op_;
1645 Expression* target_;
1646 Expression* value_;
1647 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001648 BinaryOperation* binary_operation_;
1649 int compound_load_id_;
1650 int assignment_id_;
1651
Steve Blocka7e24c12009-10-30 11:49:00 +00001652 bool block_start_;
1653 bool block_end_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001654
1655 bool is_monomorphic_;
1656 ZoneMapList* receiver_types_;
1657 Handle<Map> monomorphic_receiver_type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001658};
1659
1660
1661class Throw: public Expression {
1662 public:
1663 Throw(Expression* exception, int pos)
1664 : exception_(exception), pos_(pos) {}
1665
Ben Murdochf87a2032010-10-22 12:50:53 +01001666 DECLARE_NODE_TYPE(Throw)
Steve Block6ded16b2010-05-10 14:33:55 +01001667
Steve Blocka7e24c12009-10-30 11:49:00 +00001668 Expression* exception() const { return exception_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001669 virtual int position() const { return pos_; }
1670 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001671
1672 private:
1673 Expression* exception_;
1674 int pos_;
1675};
1676
1677
1678class FunctionLiteral: public Expression {
1679 public:
1680 FunctionLiteral(Handle<String> name,
1681 Scope* scope,
1682 ZoneList<Statement*>* body,
1683 int materialized_literal_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00001684 int expected_property_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00001685 bool has_only_simple_this_property_assignments,
1686 Handle<FixedArray> this_property_assignments,
1687 int num_parameters,
1688 int start_position,
1689 int end_position,
Ben Murdoch8b112d22011-06-08 16:22:53 +01001690 bool is_expression)
Steve Blocka7e24c12009-10-30 11:49:00 +00001691 : name_(name),
1692 scope_(scope),
1693 body_(body),
1694 materialized_literal_count_(materialized_literal_count),
Steve Blocka7e24c12009-10-30 11:49:00 +00001695 expected_property_count_(expected_property_count),
Steve Blocka7e24c12009-10-30 11:49:00 +00001696 has_only_simple_this_property_assignments_(
1697 has_only_simple_this_property_assignments),
1698 this_property_assignments_(this_property_assignments),
1699 num_parameters_(num_parameters),
1700 start_position_(start_position),
1701 end_position_(end_position),
1702 is_expression_(is_expression),
Steve Blocka7e24c12009-10-30 11:49:00 +00001703 function_token_position_(RelocInfo::kNoPosition),
Steve Block44f0eee2011-05-26 01:26:41 +01001704 inferred_name_(HEAP->empty_string()),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001705 pretenure_(false) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001706
Ben Murdochf87a2032010-10-22 12:50:53 +01001707 DECLARE_NODE_TYPE(FunctionLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00001708
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001709 Handle<String> name() const { return name_; }
1710 Scope* scope() const { return scope_; }
1711 ZoneList<Statement*>* body() const { return body_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001712 void set_function_token_position(int pos) { function_token_position_ = pos; }
1713 int function_token_position() const { return function_token_position_; }
1714 int start_position() const { return start_position_; }
1715 int end_position() const { return end_position_; }
1716 bool is_expression() const { return is_expression_; }
Steve Block44f0eee2011-05-26 01:26:41 +01001717 bool strict_mode() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001718
1719 int materialized_literal_count() { return materialized_literal_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001720 int expected_property_count() { return expected_property_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001721 bool has_only_simple_this_property_assignments() {
1722 return has_only_simple_this_property_assignments_;
1723 }
1724 Handle<FixedArray> this_property_assignments() {
1725 return this_property_assignments_;
1726 }
1727 int num_parameters() { return num_parameters_; }
1728
1729 bool AllowsLazyCompilation();
1730
Ben Murdochf87a2032010-10-22 12:50:53 +01001731 Handle<String> debug_name() const {
1732 if (name_->length() > 0) return name_;
1733 return inferred_name();
1734 }
1735
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001736 Handle<String> inferred_name() const { return inferred_name_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001737 void set_inferred_name(Handle<String> inferred_name) {
1738 inferred_name_ = inferred_name;
1739 }
1740
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08001741 bool pretenure() { return pretenure_; }
1742 void set_pretenure(bool value) { pretenure_ = value; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001743 virtual bool IsInlineable() const;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08001744
Steve Blocka7e24c12009-10-30 11:49:00 +00001745 private:
1746 Handle<String> name_;
1747 Scope* scope_;
1748 ZoneList<Statement*>* body_;
1749 int materialized_literal_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001750 int expected_property_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001751 bool has_only_simple_this_property_assignments_;
1752 Handle<FixedArray> this_property_assignments_;
1753 int num_parameters_;
1754 int start_position_;
1755 int end_position_;
1756 bool is_expression_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001757 int function_token_position_;
1758 Handle<String> inferred_name_;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08001759 bool pretenure_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001760};
1761
1762
Steve Block6ded16b2010-05-10 14:33:55 +01001763class SharedFunctionInfoLiteral: public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00001764 public:
Steve Block6ded16b2010-05-10 14:33:55 +01001765 explicit SharedFunctionInfoLiteral(
1766 Handle<SharedFunctionInfo> shared_function_info)
1767 : shared_function_info_(shared_function_info) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001768
Ben Murdochf87a2032010-10-22 12:50:53 +01001769 DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
1770
Steve Block6ded16b2010-05-10 14:33:55 +01001771 Handle<SharedFunctionInfo> shared_function_info() const {
1772 return shared_function_info_;
1773 }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001774 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001775
Steve Blocka7e24c12009-10-30 11:49:00 +00001776 private:
Steve Block6ded16b2010-05-10 14:33:55 +01001777 Handle<SharedFunctionInfo> shared_function_info_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001778};
1779
1780
1781class ThisFunction: public Expression {
1782 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001783 DECLARE_NODE_TYPE(ThisFunction)
Ben Murdoch8b112d22011-06-08 16:22:53 +01001784 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001785};
1786
1787
1788// ----------------------------------------------------------------------------
1789// Regular expressions
1790
1791
1792class RegExpVisitor BASE_EMBEDDED {
1793 public:
1794 virtual ~RegExpVisitor() { }
1795#define MAKE_CASE(Name) \
1796 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
1797 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
1798#undef MAKE_CASE
1799};
1800
1801
1802class RegExpTree: public ZoneObject {
1803 public:
1804 static const int kInfinity = kMaxInt;
1805 virtual ~RegExpTree() { }
1806 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
1807 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1808 RegExpNode* on_success) = 0;
1809 virtual bool IsTextElement() { return false; }
Ben Murdochf87a2032010-10-22 12:50:53 +01001810 virtual bool IsAnchoredAtStart() { return false; }
1811 virtual bool IsAnchoredAtEnd() { return false; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001812 virtual int min_match() = 0;
1813 virtual int max_match() = 0;
1814 // Returns the interval of registers used for captures within this
1815 // expression.
1816 virtual Interval CaptureRegisters() { return Interval::Empty(); }
1817 virtual void AppendToText(RegExpText* text);
1818 SmartPointer<const char> ToString();
1819#define MAKE_ASTYPE(Name) \
1820 virtual RegExp##Name* As##Name(); \
1821 virtual bool Is##Name();
1822 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
1823#undef MAKE_ASTYPE
1824};
1825
1826
1827class RegExpDisjunction: public RegExpTree {
1828 public:
1829 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
1830 virtual void* Accept(RegExpVisitor* visitor, void* data);
1831 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1832 RegExpNode* on_success);
1833 virtual RegExpDisjunction* AsDisjunction();
1834 virtual Interval CaptureRegisters();
1835 virtual bool IsDisjunction();
Ben Murdochf87a2032010-10-22 12:50:53 +01001836 virtual bool IsAnchoredAtStart();
1837 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001838 virtual int min_match() { return min_match_; }
1839 virtual int max_match() { return max_match_; }
1840 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
1841 private:
1842 ZoneList<RegExpTree*>* alternatives_;
1843 int min_match_;
1844 int max_match_;
1845};
1846
1847
1848class RegExpAlternative: public RegExpTree {
1849 public:
1850 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
1851 virtual void* Accept(RegExpVisitor* visitor, void* data);
1852 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1853 RegExpNode* on_success);
1854 virtual RegExpAlternative* AsAlternative();
1855 virtual Interval CaptureRegisters();
1856 virtual bool IsAlternative();
Ben Murdochf87a2032010-10-22 12:50:53 +01001857 virtual bool IsAnchoredAtStart();
1858 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001859 virtual int min_match() { return min_match_; }
1860 virtual int max_match() { return max_match_; }
1861 ZoneList<RegExpTree*>* nodes() { return nodes_; }
1862 private:
1863 ZoneList<RegExpTree*>* nodes_;
1864 int min_match_;
1865 int max_match_;
1866};
1867
1868
1869class RegExpAssertion: public RegExpTree {
1870 public:
1871 enum Type {
1872 START_OF_LINE,
1873 START_OF_INPUT,
1874 END_OF_LINE,
1875 END_OF_INPUT,
1876 BOUNDARY,
1877 NON_BOUNDARY
1878 };
1879 explicit RegExpAssertion(Type type) : type_(type) { }
1880 virtual void* Accept(RegExpVisitor* visitor, void* data);
1881 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1882 RegExpNode* on_success);
1883 virtual RegExpAssertion* AsAssertion();
1884 virtual bool IsAssertion();
Ben Murdochf87a2032010-10-22 12:50:53 +01001885 virtual bool IsAnchoredAtStart();
1886 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001887 virtual int min_match() { return 0; }
1888 virtual int max_match() { return 0; }
1889 Type type() { return type_; }
1890 private:
1891 Type type_;
1892};
1893
1894
1895class CharacterSet BASE_EMBEDDED {
1896 public:
1897 explicit CharacterSet(uc16 standard_set_type)
1898 : ranges_(NULL),
1899 standard_set_type_(standard_set_type) {}
1900 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
1901 : ranges_(ranges),
1902 standard_set_type_(0) {}
1903 ZoneList<CharacterRange>* ranges();
1904 uc16 standard_set_type() { return standard_set_type_; }
1905 void set_standard_set_type(uc16 special_set_type) {
1906 standard_set_type_ = special_set_type;
1907 }
1908 bool is_standard() { return standard_set_type_ != 0; }
Leon Clarkee46be812010-01-19 14:06:41 +00001909 void Canonicalize();
Steve Blocka7e24c12009-10-30 11:49:00 +00001910 private:
1911 ZoneList<CharacterRange>* ranges_;
1912 // If non-zero, the value represents a standard set (e.g., all whitespace
1913 // characters) without having to expand the ranges.
1914 uc16 standard_set_type_;
1915};
1916
1917
1918class RegExpCharacterClass: public RegExpTree {
1919 public:
1920 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
1921 : set_(ranges),
1922 is_negated_(is_negated) { }
1923 explicit RegExpCharacterClass(uc16 type)
1924 : set_(type),
1925 is_negated_(false) { }
1926 virtual void* Accept(RegExpVisitor* visitor, void* data);
1927 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1928 RegExpNode* on_success);
1929 virtual RegExpCharacterClass* AsCharacterClass();
1930 virtual bool IsCharacterClass();
1931 virtual bool IsTextElement() { return true; }
1932 virtual int min_match() { return 1; }
1933 virtual int max_match() { return 1; }
1934 virtual void AppendToText(RegExpText* text);
1935 CharacterSet character_set() { return set_; }
1936 // TODO(lrn): Remove need for complex version if is_standard that
1937 // recognizes a mangled standard set and just do { return set_.is_special(); }
1938 bool is_standard();
1939 // Returns a value representing the standard character set if is_standard()
1940 // returns true.
1941 // Currently used values are:
1942 // s : unicode whitespace
1943 // S : unicode non-whitespace
1944 // w : ASCII word character (digit, letter, underscore)
1945 // W : non-ASCII word character
1946 // d : ASCII digit
1947 // D : non-ASCII digit
1948 // . : non-unicode non-newline
1949 // * : All characters
1950 uc16 standard_type() { return set_.standard_set_type(); }
1951 ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
1952 bool is_negated() { return is_negated_; }
1953 private:
1954 CharacterSet set_;
1955 bool is_negated_;
1956};
1957
1958
1959class RegExpAtom: public RegExpTree {
1960 public:
1961 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
1962 virtual void* Accept(RegExpVisitor* visitor, void* data);
1963 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1964 RegExpNode* on_success);
1965 virtual RegExpAtom* AsAtom();
1966 virtual bool IsAtom();
1967 virtual bool IsTextElement() { return true; }
1968 virtual int min_match() { return data_.length(); }
1969 virtual int max_match() { return data_.length(); }
1970 virtual void AppendToText(RegExpText* text);
1971 Vector<const uc16> data() { return data_; }
1972 int length() { return data_.length(); }
1973 private:
1974 Vector<const uc16> data_;
1975};
1976
1977
1978class RegExpText: public RegExpTree {
1979 public:
1980 RegExpText() : elements_(2), length_(0) {}
1981 virtual void* Accept(RegExpVisitor* visitor, void* data);
1982 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1983 RegExpNode* on_success);
1984 virtual RegExpText* AsText();
1985 virtual bool IsText();
1986 virtual bool IsTextElement() { return true; }
1987 virtual int min_match() { return length_; }
1988 virtual int max_match() { return length_; }
1989 virtual void AppendToText(RegExpText* text);
1990 void AddElement(TextElement elm) {
1991 elements_.Add(elm);
1992 length_ += elm.length();
Iain Merrick9ac36c92010-09-13 15:29:50 +01001993 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001994 ZoneList<TextElement>* elements() { return &elements_; }
1995 private:
1996 ZoneList<TextElement> elements_;
1997 int length_;
1998};
1999
2000
2001class RegExpQuantifier: public RegExpTree {
2002 public:
Leon Clarkee46be812010-01-19 14:06:41 +00002003 enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
2004 RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
2005 : body_(body),
2006 min_(min),
Steve Blocka7e24c12009-10-30 11:49:00 +00002007 max_(max),
Leon Clarkee46be812010-01-19 14:06:41 +00002008 min_match_(min * body->min_match()),
2009 type_(type) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002010 if (max > 0 && body->max_match() > kInfinity / max) {
2011 max_match_ = kInfinity;
2012 } else {
2013 max_match_ = max * body->max_match();
2014 }
2015 }
2016 virtual void* Accept(RegExpVisitor* visitor, void* data);
2017 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2018 RegExpNode* on_success);
2019 static RegExpNode* ToNode(int min,
2020 int max,
2021 bool is_greedy,
2022 RegExpTree* body,
2023 RegExpCompiler* compiler,
2024 RegExpNode* on_success,
2025 bool not_at_start = false);
2026 virtual RegExpQuantifier* AsQuantifier();
2027 virtual Interval CaptureRegisters();
2028 virtual bool IsQuantifier();
2029 virtual int min_match() { return min_match_; }
2030 virtual int max_match() { return max_match_; }
2031 int min() { return min_; }
2032 int max() { return max_; }
Leon Clarkee46be812010-01-19 14:06:41 +00002033 bool is_possessive() { return type_ == POSSESSIVE; }
2034 bool is_non_greedy() { return type_ == NON_GREEDY; }
2035 bool is_greedy() { return type_ == GREEDY; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002036 RegExpTree* body() { return body_; }
2037 private:
Leon Clarkee46be812010-01-19 14:06:41 +00002038 RegExpTree* body_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002039 int min_;
2040 int max_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002041 int min_match_;
2042 int max_match_;
Leon Clarkee46be812010-01-19 14:06:41 +00002043 Type type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002044};
2045
2046
2047class RegExpCapture: public RegExpTree {
2048 public:
2049 explicit RegExpCapture(RegExpTree* body, int index)
2050 : body_(body), index_(index) { }
2051 virtual void* Accept(RegExpVisitor* visitor, void* data);
2052 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2053 RegExpNode* on_success);
2054 static RegExpNode* ToNode(RegExpTree* body,
2055 int index,
2056 RegExpCompiler* compiler,
2057 RegExpNode* on_success);
2058 virtual RegExpCapture* AsCapture();
Ben Murdochf87a2032010-10-22 12:50:53 +01002059 virtual bool IsAnchoredAtStart();
2060 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00002061 virtual Interval CaptureRegisters();
2062 virtual bool IsCapture();
2063 virtual int min_match() { return body_->min_match(); }
2064 virtual int max_match() { return body_->max_match(); }
2065 RegExpTree* body() { return body_; }
2066 int index() { return index_; }
2067 static int StartRegister(int index) { return index * 2; }
2068 static int EndRegister(int index) { return index * 2 + 1; }
2069 private:
2070 RegExpTree* body_;
2071 int index_;
2072};
2073
2074
2075class RegExpLookahead: public RegExpTree {
2076 public:
2077 RegExpLookahead(RegExpTree* body,
2078 bool is_positive,
2079 int capture_count,
2080 int capture_from)
2081 : body_(body),
2082 is_positive_(is_positive),
2083 capture_count_(capture_count),
2084 capture_from_(capture_from) { }
2085
2086 virtual void* Accept(RegExpVisitor* visitor, void* data);
2087 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2088 RegExpNode* on_success);
2089 virtual RegExpLookahead* AsLookahead();
2090 virtual Interval CaptureRegisters();
2091 virtual bool IsLookahead();
Ben Murdochf87a2032010-10-22 12:50:53 +01002092 virtual bool IsAnchoredAtStart();
Steve Blocka7e24c12009-10-30 11:49:00 +00002093 virtual int min_match() { return 0; }
2094 virtual int max_match() { return 0; }
2095 RegExpTree* body() { return body_; }
2096 bool is_positive() { return is_positive_; }
2097 int capture_count() { return capture_count_; }
2098 int capture_from() { return capture_from_; }
2099 private:
2100 RegExpTree* body_;
2101 bool is_positive_;
2102 int capture_count_;
2103 int capture_from_;
2104};
2105
2106
2107class RegExpBackReference: public RegExpTree {
2108 public:
2109 explicit RegExpBackReference(RegExpCapture* capture)
2110 : capture_(capture) { }
2111 virtual void* Accept(RegExpVisitor* visitor, void* data);
2112 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2113 RegExpNode* on_success);
2114 virtual RegExpBackReference* AsBackReference();
2115 virtual bool IsBackReference();
2116 virtual int min_match() { return 0; }
2117 virtual int max_match() { return capture_->max_match(); }
2118 int index() { return capture_->index(); }
2119 RegExpCapture* capture() { return capture_; }
2120 private:
2121 RegExpCapture* capture_;
2122};
2123
2124
2125class RegExpEmpty: public RegExpTree {
2126 public:
2127 RegExpEmpty() { }
2128 virtual void* Accept(RegExpVisitor* visitor, void* data);
2129 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2130 RegExpNode* on_success);
2131 virtual RegExpEmpty* AsEmpty();
2132 virtual bool IsEmpty();
2133 virtual int min_match() { return 0; }
2134 virtual int max_match() { return 0; }
2135 static RegExpEmpty* GetInstance() { return &kInstance; }
2136 private:
2137 static RegExpEmpty kInstance;
2138};
2139
2140
2141// ----------------------------------------------------------------------------
2142// Basic visitor
2143// - leaf node visitors are abstract.
2144
2145class AstVisitor BASE_EMBEDDED {
2146 public:
Steve Block44f0eee2011-05-26 01:26:41 +01002147 AstVisitor() : isolate_(Isolate::Current()), stack_overflow_(false) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00002148 virtual ~AstVisitor() { }
2149
Steve Block6ded16b2010-05-10 14:33:55 +01002150 // Stack overflow check and dynamic dispatch.
2151 void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
Steve Blocka7e24c12009-10-30 11:49:00 +00002152
Steve Block6ded16b2010-05-10 14:33:55 +01002153 // Iteration left-to-right.
Steve Block3ce2e202009-11-05 08:53:23 +00002154 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
Steve Blocka7e24c12009-10-30 11:49:00 +00002155 virtual void VisitStatements(ZoneList<Statement*>* statements);
2156 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
2157
2158 // Stack overflow tracking support.
2159 bool HasStackOverflow() const { return stack_overflow_; }
Steve Block6ded16b2010-05-10 14:33:55 +01002160 bool CheckStackOverflow();
Steve Blocka7e24c12009-10-30 11:49:00 +00002161
2162 // If a stack-overflow exception is encountered when visiting a
2163 // node, calling SetStackOverflow will make sure that the visitor
2164 // bails out without visiting more nodes.
2165 void SetStackOverflow() { stack_overflow_ = true; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01002166 void ClearStackOverflow() { stack_overflow_ = false; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002167
Ben Murdochb0fe1622011-05-05 13:52:32 +01002168 // Nodes not appearing in the AST, including slots.
2169 virtual void VisitSlot(Slot* node) { UNREACHABLE(); }
2170
2171 // Individual AST nodes.
Steve Blocka7e24c12009-10-30 11:49:00 +00002172#define DEF_VISIT(type) \
2173 virtual void Visit##type(type* node) = 0;
2174 AST_NODE_LIST(DEF_VISIT)
2175#undef DEF_VISIT
2176
Steve Block44f0eee2011-05-26 01:26:41 +01002177 protected:
2178 Isolate* isolate() { return isolate_; }
2179
Steve Blocka7e24c12009-10-30 11:49:00 +00002180 private:
Steve Block44f0eee2011-05-26 01:26:41 +01002181 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002182 bool stack_overflow_;
2183};
2184
Steve Block44f0eee2011-05-26 01:26:41 +01002185
Steve Blocka7e24c12009-10-30 11:49:00 +00002186} } // namespace v8::internal
2187
2188#endif // V8_AST_H_