blob: a01e48daeb3a77a56e94272ded74e11a887e009b [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
Steve Blocka7e24c12009-10-30 11:49:00 +0000835 private:
836 Literal* key_;
837 Expression* value_;
838 Kind kind_;
839 };
840
841 ObjectLiteral(Handle<FixedArray> constant_properties,
842 ZoneList<Property*>* properties,
843 int literal_index,
844 bool is_simple,
Steve Block6ded16b2010-05-10 14:33:55 +0100845 bool fast_elements,
Steve Blocka7e24c12009-10-30 11:49:00 +0000846 int depth)
847 : MaterializedLiteral(literal_index, is_simple, depth),
848 constant_properties_(constant_properties),
Steve Block6ded16b2010-05-10 14:33:55 +0100849 properties_(properties),
850 fast_elements_(fast_elements) {}
Steve Blocka7e24c12009-10-30 11:49:00 +0000851
Ben Murdochf87a2032010-10-22 12:50:53 +0100852 DECLARE_NODE_TYPE(ObjectLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +0000853
854 Handle<FixedArray> constant_properties() const {
855 return constant_properties_;
856 }
857 ZoneList<Property*>* properties() const { return properties_; }
858
Steve Block6ded16b2010-05-10 14:33:55 +0100859 bool fast_elements() const { return fast_elements_; }
860
Steve Blocka7e24c12009-10-30 11:49:00 +0000861 private:
862 Handle<FixedArray> constant_properties_;
863 ZoneList<Property*>* properties_;
Steve Block6ded16b2010-05-10 14:33:55 +0100864 bool fast_elements_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000865};
866
867
868// Node for capturing a regexp literal.
869class RegExpLiteral: public MaterializedLiteral {
870 public:
871 RegExpLiteral(Handle<String> pattern,
872 Handle<String> flags,
873 int literal_index)
874 : MaterializedLiteral(literal_index, false, 1),
875 pattern_(pattern),
876 flags_(flags) {}
877
Ben Murdochf87a2032010-10-22 12:50:53 +0100878 DECLARE_NODE_TYPE(RegExpLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +0000879
880 Handle<String> pattern() const { return pattern_; }
881 Handle<String> flags() const { return flags_; }
882
883 private:
884 Handle<String> pattern_;
885 Handle<String> flags_;
886};
887
888// An array literal has a literals object that is used
889// for minimizing the work when constructing it at runtime.
890class ArrayLiteral: public MaterializedLiteral {
891 public:
Leon Clarkee46be812010-01-19 14:06:41 +0000892 ArrayLiteral(Handle<FixedArray> constant_elements,
Steve Blocka7e24c12009-10-30 11:49:00 +0000893 ZoneList<Expression*>* values,
894 int literal_index,
895 bool is_simple,
896 int depth)
897 : MaterializedLiteral(literal_index, is_simple, depth),
Leon Clarkee46be812010-01-19 14:06:41 +0000898 constant_elements_(constant_elements),
Steve Blocka7e24c12009-10-30 11:49:00 +0000899 values_(values) {}
900
Ben Murdochf87a2032010-10-22 12:50:53 +0100901 DECLARE_NODE_TYPE(ArrayLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +0000902
Leon Clarkee46be812010-01-19 14:06:41 +0000903 Handle<FixedArray> constant_elements() const { return constant_elements_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000904 ZoneList<Expression*>* values() const { return values_; }
905
906 private:
Leon Clarkee46be812010-01-19 14:06:41 +0000907 Handle<FixedArray> constant_elements_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000908 ZoneList<Expression*>* values_;
909};
910
911
912// Node for constructing a context extension object for a catch block.
913// The catch context extension object has one property, the catch
914// variable, which should be DontDelete.
915class CatchExtensionObject: public Expression {
916 public:
917 CatchExtensionObject(Literal* key, VariableProxy* value)
918 : key_(key), value_(value) {
919 }
920
Ben Murdochf87a2032010-10-22 12:50:53 +0100921 DECLARE_NODE_TYPE(CatchExtensionObject)
Steve Blocka7e24c12009-10-30 11:49:00 +0000922
923 Literal* key() const { return key_; }
924 VariableProxy* value() const { return value_; }
925
926 private:
927 Literal* key_;
928 VariableProxy* value_;
929};
930
931
932class VariableProxy: public Expression {
933 public:
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100934 explicit VariableProxy(Variable* var);
935
Ben Murdochf87a2032010-10-22 12:50:53 +0100936 DECLARE_NODE_TYPE(VariableProxy)
Steve Blocka7e24c12009-10-30 11:49:00 +0000937
938 // Type testing & conversion
939 virtual Property* AsProperty() {
940 return var_ == NULL ? NULL : var_->AsProperty();
941 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100942
Steve Blocka7e24c12009-10-30 11:49:00 +0000943 Variable* AsVariable() {
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100944 if (this == NULL || var_ == NULL) return NULL;
945 Expression* rewrite = var_->rewrite();
946 if (rewrite == NULL || rewrite->AsSlot() != NULL) return var_;
947 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000948 }
949
950 virtual bool IsValidLeftHandSide() {
951 return var_ == NULL ? true : var_->IsValidLeftHandSide();
952 }
953
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100954 virtual bool IsTrivial() {
955 // Reading from a mutable variable is a side effect, but the
956 // variable for 'this' is immutable.
957 return is_this_ || is_trivial_;
Andrei Popescu402d9372010-02-26 13:31:12 +0000958 }
959
Steve Blocka7e24c12009-10-30 11:49:00 +0000960 bool IsVariable(Handle<String> n) {
961 return !is_this() && name().is_identical_to(n);
962 }
963
964 bool IsArguments() {
965 Variable* variable = AsVariable();
966 return (variable == NULL) ? false : variable->is_arguments();
967 }
968
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100969 Handle<String> name() const { return name_; }
970 Variable* var() const { return var_; }
971 bool is_this() const { return is_this_; }
972 bool inside_with() const { return inside_with_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100973
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100974 void MarkAsTrivial() { is_trivial_ = true; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000975
976 // Bind this proxy to the variable var.
977 void BindTo(Variable* var);
978
979 protected:
980 Handle<String> name_;
981 Variable* var_; // resolved variable, or NULL
982 bool is_this_;
983 bool inside_with_;
Steve Block6ded16b2010-05-10 14:33:55 +0100984 bool is_trivial_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000985
986 VariableProxy(Handle<String> name, bool is_this, bool inside_with);
987 explicit VariableProxy(bool is_this);
988
989 friend class Scope;
990};
991
992
993class VariableProxySentinel: public VariableProxy {
994 public:
995 virtual bool IsValidLeftHandSide() { return !is_this(); }
996 static VariableProxySentinel* this_proxy() { return &this_proxy_; }
997 static VariableProxySentinel* identifier_proxy() {
998 return &identifier_proxy_;
999 }
1000
1001 private:
1002 explicit VariableProxySentinel(bool is_this) : VariableProxy(is_this) { }
1003 static VariableProxySentinel this_proxy_;
1004 static VariableProxySentinel identifier_proxy_;
1005};
1006
1007
1008class Slot: public Expression {
1009 public:
1010 enum Type {
1011 // A slot in the parameter section on the stack. index() is
1012 // the parameter index, counting left-to-right, starting at 0.
1013 PARAMETER,
1014
1015 // A slot in the local section on the stack. index() is
1016 // the variable index in the stack frame, starting at 0.
1017 LOCAL,
1018
1019 // An indexed slot in a heap context. index() is the
1020 // variable index in the context object on the heap,
1021 // starting at 0. var()->scope() is the corresponding
1022 // scope.
1023 CONTEXT,
1024
1025 // A named slot in a heap context. var()->name() is the
1026 // variable name in the context object on the heap,
1027 // with lookup starting at the current context. index()
1028 // is invalid.
Steve Blockd0582a62009-12-15 09:54:21 +00001029 LOOKUP
Steve Blocka7e24c12009-10-30 11:49:00 +00001030 };
1031
1032 Slot(Variable* var, Type type, int index)
1033 : var_(var), type_(type), index_(index) {
1034 ASSERT(var != NULL);
1035 }
1036
Ben Murdochf87a2032010-10-22 12:50:53 +01001037 DECLARE_NODE_TYPE(Slot)
Steve Blocka7e24c12009-10-30 11:49:00 +00001038
Steve Block6ded16b2010-05-10 14:33:55 +01001039 bool IsStackAllocated() { return type_ == PARAMETER || type_ == LOCAL; }
1040
Steve Blocka7e24c12009-10-30 11:49:00 +00001041 // Accessors
1042 Variable* var() const { return var_; }
1043 Type type() const { return type_; }
1044 int index() const { return index_; }
1045 bool is_arguments() const { return var_->is_arguments(); }
1046
1047 private:
1048 Variable* var_;
1049 Type type_;
1050 int index_;
1051};
1052
1053
1054class Property: public Expression {
1055 public:
1056 // Synthetic properties are property lookups introduced by the system,
1057 // to objects that aren't visible to the user. Function calls to synthetic
1058 // properties should use the global object as receiver, not the base object
1059 // of the resolved Reference.
1060 enum Type { NORMAL, SYNTHETIC };
1061 Property(Expression* obj, Expression* key, int pos, Type type = NORMAL)
1062 : obj_(obj), key_(key), pos_(pos), type_(type) { }
1063
Ben Murdochf87a2032010-10-22 12:50:53 +01001064 DECLARE_NODE_TYPE(Property)
Steve Blocka7e24c12009-10-30 11:49:00 +00001065
1066 virtual bool IsValidLeftHandSide() { return true; }
1067
1068 Expression* obj() const { return obj_; }
1069 Expression* key() const { return key_; }
1070 int position() const { return pos_; }
1071 bool is_synthetic() const { return type_ == SYNTHETIC; }
1072
1073 // Returns a property singleton property access on 'this'. Used
1074 // during preparsing.
1075 static Property* this_property() { return &this_property_; }
1076
1077 private:
1078 Expression* obj_;
1079 Expression* key_;
1080 int pos_;
1081 Type type_;
1082
1083 // Dummy property used during preparsing.
1084 static Property this_property_;
1085};
1086
1087
1088class Call: public Expression {
1089 public:
1090 Call(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1091 : expression_(expression), arguments_(arguments), pos_(pos) { }
1092
Ben Murdochf87a2032010-10-22 12:50:53 +01001093 DECLARE_NODE_TYPE(Call)
Steve Blocka7e24c12009-10-30 11:49:00 +00001094
1095 Expression* expression() const { return expression_; }
1096 ZoneList<Expression*>* arguments() const { return arguments_; }
1097 int position() { return pos_; }
1098
1099 static Call* sentinel() { return &sentinel_; }
1100
1101 private:
1102 Expression* expression_;
1103 ZoneList<Expression*>* arguments_;
1104 int pos_;
1105
1106 static Call sentinel_;
1107};
1108
1109
1110class CallNew: public Expression {
1111 public:
1112 CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1113 : expression_(expression), arguments_(arguments), pos_(pos) { }
1114
Ben Murdochf87a2032010-10-22 12:50:53 +01001115 DECLARE_NODE_TYPE(CallNew)
Steve Blocka7e24c12009-10-30 11:49:00 +00001116
1117 Expression* expression() const { return expression_; }
1118 ZoneList<Expression*>* arguments() const { return arguments_; }
1119 int position() { return pos_; }
1120
1121 private:
1122 Expression* expression_;
1123 ZoneList<Expression*>* arguments_;
1124 int pos_;
1125};
1126
1127
1128// The CallRuntime class does not represent any official JavaScript
1129// language construct. Instead it is used to call a C or JS function
1130// with a set of arguments. This is used from the builtins that are
1131// implemented in JavaScript (see "v8natives.js").
1132class CallRuntime: public Expression {
1133 public:
1134 CallRuntime(Handle<String> name,
1135 Runtime::Function* function,
1136 ZoneList<Expression*>* arguments)
1137 : name_(name), function_(function), arguments_(arguments) { }
1138
Ben Murdochf87a2032010-10-22 12:50:53 +01001139 DECLARE_NODE_TYPE(CallRuntime)
Steve Blocka7e24c12009-10-30 11:49:00 +00001140
1141 Handle<String> name() const { return name_; }
1142 Runtime::Function* function() const { return function_; }
1143 ZoneList<Expression*>* arguments() const { return arguments_; }
Steve Blockd0582a62009-12-15 09:54:21 +00001144 bool is_jsruntime() const { return function_ == NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001145
1146 private:
1147 Handle<String> name_;
1148 Runtime::Function* function_;
1149 ZoneList<Expression*>* arguments_;
1150};
1151
1152
1153class UnaryOperation: public Expression {
1154 public:
1155 UnaryOperation(Token::Value op, Expression* expression)
1156 : op_(op), expression_(expression) {
1157 ASSERT(Token::IsUnaryOp(op));
1158 }
1159
Ben Murdochf87a2032010-10-22 12:50:53 +01001160 DECLARE_NODE_TYPE(UnaryOperation)
Steve Blocka7e24c12009-10-30 11:49:00 +00001161
Ben Murdochf87a2032010-10-22 12:50:53 +01001162 virtual bool ResultOverwriteAllowed();
Steve Blocka7e24c12009-10-30 11:49:00 +00001163
1164 Token::Value op() const { return op_; }
1165 Expression* expression() const { return expression_; }
1166
1167 private:
1168 Token::Value op_;
1169 Expression* expression_;
1170};
1171
1172
1173class BinaryOperation: public Expression {
1174 public:
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001175 BinaryOperation(Token::Value op,
1176 Expression* left,
1177 Expression* right,
1178 int pos)
1179 : op_(op), left_(left), right_(right), pos_(pos) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001180 ASSERT(Token::IsBinaryOp(op));
1181 }
1182
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001183 // Create the binary operation corresponding to a compound assignment.
1184 explicit BinaryOperation(Assignment* assignment);
Steve Block6ded16b2010-05-10 14:33:55 +01001185
Ben Murdochf87a2032010-10-22 12:50:53 +01001186 DECLARE_NODE_TYPE(BinaryOperation)
Steve Blocka7e24c12009-10-30 11:49:00 +00001187
Ben Murdochf87a2032010-10-22 12:50:53 +01001188 virtual bool ResultOverwriteAllowed();
Steve Blocka7e24c12009-10-30 11:49:00 +00001189
Steve Blocka7e24c12009-10-30 11:49:00 +00001190 Token::Value op() const { return op_; }
1191 Expression* left() const { return left_; }
1192 Expression* right() const { return right_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001193 int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001194
1195 private:
1196 Token::Value op_;
1197 Expression* left_;
1198 Expression* right_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001199 int pos_;
1200};
1201
1202
1203class IncrementOperation: public Expression {
1204 public:
1205 IncrementOperation(Token::Value op, Expression* expr)
1206 : op_(op), expression_(expr) {
1207 ASSERT(Token::IsCountOp(op));
1208 }
1209
Ben Murdochf87a2032010-10-22 12:50:53 +01001210 DECLARE_NODE_TYPE(IncrementOperation)
1211
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001212 Token::Value op() const { return op_; }
1213 bool is_increment() { return op_ == Token::INC; }
1214 Expression* expression() const { return expression_; }
1215
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001216 private:
1217 Token::Value op_;
1218 Expression* expression_;
1219 int pos_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001220};
1221
1222
1223class CountOperation: public Expression {
1224 public:
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001225 CountOperation(bool is_prefix, IncrementOperation* increment, int pos)
1226 : is_prefix_(is_prefix), increment_(increment), pos_(pos) { }
Steve Block6ded16b2010-05-10 14:33:55 +01001227
Ben Murdochf87a2032010-10-22 12:50:53 +01001228 DECLARE_NODE_TYPE(CountOperation)
Steve Block6ded16b2010-05-10 14:33:55 +01001229
Steve Blocka7e24c12009-10-30 11:49:00 +00001230 bool is_prefix() const { return is_prefix_; }
1231 bool is_postfix() const { return !is_prefix_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001232
1233 Token::Value op() const { return increment_->op(); }
Leon Clarkee46be812010-01-19 14:06:41 +00001234 Token::Value binary_op() {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001235 return (op() == Token::INC) ? Token::ADD : Token::SUB;
Leon Clarkee46be812010-01-19 14:06:41 +00001236 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001237
1238 Expression* expression() const { return increment_->expression(); }
1239 IncrementOperation* increment() const { return increment_; }
1240 int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001241
1242 virtual void MarkAsStatement() { is_prefix_ = true; }
1243
1244 private:
1245 bool is_prefix_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001246 IncrementOperation* increment_;
1247 int pos_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001248};
1249
1250
1251class CompareOperation: public Expression {
1252 public:
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001253 CompareOperation(Token::Value op,
1254 Expression* left,
1255 Expression* right,
1256 int pos)
1257 : op_(op), left_(left), right_(right), pos_(pos) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001258 ASSERT(Token::IsCompareOp(op));
1259 }
1260
Ben Murdochf87a2032010-10-22 12:50:53 +01001261 DECLARE_NODE_TYPE(CompareOperation)
Steve Blocka7e24c12009-10-30 11:49:00 +00001262
1263 Token::Value op() const { return op_; }
1264 Expression* left() const { return left_; }
1265 Expression* right() const { return right_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001266 int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001267
1268 private:
1269 Token::Value op_;
1270 Expression* left_;
1271 Expression* right_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001272 int pos_;
1273};
1274
1275
1276class CompareToNull: public Expression {
1277 public:
1278 CompareToNull(bool is_strict, Expression* expression)
1279 : is_strict_(is_strict), expression_(expression) { }
1280
Ben Murdochf87a2032010-10-22 12:50:53 +01001281 DECLARE_NODE_TYPE(CompareToNull)
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001282
1283 bool is_strict() const { return is_strict_; }
1284 Token::Value op() const { return is_strict_ ? Token::EQ_STRICT : Token::EQ; }
1285 Expression* expression() const { return expression_; }
1286
1287 private:
1288 bool is_strict_;
1289 Expression* expression_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001290};
1291
1292
1293class Conditional: public Expression {
1294 public:
1295 Conditional(Expression* condition,
1296 Expression* then_expression,
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001297 Expression* else_expression,
1298 int then_expression_position,
1299 int else_expression_position)
Steve Blocka7e24c12009-10-30 11:49:00 +00001300 : condition_(condition),
1301 then_expression_(then_expression),
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001302 else_expression_(else_expression),
1303 then_expression_position_(then_expression_position),
1304 else_expression_position_(else_expression_position) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001305
Ben Murdochf87a2032010-10-22 12:50:53 +01001306 DECLARE_NODE_TYPE(Conditional)
Steve Blocka7e24c12009-10-30 11:49:00 +00001307
1308 Expression* condition() const { return condition_; }
1309 Expression* then_expression() const { return then_expression_; }
1310 Expression* else_expression() const { return else_expression_; }
1311
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001312 int then_expression_position() { return then_expression_position_; }
1313 int else_expression_position() { return else_expression_position_; }
1314
Steve Blocka7e24c12009-10-30 11:49:00 +00001315 private:
1316 Expression* condition_;
1317 Expression* then_expression_;
1318 Expression* else_expression_;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001319 int then_expression_position_;
1320 int else_expression_position_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001321};
1322
1323
1324class Assignment: public Expression {
1325 public:
1326 Assignment(Token::Value op, Expression* target, Expression* value, int pos)
1327 : op_(op), target_(target), value_(value), pos_(pos),
1328 block_start_(false), block_end_(false) {
1329 ASSERT(Token::IsAssignmentOp(op));
1330 }
1331
Ben Murdochf87a2032010-10-22 12:50:53 +01001332 DECLARE_NODE_TYPE(Assignment)
Steve Blocka7e24c12009-10-30 11:49:00 +00001333
Steve Block6ded16b2010-05-10 14:33:55 +01001334 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1335
Steve Blocka7e24c12009-10-30 11:49:00 +00001336 Token::Value binary_op() const;
1337
1338 Token::Value op() const { return op_; }
1339 Expression* target() const { return target_; }
1340 Expression* value() const { return value_; }
1341 int position() { return pos_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001342 // This check relies on the definition order of token in token.h.
1343 bool is_compound() const { return op() > Token::ASSIGN; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001344
1345 // An initialization block is a series of statments of the form
1346 // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1347 // ending of these blocks to allow for optimizations of initialization
1348 // blocks.
1349 bool starts_initialization_block() { return block_start_; }
1350 bool ends_initialization_block() { return block_end_; }
1351 void mark_block_start() { block_start_ = true; }
1352 void mark_block_end() { block_end_ = true; }
1353
1354 private:
1355 Token::Value op_;
1356 Expression* target_;
1357 Expression* value_;
1358 int pos_;
1359 bool block_start_;
1360 bool block_end_;
1361};
1362
1363
1364class Throw: public Expression {
1365 public:
1366 Throw(Expression* exception, int pos)
1367 : exception_(exception), pos_(pos) {}
1368
Ben Murdochf87a2032010-10-22 12:50:53 +01001369 DECLARE_NODE_TYPE(Throw)
Steve Block6ded16b2010-05-10 14:33:55 +01001370
Steve Blocka7e24c12009-10-30 11:49:00 +00001371 Expression* exception() const { return exception_; }
1372 int position() const { return pos_; }
1373
1374 private:
1375 Expression* exception_;
1376 int pos_;
1377};
1378
1379
1380class FunctionLiteral: public Expression {
1381 public:
1382 FunctionLiteral(Handle<String> name,
1383 Scope* scope,
1384 ZoneList<Statement*>* body,
1385 int materialized_literal_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00001386 int expected_property_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00001387 bool has_only_simple_this_property_assignments,
1388 Handle<FixedArray> this_property_assignments,
1389 int num_parameters,
1390 int start_position,
1391 int end_position,
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001392 bool is_expression,
1393 bool contains_loops)
Steve Blocka7e24c12009-10-30 11:49:00 +00001394 : name_(name),
1395 scope_(scope),
1396 body_(body),
1397 materialized_literal_count_(materialized_literal_count),
Steve Blocka7e24c12009-10-30 11:49:00 +00001398 expected_property_count_(expected_property_count),
Steve Blocka7e24c12009-10-30 11:49:00 +00001399 has_only_simple_this_property_assignments_(
1400 has_only_simple_this_property_assignments),
1401 this_property_assignments_(this_property_assignments),
1402 num_parameters_(num_parameters),
1403 start_position_(start_position),
1404 end_position_(end_position),
1405 is_expression_(is_expression),
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001406 contains_loops_(contains_loops),
Steve Blocka7e24c12009-10-30 11:49:00 +00001407 function_token_position_(RelocInfo::kNoPosition),
Steve Blockd0582a62009-12-15 09:54:21 +00001408 inferred_name_(Heap::empty_string()),
Leon Clarked91b9f72010-01-27 17:25:45 +00001409 try_full_codegen_(false) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001410#ifdef DEBUG
1411 already_compiled_ = false;
1412#endif
1413 }
1414
Ben Murdochf87a2032010-10-22 12:50:53 +01001415 DECLARE_NODE_TYPE(FunctionLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00001416
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001417 Handle<String> name() const { return name_; }
1418 Scope* scope() const { return scope_; }
1419 ZoneList<Statement*>* body() const { return body_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001420 void set_function_token_position(int pos) { function_token_position_ = pos; }
1421 int function_token_position() const { return function_token_position_; }
1422 int start_position() const { return start_position_; }
1423 int end_position() const { return end_position_; }
1424 bool is_expression() const { return is_expression_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001425 bool contains_loops() const { return contains_loops_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001426
1427 int materialized_literal_count() { return materialized_literal_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001428 int expected_property_count() { return expected_property_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001429 bool has_only_simple_this_property_assignments() {
1430 return has_only_simple_this_property_assignments_;
1431 }
1432 Handle<FixedArray> this_property_assignments() {
1433 return this_property_assignments_;
1434 }
1435 int num_parameters() { return num_parameters_; }
1436
1437 bool AllowsLazyCompilation();
1438
Ben Murdochf87a2032010-10-22 12:50:53 +01001439 Handle<String> debug_name() const {
1440 if (name_->length() > 0) return name_;
1441 return inferred_name();
1442 }
1443
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001444 Handle<String> inferred_name() const { return inferred_name_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001445 void set_inferred_name(Handle<String> inferred_name) {
1446 inferred_name_ = inferred_name;
1447 }
1448
Leon Clarked91b9f72010-01-27 17:25:45 +00001449 bool try_full_codegen() { return try_full_codegen_; }
1450 void set_try_full_codegen(bool flag) { try_full_codegen_ = flag; }
Steve Blockd0582a62009-12-15 09:54:21 +00001451
Steve Blocka7e24c12009-10-30 11:49:00 +00001452#ifdef DEBUG
1453 void mark_as_compiled() {
1454 ASSERT(!already_compiled_);
1455 already_compiled_ = true;
1456 }
1457#endif
1458
1459 private:
1460 Handle<String> name_;
1461 Scope* scope_;
1462 ZoneList<Statement*>* body_;
1463 int materialized_literal_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001464 int expected_property_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001465 bool has_only_simple_this_property_assignments_;
1466 Handle<FixedArray> this_property_assignments_;
1467 int num_parameters_;
1468 int start_position_;
1469 int end_position_;
1470 bool is_expression_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001471 bool contains_loops_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001472 int function_token_position_;
1473 Handle<String> inferred_name_;
Leon Clarked91b9f72010-01-27 17:25:45 +00001474 bool try_full_codegen_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001475#ifdef DEBUG
1476 bool already_compiled_;
1477#endif
1478};
1479
1480
Steve Block6ded16b2010-05-10 14:33:55 +01001481class SharedFunctionInfoLiteral: public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00001482 public:
Steve Block6ded16b2010-05-10 14:33:55 +01001483 explicit SharedFunctionInfoLiteral(
1484 Handle<SharedFunctionInfo> shared_function_info)
1485 : shared_function_info_(shared_function_info) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001486
Ben Murdochf87a2032010-10-22 12:50:53 +01001487 DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
1488
Steve Block6ded16b2010-05-10 14:33:55 +01001489 Handle<SharedFunctionInfo> shared_function_info() const {
1490 return shared_function_info_;
1491 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001492
Steve Blocka7e24c12009-10-30 11:49:00 +00001493 private:
Steve Block6ded16b2010-05-10 14:33:55 +01001494 Handle<SharedFunctionInfo> shared_function_info_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001495};
1496
1497
1498class ThisFunction: public Expression {
1499 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001500 DECLARE_NODE_TYPE(ThisFunction)
Steve Blocka7e24c12009-10-30 11:49:00 +00001501};
1502
1503
1504// ----------------------------------------------------------------------------
1505// Regular expressions
1506
1507
1508class RegExpVisitor BASE_EMBEDDED {
1509 public:
1510 virtual ~RegExpVisitor() { }
1511#define MAKE_CASE(Name) \
1512 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
1513 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
1514#undef MAKE_CASE
1515};
1516
1517
1518class RegExpTree: public ZoneObject {
1519 public:
1520 static const int kInfinity = kMaxInt;
1521 virtual ~RegExpTree() { }
1522 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
1523 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1524 RegExpNode* on_success) = 0;
1525 virtual bool IsTextElement() { return false; }
Ben Murdochf87a2032010-10-22 12:50:53 +01001526 virtual bool IsAnchoredAtStart() { return false; }
1527 virtual bool IsAnchoredAtEnd() { return false; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001528 virtual int min_match() = 0;
1529 virtual int max_match() = 0;
1530 // Returns the interval of registers used for captures within this
1531 // expression.
1532 virtual Interval CaptureRegisters() { return Interval::Empty(); }
1533 virtual void AppendToText(RegExpText* text);
1534 SmartPointer<const char> ToString();
1535#define MAKE_ASTYPE(Name) \
1536 virtual RegExp##Name* As##Name(); \
1537 virtual bool Is##Name();
1538 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
1539#undef MAKE_ASTYPE
1540};
1541
1542
1543class RegExpDisjunction: public RegExpTree {
1544 public:
1545 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
1546 virtual void* Accept(RegExpVisitor* visitor, void* data);
1547 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1548 RegExpNode* on_success);
1549 virtual RegExpDisjunction* AsDisjunction();
1550 virtual Interval CaptureRegisters();
1551 virtual bool IsDisjunction();
Ben Murdochf87a2032010-10-22 12:50:53 +01001552 virtual bool IsAnchoredAtStart();
1553 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001554 virtual int min_match() { return min_match_; }
1555 virtual int max_match() { return max_match_; }
1556 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
1557 private:
1558 ZoneList<RegExpTree*>* alternatives_;
1559 int min_match_;
1560 int max_match_;
1561};
1562
1563
1564class RegExpAlternative: public RegExpTree {
1565 public:
1566 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
1567 virtual void* Accept(RegExpVisitor* visitor, void* data);
1568 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1569 RegExpNode* on_success);
1570 virtual RegExpAlternative* AsAlternative();
1571 virtual Interval CaptureRegisters();
1572 virtual bool IsAlternative();
Ben Murdochf87a2032010-10-22 12:50:53 +01001573 virtual bool IsAnchoredAtStart();
1574 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001575 virtual int min_match() { return min_match_; }
1576 virtual int max_match() { return max_match_; }
1577 ZoneList<RegExpTree*>* nodes() { return nodes_; }
1578 private:
1579 ZoneList<RegExpTree*>* nodes_;
1580 int min_match_;
1581 int max_match_;
1582};
1583
1584
1585class RegExpAssertion: public RegExpTree {
1586 public:
1587 enum Type {
1588 START_OF_LINE,
1589 START_OF_INPUT,
1590 END_OF_LINE,
1591 END_OF_INPUT,
1592 BOUNDARY,
1593 NON_BOUNDARY
1594 };
1595 explicit RegExpAssertion(Type type) : type_(type) { }
1596 virtual void* Accept(RegExpVisitor* visitor, void* data);
1597 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1598 RegExpNode* on_success);
1599 virtual RegExpAssertion* AsAssertion();
1600 virtual bool IsAssertion();
Ben Murdochf87a2032010-10-22 12:50:53 +01001601 virtual bool IsAnchoredAtStart();
1602 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001603 virtual int min_match() { return 0; }
1604 virtual int max_match() { return 0; }
1605 Type type() { return type_; }
1606 private:
1607 Type type_;
1608};
1609
1610
1611class CharacterSet BASE_EMBEDDED {
1612 public:
1613 explicit CharacterSet(uc16 standard_set_type)
1614 : ranges_(NULL),
1615 standard_set_type_(standard_set_type) {}
1616 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
1617 : ranges_(ranges),
1618 standard_set_type_(0) {}
1619 ZoneList<CharacterRange>* ranges();
1620 uc16 standard_set_type() { return standard_set_type_; }
1621 void set_standard_set_type(uc16 special_set_type) {
1622 standard_set_type_ = special_set_type;
1623 }
1624 bool is_standard() { return standard_set_type_ != 0; }
Leon Clarkee46be812010-01-19 14:06:41 +00001625 void Canonicalize();
Steve Blocka7e24c12009-10-30 11:49:00 +00001626 private:
1627 ZoneList<CharacterRange>* ranges_;
1628 // If non-zero, the value represents a standard set (e.g., all whitespace
1629 // characters) without having to expand the ranges.
1630 uc16 standard_set_type_;
1631};
1632
1633
1634class RegExpCharacterClass: public RegExpTree {
1635 public:
1636 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
1637 : set_(ranges),
1638 is_negated_(is_negated) { }
1639 explicit RegExpCharacterClass(uc16 type)
1640 : set_(type),
1641 is_negated_(false) { }
1642 virtual void* Accept(RegExpVisitor* visitor, void* data);
1643 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1644 RegExpNode* on_success);
1645 virtual RegExpCharacterClass* AsCharacterClass();
1646 virtual bool IsCharacterClass();
1647 virtual bool IsTextElement() { return true; }
1648 virtual int min_match() { return 1; }
1649 virtual int max_match() { return 1; }
1650 virtual void AppendToText(RegExpText* text);
1651 CharacterSet character_set() { return set_; }
1652 // TODO(lrn): Remove need for complex version if is_standard that
1653 // recognizes a mangled standard set and just do { return set_.is_special(); }
1654 bool is_standard();
1655 // Returns a value representing the standard character set if is_standard()
1656 // returns true.
1657 // Currently used values are:
1658 // s : unicode whitespace
1659 // S : unicode non-whitespace
1660 // w : ASCII word character (digit, letter, underscore)
1661 // W : non-ASCII word character
1662 // d : ASCII digit
1663 // D : non-ASCII digit
1664 // . : non-unicode non-newline
1665 // * : All characters
1666 uc16 standard_type() { return set_.standard_set_type(); }
1667 ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
1668 bool is_negated() { return is_negated_; }
1669 private:
1670 CharacterSet set_;
1671 bool is_negated_;
1672};
1673
1674
1675class RegExpAtom: public RegExpTree {
1676 public:
1677 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
1678 virtual void* Accept(RegExpVisitor* visitor, void* data);
1679 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1680 RegExpNode* on_success);
1681 virtual RegExpAtom* AsAtom();
1682 virtual bool IsAtom();
1683 virtual bool IsTextElement() { return true; }
1684 virtual int min_match() { return data_.length(); }
1685 virtual int max_match() { return data_.length(); }
1686 virtual void AppendToText(RegExpText* text);
1687 Vector<const uc16> data() { return data_; }
1688 int length() { return data_.length(); }
1689 private:
1690 Vector<const uc16> data_;
1691};
1692
1693
1694class RegExpText: public RegExpTree {
1695 public:
1696 RegExpText() : elements_(2), length_(0) {}
1697 virtual void* Accept(RegExpVisitor* visitor, void* data);
1698 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1699 RegExpNode* on_success);
1700 virtual RegExpText* AsText();
1701 virtual bool IsText();
1702 virtual bool IsTextElement() { return true; }
1703 virtual int min_match() { return length_; }
1704 virtual int max_match() { return length_; }
1705 virtual void AppendToText(RegExpText* text);
1706 void AddElement(TextElement elm) {
1707 elements_.Add(elm);
1708 length_ += elm.length();
Iain Merrick9ac36c92010-09-13 15:29:50 +01001709 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001710 ZoneList<TextElement>* elements() { return &elements_; }
1711 private:
1712 ZoneList<TextElement> elements_;
1713 int length_;
1714};
1715
1716
1717class RegExpQuantifier: public RegExpTree {
1718 public:
Leon Clarkee46be812010-01-19 14:06:41 +00001719 enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
1720 RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
1721 : body_(body),
1722 min_(min),
Steve Blocka7e24c12009-10-30 11:49:00 +00001723 max_(max),
Leon Clarkee46be812010-01-19 14:06:41 +00001724 min_match_(min * body->min_match()),
1725 type_(type) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001726 if (max > 0 && body->max_match() > kInfinity / max) {
1727 max_match_ = kInfinity;
1728 } else {
1729 max_match_ = max * body->max_match();
1730 }
1731 }
1732 virtual void* Accept(RegExpVisitor* visitor, void* data);
1733 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1734 RegExpNode* on_success);
1735 static RegExpNode* ToNode(int min,
1736 int max,
1737 bool is_greedy,
1738 RegExpTree* body,
1739 RegExpCompiler* compiler,
1740 RegExpNode* on_success,
1741 bool not_at_start = false);
1742 virtual RegExpQuantifier* AsQuantifier();
1743 virtual Interval CaptureRegisters();
1744 virtual bool IsQuantifier();
1745 virtual int min_match() { return min_match_; }
1746 virtual int max_match() { return max_match_; }
1747 int min() { return min_; }
1748 int max() { return max_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001749 bool is_possessive() { return type_ == POSSESSIVE; }
1750 bool is_non_greedy() { return type_ == NON_GREEDY; }
1751 bool is_greedy() { return type_ == GREEDY; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001752 RegExpTree* body() { return body_; }
1753 private:
Leon Clarkee46be812010-01-19 14:06:41 +00001754 RegExpTree* body_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001755 int min_;
1756 int max_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001757 int min_match_;
1758 int max_match_;
Leon Clarkee46be812010-01-19 14:06:41 +00001759 Type type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001760};
1761
1762
1763class RegExpCapture: public RegExpTree {
1764 public:
1765 explicit RegExpCapture(RegExpTree* body, int index)
1766 : body_(body), index_(index) { }
1767 virtual void* Accept(RegExpVisitor* visitor, void* data);
1768 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1769 RegExpNode* on_success);
1770 static RegExpNode* ToNode(RegExpTree* body,
1771 int index,
1772 RegExpCompiler* compiler,
1773 RegExpNode* on_success);
1774 virtual RegExpCapture* AsCapture();
Ben Murdochf87a2032010-10-22 12:50:53 +01001775 virtual bool IsAnchoredAtStart();
1776 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001777 virtual Interval CaptureRegisters();
1778 virtual bool IsCapture();
1779 virtual int min_match() { return body_->min_match(); }
1780 virtual int max_match() { return body_->max_match(); }
1781 RegExpTree* body() { return body_; }
1782 int index() { return index_; }
1783 static int StartRegister(int index) { return index * 2; }
1784 static int EndRegister(int index) { return index * 2 + 1; }
1785 private:
1786 RegExpTree* body_;
1787 int index_;
1788};
1789
1790
1791class RegExpLookahead: public RegExpTree {
1792 public:
1793 RegExpLookahead(RegExpTree* body,
1794 bool is_positive,
1795 int capture_count,
1796 int capture_from)
1797 : body_(body),
1798 is_positive_(is_positive),
1799 capture_count_(capture_count),
1800 capture_from_(capture_from) { }
1801
1802 virtual void* Accept(RegExpVisitor* visitor, void* data);
1803 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1804 RegExpNode* on_success);
1805 virtual RegExpLookahead* AsLookahead();
1806 virtual Interval CaptureRegisters();
1807 virtual bool IsLookahead();
Ben Murdochf87a2032010-10-22 12:50:53 +01001808 virtual bool IsAnchoredAtStart();
Steve Blocka7e24c12009-10-30 11:49:00 +00001809 virtual int min_match() { return 0; }
1810 virtual int max_match() { return 0; }
1811 RegExpTree* body() { return body_; }
1812 bool is_positive() { return is_positive_; }
1813 int capture_count() { return capture_count_; }
1814 int capture_from() { return capture_from_; }
1815 private:
1816 RegExpTree* body_;
1817 bool is_positive_;
1818 int capture_count_;
1819 int capture_from_;
1820};
1821
1822
1823class RegExpBackReference: public RegExpTree {
1824 public:
1825 explicit RegExpBackReference(RegExpCapture* capture)
1826 : capture_(capture) { }
1827 virtual void* Accept(RegExpVisitor* visitor, void* data);
1828 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1829 RegExpNode* on_success);
1830 virtual RegExpBackReference* AsBackReference();
1831 virtual bool IsBackReference();
1832 virtual int min_match() { return 0; }
1833 virtual int max_match() { return capture_->max_match(); }
1834 int index() { return capture_->index(); }
1835 RegExpCapture* capture() { return capture_; }
1836 private:
1837 RegExpCapture* capture_;
1838};
1839
1840
1841class RegExpEmpty: public RegExpTree {
1842 public:
1843 RegExpEmpty() { }
1844 virtual void* Accept(RegExpVisitor* visitor, void* data);
1845 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1846 RegExpNode* on_success);
1847 virtual RegExpEmpty* AsEmpty();
1848 virtual bool IsEmpty();
1849 virtual int min_match() { return 0; }
1850 virtual int max_match() { return 0; }
1851 static RegExpEmpty* GetInstance() { return &kInstance; }
1852 private:
1853 static RegExpEmpty kInstance;
1854};
1855
1856
1857// ----------------------------------------------------------------------------
1858// Basic visitor
1859// - leaf node visitors are abstract.
1860
1861class AstVisitor BASE_EMBEDDED {
1862 public:
1863 AstVisitor() : stack_overflow_(false) { }
1864 virtual ~AstVisitor() { }
1865
Steve Block6ded16b2010-05-10 14:33:55 +01001866 // Stack overflow check and dynamic dispatch.
1867 void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
Steve Blocka7e24c12009-10-30 11:49:00 +00001868
Steve Block6ded16b2010-05-10 14:33:55 +01001869 // Iteration left-to-right.
Steve Block3ce2e202009-11-05 08:53:23 +00001870 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
Steve Blocka7e24c12009-10-30 11:49:00 +00001871 virtual void VisitStatements(ZoneList<Statement*>* statements);
1872 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
1873
1874 // Stack overflow tracking support.
1875 bool HasStackOverflow() const { return stack_overflow_; }
Steve Block6ded16b2010-05-10 14:33:55 +01001876 bool CheckStackOverflow();
Steve Blocka7e24c12009-10-30 11:49:00 +00001877
1878 // If a stack-overflow exception is encountered when visiting a
1879 // node, calling SetStackOverflow will make sure that the visitor
1880 // bails out without visiting more nodes.
1881 void SetStackOverflow() { stack_overflow_ = true; }
1882
Steve Blocka7e24c12009-10-30 11:49:00 +00001883 // Individual nodes
1884#define DEF_VISIT(type) \
1885 virtual void Visit##type(type* node) = 0;
1886 AST_NODE_LIST(DEF_VISIT)
1887#undef DEF_VISIT
1888
1889 private:
1890 bool stack_overflow_;
1891};
1892
Steve Blocka7e24c12009-10-30 11:49:00 +00001893} } // namespace v8::internal
1894
1895#endif // V8_AST_H_