blob: 0846dbc537fb1280b66c8c95e80287c1296a7aec [file] [log] [blame]
Andrei Popescu402d9372010-02-26 13:31:12 +00001// Copyright 2010 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
31#include "execution.h"
32#include "factory.h"
Steve Block3ce2e202009-11-05 08:53:23 +000033#include "jsregexp.h"
34#include "jump-target.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) \
78 V(Slot) \
79 V(VariableProxy) \
80 V(Literal) \
81 V(RegExpLiteral) \
82 V(ObjectLiteral) \
83 V(ArrayLiteral) \
84 V(CatchExtensionObject) \
85 V(Assignment) \
86 V(Throw) \
87 V(Property) \
88 V(Call) \
89 V(CallNew) \
90 V(CallRuntime) \
91 V(UnaryOperation) \
Kristian Monsen80d68ea2010-09-08 11:05:35 +010092 V(IncrementOperation) \
Steve Blocka7e24c12009-10-30 11:49:00 +000093 V(CountOperation) \
94 V(BinaryOperation) \
95 V(CompareOperation) \
Kristian Monsen80d68ea2010-09-08 11:05:35 +010096 V(CompareToNull) \
Steve Blocka7e24c12009-10-30 11:49:00 +000097 V(ThisFunction)
98
99#define AST_NODE_LIST(V) \
100 V(Declaration) \
101 STATEMENT_NODE_LIST(V) \
102 EXPRESSION_NODE_LIST(V)
103
104// Forward declarations
105class TargetCollector;
106class MaterializedLiteral;
Andrei Popescu402d9372010-02-26 13:31:12 +0000107class DefinitionInfo;
Steve Block6ded16b2010-05-10 14:33:55 +0100108class BitVector;
Steve Blocka7e24c12009-10-30 11:49:00 +0000109
110#define DEF_FORWARD_DECLARATION(type) class type;
111AST_NODE_LIST(DEF_FORWARD_DECLARATION)
112#undef DEF_FORWARD_DECLARATION
113
114
115// Typedef only introduced to avoid unreadable code.
116// Please do appreciate the required space in "> >".
117typedef ZoneList<Handle<String> > ZoneStringList;
118typedef ZoneList<Handle<Object> > ZoneObjectList;
119
120
Ben Murdochf87a2032010-10-22 12:50:53 +0100121#define DECLARE_NODE_TYPE(type) \
122 virtual void Accept(AstVisitor* v); \
123 virtual AstNode::Type node_type() const { return AstNode::k##type; } \
124 virtual type* As##type() { return this; }
125
126
Steve Blocka7e24c12009-10-30 11:49:00 +0000127class AstNode: public ZoneObject {
128 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100129#define DECLARE_TYPE_ENUM(type) k##type,
130 enum Type {
131 AST_NODE_LIST(DECLARE_TYPE_ENUM)
132 kInvalid = -1
133 };
134#undef DECLARE_TYPE_ENUM
Steve Blocka7e24c12009-10-30 11:49:00 +0000135
Ben Murdochf87a2032010-10-22 12:50:53 +0100136 virtual ~AstNode() { }
137
138 virtual void Accept(AstVisitor* v) = 0;
139 virtual Type node_type() const { return kInvalid; }
140
141 // Type testing & conversion functions overridden by concrete subclasses.
142#define DECLARE_NODE_FUNCTIONS(type) \
143 virtual type* As##type() { return NULL; }
144 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
145#undef DECLARE_NODE_FUNCTIONS
146
Steve Blocka7e24c12009-10-30 11:49:00 +0000147 virtual Statement* AsStatement() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000148 virtual Expression* AsExpression() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000149 virtual TargetCollector* AsTargetCollector() { return NULL; }
150 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
151 virtual IterationStatement* AsIterationStatement() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000152 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000153};
154
155
156class Statement: public AstNode {
157 public:
158 Statement() : statement_pos_(RelocInfo::kNoPosition) {}
159
160 virtual Statement* AsStatement() { return this; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000161
Steve Block6ded16b2010-05-10 14:33:55 +0100162 virtual Assignment* StatementAsSimpleAssignment() { return NULL; }
163 virtual CountOperation* StatementAsCountOperation() { return NULL; }
164
Steve Blocka7e24c12009-10-30 11:49:00 +0000165 bool IsEmpty() { return AsEmptyStatement() != NULL; }
166
167 void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
168 int statement_pos() const { return statement_pos_; }
169
170 private:
171 int statement_pos_;
172};
173
174
175class Expression: public AstNode {
176 public:
Steve Block6ded16b2010-05-10 14:33:55 +0100177 Expression() : bitfields_(0) {}
Leon Clarke4515c472010-02-03 11:58:03 +0000178
Steve Blocka7e24c12009-10-30 11:49:00 +0000179 virtual Expression* AsExpression() { return this; }
180
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100181 virtual bool IsTrivial() { return false; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000182 virtual bool IsValidLeftHandSide() { return false; }
183
Leon Clarkee46be812010-01-19 14:06:41 +0000184 // Symbols that cannot be parsed as array indices are considered property
185 // names. We do not treat symbols that can be array indexes as property
186 // names because [] for string objects is handled only by keyed ICs.
187 virtual bool IsPropertyName() { return false; }
188
Steve Blocka7e24c12009-10-30 11:49:00 +0000189 // Mark the expression as being compiled as an expression
190 // statement. This is used to transform postfix increments to
191 // (faster) prefix increments.
192 virtual void MarkAsStatement() { /* do nothing */ }
193
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100194 // True iff the result can be safely overwritten (to avoid allocation).
195 // False for operations that can return one of their operands.
196 virtual bool ResultOverwriteAllowed() { return false; }
197
198 // True iff the expression is a literal represented as a smi.
199 virtual bool IsSmiLiteral() { return false; }
200
Steve Blocka7e24c12009-10-30 11:49:00 +0000201 // Static type information for this expression.
Leon Clarkee46be812010-01-19 14:06:41 +0000202 StaticType* type() { return &type_; }
Steve Block3ce2e202009-11-05 08:53:23 +0000203
Steve Block6ded16b2010-05-10 14:33:55 +0100204 // True if the expression is a loop condition.
205 bool is_loop_condition() const {
206 return LoopConditionField::decode(bitfields_);
207 }
208 void set_is_loop_condition(bool flag) {
209 bitfields_ = (bitfields_ & ~LoopConditionField::mask()) |
210 LoopConditionField::encode(flag);
211 }
Leon Clarke4515c472010-02-03 11:58:03 +0000212
Steve Block6ded16b2010-05-10 14:33:55 +0100213 // The value of the expression is guaranteed to be a smi, because the
214 // top operation is a bit operation with a mask, or a shift.
215 bool GuaranteedSmiResult();
Leon Clarke4515c472010-02-03 11:58:03 +0000216
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100217 // AST analysis results.
218 void CopyAnalysisResultsFrom(Expression* other);
Andrei Popescu402d9372010-02-26 13:31:12 +0000219
Steve Block6ded16b2010-05-10 14:33:55 +0100220 // True if the expression rooted at this node can be compiled by the
221 // side-effect free compiler.
222 bool side_effect_free() { return SideEffectFreeField::decode(bitfields_); }
223 void set_side_effect_free(bool is_side_effect_free) {
224 bitfields_ &= ~SideEffectFreeField::mask();
225 bitfields_ |= SideEffectFreeField::encode(is_side_effect_free);
226 }
227
228 // Will the use of this expression treat -0 the same as 0 in all cases?
229 // If so, we can return 0 instead of -0 if we want to, to optimize code.
230 bool no_negative_zero() { return NoNegativeZeroField::decode(bitfields_); }
231 void set_no_negative_zero(bool no_negative_zero) {
232 bitfields_ &= ~NoNegativeZeroField::mask();
233 bitfields_ |= NoNegativeZeroField::encode(no_negative_zero);
234 }
235
236 // Will ToInt32 (ECMA 262-3 9.5) or ToUint32 (ECMA 262-3 9.6)
237 // be applied to the value of this expression?
238 // If so, we may be able to optimize the calculation of the value.
239 bool to_int32() { return ToInt32Field::decode(bitfields_); }
240 void set_to_int32(bool to_int32) {
241 bitfields_ &= ~ToInt32Field::mask();
242 bitfields_ |= ToInt32Field::encode(to_int32);
243 }
244
245 // How many bitwise logical or shift operators are used in this expression?
246 int num_bit_ops() { return NumBitOpsField::decode(bitfields_); }
247 void set_num_bit_ops(int num_bit_ops) {
248 bitfields_ &= ~NumBitOpsField::mask();
249 num_bit_ops = Min(num_bit_ops, kMaxNumBitOps);
250 bitfields_ |= NumBitOpsField::encode(num_bit_ops);
Andrei Popescu402d9372010-02-26 13:31:12 +0000251 }
252
Steve Blocka7e24c12009-10-30 11:49:00 +0000253 private:
Steve Block6ded16b2010-05-10 14:33:55 +0100254 static const int kMaxNumBitOps = (1 << 5) - 1;
255
256 uint32_t bitfields_;
Leon Clarkee46be812010-01-19 14:06:41 +0000257 StaticType type_;
Steve Block6ded16b2010-05-10 14:33:55 +0100258
259 // Using template BitField<type, start, size>.
260 class SideEffectFreeField : public BitField<bool, 0, 1> {};
261 class NoNegativeZeroField : public BitField<bool, 1, 1> {};
262 class ToInt32Field : public BitField<bool, 2, 1> {};
263 class NumBitOpsField : public BitField<int, 3, 5> {};
264 class LoopConditionField: public BitField<bool, 8, 1> {};
Steve Blocka7e24c12009-10-30 11:49:00 +0000265};
266
267
268/**
269 * A sentinel used during pre parsing that represents some expression
270 * that is a valid left hand side without having to actually build
271 * the expression.
272 */
273class ValidLeftHandSideSentinel: public Expression {
274 public:
275 virtual bool IsValidLeftHandSide() { return true; }
276 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
277 static ValidLeftHandSideSentinel* instance() { return &instance_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100278
Steve Blocka7e24c12009-10-30 11:49:00 +0000279 private:
280 static ValidLeftHandSideSentinel instance_;
281};
282
283
284class BreakableStatement: public Statement {
285 public:
286 enum Type {
287 TARGET_FOR_ANONYMOUS,
288 TARGET_FOR_NAMED_ONLY
289 };
290
291 // The labels associated with this statement. May be NULL;
292 // if it is != NULL, guaranteed to contain at least one entry.
293 ZoneStringList* labels() const { return labels_; }
294
295 // Type testing & conversion.
296 virtual BreakableStatement* AsBreakableStatement() { return this; }
297
298 // Code generation
299 BreakTarget* break_target() { return &break_target_; }
300
301 // Testers.
302 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
303
304 protected:
Kristian Monsen25f61362010-05-21 11:50:48 +0100305 inline BreakableStatement(ZoneStringList* labels, Type type);
Steve Blocka7e24c12009-10-30 11:49:00 +0000306
307 private:
308 ZoneStringList* labels_;
309 Type type_;
310 BreakTarget break_target_;
311};
312
313
314class Block: public BreakableStatement {
315 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100316 inline Block(ZoneStringList* labels, int capacity, bool is_initializer_block);
Steve Blocka7e24c12009-10-30 11:49:00 +0000317
Ben Murdochf87a2032010-10-22 12:50:53 +0100318 DECLARE_NODE_TYPE(Block)
Steve Block6ded16b2010-05-10 14:33:55 +0100319
320 virtual Assignment* StatementAsSimpleAssignment() {
321 if (statements_.length() != 1) return NULL;
322 return statements_[0]->StatementAsSimpleAssignment();
323 }
324
325 virtual CountOperation* StatementAsCountOperation() {
326 if (statements_.length() != 1) return NULL;
327 return statements_[0]->StatementAsCountOperation();
328 }
329
Steve Blocka7e24c12009-10-30 11:49:00 +0000330 void AddStatement(Statement* statement) { statements_.Add(statement); }
331
332 ZoneList<Statement*>* statements() { return &statements_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100333 bool is_initializer_block() const { return is_initializer_block_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000334
335 private:
336 ZoneList<Statement*> statements_;
337 bool is_initializer_block_;
338};
339
340
341class Declaration: public AstNode {
342 public:
343 Declaration(VariableProxy* proxy, Variable::Mode mode, FunctionLiteral* fun)
344 : proxy_(proxy),
345 mode_(mode),
346 fun_(fun) {
347 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
348 // At the moment there are no "const functions"'s in JavaScript...
349 ASSERT(fun == NULL || mode == Variable::VAR);
350 }
351
Ben Murdochf87a2032010-10-22 12:50:53 +0100352 DECLARE_NODE_TYPE(Declaration)
Steve Blocka7e24c12009-10-30 11:49:00 +0000353
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100354 VariableProxy* proxy() const { return proxy_; }
355 Variable::Mode mode() const { return mode_; }
356 FunctionLiteral* fun() const { return fun_; } // may be NULL
Steve Blocka7e24c12009-10-30 11:49:00 +0000357
358 private:
359 VariableProxy* proxy_;
360 Variable::Mode mode_;
361 FunctionLiteral* fun_;
362};
363
364
365class IterationStatement: public BreakableStatement {
366 public:
367 // Type testing & conversion.
368 virtual IterationStatement* AsIterationStatement() { return this; }
369
370 Statement* body() const { return body_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100371 void set_body(Statement* stmt) { body_ = stmt; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000372
373 // Code generation
374 BreakTarget* continue_target() { return &continue_target_; }
375
376 protected:
Kristian Monsen25f61362010-05-21 11:50:48 +0100377 explicit inline IterationStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000378
379 void Initialize(Statement* body) {
380 body_ = body;
381 }
382
383 private:
384 Statement* body_;
385 BreakTarget continue_target_;
386};
387
388
Steve Block3ce2e202009-11-05 08:53:23 +0000389class DoWhileStatement: public IterationStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000390 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100391 explicit inline DoWhileStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000392
Ben Murdochf87a2032010-10-22 12:50:53 +0100393 DECLARE_NODE_TYPE(DoWhileStatement)
394
Steve Block3ce2e202009-11-05 08:53:23 +0000395 void Initialize(Expression* cond, Statement* body) {
396 IterationStatement::Initialize(body);
397 cond_ = cond;
398 }
399
Steve Block3ce2e202009-11-05 08:53:23 +0000400 Expression* cond() const { return cond_; }
401
Steve Blockd0582a62009-12-15 09:54:21 +0000402 // Position where condition expression starts. We need it to make
403 // the loop's condition a breakable location.
404 int condition_position() { return condition_position_; }
405 void set_condition_position(int pos) { condition_position_ = pos; }
406
Steve Block3ce2e202009-11-05 08:53:23 +0000407 private:
408 Expression* cond_;
Steve Blockd0582a62009-12-15 09:54:21 +0000409 int condition_position_;
Steve Block3ce2e202009-11-05 08:53:23 +0000410};
411
412
413class WhileStatement: public IterationStatement {
414 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100415 explicit WhileStatement(ZoneStringList* labels);
Steve Block3ce2e202009-11-05 08:53:23 +0000416
Ben Murdochf87a2032010-10-22 12:50:53 +0100417 DECLARE_NODE_TYPE(WhileStatement)
418
Steve Block3ce2e202009-11-05 08:53:23 +0000419 void Initialize(Expression* cond, Statement* body) {
420 IterationStatement::Initialize(body);
421 cond_ = cond;
422 }
423
Steve Block3ce2e202009-11-05 08:53:23 +0000424 Expression* cond() const { return cond_; }
425 bool may_have_function_literal() const {
426 return may_have_function_literal_;
427 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100428 void set_may_have_function_literal(bool value) {
429 may_have_function_literal_ = value;
430 }
Steve Block3ce2e202009-11-05 08:53:23 +0000431
432 private:
433 Expression* cond_;
434 // True if there is a function literal subexpression in the condition.
435 bool may_have_function_literal_;
Steve Block3ce2e202009-11-05 08:53:23 +0000436};
437
438
439class ForStatement: public IterationStatement {
440 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100441 explicit inline ForStatement(ZoneStringList* labels);
Steve Block6ded16b2010-05-10 14:33:55 +0100442
Ben Murdochf87a2032010-10-22 12:50:53 +0100443 DECLARE_NODE_TYPE(ForStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000444
445 void Initialize(Statement* init,
446 Expression* cond,
447 Statement* next,
448 Statement* body) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000449 IterationStatement::Initialize(body);
450 init_ = init;
451 cond_ = cond;
452 next_ = next;
453 }
454
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100455 Statement* init() const { return init_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100456 void set_init(Statement* stmt) { init_ = stmt; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100457 Expression* cond() const { return cond_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100458 void set_cond(Expression* expr) { cond_ = expr; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100459 Statement* next() const { return next_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100460 void set_next(Statement* stmt) { next_ = stmt; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100461
Steve Blocka7e24c12009-10-30 11:49:00 +0000462 bool may_have_function_literal() const {
463 return may_have_function_literal_;
464 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100465 void set_may_have_function_literal(bool value) {
466 may_have_function_literal_ = value;
467 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000468
Steve Block6ded16b2010-05-10 14:33:55 +0100469 bool is_fast_smi_loop() { return loop_variable_ != NULL; }
470 Variable* loop_variable() { return loop_variable_; }
471 void set_loop_variable(Variable* var) { loop_variable_ = var; }
472
Steve Blocka7e24c12009-10-30 11:49:00 +0000473 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000474 Statement* init_;
475 Expression* cond_;
476 Statement* next_;
477 // True if there is a function literal subexpression in the condition.
478 bool may_have_function_literal_;
Steve Block6ded16b2010-05-10 14:33:55 +0100479 Variable* loop_variable_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000480};
481
482
483class ForInStatement: public IterationStatement {
484 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100485 explicit inline ForInStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000486
Ben Murdochf87a2032010-10-22 12:50:53 +0100487 DECLARE_NODE_TYPE(ForInStatement)
488
Steve Blocka7e24c12009-10-30 11:49:00 +0000489 void Initialize(Expression* each, Expression* enumerable, Statement* body) {
490 IterationStatement::Initialize(body);
491 each_ = each;
492 enumerable_ = enumerable;
493 }
494
Steve Blocka7e24c12009-10-30 11:49:00 +0000495 Expression* each() const { return each_; }
496 Expression* enumerable() const { return enumerable_; }
497
498 private:
499 Expression* each_;
500 Expression* enumerable_;
501};
502
503
504class ExpressionStatement: public Statement {
505 public:
506 explicit ExpressionStatement(Expression* expression)
507 : expression_(expression) { }
508
Ben Murdochf87a2032010-10-22 12:50:53 +0100509 DECLARE_NODE_TYPE(ExpressionStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000510
Steve Block6ded16b2010-05-10 14:33:55 +0100511 virtual Assignment* StatementAsSimpleAssignment();
512 virtual CountOperation* StatementAsCountOperation();
513
Steve Blocka7e24c12009-10-30 11:49:00 +0000514 void set_expression(Expression* e) { expression_ = e; }
515 Expression* expression() { return expression_; }
516
517 private:
518 Expression* expression_;
519};
520
521
522class ContinueStatement: public Statement {
523 public:
524 explicit ContinueStatement(IterationStatement* target)
525 : target_(target) { }
526
Ben Murdochf87a2032010-10-22 12:50:53 +0100527 DECLARE_NODE_TYPE(ContinueStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000528
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100529 IterationStatement* target() const { return target_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000530
531 private:
532 IterationStatement* target_;
533};
534
535
536class BreakStatement: public Statement {
537 public:
538 explicit BreakStatement(BreakableStatement* target)
539 : target_(target) { }
540
Ben Murdochf87a2032010-10-22 12:50:53 +0100541 DECLARE_NODE_TYPE(BreakStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000542
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100543 BreakableStatement* target() const { return target_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000544
545 private:
546 BreakableStatement* target_;
547};
548
549
550class ReturnStatement: public Statement {
551 public:
552 explicit ReturnStatement(Expression* expression)
553 : expression_(expression) { }
554
Ben Murdochf87a2032010-10-22 12:50:53 +0100555 DECLARE_NODE_TYPE(ReturnStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000556
557 Expression* expression() { return expression_; }
558
559 private:
560 Expression* expression_;
561};
562
563
564class WithEnterStatement: public Statement {
565 public:
566 explicit WithEnterStatement(Expression* expression, bool is_catch_block)
567 : expression_(expression), is_catch_block_(is_catch_block) { }
568
Ben Murdochf87a2032010-10-22 12:50:53 +0100569 DECLARE_NODE_TYPE(WithEnterStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000570
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100571 Expression* expression() const { return expression_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000572
573 bool is_catch_block() const { return is_catch_block_; }
574
575 private:
576 Expression* expression_;
577 bool is_catch_block_;
578};
579
580
581class WithExitStatement: public Statement {
582 public:
583 WithExitStatement() { }
584
Ben Murdochf87a2032010-10-22 12:50:53 +0100585 DECLARE_NODE_TYPE(WithExitStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000586};
587
588
589class CaseClause: public ZoneObject {
590 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100591 CaseClause(Expression* label, ZoneList<Statement*>* statements);
Steve Blocka7e24c12009-10-30 11:49:00 +0000592
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100593 bool is_default() const { return label_ == NULL; }
594 Expression* label() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000595 CHECK(!is_default());
596 return label_;
597 }
598 JumpTarget* body_target() { return &body_target_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100599 ZoneList<Statement*>* statements() const { return statements_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000600
601 private:
602 Expression* label_;
603 JumpTarget body_target_;
604 ZoneList<Statement*>* statements_;
605};
606
607
608class SwitchStatement: public BreakableStatement {
609 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100610 explicit inline SwitchStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000611
Ben Murdochf87a2032010-10-22 12:50:53 +0100612 DECLARE_NODE_TYPE(SwitchStatement)
613
Steve Blocka7e24c12009-10-30 11:49:00 +0000614 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
615 tag_ = tag;
616 cases_ = cases;
617 }
618
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100619 Expression* tag() const { return tag_; }
620 ZoneList<CaseClause*>* cases() const { return cases_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000621
622 private:
623 Expression* tag_;
624 ZoneList<CaseClause*>* cases_;
625};
626
627
628// If-statements always have non-null references to their then- and
629// else-parts. When parsing if-statements with no explicit else-part,
630// the parser implicitly creates an empty statement. Use the
631// HasThenStatement() and HasElseStatement() functions to check if a
632// given if-statement has a then- or an else-part containing code.
633class IfStatement: public Statement {
634 public:
635 IfStatement(Expression* condition,
636 Statement* then_statement,
637 Statement* else_statement)
638 : condition_(condition),
639 then_statement_(then_statement),
640 else_statement_(else_statement) { }
641
Ben Murdochf87a2032010-10-22 12:50:53 +0100642 DECLARE_NODE_TYPE(IfStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000643
644 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
645 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
646
647 Expression* condition() const { return condition_; }
648 Statement* then_statement() const { return then_statement_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100649 void set_then_statement(Statement* stmt) { then_statement_ = stmt; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000650 Statement* else_statement() const { return else_statement_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100651 void set_else_statement(Statement* stmt) { else_statement_ = stmt; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000652
653 private:
654 Expression* condition_;
655 Statement* then_statement_;
656 Statement* else_statement_;
657};
658
659
660// NOTE: TargetCollectors are represented as nodes to fit in the target
661// stack in the compiler; this should probably be reworked.
662class TargetCollector: public AstNode {
663 public:
664 explicit TargetCollector(ZoneList<BreakTarget*>* targets)
665 : targets_(targets) {
666 }
667
668 // Adds a jump target to the collector. The collector stores a pointer not
669 // a copy of the target to make binding work, so make sure not to pass in
670 // references to something on the stack.
671 void AddTarget(BreakTarget* target);
672
673 // Virtual behaviour. TargetCollectors are never part of the AST.
674 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
675 virtual TargetCollector* AsTargetCollector() { return this; }
676
677 ZoneList<BreakTarget*>* targets() { return targets_; }
678
679 private:
680 ZoneList<BreakTarget*>* targets_;
681};
682
683
684class TryStatement: public Statement {
685 public:
686 explicit TryStatement(Block* try_block)
687 : try_block_(try_block), escaping_targets_(NULL) { }
688
689 void set_escaping_targets(ZoneList<BreakTarget*>* targets) {
690 escaping_targets_ = targets;
691 }
692
693 Block* try_block() const { return try_block_; }
694 ZoneList<BreakTarget*>* escaping_targets() const { return escaping_targets_; }
695
696 private:
697 Block* try_block_;
698 ZoneList<BreakTarget*>* escaping_targets_;
699};
700
701
Steve Block3ce2e202009-11-05 08:53:23 +0000702class TryCatchStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000703 public:
Steve Block3ce2e202009-11-05 08:53:23 +0000704 TryCatchStatement(Block* try_block,
Leon Clarkee46be812010-01-19 14:06:41 +0000705 VariableProxy* catch_var,
Steve Block3ce2e202009-11-05 08:53:23 +0000706 Block* catch_block)
Steve Blocka7e24c12009-10-30 11:49:00 +0000707 : TryStatement(try_block),
708 catch_var_(catch_var),
709 catch_block_(catch_block) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000710 }
711
Ben Murdochf87a2032010-10-22 12:50:53 +0100712 DECLARE_NODE_TYPE(TryCatchStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000713
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100714 VariableProxy* catch_var() const { return catch_var_; }
715 Block* catch_block() const { return catch_block_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000716
717 private:
Leon Clarkee46be812010-01-19 14:06:41 +0000718 VariableProxy* catch_var_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000719 Block* catch_block_;
720};
721
722
Steve Block3ce2e202009-11-05 08:53:23 +0000723class TryFinallyStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000724 public:
Steve Block3ce2e202009-11-05 08:53:23 +0000725 TryFinallyStatement(Block* try_block, Block* finally_block)
Steve Blocka7e24c12009-10-30 11:49:00 +0000726 : TryStatement(try_block),
727 finally_block_(finally_block) { }
728
Ben Murdochf87a2032010-10-22 12:50:53 +0100729 DECLARE_NODE_TYPE(TryFinallyStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000730
731 Block* finally_block() const { return finally_block_; }
732
733 private:
734 Block* finally_block_;
735};
736
737
738class DebuggerStatement: public Statement {
739 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100740 DECLARE_NODE_TYPE(DebuggerStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000741};
742
743
744class EmptyStatement: public Statement {
745 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100746 DECLARE_NODE_TYPE(EmptyStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000747};
748
749
750class Literal: public Expression {
751 public:
752 explicit Literal(Handle<Object> handle) : handle_(handle) { }
753
Ben Murdochf87a2032010-10-22 12:50:53 +0100754 DECLARE_NODE_TYPE(Literal)
755
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100756 virtual bool IsTrivial() { return true; }
757 virtual bool IsSmiLiteral() { return handle_->IsSmi(); }
Steve Blocka7e24c12009-10-30 11:49:00 +0000758
Steve Blocka7e24c12009-10-30 11:49:00 +0000759 // Check if this literal is identical to the other literal.
760 bool IsIdenticalTo(const Literal* other) const {
761 return handle_.is_identical_to(other->handle_);
762 }
763
Leon Clarkee46be812010-01-19 14:06:41 +0000764 virtual bool IsPropertyName() {
765 if (handle_->IsSymbol()) {
766 uint32_t ignored;
767 return !String::cast(*handle_)->AsArrayIndex(&ignored);
768 }
769 return false;
770 }
771
Steve Blocka7e24c12009-10-30 11:49:00 +0000772 // Identity testers.
773 bool IsNull() const { return handle_.is_identical_to(Factory::null_value()); }
774 bool IsTrue() const { return handle_.is_identical_to(Factory::true_value()); }
775 bool IsFalse() const {
776 return handle_.is_identical_to(Factory::false_value());
777 }
778
779 Handle<Object> handle() const { return handle_; }
780
781 private:
782 Handle<Object> handle_;
783};
784
785
786// Base class for literals that needs space in the corresponding JSFunction.
787class MaterializedLiteral: public Expression {
788 public:
789 explicit MaterializedLiteral(int literal_index, bool is_simple, int depth)
790 : literal_index_(literal_index), is_simple_(is_simple), depth_(depth) {}
791
792 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
793
794 int literal_index() { return literal_index_; }
795
796 // A materialized literal is simple if the values consist of only
797 // constants and simple object and array literals.
798 bool is_simple() const { return is_simple_; }
799
Steve Blocka7e24c12009-10-30 11:49:00 +0000800 int depth() const { return depth_; }
801
802 private:
803 int literal_index_;
804 bool is_simple_;
805 int depth_;
806};
807
808
809// An object literal has a boilerplate object that is used
810// for minimizing the work when constructing it at runtime.
811class ObjectLiteral: public MaterializedLiteral {
812 public:
813 // Property is used for passing information
814 // about an object literal's properties from the parser
815 // to the code generator.
816 class Property: public ZoneObject {
817 public:
Steve Blocka7e24c12009-10-30 11:49:00 +0000818 enum Kind {
819 CONSTANT, // Property with constant value (compile time).
820 COMPUTED, // Property with computed value (execution time).
821 MATERIALIZED_LITERAL, // Property value is a materialized literal.
822 GETTER, SETTER, // Property is an accessor function.
823 PROTOTYPE // Property is __proto__.
824 };
825
826 Property(Literal* key, Expression* value);
827 Property(bool is_getter, FunctionLiteral* value);
828
829 Literal* key() { return key_; }
830 Expression* value() { return value_; }
831 Kind kind() { return kind_; }
832
Steve Blockd0582a62009-12-15 09:54:21 +0000833 bool IsCompileTimeValue();
834
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800835 void set_emit_store(bool emit_store);
836 bool emit_store();
837
Steve Blocka7e24c12009-10-30 11:49:00 +0000838 private:
839 Literal* key_;
840 Expression* value_;
841 Kind kind_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800842 bool emit_store_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000843 };
844
845 ObjectLiteral(Handle<FixedArray> constant_properties,
846 ZoneList<Property*>* properties,
847 int literal_index,
848 bool is_simple,
Steve Block6ded16b2010-05-10 14:33:55 +0100849 bool fast_elements,
Steve Blocka7e24c12009-10-30 11:49:00 +0000850 int depth)
851 : MaterializedLiteral(literal_index, is_simple, depth),
852 constant_properties_(constant_properties),
Steve Block6ded16b2010-05-10 14:33:55 +0100853 properties_(properties),
854 fast_elements_(fast_elements) {}
Steve Blocka7e24c12009-10-30 11:49:00 +0000855
Ben Murdochf87a2032010-10-22 12:50:53 +0100856 DECLARE_NODE_TYPE(ObjectLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +0000857
858 Handle<FixedArray> constant_properties() const {
859 return constant_properties_;
860 }
861 ZoneList<Property*>* properties() const { return properties_; }
862
Steve Block6ded16b2010-05-10 14:33:55 +0100863 bool fast_elements() const { return fast_elements_; }
864
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800865
866 // Mark all computed expressions that are bound to a key that
867 // is shadowed by a later occurrence of the same key. For the
868 // marked expressions, no store code is emitted.
869 void CalculateEmitStore();
870
Steve Blocka7e24c12009-10-30 11:49:00 +0000871 private:
872 Handle<FixedArray> constant_properties_;
873 ZoneList<Property*>* properties_;
Steve Block6ded16b2010-05-10 14:33:55 +0100874 bool fast_elements_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000875};
876
877
878// Node for capturing a regexp literal.
879class RegExpLiteral: public MaterializedLiteral {
880 public:
881 RegExpLiteral(Handle<String> pattern,
882 Handle<String> flags,
883 int literal_index)
884 : MaterializedLiteral(literal_index, false, 1),
885 pattern_(pattern),
886 flags_(flags) {}
887
Ben Murdochf87a2032010-10-22 12:50:53 +0100888 DECLARE_NODE_TYPE(RegExpLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +0000889
890 Handle<String> pattern() const { return pattern_; }
891 Handle<String> flags() const { return flags_; }
892
893 private:
894 Handle<String> pattern_;
895 Handle<String> flags_;
896};
897
898// An array literal has a literals object that is used
899// for minimizing the work when constructing it at runtime.
900class ArrayLiteral: public MaterializedLiteral {
901 public:
Leon Clarkee46be812010-01-19 14:06:41 +0000902 ArrayLiteral(Handle<FixedArray> constant_elements,
Steve Blocka7e24c12009-10-30 11:49:00 +0000903 ZoneList<Expression*>* values,
904 int literal_index,
905 bool is_simple,
906 int depth)
907 : MaterializedLiteral(literal_index, is_simple, depth),
Leon Clarkee46be812010-01-19 14:06:41 +0000908 constant_elements_(constant_elements),
Steve Blocka7e24c12009-10-30 11:49:00 +0000909 values_(values) {}
910
Ben Murdochf87a2032010-10-22 12:50:53 +0100911 DECLARE_NODE_TYPE(ArrayLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +0000912
Leon Clarkee46be812010-01-19 14:06:41 +0000913 Handle<FixedArray> constant_elements() const { return constant_elements_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000914 ZoneList<Expression*>* values() const { return values_; }
915
916 private:
Leon Clarkee46be812010-01-19 14:06:41 +0000917 Handle<FixedArray> constant_elements_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000918 ZoneList<Expression*>* values_;
919};
920
921
922// Node for constructing a context extension object for a catch block.
923// The catch context extension object has one property, the catch
924// variable, which should be DontDelete.
925class CatchExtensionObject: public Expression {
926 public:
927 CatchExtensionObject(Literal* key, VariableProxy* value)
928 : key_(key), value_(value) {
929 }
930
Ben Murdochf87a2032010-10-22 12:50:53 +0100931 DECLARE_NODE_TYPE(CatchExtensionObject)
Steve Blocka7e24c12009-10-30 11:49:00 +0000932
933 Literal* key() const { return key_; }
934 VariableProxy* value() const { return value_; }
935
936 private:
937 Literal* key_;
938 VariableProxy* value_;
939};
940
941
942class VariableProxy: public Expression {
943 public:
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100944 explicit VariableProxy(Variable* var);
945
Ben Murdochf87a2032010-10-22 12:50:53 +0100946 DECLARE_NODE_TYPE(VariableProxy)
Steve Blocka7e24c12009-10-30 11:49:00 +0000947
948 // Type testing & conversion
949 virtual Property* AsProperty() {
950 return var_ == NULL ? NULL : var_->AsProperty();
951 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100952
Steve Blocka7e24c12009-10-30 11:49:00 +0000953 Variable* AsVariable() {
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100954 if (this == NULL || var_ == NULL) return NULL;
955 Expression* rewrite = var_->rewrite();
956 if (rewrite == NULL || rewrite->AsSlot() != NULL) return var_;
957 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000958 }
959
960 virtual bool IsValidLeftHandSide() {
961 return var_ == NULL ? true : var_->IsValidLeftHandSide();
962 }
963
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100964 virtual bool IsTrivial() {
965 // Reading from a mutable variable is a side effect, but the
966 // variable for 'this' is immutable.
967 return is_this_ || is_trivial_;
Andrei Popescu402d9372010-02-26 13:31:12 +0000968 }
969
Steve Blocka7e24c12009-10-30 11:49:00 +0000970 bool IsVariable(Handle<String> n) {
971 return !is_this() && name().is_identical_to(n);
972 }
973
974 bool IsArguments() {
975 Variable* variable = AsVariable();
976 return (variable == NULL) ? false : variable->is_arguments();
977 }
978
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100979 Handle<String> name() const { return name_; }
980 Variable* var() const { return var_; }
981 bool is_this() const { return is_this_; }
982 bool inside_with() const { return inside_with_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100983
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100984 void MarkAsTrivial() { is_trivial_ = true; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000985
986 // Bind this proxy to the variable var.
987 void BindTo(Variable* var);
988
989 protected:
990 Handle<String> name_;
991 Variable* var_; // resolved variable, or NULL
992 bool is_this_;
993 bool inside_with_;
Steve Block6ded16b2010-05-10 14:33:55 +0100994 bool is_trivial_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000995
996 VariableProxy(Handle<String> name, bool is_this, bool inside_with);
997 explicit VariableProxy(bool is_this);
998
999 friend class Scope;
1000};
1001
1002
1003class VariableProxySentinel: public VariableProxy {
1004 public:
1005 virtual bool IsValidLeftHandSide() { return !is_this(); }
1006 static VariableProxySentinel* this_proxy() { return &this_proxy_; }
1007 static VariableProxySentinel* identifier_proxy() {
1008 return &identifier_proxy_;
1009 }
1010
1011 private:
1012 explicit VariableProxySentinel(bool is_this) : VariableProxy(is_this) { }
1013 static VariableProxySentinel this_proxy_;
1014 static VariableProxySentinel identifier_proxy_;
1015};
1016
1017
1018class Slot: public Expression {
1019 public:
1020 enum Type {
1021 // A slot in the parameter section on the stack. index() is
1022 // the parameter index, counting left-to-right, starting at 0.
1023 PARAMETER,
1024
1025 // A slot in the local section on the stack. index() is
1026 // the variable index in the stack frame, starting at 0.
1027 LOCAL,
1028
1029 // An indexed slot in a heap context. index() is the
1030 // variable index in the context object on the heap,
1031 // starting at 0. var()->scope() is the corresponding
1032 // scope.
1033 CONTEXT,
1034
1035 // A named slot in a heap context. var()->name() is the
1036 // variable name in the context object on the heap,
1037 // with lookup starting at the current context. index()
1038 // is invalid.
Steve Blockd0582a62009-12-15 09:54:21 +00001039 LOOKUP
Steve Blocka7e24c12009-10-30 11:49:00 +00001040 };
1041
1042 Slot(Variable* var, Type type, int index)
1043 : var_(var), type_(type), index_(index) {
1044 ASSERT(var != NULL);
1045 }
1046
Ben Murdochf87a2032010-10-22 12:50:53 +01001047 DECLARE_NODE_TYPE(Slot)
Steve Blocka7e24c12009-10-30 11:49:00 +00001048
Steve Block6ded16b2010-05-10 14:33:55 +01001049 bool IsStackAllocated() { return type_ == PARAMETER || type_ == LOCAL; }
1050
Steve Blocka7e24c12009-10-30 11:49:00 +00001051 // Accessors
1052 Variable* var() const { return var_; }
1053 Type type() const { return type_; }
1054 int index() const { return index_; }
1055 bool is_arguments() const { return var_->is_arguments(); }
1056
1057 private:
1058 Variable* var_;
1059 Type type_;
1060 int index_;
1061};
1062
1063
1064class Property: public Expression {
1065 public:
1066 // Synthetic properties are property lookups introduced by the system,
1067 // to objects that aren't visible to the user. Function calls to synthetic
1068 // properties should use the global object as receiver, not the base object
1069 // of the resolved Reference.
1070 enum Type { NORMAL, SYNTHETIC };
1071 Property(Expression* obj, Expression* key, int pos, Type type = NORMAL)
1072 : obj_(obj), key_(key), pos_(pos), type_(type) { }
1073
Ben Murdochf87a2032010-10-22 12:50:53 +01001074 DECLARE_NODE_TYPE(Property)
Steve Blocka7e24c12009-10-30 11:49:00 +00001075
1076 virtual bool IsValidLeftHandSide() { return true; }
1077
1078 Expression* obj() const { return obj_; }
1079 Expression* key() const { return key_; }
1080 int position() const { return pos_; }
1081 bool is_synthetic() const { return type_ == SYNTHETIC; }
1082
1083 // Returns a property singleton property access on 'this'. Used
1084 // during preparsing.
1085 static Property* this_property() { return &this_property_; }
1086
1087 private:
1088 Expression* obj_;
1089 Expression* key_;
1090 int pos_;
1091 Type type_;
1092
1093 // Dummy property used during preparsing.
1094 static Property this_property_;
1095};
1096
1097
1098class Call: public Expression {
1099 public:
1100 Call(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1101 : expression_(expression), arguments_(arguments), pos_(pos) { }
1102
Ben Murdochf87a2032010-10-22 12:50:53 +01001103 DECLARE_NODE_TYPE(Call)
Steve Blocka7e24c12009-10-30 11:49:00 +00001104
1105 Expression* expression() const { return expression_; }
1106 ZoneList<Expression*>* arguments() const { return arguments_; }
1107 int position() { return pos_; }
1108
1109 static Call* sentinel() { return &sentinel_; }
1110
1111 private:
1112 Expression* expression_;
1113 ZoneList<Expression*>* arguments_;
1114 int pos_;
1115
1116 static Call sentinel_;
1117};
1118
1119
1120class CallNew: public Expression {
1121 public:
1122 CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1123 : expression_(expression), arguments_(arguments), pos_(pos) { }
1124
Ben Murdochf87a2032010-10-22 12:50:53 +01001125 DECLARE_NODE_TYPE(CallNew)
Steve Blocka7e24c12009-10-30 11:49:00 +00001126
1127 Expression* expression() const { return expression_; }
1128 ZoneList<Expression*>* arguments() const { return arguments_; }
1129 int position() { return pos_; }
1130
1131 private:
1132 Expression* expression_;
1133 ZoneList<Expression*>* arguments_;
1134 int pos_;
1135};
1136
1137
1138// The CallRuntime class does not represent any official JavaScript
1139// language construct. Instead it is used to call a C or JS function
1140// with a set of arguments. This is used from the builtins that are
1141// implemented in JavaScript (see "v8natives.js").
1142class CallRuntime: public Expression {
1143 public:
1144 CallRuntime(Handle<String> name,
1145 Runtime::Function* function,
1146 ZoneList<Expression*>* arguments)
1147 : name_(name), function_(function), arguments_(arguments) { }
1148
Ben Murdochf87a2032010-10-22 12:50:53 +01001149 DECLARE_NODE_TYPE(CallRuntime)
Steve Blocka7e24c12009-10-30 11:49:00 +00001150
1151 Handle<String> name() const { return name_; }
1152 Runtime::Function* function() const { return function_; }
1153 ZoneList<Expression*>* arguments() const { return arguments_; }
Steve Blockd0582a62009-12-15 09:54:21 +00001154 bool is_jsruntime() const { return function_ == NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001155
1156 private:
1157 Handle<String> name_;
1158 Runtime::Function* function_;
1159 ZoneList<Expression*>* arguments_;
1160};
1161
1162
1163class UnaryOperation: public Expression {
1164 public:
1165 UnaryOperation(Token::Value op, Expression* expression)
1166 : op_(op), expression_(expression) {
1167 ASSERT(Token::IsUnaryOp(op));
1168 }
1169
Ben Murdochf87a2032010-10-22 12:50:53 +01001170 DECLARE_NODE_TYPE(UnaryOperation)
Steve Blocka7e24c12009-10-30 11:49:00 +00001171
Ben Murdochf87a2032010-10-22 12:50:53 +01001172 virtual bool ResultOverwriteAllowed();
Steve Blocka7e24c12009-10-30 11:49:00 +00001173
1174 Token::Value op() const { return op_; }
1175 Expression* expression() const { return expression_; }
1176
1177 private:
1178 Token::Value op_;
1179 Expression* expression_;
1180};
1181
1182
1183class BinaryOperation: public Expression {
1184 public:
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001185 BinaryOperation(Token::Value op,
1186 Expression* left,
1187 Expression* right,
1188 int pos)
1189 : op_(op), left_(left), right_(right), pos_(pos) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001190 ASSERT(Token::IsBinaryOp(op));
1191 }
1192
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001193 // Create the binary operation corresponding to a compound assignment.
1194 explicit BinaryOperation(Assignment* assignment);
Steve Block6ded16b2010-05-10 14:33:55 +01001195
Ben Murdochf87a2032010-10-22 12:50:53 +01001196 DECLARE_NODE_TYPE(BinaryOperation)
Steve Blocka7e24c12009-10-30 11:49:00 +00001197
Ben Murdochf87a2032010-10-22 12:50:53 +01001198 virtual bool ResultOverwriteAllowed();
Steve Blocka7e24c12009-10-30 11:49:00 +00001199
Steve Blocka7e24c12009-10-30 11:49:00 +00001200 Token::Value op() const { return op_; }
1201 Expression* left() const { return left_; }
1202 Expression* right() const { return right_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001203 int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001204
1205 private:
1206 Token::Value op_;
1207 Expression* left_;
1208 Expression* right_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001209 int pos_;
1210};
1211
1212
1213class IncrementOperation: public Expression {
1214 public:
1215 IncrementOperation(Token::Value op, Expression* expr)
1216 : op_(op), expression_(expr) {
1217 ASSERT(Token::IsCountOp(op));
1218 }
1219
Ben Murdochf87a2032010-10-22 12:50:53 +01001220 DECLARE_NODE_TYPE(IncrementOperation)
1221
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001222 Token::Value op() const { return op_; }
1223 bool is_increment() { return op_ == Token::INC; }
1224 Expression* expression() const { return expression_; }
1225
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001226 private:
1227 Token::Value op_;
1228 Expression* expression_;
1229 int pos_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001230};
1231
1232
1233class CountOperation: public Expression {
1234 public:
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001235 CountOperation(bool is_prefix, IncrementOperation* increment, int pos)
1236 : is_prefix_(is_prefix), increment_(increment), pos_(pos) { }
Steve Block6ded16b2010-05-10 14:33:55 +01001237
Ben Murdochf87a2032010-10-22 12:50:53 +01001238 DECLARE_NODE_TYPE(CountOperation)
Steve Block6ded16b2010-05-10 14:33:55 +01001239
Steve Blocka7e24c12009-10-30 11:49:00 +00001240 bool is_prefix() const { return is_prefix_; }
1241 bool is_postfix() const { return !is_prefix_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001242
1243 Token::Value op() const { return increment_->op(); }
Leon Clarkee46be812010-01-19 14:06:41 +00001244 Token::Value binary_op() {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001245 return (op() == Token::INC) ? Token::ADD : Token::SUB;
Leon Clarkee46be812010-01-19 14:06:41 +00001246 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001247
1248 Expression* expression() const { return increment_->expression(); }
1249 IncrementOperation* increment() const { return increment_; }
1250 int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001251
1252 virtual void MarkAsStatement() { is_prefix_ = true; }
1253
1254 private:
1255 bool is_prefix_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001256 IncrementOperation* increment_;
1257 int pos_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001258};
1259
1260
1261class CompareOperation: public Expression {
1262 public:
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001263 CompareOperation(Token::Value op,
1264 Expression* left,
1265 Expression* right,
1266 int pos)
1267 : op_(op), left_(left), right_(right), pos_(pos) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001268 ASSERT(Token::IsCompareOp(op));
1269 }
1270
Ben Murdochf87a2032010-10-22 12:50:53 +01001271 DECLARE_NODE_TYPE(CompareOperation)
Steve Blocka7e24c12009-10-30 11:49:00 +00001272
1273 Token::Value op() const { return op_; }
1274 Expression* left() const { return left_; }
1275 Expression* right() const { return right_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001276 int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001277
1278 private:
1279 Token::Value op_;
1280 Expression* left_;
1281 Expression* right_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001282 int pos_;
1283};
1284
1285
1286class CompareToNull: public Expression {
1287 public:
1288 CompareToNull(bool is_strict, Expression* expression)
1289 : is_strict_(is_strict), expression_(expression) { }
1290
Ben Murdochf87a2032010-10-22 12:50:53 +01001291 DECLARE_NODE_TYPE(CompareToNull)
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001292
1293 bool is_strict() const { return is_strict_; }
1294 Token::Value op() const { return is_strict_ ? Token::EQ_STRICT : Token::EQ; }
1295 Expression* expression() const { return expression_; }
1296
1297 private:
1298 bool is_strict_;
1299 Expression* expression_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001300};
1301
1302
1303class Conditional: public Expression {
1304 public:
1305 Conditional(Expression* condition,
1306 Expression* then_expression,
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001307 Expression* else_expression,
1308 int then_expression_position,
1309 int else_expression_position)
Steve Blocka7e24c12009-10-30 11:49:00 +00001310 : condition_(condition),
1311 then_expression_(then_expression),
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001312 else_expression_(else_expression),
1313 then_expression_position_(then_expression_position),
1314 else_expression_position_(else_expression_position) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001315
Ben Murdochf87a2032010-10-22 12:50:53 +01001316 DECLARE_NODE_TYPE(Conditional)
Steve Blocka7e24c12009-10-30 11:49:00 +00001317
1318 Expression* condition() const { return condition_; }
1319 Expression* then_expression() const { return then_expression_; }
1320 Expression* else_expression() const { return else_expression_; }
1321
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001322 int then_expression_position() { return then_expression_position_; }
1323 int else_expression_position() { return else_expression_position_; }
1324
Steve Blocka7e24c12009-10-30 11:49:00 +00001325 private:
1326 Expression* condition_;
1327 Expression* then_expression_;
1328 Expression* else_expression_;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001329 int then_expression_position_;
1330 int else_expression_position_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001331};
1332
1333
1334class Assignment: public Expression {
1335 public:
1336 Assignment(Token::Value op, Expression* target, Expression* value, int pos)
1337 : op_(op), target_(target), value_(value), pos_(pos),
1338 block_start_(false), block_end_(false) {
1339 ASSERT(Token::IsAssignmentOp(op));
1340 }
1341
Ben Murdochf87a2032010-10-22 12:50:53 +01001342 DECLARE_NODE_TYPE(Assignment)
Steve Blocka7e24c12009-10-30 11:49:00 +00001343
Steve Block6ded16b2010-05-10 14:33:55 +01001344 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1345
Steve Blocka7e24c12009-10-30 11:49:00 +00001346 Token::Value binary_op() const;
1347
1348 Token::Value op() const { return op_; }
1349 Expression* target() const { return target_; }
1350 Expression* value() const { return value_; }
1351 int position() { return pos_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001352 // This check relies on the definition order of token in token.h.
1353 bool is_compound() const { return op() > Token::ASSIGN; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001354
1355 // An initialization block is a series of statments of the form
1356 // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1357 // ending of these blocks to allow for optimizations of initialization
1358 // blocks.
1359 bool starts_initialization_block() { return block_start_; }
1360 bool ends_initialization_block() { return block_end_; }
1361 void mark_block_start() { block_start_ = true; }
1362 void mark_block_end() { block_end_ = true; }
1363
1364 private:
1365 Token::Value op_;
1366 Expression* target_;
1367 Expression* value_;
1368 int pos_;
1369 bool block_start_;
1370 bool block_end_;
1371};
1372
1373
1374class Throw: public Expression {
1375 public:
1376 Throw(Expression* exception, int pos)
1377 : exception_(exception), pos_(pos) {}
1378
Ben Murdochf87a2032010-10-22 12:50:53 +01001379 DECLARE_NODE_TYPE(Throw)
Steve Block6ded16b2010-05-10 14:33:55 +01001380
Steve Blocka7e24c12009-10-30 11:49:00 +00001381 Expression* exception() const { return exception_; }
1382 int position() const { return pos_; }
1383
1384 private:
1385 Expression* exception_;
1386 int pos_;
1387};
1388
1389
1390class FunctionLiteral: public Expression {
1391 public:
1392 FunctionLiteral(Handle<String> name,
1393 Scope* scope,
1394 ZoneList<Statement*>* body,
1395 int materialized_literal_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00001396 int expected_property_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00001397 bool has_only_simple_this_property_assignments,
1398 Handle<FixedArray> this_property_assignments,
1399 int num_parameters,
1400 int start_position,
1401 int end_position,
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001402 bool is_expression,
1403 bool contains_loops)
Steve Blocka7e24c12009-10-30 11:49:00 +00001404 : name_(name),
1405 scope_(scope),
1406 body_(body),
1407 materialized_literal_count_(materialized_literal_count),
Steve Blocka7e24c12009-10-30 11:49:00 +00001408 expected_property_count_(expected_property_count),
Steve Blocka7e24c12009-10-30 11:49:00 +00001409 has_only_simple_this_property_assignments_(
1410 has_only_simple_this_property_assignments),
1411 this_property_assignments_(this_property_assignments),
1412 num_parameters_(num_parameters),
1413 start_position_(start_position),
1414 end_position_(end_position),
1415 is_expression_(is_expression),
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001416 contains_loops_(contains_loops),
Steve Blocka7e24c12009-10-30 11:49:00 +00001417 function_token_position_(RelocInfo::kNoPosition),
Steve Blockd0582a62009-12-15 09:54:21 +00001418 inferred_name_(Heap::empty_string()),
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08001419 try_full_codegen_(false),
1420 pretenure_(false) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001421#ifdef DEBUG
1422 already_compiled_ = false;
1423#endif
1424 }
1425
Ben Murdochf87a2032010-10-22 12:50:53 +01001426 DECLARE_NODE_TYPE(FunctionLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00001427
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001428 Handle<String> name() const { return name_; }
1429 Scope* scope() const { return scope_; }
1430 ZoneList<Statement*>* body() const { return body_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001431 void set_function_token_position(int pos) { function_token_position_ = pos; }
1432 int function_token_position() const { return function_token_position_; }
1433 int start_position() const { return start_position_; }
1434 int end_position() const { return end_position_; }
1435 bool is_expression() const { return is_expression_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001436 bool contains_loops() const { return contains_loops_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001437
1438 int materialized_literal_count() { return materialized_literal_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001439 int expected_property_count() { return expected_property_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001440 bool has_only_simple_this_property_assignments() {
1441 return has_only_simple_this_property_assignments_;
1442 }
1443 Handle<FixedArray> this_property_assignments() {
1444 return this_property_assignments_;
1445 }
1446 int num_parameters() { return num_parameters_; }
1447
1448 bool AllowsLazyCompilation();
1449
Ben Murdochf87a2032010-10-22 12:50:53 +01001450 Handle<String> debug_name() const {
1451 if (name_->length() > 0) return name_;
1452 return inferred_name();
1453 }
1454
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001455 Handle<String> inferred_name() const { return inferred_name_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001456 void set_inferred_name(Handle<String> inferred_name) {
1457 inferred_name_ = inferred_name;
1458 }
1459
Leon Clarked91b9f72010-01-27 17:25:45 +00001460 bool try_full_codegen() { return try_full_codegen_; }
1461 void set_try_full_codegen(bool flag) { try_full_codegen_ = flag; }
Steve Blockd0582a62009-12-15 09:54:21 +00001462
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08001463 bool pretenure() { return pretenure_; }
1464 void set_pretenure(bool value) { pretenure_ = value; }
1465
Steve Blocka7e24c12009-10-30 11:49:00 +00001466#ifdef DEBUG
1467 void mark_as_compiled() {
1468 ASSERT(!already_compiled_);
1469 already_compiled_ = true;
1470 }
1471#endif
1472
1473 private:
1474 Handle<String> name_;
1475 Scope* scope_;
1476 ZoneList<Statement*>* body_;
1477 int materialized_literal_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001478 int expected_property_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001479 bool has_only_simple_this_property_assignments_;
1480 Handle<FixedArray> this_property_assignments_;
1481 int num_parameters_;
1482 int start_position_;
1483 int end_position_;
1484 bool is_expression_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001485 bool contains_loops_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001486 int function_token_position_;
1487 Handle<String> inferred_name_;
Leon Clarked91b9f72010-01-27 17:25:45 +00001488 bool try_full_codegen_;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08001489 bool pretenure_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001490#ifdef DEBUG
1491 bool already_compiled_;
1492#endif
1493};
1494
1495
Steve Block6ded16b2010-05-10 14:33:55 +01001496class SharedFunctionInfoLiteral: public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00001497 public:
Steve Block6ded16b2010-05-10 14:33:55 +01001498 explicit SharedFunctionInfoLiteral(
1499 Handle<SharedFunctionInfo> shared_function_info)
1500 : shared_function_info_(shared_function_info) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001501
Ben Murdochf87a2032010-10-22 12:50:53 +01001502 DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
1503
Steve Block6ded16b2010-05-10 14:33:55 +01001504 Handle<SharedFunctionInfo> shared_function_info() const {
1505 return shared_function_info_;
1506 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001507
Steve Blocka7e24c12009-10-30 11:49:00 +00001508 private:
Steve Block6ded16b2010-05-10 14:33:55 +01001509 Handle<SharedFunctionInfo> shared_function_info_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001510};
1511
1512
1513class ThisFunction: public Expression {
1514 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001515 DECLARE_NODE_TYPE(ThisFunction)
Steve Blocka7e24c12009-10-30 11:49:00 +00001516};
1517
1518
1519// ----------------------------------------------------------------------------
1520// Regular expressions
1521
1522
1523class RegExpVisitor BASE_EMBEDDED {
1524 public:
1525 virtual ~RegExpVisitor() { }
1526#define MAKE_CASE(Name) \
1527 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
1528 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
1529#undef MAKE_CASE
1530};
1531
1532
1533class RegExpTree: public ZoneObject {
1534 public:
1535 static const int kInfinity = kMaxInt;
1536 virtual ~RegExpTree() { }
1537 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
1538 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1539 RegExpNode* on_success) = 0;
1540 virtual bool IsTextElement() { return false; }
Ben Murdochf87a2032010-10-22 12:50:53 +01001541 virtual bool IsAnchoredAtStart() { return false; }
1542 virtual bool IsAnchoredAtEnd() { return false; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001543 virtual int min_match() = 0;
1544 virtual int max_match() = 0;
1545 // Returns the interval of registers used for captures within this
1546 // expression.
1547 virtual Interval CaptureRegisters() { return Interval::Empty(); }
1548 virtual void AppendToText(RegExpText* text);
1549 SmartPointer<const char> ToString();
1550#define MAKE_ASTYPE(Name) \
1551 virtual RegExp##Name* As##Name(); \
1552 virtual bool Is##Name();
1553 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
1554#undef MAKE_ASTYPE
1555};
1556
1557
1558class RegExpDisjunction: public RegExpTree {
1559 public:
1560 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
1561 virtual void* Accept(RegExpVisitor* visitor, void* data);
1562 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1563 RegExpNode* on_success);
1564 virtual RegExpDisjunction* AsDisjunction();
1565 virtual Interval CaptureRegisters();
1566 virtual bool IsDisjunction();
Ben Murdochf87a2032010-10-22 12:50:53 +01001567 virtual bool IsAnchoredAtStart();
1568 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001569 virtual int min_match() { return min_match_; }
1570 virtual int max_match() { return max_match_; }
1571 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
1572 private:
1573 ZoneList<RegExpTree*>* alternatives_;
1574 int min_match_;
1575 int max_match_;
1576};
1577
1578
1579class RegExpAlternative: public RegExpTree {
1580 public:
1581 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
1582 virtual void* Accept(RegExpVisitor* visitor, void* data);
1583 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1584 RegExpNode* on_success);
1585 virtual RegExpAlternative* AsAlternative();
1586 virtual Interval CaptureRegisters();
1587 virtual bool IsAlternative();
Ben Murdochf87a2032010-10-22 12:50:53 +01001588 virtual bool IsAnchoredAtStart();
1589 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001590 virtual int min_match() { return min_match_; }
1591 virtual int max_match() { return max_match_; }
1592 ZoneList<RegExpTree*>* nodes() { return nodes_; }
1593 private:
1594 ZoneList<RegExpTree*>* nodes_;
1595 int min_match_;
1596 int max_match_;
1597};
1598
1599
1600class RegExpAssertion: public RegExpTree {
1601 public:
1602 enum Type {
1603 START_OF_LINE,
1604 START_OF_INPUT,
1605 END_OF_LINE,
1606 END_OF_INPUT,
1607 BOUNDARY,
1608 NON_BOUNDARY
1609 };
1610 explicit RegExpAssertion(Type type) : type_(type) { }
1611 virtual void* Accept(RegExpVisitor* visitor, void* data);
1612 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1613 RegExpNode* on_success);
1614 virtual RegExpAssertion* AsAssertion();
1615 virtual bool IsAssertion();
Ben Murdochf87a2032010-10-22 12:50:53 +01001616 virtual bool IsAnchoredAtStart();
1617 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001618 virtual int min_match() { return 0; }
1619 virtual int max_match() { return 0; }
1620 Type type() { return type_; }
1621 private:
1622 Type type_;
1623};
1624
1625
1626class CharacterSet BASE_EMBEDDED {
1627 public:
1628 explicit CharacterSet(uc16 standard_set_type)
1629 : ranges_(NULL),
1630 standard_set_type_(standard_set_type) {}
1631 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
1632 : ranges_(ranges),
1633 standard_set_type_(0) {}
1634 ZoneList<CharacterRange>* ranges();
1635 uc16 standard_set_type() { return standard_set_type_; }
1636 void set_standard_set_type(uc16 special_set_type) {
1637 standard_set_type_ = special_set_type;
1638 }
1639 bool is_standard() { return standard_set_type_ != 0; }
Leon Clarkee46be812010-01-19 14:06:41 +00001640 void Canonicalize();
Steve Blocka7e24c12009-10-30 11:49:00 +00001641 private:
1642 ZoneList<CharacterRange>* ranges_;
1643 // If non-zero, the value represents a standard set (e.g., all whitespace
1644 // characters) without having to expand the ranges.
1645 uc16 standard_set_type_;
1646};
1647
1648
1649class RegExpCharacterClass: public RegExpTree {
1650 public:
1651 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
1652 : set_(ranges),
1653 is_negated_(is_negated) { }
1654 explicit RegExpCharacterClass(uc16 type)
1655 : set_(type),
1656 is_negated_(false) { }
1657 virtual void* Accept(RegExpVisitor* visitor, void* data);
1658 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1659 RegExpNode* on_success);
1660 virtual RegExpCharacterClass* AsCharacterClass();
1661 virtual bool IsCharacterClass();
1662 virtual bool IsTextElement() { return true; }
1663 virtual int min_match() { return 1; }
1664 virtual int max_match() { return 1; }
1665 virtual void AppendToText(RegExpText* text);
1666 CharacterSet character_set() { return set_; }
1667 // TODO(lrn): Remove need for complex version if is_standard that
1668 // recognizes a mangled standard set and just do { return set_.is_special(); }
1669 bool is_standard();
1670 // Returns a value representing the standard character set if is_standard()
1671 // returns true.
1672 // Currently used values are:
1673 // s : unicode whitespace
1674 // S : unicode non-whitespace
1675 // w : ASCII word character (digit, letter, underscore)
1676 // W : non-ASCII word character
1677 // d : ASCII digit
1678 // D : non-ASCII digit
1679 // . : non-unicode non-newline
1680 // * : All characters
1681 uc16 standard_type() { return set_.standard_set_type(); }
1682 ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
1683 bool is_negated() { return is_negated_; }
1684 private:
1685 CharacterSet set_;
1686 bool is_negated_;
1687};
1688
1689
1690class RegExpAtom: public RegExpTree {
1691 public:
1692 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
1693 virtual void* Accept(RegExpVisitor* visitor, void* data);
1694 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1695 RegExpNode* on_success);
1696 virtual RegExpAtom* AsAtom();
1697 virtual bool IsAtom();
1698 virtual bool IsTextElement() { return true; }
1699 virtual int min_match() { return data_.length(); }
1700 virtual int max_match() { return data_.length(); }
1701 virtual void AppendToText(RegExpText* text);
1702 Vector<const uc16> data() { return data_; }
1703 int length() { return data_.length(); }
1704 private:
1705 Vector<const uc16> data_;
1706};
1707
1708
1709class RegExpText: public RegExpTree {
1710 public:
1711 RegExpText() : elements_(2), length_(0) {}
1712 virtual void* Accept(RegExpVisitor* visitor, void* data);
1713 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1714 RegExpNode* on_success);
1715 virtual RegExpText* AsText();
1716 virtual bool IsText();
1717 virtual bool IsTextElement() { return true; }
1718 virtual int min_match() { return length_; }
1719 virtual int max_match() { return length_; }
1720 virtual void AppendToText(RegExpText* text);
1721 void AddElement(TextElement elm) {
1722 elements_.Add(elm);
1723 length_ += elm.length();
Iain Merrick9ac36c92010-09-13 15:29:50 +01001724 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001725 ZoneList<TextElement>* elements() { return &elements_; }
1726 private:
1727 ZoneList<TextElement> elements_;
1728 int length_;
1729};
1730
1731
1732class RegExpQuantifier: public RegExpTree {
1733 public:
Leon Clarkee46be812010-01-19 14:06:41 +00001734 enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
1735 RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
1736 : body_(body),
1737 min_(min),
Steve Blocka7e24c12009-10-30 11:49:00 +00001738 max_(max),
Leon Clarkee46be812010-01-19 14:06:41 +00001739 min_match_(min * body->min_match()),
1740 type_(type) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001741 if (max > 0 && body->max_match() > kInfinity / max) {
1742 max_match_ = kInfinity;
1743 } else {
1744 max_match_ = max * body->max_match();
1745 }
1746 }
1747 virtual void* Accept(RegExpVisitor* visitor, void* data);
1748 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1749 RegExpNode* on_success);
1750 static RegExpNode* ToNode(int min,
1751 int max,
1752 bool is_greedy,
1753 RegExpTree* body,
1754 RegExpCompiler* compiler,
1755 RegExpNode* on_success,
1756 bool not_at_start = false);
1757 virtual RegExpQuantifier* AsQuantifier();
1758 virtual Interval CaptureRegisters();
1759 virtual bool IsQuantifier();
1760 virtual int min_match() { return min_match_; }
1761 virtual int max_match() { return max_match_; }
1762 int min() { return min_; }
1763 int max() { return max_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001764 bool is_possessive() { return type_ == POSSESSIVE; }
1765 bool is_non_greedy() { return type_ == NON_GREEDY; }
1766 bool is_greedy() { return type_ == GREEDY; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001767 RegExpTree* body() { return body_; }
1768 private:
Leon Clarkee46be812010-01-19 14:06:41 +00001769 RegExpTree* body_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001770 int min_;
1771 int max_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001772 int min_match_;
1773 int max_match_;
Leon Clarkee46be812010-01-19 14:06:41 +00001774 Type type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001775};
1776
1777
1778class RegExpCapture: public RegExpTree {
1779 public:
1780 explicit RegExpCapture(RegExpTree* body, int index)
1781 : body_(body), index_(index) { }
1782 virtual void* Accept(RegExpVisitor* visitor, void* data);
1783 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1784 RegExpNode* on_success);
1785 static RegExpNode* ToNode(RegExpTree* body,
1786 int index,
1787 RegExpCompiler* compiler,
1788 RegExpNode* on_success);
1789 virtual RegExpCapture* AsCapture();
Ben Murdochf87a2032010-10-22 12:50:53 +01001790 virtual bool IsAnchoredAtStart();
1791 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001792 virtual Interval CaptureRegisters();
1793 virtual bool IsCapture();
1794 virtual int min_match() { return body_->min_match(); }
1795 virtual int max_match() { return body_->max_match(); }
1796 RegExpTree* body() { return body_; }
1797 int index() { return index_; }
1798 static int StartRegister(int index) { return index * 2; }
1799 static int EndRegister(int index) { return index * 2 + 1; }
1800 private:
1801 RegExpTree* body_;
1802 int index_;
1803};
1804
1805
1806class RegExpLookahead: public RegExpTree {
1807 public:
1808 RegExpLookahead(RegExpTree* body,
1809 bool is_positive,
1810 int capture_count,
1811 int capture_from)
1812 : body_(body),
1813 is_positive_(is_positive),
1814 capture_count_(capture_count),
1815 capture_from_(capture_from) { }
1816
1817 virtual void* Accept(RegExpVisitor* visitor, void* data);
1818 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1819 RegExpNode* on_success);
1820 virtual RegExpLookahead* AsLookahead();
1821 virtual Interval CaptureRegisters();
1822 virtual bool IsLookahead();
Ben Murdochf87a2032010-10-22 12:50:53 +01001823 virtual bool IsAnchoredAtStart();
Steve Blocka7e24c12009-10-30 11:49:00 +00001824 virtual int min_match() { return 0; }
1825 virtual int max_match() { return 0; }
1826 RegExpTree* body() { return body_; }
1827 bool is_positive() { return is_positive_; }
1828 int capture_count() { return capture_count_; }
1829 int capture_from() { return capture_from_; }
1830 private:
1831 RegExpTree* body_;
1832 bool is_positive_;
1833 int capture_count_;
1834 int capture_from_;
1835};
1836
1837
1838class RegExpBackReference: public RegExpTree {
1839 public:
1840 explicit RegExpBackReference(RegExpCapture* capture)
1841 : capture_(capture) { }
1842 virtual void* Accept(RegExpVisitor* visitor, void* data);
1843 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1844 RegExpNode* on_success);
1845 virtual RegExpBackReference* AsBackReference();
1846 virtual bool IsBackReference();
1847 virtual int min_match() { return 0; }
1848 virtual int max_match() { return capture_->max_match(); }
1849 int index() { return capture_->index(); }
1850 RegExpCapture* capture() { return capture_; }
1851 private:
1852 RegExpCapture* capture_;
1853};
1854
1855
1856class RegExpEmpty: public RegExpTree {
1857 public:
1858 RegExpEmpty() { }
1859 virtual void* Accept(RegExpVisitor* visitor, void* data);
1860 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1861 RegExpNode* on_success);
1862 virtual RegExpEmpty* AsEmpty();
1863 virtual bool IsEmpty();
1864 virtual int min_match() { return 0; }
1865 virtual int max_match() { return 0; }
1866 static RegExpEmpty* GetInstance() { return &kInstance; }
1867 private:
1868 static RegExpEmpty kInstance;
1869};
1870
1871
1872// ----------------------------------------------------------------------------
1873// Basic visitor
1874// - leaf node visitors are abstract.
1875
1876class AstVisitor BASE_EMBEDDED {
1877 public:
1878 AstVisitor() : stack_overflow_(false) { }
1879 virtual ~AstVisitor() { }
1880
Steve Block6ded16b2010-05-10 14:33:55 +01001881 // Stack overflow check and dynamic dispatch.
1882 void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
Steve Blocka7e24c12009-10-30 11:49:00 +00001883
Steve Block6ded16b2010-05-10 14:33:55 +01001884 // Iteration left-to-right.
Steve Block3ce2e202009-11-05 08:53:23 +00001885 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
Steve Blocka7e24c12009-10-30 11:49:00 +00001886 virtual void VisitStatements(ZoneList<Statement*>* statements);
1887 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
1888
1889 // Stack overflow tracking support.
1890 bool HasStackOverflow() const { return stack_overflow_; }
Steve Block6ded16b2010-05-10 14:33:55 +01001891 bool CheckStackOverflow();
Steve Blocka7e24c12009-10-30 11:49:00 +00001892
1893 // If a stack-overflow exception is encountered when visiting a
1894 // node, calling SetStackOverflow will make sure that the visitor
1895 // bails out without visiting more nodes.
1896 void SetStackOverflow() { stack_overflow_ = true; }
1897
Steve Blocka7e24c12009-10-30 11:49:00 +00001898 // Individual nodes
1899#define DEF_VISIT(type) \
1900 virtual void Visit##type(type* node) = 0;
1901 AST_NODE_LIST(DEF_VISIT)
1902#undef DEF_VISIT
1903
1904 private:
1905 bool stack_overflow_;
1906};
1907
Steve Blocka7e24c12009-10-30 11:49:00 +00001908} } // namespace v8::internal
1909
1910#endif // V8_AST_H_