blob: a3a97341dd34971f899017add3a4e08bca82df22 [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) \
92 V(CountOperation) \
93 V(BinaryOperation) \
94 V(CompareOperation) \
95 V(ThisFunction)
96
97#define AST_NODE_LIST(V) \
98 V(Declaration) \
99 STATEMENT_NODE_LIST(V) \
100 EXPRESSION_NODE_LIST(V)
101
102// Forward declarations
103class TargetCollector;
104class MaterializedLiteral;
Andrei Popescu402d9372010-02-26 13:31:12 +0000105class DefinitionInfo;
Steve Block6ded16b2010-05-10 14:33:55 +0100106class BitVector;
Steve Blocka7e24c12009-10-30 11:49:00 +0000107
108#define DEF_FORWARD_DECLARATION(type) class type;
109AST_NODE_LIST(DEF_FORWARD_DECLARATION)
110#undef DEF_FORWARD_DECLARATION
111
112
113// Typedef only introduced to avoid unreadable code.
114// Please do appreciate the required space in "> >".
115typedef ZoneList<Handle<String> > ZoneStringList;
116typedef ZoneList<Handle<Object> > ZoneObjectList;
117
118
119class AstNode: public ZoneObject {
120 public:
Steve Block6ded16b2010-05-10 14:33:55 +0100121 static const int kNoNumber = -1;
122
123 AstNode() : num_(kNoNumber) {}
124
125 explicit AstNode(AstNode* other);
126
Steve Blocka7e24c12009-10-30 11:49:00 +0000127 virtual ~AstNode() { }
128 virtual void Accept(AstVisitor* v) = 0;
129
130 // Type testing & conversion.
131 virtual Statement* AsStatement() { return NULL; }
Steve Block6ded16b2010-05-10 14:33:55 +0100132 virtual Block* AsBlock() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000133 virtual ExpressionStatement* AsExpressionStatement() { return NULL; }
134 virtual EmptyStatement* AsEmptyStatement() { return NULL; }
135 virtual Expression* AsExpression() { return NULL; }
136 virtual Literal* AsLiteral() { return NULL; }
137 virtual Slot* AsSlot() { return NULL; }
138 virtual VariableProxy* AsVariableProxy() { return NULL; }
139 virtual Property* AsProperty() { return NULL; }
140 virtual Call* AsCall() { return NULL; }
141 virtual TargetCollector* AsTargetCollector() { return NULL; }
142 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
143 virtual IterationStatement* AsIterationStatement() { return NULL; }
Steve Block6ded16b2010-05-10 14:33:55 +0100144 virtual ForStatement* AsForStatement() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000145 virtual UnaryOperation* AsUnaryOperation() { return NULL; }
Steve Block6ded16b2010-05-10 14:33:55 +0100146 virtual CountOperation* AsCountOperation() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000147 virtual BinaryOperation* AsBinaryOperation() { return NULL; }
148 virtual Assignment* AsAssignment() { return NULL; }
149 virtual FunctionLiteral* AsFunctionLiteral() { return NULL; }
150 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
151 virtual ObjectLiteral* AsObjectLiteral() { return NULL; }
152 virtual ArrayLiteral* AsArrayLiteral() { return NULL; }
Leon Clarkee46be812010-01-19 14:06:41 +0000153 virtual CompareOperation* AsCompareOperation() { return NULL; }
Steve Block6ded16b2010-05-10 14:33:55 +0100154
155 // True if the AST node is critical (its execution is needed or externally
156 // visible in some way).
157 virtual bool IsCritical() {
158 UNREACHABLE();
159 return true;
160 }
161
162 int num() { return num_; }
163 void set_num(int n) { num_ = n; }
164
165 private:
166 // Support for ast node numbering.
167 int num_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000168};
169
170
171class Statement: public AstNode {
172 public:
173 Statement() : statement_pos_(RelocInfo::kNoPosition) {}
174
Steve Block6ded16b2010-05-10 14:33:55 +0100175 explicit Statement(Statement* other);
176
Steve Blocka7e24c12009-10-30 11:49:00 +0000177 virtual Statement* AsStatement() { return this; }
178 virtual ReturnStatement* AsReturnStatement() { return NULL; }
179
Steve Block6ded16b2010-05-10 14:33:55 +0100180 virtual Assignment* StatementAsSimpleAssignment() { return NULL; }
181 virtual CountOperation* StatementAsCountOperation() { return NULL; }
182
Steve Blocka7e24c12009-10-30 11:49:00 +0000183 bool IsEmpty() { return AsEmptyStatement() != NULL; }
184
185 void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
186 int statement_pos() const { return statement_pos_; }
187
188 private:
189 int statement_pos_;
190};
191
192
193class Expression: public AstNode {
194 public:
Steve Blockd0582a62009-12-15 09:54:21 +0000195 enum Context {
196 // Not assigned a context yet, or else will not be visited during
197 // code generation.
198 kUninitialized,
199 // Evaluated for its side effects.
200 kEffect,
201 // Evaluated for its value (and side effects).
202 kValue,
203 // Evaluated for control flow (and side effects).
204 kTest,
205 // Evaluated for control flow and side effects. Value is also
206 // needed if true.
207 kValueTest,
208 // Evaluated for control flow and side effects. Value is also
209 // needed if false.
210 kTestValue
211 };
212
Steve Block6ded16b2010-05-10 14:33:55 +0100213 Expression() : bitfields_(0) {}
Leon Clarke4515c472010-02-03 11:58:03 +0000214
Steve Block6ded16b2010-05-10 14:33:55 +0100215 explicit Expression(Expression* other);
Leon Clarke4515c472010-02-03 11:58:03 +0000216
Steve Blocka7e24c12009-10-30 11:49:00 +0000217 virtual Expression* AsExpression() { return this; }
218
Steve Blocka7e24c12009-10-30 11:49:00 +0000219 virtual bool IsValidLeftHandSide() { return false; }
220
Steve Block6ded16b2010-05-10 14:33:55 +0100221 virtual Variable* AssignedVariable() { return NULL; }
222
Leon Clarkee46be812010-01-19 14:06:41 +0000223 // Symbols that cannot be parsed as array indices are considered property
224 // names. We do not treat symbols that can be array indexes as property
225 // names because [] for string objects is handled only by keyed ICs.
226 virtual bool IsPropertyName() { return false; }
227
Andrei Popescu402d9372010-02-26 13:31:12 +0000228 // True if the expression does not have (evaluated) subexpressions.
229 // Function literals are leaves because their subexpressions are not
230 // evaluated.
231 virtual bool IsLeaf() { return false; }
232
233 // True if the expression has no side effects and is safe to
234 // evaluate out of order.
235 virtual bool IsTrivial() { return false; }
236
Steve Block6ded16b2010-05-10 14:33:55 +0100237 // True if the expression always has one of the non-Object JS types
238 // (Undefined, Null, Boolean, String, or Number).
239 virtual bool IsPrimitive() = 0;
240
Steve Blocka7e24c12009-10-30 11:49:00 +0000241 // Mark the expression as being compiled as an expression
242 // statement. This is used to transform postfix increments to
243 // (faster) prefix increments.
244 virtual void MarkAsStatement() { /* do nothing */ }
245
246 // Static type information for this expression.
Leon Clarkee46be812010-01-19 14:06:41 +0000247 StaticType* type() { return &type_; }
Steve Block3ce2e202009-11-05 08:53:23 +0000248
Steve Block6ded16b2010-05-10 14:33:55 +0100249 // True if the expression is a loop condition.
250 bool is_loop_condition() const {
251 return LoopConditionField::decode(bitfields_);
252 }
253 void set_is_loop_condition(bool flag) {
254 bitfields_ = (bitfields_ & ~LoopConditionField::mask()) |
255 LoopConditionField::encode(flag);
256 }
Leon Clarke4515c472010-02-03 11:58:03 +0000257
Steve Block6ded16b2010-05-10 14:33:55 +0100258 // The value of the expression is guaranteed to be a smi, because the
259 // top operation is a bit operation with a mask, or a shift.
260 bool GuaranteedSmiResult();
Leon Clarke4515c472010-02-03 11:58:03 +0000261
Steve Block6ded16b2010-05-10 14:33:55 +0100262 // AST analysis results
Andrei Popescu402d9372010-02-26 13:31:12 +0000263
Steve Block6ded16b2010-05-10 14:33:55 +0100264 // True if the expression rooted at this node can be compiled by the
265 // side-effect free compiler.
266 bool side_effect_free() { return SideEffectFreeField::decode(bitfields_); }
267 void set_side_effect_free(bool is_side_effect_free) {
268 bitfields_ &= ~SideEffectFreeField::mask();
269 bitfields_ |= SideEffectFreeField::encode(is_side_effect_free);
270 }
271
272 // Will the use of this expression treat -0 the same as 0 in all cases?
273 // If so, we can return 0 instead of -0 if we want to, to optimize code.
274 bool no_negative_zero() { return NoNegativeZeroField::decode(bitfields_); }
275 void set_no_negative_zero(bool no_negative_zero) {
276 bitfields_ &= ~NoNegativeZeroField::mask();
277 bitfields_ |= NoNegativeZeroField::encode(no_negative_zero);
278 }
279
280 // Will ToInt32 (ECMA 262-3 9.5) or ToUint32 (ECMA 262-3 9.6)
281 // be applied to the value of this expression?
282 // If so, we may be able to optimize the calculation of the value.
283 bool to_int32() { return ToInt32Field::decode(bitfields_); }
284 void set_to_int32(bool to_int32) {
285 bitfields_ &= ~ToInt32Field::mask();
286 bitfields_ |= ToInt32Field::encode(to_int32);
287 }
288
289 // How many bitwise logical or shift operators are used in this expression?
290 int num_bit_ops() { return NumBitOpsField::decode(bitfields_); }
291 void set_num_bit_ops(int num_bit_ops) {
292 bitfields_ &= ~NumBitOpsField::mask();
293 num_bit_ops = Min(num_bit_ops, kMaxNumBitOps);
294 bitfields_ |= NumBitOpsField::encode(num_bit_ops);
Andrei Popescu402d9372010-02-26 13:31:12 +0000295 }
296
Steve Blocka7e24c12009-10-30 11:49:00 +0000297 private:
Steve Block6ded16b2010-05-10 14:33:55 +0100298 static const int kMaxNumBitOps = (1 << 5) - 1;
299
300 uint32_t bitfields_;
Leon Clarkee46be812010-01-19 14:06:41 +0000301 StaticType type_;
Steve Block6ded16b2010-05-10 14:33:55 +0100302
303 // Using template BitField<type, start, size>.
304 class SideEffectFreeField : public BitField<bool, 0, 1> {};
305 class NoNegativeZeroField : public BitField<bool, 1, 1> {};
306 class ToInt32Field : public BitField<bool, 2, 1> {};
307 class NumBitOpsField : public BitField<int, 3, 5> {};
308 class LoopConditionField: public BitField<bool, 8, 1> {};
Steve Blocka7e24c12009-10-30 11:49:00 +0000309};
310
311
312/**
313 * A sentinel used during pre parsing that represents some expression
314 * that is a valid left hand side without having to actually build
315 * the expression.
316 */
317class ValidLeftHandSideSentinel: public Expression {
318 public:
319 virtual bool IsValidLeftHandSide() { return true; }
320 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
321 static ValidLeftHandSideSentinel* instance() { return &instance_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100322
323 virtual bool IsPrimitive() {
324 UNREACHABLE();
325 return false;
326 }
327
Steve Blocka7e24c12009-10-30 11:49:00 +0000328 private:
329 static ValidLeftHandSideSentinel instance_;
330};
331
332
333class BreakableStatement: public Statement {
334 public:
335 enum Type {
336 TARGET_FOR_ANONYMOUS,
337 TARGET_FOR_NAMED_ONLY
338 };
339
340 // The labels associated with this statement. May be NULL;
341 // if it is != NULL, guaranteed to contain at least one entry.
342 ZoneStringList* labels() const { return labels_; }
343
344 // Type testing & conversion.
345 virtual BreakableStatement* AsBreakableStatement() { return this; }
346
347 // Code generation
348 BreakTarget* break_target() { return &break_target_; }
349
350 // Testers.
351 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
352
353 protected:
Kristian Monsen25f61362010-05-21 11:50:48 +0100354 inline BreakableStatement(ZoneStringList* labels, Type type);
Steve Blocka7e24c12009-10-30 11:49:00 +0000355
Steve Block6ded16b2010-05-10 14:33:55 +0100356 explicit BreakableStatement(BreakableStatement* other);
357
Steve Blocka7e24c12009-10-30 11:49:00 +0000358 private:
359 ZoneStringList* labels_;
360 Type type_;
361 BreakTarget break_target_;
362};
363
364
365class Block: public BreakableStatement {
366 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100367 inline Block(ZoneStringList* labels, int capacity, bool is_initializer_block);
Steve Blocka7e24c12009-10-30 11:49:00 +0000368
Steve Block6ded16b2010-05-10 14:33:55 +0100369 // Construct a clone initialized from the original block and
370 // a deep copy of all statements of the original block.
371 Block(Block* other, ZoneList<Statement*>* statements);
372
Steve Blocka7e24c12009-10-30 11:49:00 +0000373 virtual void Accept(AstVisitor* v);
374
Steve Block6ded16b2010-05-10 14:33:55 +0100375 virtual Block* AsBlock() { return this; }
376
377 virtual Assignment* StatementAsSimpleAssignment() {
378 if (statements_.length() != 1) return NULL;
379 return statements_[0]->StatementAsSimpleAssignment();
380 }
381
382 virtual CountOperation* StatementAsCountOperation() {
383 if (statements_.length() != 1) return NULL;
384 return statements_[0]->StatementAsCountOperation();
385 }
386
Steve Blocka7e24c12009-10-30 11:49:00 +0000387 void AddStatement(Statement* statement) { statements_.Add(statement); }
388
389 ZoneList<Statement*>* statements() { return &statements_; }
390 bool is_initializer_block() const { return is_initializer_block_; }
391
392 private:
393 ZoneList<Statement*> statements_;
394 bool is_initializer_block_;
395};
396
397
398class Declaration: public AstNode {
399 public:
400 Declaration(VariableProxy* proxy, Variable::Mode mode, FunctionLiteral* fun)
401 : proxy_(proxy),
402 mode_(mode),
403 fun_(fun) {
404 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
405 // At the moment there are no "const functions"'s in JavaScript...
406 ASSERT(fun == NULL || mode == Variable::VAR);
407 }
408
409 virtual void Accept(AstVisitor* v);
410
411 VariableProxy* proxy() const { return proxy_; }
412 Variable::Mode mode() const { return mode_; }
413 FunctionLiteral* fun() const { return fun_; } // may be NULL
414
415 private:
416 VariableProxy* proxy_;
417 Variable::Mode mode_;
418 FunctionLiteral* fun_;
419};
420
421
422class IterationStatement: public BreakableStatement {
423 public:
424 // Type testing & conversion.
425 virtual IterationStatement* AsIterationStatement() { return this; }
426
427 Statement* body() const { return body_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100428 void set_body(Statement* stmt) { body_ = stmt; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000429
430 // Code generation
431 BreakTarget* continue_target() { return &continue_target_; }
432
433 protected:
Kristian Monsen25f61362010-05-21 11:50:48 +0100434 explicit inline IterationStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000435
Steve Block6ded16b2010-05-10 14:33:55 +0100436 // Construct a clone initialized from original and
437 // a deep copy of the original body.
438 IterationStatement(IterationStatement* other, Statement* body);
439
Steve Blocka7e24c12009-10-30 11:49:00 +0000440 void Initialize(Statement* body) {
441 body_ = body;
442 }
443
444 private:
445 Statement* body_;
446 BreakTarget continue_target_;
447};
448
449
Steve Block3ce2e202009-11-05 08:53:23 +0000450class DoWhileStatement: public IterationStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000451 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100452 explicit inline DoWhileStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000453
Steve Block3ce2e202009-11-05 08:53:23 +0000454 void Initialize(Expression* cond, Statement* body) {
455 IterationStatement::Initialize(body);
456 cond_ = cond;
457 }
458
459 virtual void Accept(AstVisitor* v);
460
461 Expression* cond() const { return cond_; }
462
Steve Blockd0582a62009-12-15 09:54:21 +0000463 // Position where condition expression starts. We need it to make
464 // the loop's condition a breakable location.
465 int condition_position() { return condition_position_; }
466 void set_condition_position(int pos) { condition_position_ = pos; }
467
Steve Block3ce2e202009-11-05 08:53:23 +0000468 private:
469 Expression* cond_;
Steve Blockd0582a62009-12-15 09:54:21 +0000470 int condition_position_;
Steve Block3ce2e202009-11-05 08:53:23 +0000471};
472
473
474class WhileStatement: public IterationStatement {
475 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100476 explicit WhileStatement(ZoneStringList* labels);
Steve Block3ce2e202009-11-05 08:53:23 +0000477
478 void Initialize(Expression* cond, Statement* body) {
479 IterationStatement::Initialize(body);
480 cond_ = cond;
481 }
482
483 virtual void Accept(AstVisitor* v);
484
485 Expression* cond() const { return cond_; }
486 bool may_have_function_literal() const {
487 return may_have_function_literal_;
488 }
489
490 private:
491 Expression* cond_;
492 // True if there is a function literal subexpression in the condition.
493 bool may_have_function_literal_;
494
495 friend class AstOptimizer;
496};
497
498
499class ForStatement: public IterationStatement {
500 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100501 explicit inline ForStatement(ZoneStringList* labels);
Steve Block6ded16b2010-05-10 14:33:55 +0100502
503 // Construct a for-statement initialized from another for-statement
504 // and deep copies of all parts of the original statement.
505 ForStatement(ForStatement* other,
506 Statement* init,
507 Expression* cond,
508 Statement* next,
509 Statement* body);
510
511 virtual ForStatement* AsForStatement() { return this; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000512
513 void Initialize(Statement* init,
514 Expression* cond,
515 Statement* next,
516 Statement* body) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000517 IterationStatement::Initialize(body);
518 init_ = init;
519 cond_ = cond;
520 next_ = next;
521 }
522
523 virtual void Accept(AstVisitor* v);
524
Steve Blocka7e24c12009-10-30 11:49:00 +0000525 Statement* init() const { return init_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100526 void set_init(Statement* stmt) { init_ = stmt; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000527 Expression* cond() const { return cond_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100528 void set_cond(Expression* expr) { cond_ = expr; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000529 Statement* next() const { return next_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100530 void set_next(Statement* stmt) { next_ = stmt; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000531 bool may_have_function_literal() const {
532 return may_have_function_literal_;
533 }
534
Steve Block6ded16b2010-05-10 14:33:55 +0100535 bool is_fast_smi_loop() { return loop_variable_ != NULL; }
536 Variable* loop_variable() { return loop_variable_; }
537 void set_loop_variable(Variable* var) { loop_variable_ = var; }
538
539 bool peel_this_loop() { return peel_this_loop_; }
540 void set_peel_this_loop(bool b) { peel_this_loop_ = b; }
541
Steve Blocka7e24c12009-10-30 11:49:00 +0000542 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000543 Statement* init_;
544 Expression* cond_;
545 Statement* next_;
546 // True if there is a function literal subexpression in the condition.
547 bool may_have_function_literal_;
Steve Block6ded16b2010-05-10 14:33:55 +0100548 Variable* loop_variable_;
549 bool peel_this_loop_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000550
551 friend class AstOptimizer;
552};
553
554
555class ForInStatement: public IterationStatement {
556 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100557 explicit inline ForInStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000558
559 void Initialize(Expression* each, Expression* enumerable, Statement* body) {
560 IterationStatement::Initialize(body);
561 each_ = each;
562 enumerable_ = enumerable;
563 }
564
565 virtual void Accept(AstVisitor* v);
566
567 Expression* each() const { return each_; }
568 Expression* enumerable() const { return enumerable_; }
569
570 private:
571 Expression* each_;
572 Expression* enumerable_;
573};
574
575
576class ExpressionStatement: public Statement {
577 public:
578 explicit ExpressionStatement(Expression* expression)
579 : expression_(expression) { }
580
Steve Block6ded16b2010-05-10 14:33:55 +0100581 // Construct an expression statement initialized from another
582 // expression statement and a deep copy of the original expression.
583 ExpressionStatement(ExpressionStatement* other, Expression* expression);
584
Steve Blocka7e24c12009-10-30 11:49:00 +0000585 virtual void Accept(AstVisitor* v);
586
587 // Type testing & conversion.
588 virtual ExpressionStatement* AsExpressionStatement() { return this; }
589
Steve Block6ded16b2010-05-10 14:33:55 +0100590 virtual Assignment* StatementAsSimpleAssignment();
591 virtual CountOperation* StatementAsCountOperation();
592
Steve Blocka7e24c12009-10-30 11:49:00 +0000593 void set_expression(Expression* e) { expression_ = e; }
594 Expression* expression() { return expression_; }
595
596 private:
597 Expression* expression_;
598};
599
600
601class ContinueStatement: public Statement {
602 public:
603 explicit ContinueStatement(IterationStatement* target)
604 : target_(target) { }
605
606 virtual void Accept(AstVisitor* v);
607
608 IterationStatement* target() const { return target_; }
609
610 private:
611 IterationStatement* target_;
612};
613
614
615class BreakStatement: public Statement {
616 public:
617 explicit BreakStatement(BreakableStatement* target)
618 : target_(target) { }
619
620 virtual void Accept(AstVisitor* v);
621
622 BreakableStatement* target() const { return target_; }
623
624 private:
625 BreakableStatement* target_;
626};
627
628
629class ReturnStatement: public Statement {
630 public:
631 explicit ReturnStatement(Expression* expression)
632 : expression_(expression) { }
633
634 virtual void Accept(AstVisitor* v);
635
636 // Type testing & conversion.
637 virtual ReturnStatement* AsReturnStatement() { return this; }
638
639 Expression* expression() { return expression_; }
640
641 private:
642 Expression* expression_;
643};
644
645
646class WithEnterStatement: public Statement {
647 public:
648 explicit WithEnterStatement(Expression* expression, bool is_catch_block)
649 : expression_(expression), is_catch_block_(is_catch_block) { }
650
651 virtual void Accept(AstVisitor* v);
652
653 Expression* expression() const { return expression_; }
654
655 bool is_catch_block() const { return is_catch_block_; }
656
657 private:
658 Expression* expression_;
659 bool is_catch_block_;
660};
661
662
663class WithExitStatement: public Statement {
664 public:
665 WithExitStatement() { }
666
667 virtual void Accept(AstVisitor* v);
668};
669
670
671class CaseClause: public ZoneObject {
672 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100673 CaseClause(Expression* label, ZoneList<Statement*>* statements);
Steve Blocka7e24c12009-10-30 11:49:00 +0000674
675 bool is_default() const { return label_ == NULL; }
676 Expression* label() const {
677 CHECK(!is_default());
678 return label_;
679 }
680 JumpTarget* body_target() { return &body_target_; }
681 ZoneList<Statement*>* statements() const { return statements_; }
682
683 private:
684 Expression* label_;
685 JumpTarget body_target_;
686 ZoneList<Statement*>* statements_;
687};
688
689
690class SwitchStatement: public BreakableStatement {
691 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100692 explicit inline SwitchStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000693
694 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
695 tag_ = tag;
696 cases_ = cases;
697 }
698
699 virtual void Accept(AstVisitor* v);
700
701 Expression* tag() const { return tag_; }
702 ZoneList<CaseClause*>* cases() const { return cases_; }
703
704 private:
705 Expression* tag_;
706 ZoneList<CaseClause*>* cases_;
707};
708
709
710// If-statements always have non-null references to their then- and
711// else-parts. When parsing if-statements with no explicit else-part,
712// the parser implicitly creates an empty statement. Use the
713// HasThenStatement() and HasElseStatement() functions to check if a
714// given if-statement has a then- or an else-part containing code.
715class IfStatement: public Statement {
716 public:
717 IfStatement(Expression* condition,
718 Statement* then_statement,
719 Statement* else_statement)
720 : condition_(condition),
721 then_statement_(then_statement),
722 else_statement_(else_statement) { }
723
Steve Block6ded16b2010-05-10 14:33:55 +0100724 // Construct an if-statement initialized from another if-statement
725 // and deep copies of all parts of the original.
726 IfStatement(IfStatement* other,
727 Expression* condition,
728 Statement* then_statement,
729 Statement* else_statement);
730
Steve Blocka7e24c12009-10-30 11:49:00 +0000731 virtual void Accept(AstVisitor* v);
732
733 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
734 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
735
736 Expression* condition() const { return condition_; }
737 Statement* then_statement() const { return then_statement_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100738 void set_then_statement(Statement* stmt) { then_statement_ = stmt; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000739 Statement* else_statement() const { return else_statement_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100740 void set_else_statement(Statement* stmt) { else_statement_ = stmt; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000741
742 private:
743 Expression* condition_;
744 Statement* then_statement_;
745 Statement* else_statement_;
746};
747
748
749// NOTE: TargetCollectors are represented as nodes to fit in the target
750// stack in the compiler; this should probably be reworked.
751class TargetCollector: public AstNode {
752 public:
753 explicit TargetCollector(ZoneList<BreakTarget*>* targets)
754 : targets_(targets) {
755 }
756
757 // Adds a jump target to the collector. The collector stores a pointer not
758 // a copy of the target to make binding work, so make sure not to pass in
759 // references to something on the stack.
760 void AddTarget(BreakTarget* target);
761
762 // Virtual behaviour. TargetCollectors are never part of the AST.
763 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
764 virtual TargetCollector* AsTargetCollector() { return this; }
765
766 ZoneList<BreakTarget*>* targets() { return targets_; }
767
768 private:
769 ZoneList<BreakTarget*>* targets_;
770};
771
772
773class TryStatement: public Statement {
774 public:
775 explicit TryStatement(Block* try_block)
776 : try_block_(try_block), escaping_targets_(NULL) { }
777
778 void set_escaping_targets(ZoneList<BreakTarget*>* targets) {
779 escaping_targets_ = targets;
780 }
781
782 Block* try_block() const { return try_block_; }
783 ZoneList<BreakTarget*>* escaping_targets() const { return escaping_targets_; }
784
785 private:
786 Block* try_block_;
787 ZoneList<BreakTarget*>* escaping_targets_;
788};
789
790
Steve Block3ce2e202009-11-05 08:53:23 +0000791class TryCatchStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000792 public:
Steve Block3ce2e202009-11-05 08:53:23 +0000793 TryCatchStatement(Block* try_block,
Leon Clarkee46be812010-01-19 14:06:41 +0000794 VariableProxy* catch_var,
Steve Block3ce2e202009-11-05 08:53:23 +0000795 Block* catch_block)
Steve Blocka7e24c12009-10-30 11:49:00 +0000796 : TryStatement(try_block),
797 catch_var_(catch_var),
798 catch_block_(catch_block) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000799 }
800
801 virtual void Accept(AstVisitor* v);
802
Leon Clarkee46be812010-01-19 14:06:41 +0000803 VariableProxy* catch_var() const { return catch_var_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000804 Block* catch_block() const { return catch_block_; }
805
806 private:
Leon Clarkee46be812010-01-19 14:06:41 +0000807 VariableProxy* catch_var_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000808 Block* catch_block_;
809};
810
811
Steve Block3ce2e202009-11-05 08:53:23 +0000812class TryFinallyStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000813 public:
Steve Block3ce2e202009-11-05 08:53:23 +0000814 TryFinallyStatement(Block* try_block, Block* finally_block)
Steve Blocka7e24c12009-10-30 11:49:00 +0000815 : TryStatement(try_block),
816 finally_block_(finally_block) { }
817
818 virtual void Accept(AstVisitor* v);
819
820 Block* finally_block() const { return finally_block_; }
821
822 private:
823 Block* finally_block_;
824};
825
826
827class DebuggerStatement: public Statement {
828 public:
829 virtual void Accept(AstVisitor* v);
830};
831
832
833class EmptyStatement: public Statement {
834 public:
Steve Block6ded16b2010-05-10 14:33:55 +0100835 EmptyStatement() {}
836
837 explicit EmptyStatement(EmptyStatement* other);
838
Steve Blocka7e24c12009-10-30 11:49:00 +0000839 virtual void Accept(AstVisitor* v);
840
841 // Type testing & conversion.
842 virtual EmptyStatement* AsEmptyStatement() { return this; }
843};
844
845
846class Literal: public Expression {
847 public:
848 explicit Literal(Handle<Object> handle) : handle_(handle) { }
849
850 virtual void Accept(AstVisitor* v);
851
852 // Type testing & conversion.
853 virtual Literal* AsLiteral() { return this; }
854
855 // Check if this literal is identical to the other literal.
856 bool IsIdenticalTo(const Literal* other) const {
857 return handle_.is_identical_to(other->handle_);
858 }
859
Leon Clarkee46be812010-01-19 14:06:41 +0000860 virtual bool IsPropertyName() {
861 if (handle_->IsSymbol()) {
862 uint32_t ignored;
863 return !String::cast(*handle_)->AsArrayIndex(&ignored);
864 }
865 return false;
866 }
867
Andrei Popescu402d9372010-02-26 13:31:12 +0000868 virtual bool IsLeaf() { return true; }
869 virtual bool IsTrivial() { return true; }
Steve Block6ded16b2010-05-10 14:33:55 +0100870 virtual bool IsPrimitive();
871 virtual bool IsCritical();
Andrei Popescu402d9372010-02-26 13:31:12 +0000872
Steve Blocka7e24c12009-10-30 11:49:00 +0000873 // Identity testers.
874 bool IsNull() const { return handle_.is_identical_to(Factory::null_value()); }
875 bool IsTrue() const { return handle_.is_identical_to(Factory::true_value()); }
876 bool IsFalse() const {
877 return handle_.is_identical_to(Factory::false_value());
878 }
879
880 Handle<Object> handle() const { return handle_; }
881
882 private:
883 Handle<Object> handle_;
884};
885
886
887// Base class for literals that needs space in the corresponding JSFunction.
888class MaterializedLiteral: public Expression {
889 public:
890 explicit MaterializedLiteral(int literal_index, bool is_simple, int depth)
891 : literal_index_(literal_index), is_simple_(is_simple), depth_(depth) {}
892
893 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
894
895 int literal_index() { return literal_index_; }
896
897 // A materialized literal is simple if the values consist of only
898 // constants and simple object and array literals.
899 bool is_simple() const { return is_simple_; }
900
Steve Blocka7e24c12009-10-30 11:49:00 +0000901 int depth() const { return depth_; }
902
903 private:
904 int literal_index_;
905 bool is_simple_;
906 int depth_;
907};
908
909
910// An object literal has a boilerplate object that is used
911// for minimizing the work when constructing it at runtime.
912class ObjectLiteral: public MaterializedLiteral {
913 public:
914 // Property is used for passing information
915 // about an object literal's properties from the parser
916 // to the code generator.
917 class Property: public ZoneObject {
918 public:
919
920 enum Kind {
921 CONSTANT, // Property with constant value (compile time).
922 COMPUTED, // Property with computed value (execution time).
923 MATERIALIZED_LITERAL, // Property value is a materialized literal.
924 GETTER, SETTER, // Property is an accessor function.
925 PROTOTYPE // Property is __proto__.
926 };
927
928 Property(Literal* key, Expression* value);
929 Property(bool is_getter, FunctionLiteral* value);
930
931 Literal* key() { return key_; }
932 Expression* value() { return value_; }
933 Kind kind() { return kind_; }
934
Steve Blockd0582a62009-12-15 09:54:21 +0000935 bool IsCompileTimeValue();
936
Steve Blocka7e24c12009-10-30 11:49:00 +0000937 private:
938 Literal* key_;
939 Expression* value_;
940 Kind kind_;
941 };
942
943 ObjectLiteral(Handle<FixedArray> constant_properties,
944 ZoneList<Property*>* properties,
945 int literal_index,
946 bool is_simple,
Steve Block6ded16b2010-05-10 14:33:55 +0100947 bool fast_elements,
Steve Blocka7e24c12009-10-30 11:49:00 +0000948 int depth)
949 : MaterializedLiteral(literal_index, is_simple, depth),
950 constant_properties_(constant_properties),
Steve Block6ded16b2010-05-10 14:33:55 +0100951 properties_(properties),
952 fast_elements_(fast_elements) {}
Steve Blocka7e24c12009-10-30 11:49:00 +0000953
954 virtual ObjectLiteral* AsObjectLiteral() { return this; }
955 virtual void Accept(AstVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +0000956
Andrei Popescu402d9372010-02-26 13:31:12 +0000957 virtual bool IsLeaf() { return properties()->is_empty(); }
958
Steve Block6ded16b2010-05-10 14:33:55 +0100959 virtual bool IsPrimitive();
960
Steve Blocka7e24c12009-10-30 11:49:00 +0000961 Handle<FixedArray> constant_properties() const {
962 return constant_properties_;
963 }
964 ZoneList<Property*>* properties() const { return properties_; }
965
Steve Block6ded16b2010-05-10 14:33:55 +0100966 bool fast_elements() const { return fast_elements_; }
967
Steve Blocka7e24c12009-10-30 11:49:00 +0000968 private:
969 Handle<FixedArray> constant_properties_;
970 ZoneList<Property*>* properties_;
Steve Block6ded16b2010-05-10 14:33:55 +0100971 bool fast_elements_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000972};
973
974
975// Node for capturing a regexp literal.
976class RegExpLiteral: public MaterializedLiteral {
977 public:
978 RegExpLiteral(Handle<String> pattern,
979 Handle<String> flags,
980 int literal_index)
981 : MaterializedLiteral(literal_index, false, 1),
982 pattern_(pattern),
983 flags_(flags) {}
984
985 virtual void Accept(AstVisitor* v);
986
Andrei Popescu402d9372010-02-26 13:31:12 +0000987 virtual bool IsLeaf() { return true; }
988
Steve Block6ded16b2010-05-10 14:33:55 +0100989 virtual bool IsPrimitive();
990
Steve Blocka7e24c12009-10-30 11:49:00 +0000991 Handle<String> pattern() const { return pattern_; }
992 Handle<String> flags() const { return flags_; }
993
994 private:
995 Handle<String> pattern_;
996 Handle<String> flags_;
997};
998
999// An array literal has a literals object that is used
1000// for minimizing the work when constructing it at runtime.
1001class ArrayLiteral: public MaterializedLiteral {
1002 public:
Leon Clarkee46be812010-01-19 14:06:41 +00001003 ArrayLiteral(Handle<FixedArray> constant_elements,
Steve Blocka7e24c12009-10-30 11:49:00 +00001004 ZoneList<Expression*>* values,
1005 int literal_index,
1006 bool is_simple,
1007 int depth)
1008 : MaterializedLiteral(literal_index, is_simple, depth),
Leon Clarkee46be812010-01-19 14:06:41 +00001009 constant_elements_(constant_elements),
Steve Blocka7e24c12009-10-30 11:49:00 +00001010 values_(values) {}
1011
1012 virtual void Accept(AstVisitor* v);
1013 virtual ArrayLiteral* AsArrayLiteral() { return this; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001014
Andrei Popescu402d9372010-02-26 13:31:12 +00001015 virtual bool IsLeaf() { return values()->is_empty(); }
1016
Steve Block6ded16b2010-05-10 14:33:55 +01001017 virtual bool IsPrimitive();
1018
Leon Clarkee46be812010-01-19 14:06:41 +00001019 Handle<FixedArray> constant_elements() const { return constant_elements_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001020 ZoneList<Expression*>* values() const { return values_; }
1021
1022 private:
Leon Clarkee46be812010-01-19 14:06:41 +00001023 Handle<FixedArray> constant_elements_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001024 ZoneList<Expression*>* values_;
1025};
1026
1027
1028// Node for constructing a context extension object for a catch block.
1029// The catch context extension object has one property, the catch
1030// variable, which should be DontDelete.
1031class CatchExtensionObject: public Expression {
1032 public:
1033 CatchExtensionObject(Literal* key, VariableProxy* value)
1034 : key_(key), value_(value) {
1035 }
1036
1037 virtual void Accept(AstVisitor* v);
1038
Steve Block6ded16b2010-05-10 14:33:55 +01001039 virtual bool IsPrimitive();
1040
Steve Blocka7e24c12009-10-30 11:49:00 +00001041 Literal* key() const { return key_; }
1042 VariableProxy* value() const { return value_; }
1043
1044 private:
1045 Literal* key_;
1046 VariableProxy* value_;
1047};
1048
1049
1050class VariableProxy: public Expression {
1051 public:
1052 virtual void Accept(AstVisitor* v);
1053
1054 // Type testing & conversion
1055 virtual Property* AsProperty() {
1056 return var_ == NULL ? NULL : var_->AsProperty();
1057 }
1058 virtual VariableProxy* AsVariableProxy() { return this; }
1059
1060 Variable* AsVariable() {
1061 return this == NULL || var_ == NULL ? NULL : var_->AsVariable();
1062 }
1063
1064 virtual bool IsValidLeftHandSide() {
1065 return var_ == NULL ? true : var_->IsValidLeftHandSide();
1066 }
1067
Andrei Popescu402d9372010-02-26 13:31:12 +00001068 virtual bool IsLeaf() {
1069 ASSERT(var_ != NULL); // Variable must be resolved.
1070 return var()->is_global() || var()->rewrite()->IsLeaf();
1071 }
1072
1073 // Reading from a mutable variable is a side effect, but 'this' is
1074 // immutable.
Steve Block6ded16b2010-05-10 14:33:55 +01001075 virtual bool IsTrivial() { return is_trivial_; }
1076
1077 virtual bool IsPrimitive();
1078 virtual bool IsCritical();
1079
1080 void SetIsPrimitive(bool value) { is_primitive_ = value; }
Andrei Popescu402d9372010-02-26 13:31:12 +00001081
Steve Blocka7e24c12009-10-30 11:49:00 +00001082 bool IsVariable(Handle<String> n) {
1083 return !is_this() && name().is_identical_to(n);
1084 }
1085
1086 bool IsArguments() {
1087 Variable* variable = AsVariable();
1088 return (variable == NULL) ? false : variable->is_arguments();
1089 }
1090
1091 Handle<String> name() const { return name_; }
1092 Variable* var() const { return var_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001093 bool is_this() const { return is_this_; }
1094 bool inside_with() const { return inside_with_; }
Steve Block6ded16b2010-05-10 14:33:55 +01001095 bool is_trivial() { return is_trivial_; }
1096 void set_is_trivial(bool b) { is_trivial_ = b; }
1097
1098 BitVector* reaching_definitions() { return reaching_definitions_; }
1099 void set_reaching_definitions(BitVector* rd) { reaching_definitions_ = rd; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001100
1101 // Bind this proxy to the variable var.
1102 void BindTo(Variable* var);
1103
1104 protected:
1105 Handle<String> name_;
1106 Variable* var_; // resolved variable, or NULL
1107 bool is_this_;
1108 bool inside_with_;
Steve Block6ded16b2010-05-10 14:33:55 +01001109 bool is_trivial_;
1110 BitVector* reaching_definitions_;
1111 bool is_primitive_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001112
1113 VariableProxy(Handle<String> name, bool is_this, bool inside_with);
1114 explicit VariableProxy(bool is_this);
1115
1116 friend class Scope;
1117};
1118
1119
1120class VariableProxySentinel: public VariableProxy {
1121 public:
1122 virtual bool IsValidLeftHandSide() { return !is_this(); }
1123 static VariableProxySentinel* this_proxy() { return &this_proxy_; }
1124 static VariableProxySentinel* identifier_proxy() {
1125 return &identifier_proxy_;
1126 }
1127
Steve Block6ded16b2010-05-10 14:33:55 +01001128 virtual bool IsPrimitive() {
1129 UNREACHABLE();
1130 return false;
1131 }
1132
Steve Blocka7e24c12009-10-30 11:49:00 +00001133 private:
1134 explicit VariableProxySentinel(bool is_this) : VariableProxy(is_this) { }
1135 static VariableProxySentinel this_proxy_;
1136 static VariableProxySentinel identifier_proxy_;
1137};
1138
1139
1140class Slot: public Expression {
1141 public:
1142 enum Type {
1143 // A slot in the parameter section on the stack. index() is
1144 // the parameter index, counting left-to-right, starting at 0.
1145 PARAMETER,
1146
1147 // A slot in the local section on the stack. index() is
1148 // the variable index in the stack frame, starting at 0.
1149 LOCAL,
1150
1151 // An indexed slot in a heap context. index() is the
1152 // variable index in the context object on the heap,
1153 // starting at 0. var()->scope() is the corresponding
1154 // scope.
1155 CONTEXT,
1156
1157 // A named slot in a heap context. var()->name() is the
1158 // variable name in the context object on the heap,
1159 // with lookup starting at the current context. index()
1160 // is invalid.
Steve Blockd0582a62009-12-15 09:54:21 +00001161 LOOKUP
Steve Blocka7e24c12009-10-30 11:49:00 +00001162 };
1163
1164 Slot(Variable* var, Type type, int index)
1165 : var_(var), type_(type), index_(index) {
1166 ASSERT(var != NULL);
1167 }
1168
1169 virtual void Accept(AstVisitor* v);
1170
1171 // Type testing & conversion
1172 virtual Slot* AsSlot() { return this; }
1173
Andrei Popescu402d9372010-02-26 13:31:12 +00001174 virtual bool IsLeaf() { return true; }
1175
Steve Block6ded16b2010-05-10 14:33:55 +01001176 virtual bool IsPrimitive() {
1177 UNREACHABLE();
1178 return false;
1179 }
1180
1181 bool IsStackAllocated() { return type_ == PARAMETER || type_ == LOCAL; }
1182
Steve Blocka7e24c12009-10-30 11:49:00 +00001183 // Accessors
1184 Variable* var() const { return var_; }
1185 Type type() const { return type_; }
1186 int index() const { return index_; }
1187 bool is_arguments() const { return var_->is_arguments(); }
1188
1189 private:
1190 Variable* var_;
1191 Type type_;
1192 int index_;
1193};
1194
1195
1196class Property: public Expression {
1197 public:
1198 // Synthetic properties are property lookups introduced by the system,
1199 // to objects that aren't visible to the user. Function calls to synthetic
1200 // properties should use the global object as receiver, not the base object
1201 // of the resolved Reference.
1202 enum Type { NORMAL, SYNTHETIC };
1203 Property(Expression* obj, Expression* key, int pos, Type type = NORMAL)
1204 : obj_(obj), key_(key), pos_(pos), type_(type) { }
1205
Steve Block6ded16b2010-05-10 14:33:55 +01001206 Property(Property* other, Expression* obj, Expression* key);
1207
Steve Blocka7e24c12009-10-30 11:49:00 +00001208 virtual void Accept(AstVisitor* v);
1209
1210 // Type testing & conversion
1211 virtual Property* AsProperty() { return this; }
1212
1213 virtual bool IsValidLeftHandSide() { return true; }
1214
Steve Block6ded16b2010-05-10 14:33:55 +01001215 virtual bool IsPrimitive();
1216 virtual bool IsCritical();
1217
Steve Blocka7e24c12009-10-30 11:49:00 +00001218 Expression* obj() const { return obj_; }
1219 Expression* key() const { return key_; }
1220 int position() const { return pos_; }
1221 bool is_synthetic() const { return type_ == SYNTHETIC; }
1222
1223 // Returns a property singleton property access on 'this'. Used
1224 // during preparsing.
1225 static Property* this_property() { return &this_property_; }
1226
1227 private:
1228 Expression* obj_;
1229 Expression* key_;
1230 int pos_;
1231 Type type_;
1232
1233 // Dummy property used during preparsing.
1234 static Property this_property_;
1235};
1236
1237
1238class Call: public Expression {
1239 public:
1240 Call(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1241 : expression_(expression), arguments_(arguments), pos_(pos) { }
1242
Steve Block6ded16b2010-05-10 14:33:55 +01001243 Call(Call* other, Expression* expression, ZoneList<Expression*>* arguments);
1244
Steve Blocka7e24c12009-10-30 11:49:00 +00001245 virtual void Accept(AstVisitor* v);
1246
1247 // Type testing and conversion.
1248 virtual Call* AsCall() { return this; }
1249
Steve Block6ded16b2010-05-10 14:33:55 +01001250 virtual bool IsPrimitive();
1251 virtual bool IsCritical();
1252
Steve Blocka7e24c12009-10-30 11:49:00 +00001253 Expression* expression() const { return expression_; }
1254 ZoneList<Expression*>* arguments() const { return arguments_; }
1255 int position() { return pos_; }
1256
1257 static Call* sentinel() { return &sentinel_; }
1258
1259 private:
1260 Expression* expression_;
1261 ZoneList<Expression*>* arguments_;
1262 int pos_;
1263
1264 static Call sentinel_;
1265};
1266
1267
1268class CallNew: public Expression {
1269 public:
1270 CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1271 : expression_(expression), arguments_(arguments), pos_(pos) { }
1272
1273 virtual void Accept(AstVisitor* v);
1274
Steve Block6ded16b2010-05-10 14:33:55 +01001275 virtual bool IsPrimitive();
1276
Steve Blocka7e24c12009-10-30 11:49:00 +00001277 Expression* expression() const { return expression_; }
1278 ZoneList<Expression*>* arguments() const { return arguments_; }
1279 int position() { return pos_; }
1280
1281 private:
1282 Expression* expression_;
1283 ZoneList<Expression*>* arguments_;
1284 int pos_;
1285};
1286
1287
1288// The CallRuntime class does not represent any official JavaScript
1289// language construct. Instead it is used to call a C or JS function
1290// with a set of arguments. This is used from the builtins that are
1291// implemented in JavaScript (see "v8natives.js").
1292class CallRuntime: public Expression {
1293 public:
1294 CallRuntime(Handle<String> name,
1295 Runtime::Function* function,
1296 ZoneList<Expression*>* arguments)
1297 : name_(name), function_(function), arguments_(arguments) { }
1298
1299 virtual void Accept(AstVisitor* v);
1300
Steve Block6ded16b2010-05-10 14:33:55 +01001301 virtual bool IsPrimitive();
1302
Steve Blocka7e24c12009-10-30 11:49:00 +00001303 Handle<String> name() const { return name_; }
1304 Runtime::Function* function() const { return function_; }
1305 ZoneList<Expression*>* arguments() const { return arguments_; }
Steve Blockd0582a62009-12-15 09:54:21 +00001306 bool is_jsruntime() const { return function_ == NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001307
1308 private:
1309 Handle<String> name_;
1310 Runtime::Function* function_;
1311 ZoneList<Expression*>* arguments_;
1312};
1313
1314
1315class UnaryOperation: public Expression {
1316 public:
1317 UnaryOperation(Token::Value op, Expression* expression)
1318 : op_(op), expression_(expression) {
1319 ASSERT(Token::IsUnaryOp(op));
1320 }
1321
Steve Block6ded16b2010-05-10 14:33:55 +01001322 UnaryOperation(UnaryOperation* other, Expression* expression);
1323
Steve Blocka7e24c12009-10-30 11:49:00 +00001324 virtual void Accept(AstVisitor* v);
1325
1326 // Type testing & conversion
1327 virtual UnaryOperation* AsUnaryOperation() { return this; }
1328
Steve Block6ded16b2010-05-10 14:33:55 +01001329 virtual bool IsPrimitive();
1330 virtual bool IsCritical();
1331
Steve Blocka7e24c12009-10-30 11:49:00 +00001332 Token::Value op() const { return op_; }
1333 Expression* expression() const { return expression_; }
1334
1335 private:
1336 Token::Value op_;
1337 Expression* expression_;
1338};
1339
1340
1341class BinaryOperation: public Expression {
1342 public:
1343 BinaryOperation(Token::Value op, Expression* left, Expression* right)
1344 : op_(op), left_(left), right_(right) {
1345 ASSERT(Token::IsBinaryOp(op));
1346 }
1347
Steve Block6ded16b2010-05-10 14:33:55 +01001348 // Construct a binary operation with a given operator and left and right
1349 // subexpressions. The rest of the expression state is copied from
1350 // another expression.
1351 BinaryOperation(Expression* other,
1352 Token::Value op,
1353 Expression* left,
1354 Expression* right);
1355
Steve Blocka7e24c12009-10-30 11:49:00 +00001356 virtual void Accept(AstVisitor* v);
1357
1358 // Type testing & conversion
1359 virtual BinaryOperation* AsBinaryOperation() { return this; }
1360
Steve Block6ded16b2010-05-10 14:33:55 +01001361 virtual bool IsPrimitive();
1362 virtual bool IsCritical();
1363
Steve Blocka7e24c12009-10-30 11:49:00 +00001364 // True iff the result can be safely overwritten (to avoid allocation).
1365 // False for operations that can return one of their operands.
1366 bool ResultOverwriteAllowed() {
1367 switch (op_) {
1368 case Token::COMMA:
1369 case Token::OR:
1370 case Token::AND:
1371 return false;
1372 case Token::BIT_OR:
1373 case Token::BIT_XOR:
1374 case Token::BIT_AND:
1375 case Token::SHL:
1376 case Token::SAR:
1377 case Token::SHR:
1378 case Token::ADD:
1379 case Token::SUB:
1380 case Token::MUL:
1381 case Token::DIV:
1382 case Token::MOD:
1383 return true;
1384 default:
1385 UNREACHABLE();
1386 }
1387 return false;
1388 }
1389
1390 Token::Value op() const { return op_; }
1391 Expression* left() const { return left_; }
1392 Expression* right() const { return right_; }
1393
1394 private:
1395 Token::Value op_;
1396 Expression* left_;
1397 Expression* right_;
1398};
1399
1400
1401class CountOperation: public Expression {
1402 public:
1403 CountOperation(bool is_prefix, Token::Value op, Expression* expression)
1404 : is_prefix_(is_prefix), op_(op), expression_(expression) {
1405 ASSERT(Token::IsCountOp(op));
1406 }
1407
Steve Block6ded16b2010-05-10 14:33:55 +01001408 CountOperation(CountOperation* other, Expression* expression);
1409
Steve Blocka7e24c12009-10-30 11:49:00 +00001410 virtual void Accept(AstVisitor* v);
1411
Steve Block6ded16b2010-05-10 14:33:55 +01001412 virtual CountOperation* AsCountOperation() { return this; }
1413
1414 virtual Variable* AssignedVariable() {
1415 return expression()->AsVariableProxy()->AsVariable();
1416 }
1417
1418 virtual bool IsPrimitive();
1419 virtual bool IsCritical();
1420
Steve Blocka7e24c12009-10-30 11:49:00 +00001421 bool is_prefix() const { return is_prefix_; }
1422 bool is_postfix() const { return !is_prefix_; }
1423 Token::Value op() const { return op_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001424 Token::Value binary_op() {
1425 return op_ == Token::INC ? Token::ADD : Token::SUB;
1426 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001427 Expression* expression() const { return expression_; }
1428
1429 virtual void MarkAsStatement() { is_prefix_ = true; }
1430
1431 private:
1432 bool is_prefix_;
1433 Token::Value op_;
1434 Expression* expression_;
1435};
1436
1437
1438class CompareOperation: public Expression {
1439 public:
1440 CompareOperation(Token::Value op, Expression* left, Expression* right)
Steve Block6ded16b2010-05-10 14:33:55 +01001441 : op_(op), left_(left), right_(right) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001442 ASSERT(Token::IsCompareOp(op));
1443 }
1444
Steve Block6ded16b2010-05-10 14:33:55 +01001445 CompareOperation(CompareOperation* other,
1446 Expression* left,
1447 Expression* right);
1448
Steve Blocka7e24c12009-10-30 11:49:00 +00001449 virtual void Accept(AstVisitor* v);
1450
Steve Block6ded16b2010-05-10 14:33:55 +01001451 virtual bool IsPrimitive();
1452 virtual bool IsCritical();
1453
Steve Blocka7e24c12009-10-30 11:49:00 +00001454 Token::Value op() const { return op_; }
1455 Expression* left() const { return left_; }
1456 Expression* right() const { return right_; }
1457
Leon Clarkee46be812010-01-19 14:06:41 +00001458 // Type testing & conversion
1459 virtual CompareOperation* AsCompareOperation() { return this; }
1460
Steve Blocka7e24c12009-10-30 11:49:00 +00001461 private:
1462 Token::Value op_;
1463 Expression* left_;
1464 Expression* right_;
1465};
1466
1467
1468class Conditional: public Expression {
1469 public:
1470 Conditional(Expression* condition,
1471 Expression* then_expression,
1472 Expression* else_expression)
1473 : condition_(condition),
1474 then_expression_(then_expression),
1475 else_expression_(else_expression) { }
1476
1477 virtual void Accept(AstVisitor* v);
1478
Steve Block6ded16b2010-05-10 14:33:55 +01001479 virtual bool IsPrimitive();
1480
Steve Blocka7e24c12009-10-30 11:49:00 +00001481 Expression* condition() const { return condition_; }
1482 Expression* then_expression() const { return then_expression_; }
1483 Expression* else_expression() const { return else_expression_; }
1484
1485 private:
1486 Expression* condition_;
1487 Expression* then_expression_;
1488 Expression* else_expression_;
1489};
1490
1491
1492class Assignment: public Expression {
1493 public:
1494 Assignment(Token::Value op, Expression* target, Expression* value, int pos)
1495 : op_(op), target_(target), value_(value), pos_(pos),
1496 block_start_(false), block_end_(false) {
1497 ASSERT(Token::IsAssignmentOp(op));
1498 }
1499
Steve Block6ded16b2010-05-10 14:33:55 +01001500 Assignment(Assignment* other, Expression* target, Expression* value);
1501
Steve Blocka7e24c12009-10-30 11:49:00 +00001502 virtual void Accept(AstVisitor* v);
1503 virtual Assignment* AsAssignment() { return this; }
1504
Steve Block6ded16b2010-05-10 14:33:55 +01001505 virtual bool IsPrimitive();
1506 virtual bool IsCritical();
1507
1508 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1509
1510 virtual Variable* AssignedVariable() {
1511 return target()->AsVariableProxy()->AsVariable();
1512 }
1513
Steve Blocka7e24c12009-10-30 11:49:00 +00001514 Token::Value binary_op() const;
1515
1516 Token::Value op() const { return op_; }
1517 Expression* target() const { return target_; }
1518 Expression* value() const { return value_; }
1519 int position() { return pos_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001520 // This check relies on the definition order of token in token.h.
1521 bool is_compound() const { return op() > Token::ASSIGN; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001522
1523 // An initialization block is a series of statments of the form
1524 // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1525 // ending of these blocks to allow for optimizations of initialization
1526 // blocks.
1527 bool starts_initialization_block() { return block_start_; }
1528 bool ends_initialization_block() { return block_end_; }
1529 void mark_block_start() { block_start_ = true; }
1530 void mark_block_end() { block_end_ = true; }
1531
1532 private:
1533 Token::Value op_;
1534 Expression* target_;
1535 Expression* value_;
1536 int pos_;
1537 bool block_start_;
1538 bool block_end_;
1539};
1540
1541
1542class Throw: public Expression {
1543 public:
1544 Throw(Expression* exception, int pos)
1545 : exception_(exception), pos_(pos) {}
1546
1547 virtual void Accept(AstVisitor* v);
Steve Block6ded16b2010-05-10 14:33:55 +01001548
1549 virtual bool IsPrimitive();
1550
Steve Blocka7e24c12009-10-30 11:49:00 +00001551 Expression* exception() const { return exception_; }
1552 int position() const { return pos_; }
1553
1554 private:
1555 Expression* exception_;
1556 int pos_;
1557};
1558
1559
1560class FunctionLiteral: public Expression {
1561 public:
1562 FunctionLiteral(Handle<String> name,
1563 Scope* scope,
1564 ZoneList<Statement*>* body,
1565 int materialized_literal_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00001566 int expected_property_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00001567 bool has_only_simple_this_property_assignments,
1568 Handle<FixedArray> this_property_assignments,
1569 int num_parameters,
1570 int start_position,
1571 int end_position,
1572 bool is_expression)
1573 : name_(name),
1574 scope_(scope),
1575 body_(body),
1576 materialized_literal_count_(materialized_literal_count),
Steve Blocka7e24c12009-10-30 11:49:00 +00001577 expected_property_count_(expected_property_count),
Steve Blocka7e24c12009-10-30 11:49:00 +00001578 has_only_simple_this_property_assignments_(
1579 has_only_simple_this_property_assignments),
1580 this_property_assignments_(this_property_assignments),
1581 num_parameters_(num_parameters),
1582 start_position_(start_position),
1583 end_position_(end_position),
1584 is_expression_(is_expression),
Steve Blocka7e24c12009-10-30 11:49:00 +00001585 function_token_position_(RelocInfo::kNoPosition),
Steve Blockd0582a62009-12-15 09:54:21 +00001586 inferred_name_(Heap::empty_string()),
Leon Clarked91b9f72010-01-27 17:25:45 +00001587 try_full_codegen_(false) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001588#ifdef DEBUG
1589 already_compiled_ = false;
1590#endif
1591 }
1592
1593 virtual void Accept(AstVisitor* v);
1594
1595 // Type testing & conversion
1596 virtual FunctionLiteral* AsFunctionLiteral() { return this; }
1597
Andrei Popescu402d9372010-02-26 13:31:12 +00001598 virtual bool IsLeaf() { return true; }
1599
Steve Block6ded16b2010-05-10 14:33:55 +01001600 virtual bool IsPrimitive();
1601
Steve Blocka7e24c12009-10-30 11:49:00 +00001602 Handle<String> name() const { return name_; }
1603 Scope* scope() const { return scope_; }
1604 ZoneList<Statement*>* body() const { return body_; }
1605 void set_function_token_position(int pos) { function_token_position_ = pos; }
1606 int function_token_position() const { return function_token_position_; }
1607 int start_position() const { return start_position_; }
1608 int end_position() const { return end_position_; }
1609 bool is_expression() const { return is_expression_; }
1610
1611 int materialized_literal_count() { return materialized_literal_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001612 int expected_property_count() { return expected_property_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001613 bool has_only_simple_this_property_assignments() {
1614 return has_only_simple_this_property_assignments_;
1615 }
1616 Handle<FixedArray> this_property_assignments() {
1617 return this_property_assignments_;
1618 }
1619 int num_parameters() { return num_parameters_; }
1620
1621 bool AllowsLazyCompilation();
1622
Steve Blocka7e24c12009-10-30 11:49:00 +00001623 Handle<String> inferred_name() const { return inferred_name_; }
1624 void set_inferred_name(Handle<String> inferred_name) {
1625 inferred_name_ = inferred_name;
1626 }
1627
Leon Clarked91b9f72010-01-27 17:25:45 +00001628 bool try_full_codegen() { return try_full_codegen_; }
1629 void set_try_full_codegen(bool flag) { try_full_codegen_ = flag; }
Steve Blockd0582a62009-12-15 09:54:21 +00001630
Steve Blocka7e24c12009-10-30 11:49:00 +00001631#ifdef DEBUG
1632 void mark_as_compiled() {
1633 ASSERT(!already_compiled_);
1634 already_compiled_ = true;
1635 }
1636#endif
1637
1638 private:
1639 Handle<String> name_;
1640 Scope* scope_;
1641 ZoneList<Statement*>* body_;
1642 int materialized_literal_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001643 int expected_property_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001644 bool has_only_simple_this_property_assignments_;
1645 Handle<FixedArray> this_property_assignments_;
1646 int num_parameters_;
1647 int start_position_;
1648 int end_position_;
1649 bool is_expression_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001650 int function_token_position_;
1651 Handle<String> inferred_name_;
Leon Clarked91b9f72010-01-27 17:25:45 +00001652 bool try_full_codegen_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001653#ifdef DEBUG
1654 bool already_compiled_;
1655#endif
1656};
1657
1658
Steve Block6ded16b2010-05-10 14:33:55 +01001659class SharedFunctionInfoLiteral: public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00001660 public:
Steve Block6ded16b2010-05-10 14:33:55 +01001661 explicit SharedFunctionInfoLiteral(
1662 Handle<SharedFunctionInfo> shared_function_info)
1663 : shared_function_info_(shared_function_info) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001664
Steve Block6ded16b2010-05-10 14:33:55 +01001665 Handle<SharedFunctionInfo> shared_function_info() const {
1666 return shared_function_info_;
1667 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001668
Andrei Popescu402d9372010-02-26 13:31:12 +00001669 virtual bool IsLeaf() { return true; }
1670
Steve Blocka7e24c12009-10-30 11:49:00 +00001671 virtual void Accept(AstVisitor* v);
1672
Steve Block6ded16b2010-05-10 14:33:55 +01001673 virtual bool IsPrimitive();
1674
Steve Blocka7e24c12009-10-30 11:49:00 +00001675 private:
Steve Block6ded16b2010-05-10 14:33:55 +01001676 Handle<SharedFunctionInfo> shared_function_info_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001677};
1678
1679
1680class ThisFunction: public Expression {
1681 public:
1682 virtual void Accept(AstVisitor* v);
Andrei Popescu402d9372010-02-26 13:31:12 +00001683 virtual bool IsLeaf() { return true; }
Steve Block6ded16b2010-05-10 14:33:55 +01001684 virtual bool IsPrimitive();
Steve Blocka7e24c12009-10-30 11:49:00 +00001685};
1686
1687
1688// ----------------------------------------------------------------------------
1689// Regular expressions
1690
1691
1692class RegExpVisitor BASE_EMBEDDED {
1693 public:
1694 virtual ~RegExpVisitor() { }
1695#define MAKE_CASE(Name) \
1696 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
1697 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
1698#undef MAKE_CASE
1699};
1700
1701
1702class RegExpTree: public ZoneObject {
1703 public:
1704 static const int kInfinity = kMaxInt;
1705 virtual ~RegExpTree() { }
1706 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
1707 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1708 RegExpNode* on_success) = 0;
1709 virtual bool IsTextElement() { return false; }
1710 virtual bool IsAnchored() { return false; }
1711 virtual int min_match() = 0;
1712 virtual int max_match() = 0;
1713 // Returns the interval of registers used for captures within this
1714 // expression.
1715 virtual Interval CaptureRegisters() { return Interval::Empty(); }
1716 virtual void AppendToText(RegExpText* text);
1717 SmartPointer<const char> ToString();
1718#define MAKE_ASTYPE(Name) \
1719 virtual RegExp##Name* As##Name(); \
1720 virtual bool Is##Name();
1721 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
1722#undef MAKE_ASTYPE
1723};
1724
1725
1726class RegExpDisjunction: public RegExpTree {
1727 public:
1728 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
1729 virtual void* Accept(RegExpVisitor* visitor, void* data);
1730 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1731 RegExpNode* on_success);
1732 virtual RegExpDisjunction* AsDisjunction();
1733 virtual Interval CaptureRegisters();
1734 virtual bool IsDisjunction();
1735 virtual bool IsAnchored();
1736 virtual int min_match() { return min_match_; }
1737 virtual int max_match() { return max_match_; }
1738 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
1739 private:
1740 ZoneList<RegExpTree*>* alternatives_;
1741 int min_match_;
1742 int max_match_;
1743};
1744
1745
1746class RegExpAlternative: public RegExpTree {
1747 public:
1748 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
1749 virtual void* Accept(RegExpVisitor* visitor, void* data);
1750 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1751 RegExpNode* on_success);
1752 virtual RegExpAlternative* AsAlternative();
1753 virtual Interval CaptureRegisters();
1754 virtual bool IsAlternative();
1755 virtual bool IsAnchored();
1756 virtual int min_match() { return min_match_; }
1757 virtual int max_match() { return max_match_; }
1758 ZoneList<RegExpTree*>* nodes() { return nodes_; }
1759 private:
1760 ZoneList<RegExpTree*>* nodes_;
1761 int min_match_;
1762 int max_match_;
1763};
1764
1765
1766class RegExpAssertion: public RegExpTree {
1767 public:
1768 enum Type {
1769 START_OF_LINE,
1770 START_OF_INPUT,
1771 END_OF_LINE,
1772 END_OF_INPUT,
1773 BOUNDARY,
1774 NON_BOUNDARY
1775 };
1776 explicit RegExpAssertion(Type type) : type_(type) { }
1777 virtual void* Accept(RegExpVisitor* visitor, void* data);
1778 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1779 RegExpNode* on_success);
1780 virtual RegExpAssertion* AsAssertion();
1781 virtual bool IsAssertion();
1782 virtual bool IsAnchored();
1783 virtual int min_match() { return 0; }
1784 virtual int max_match() { return 0; }
1785 Type type() { return type_; }
1786 private:
1787 Type type_;
1788};
1789
1790
1791class CharacterSet BASE_EMBEDDED {
1792 public:
1793 explicit CharacterSet(uc16 standard_set_type)
1794 : ranges_(NULL),
1795 standard_set_type_(standard_set_type) {}
1796 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
1797 : ranges_(ranges),
1798 standard_set_type_(0) {}
1799 ZoneList<CharacterRange>* ranges();
1800 uc16 standard_set_type() { return standard_set_type_; }
1801 void set_standard_set_type(uc16 special_set_type) {
1802 standard_set_type_ = special_set_type;
1803 }
1804 bool is_standard() { return standard_set_type_ != 0; }
Leon Clarkee46be812010-01-19 14:06:41 +00001805 void Canonicalize();
Steve Blocka7e24c12009-10-30 11:49:00 +00001806 private:
1807 ZoneList<CharacterRange>* ranges_;
1808 // If non-zero, the value represents a standard set (e.g., all whitespace
1809 // characters) without having to expand the ranges.
1810 uc16 standard_set_type_;
1811};
1812
1813
1814class RegExpCharacterClass: public RegExpTree {
1815 public:
1816 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
1817 : set_(ranges),
1818 is_negated_(is_negated) { }
1819 explicit RegExpCharacterClass(uc16 type)
1820 : set_(type),
1821 is_negated_(false) { }
1822 virtual void* Accept(RegExpVisitor* visitor, void* data);
1823 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1824 RegExpNode* on_success);
1825 virtual RegExpCharacterClass* AsCharacterClass();
1826 virtual bool IsCharacterClass();
1827 virtual bool IsTextElement() { return true; }
1828 virtual int min_match() { return 1; }
1829 virtual int max_match() { return 1; }
1830 virtual void AppendToText(RegExpText* text);
1831 CharacterSet character_set() { return set_; }
1832 // TODO(lrn): Remove need for complex version if is_standard that
1833 // recognizes a mangled standard set and just do { return set_.is_special(); }
1834 bool is_standard();
1835 // Returns a value representing the standard character set if is_standard()
1836 // returns true.
1837 // Currently used values are:
1838 // s : unicode whitespace
1839 // S : unicode non-whitespace
1840 // w : ASCII word character (digit, letter, underscore)
1841 // W : non-ASCII word character
1842 // d : ASCII digit
1843 // D : non-ASCII digit
1844 // . : non-unicode non-newline
1845 // * : All characters
1846 uc16 standard_type() { return set_.standard_set_type(); }
1847 ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
1848 bool is_negated() { return is_negated_; }
1849 private:
1850 CharacterSet set_;
1851 bool is_negated_;
1852};
1853
1854
1855class RegExpAtom: public RegExpTree {
1856 public:
1857 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
1858 virtual void* Accept(RegExpVisitor* visitor, void* data);
1859 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1860 RegExpNode* on_success);
1861 virtual RegExpAtom* AsAtom();
1862 virtual bool IsAtom();
1863 virtual bool IsTextElement() { return true; }
1864 virtual int min_match() { return data_.length(); }
1865 virtual int max_match() { return data_.length(); }
1866 virtual void AppendToText(RegExpText* text);
1867 Vector<const uc16> data() { return data_; }
1868 int length() { return data_.length(); }
1869 private:
1870 Vector<const uc16> data_;
1871};
1872
1873
1874class RegExpText: public RegExpTree {
1875 public:
1876 RegExpText() : elements_(2), length_(0) {}
1877 virtual void* Accept(RegExpVisitor* visitor, void* data);
1878 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1879 RegExpNode* on_success);
1880 virtual RegExpText* AsText();
1881 virtual bool IsText();
1882 virtual bool IsTextElement() { return true; }
1883 virtual int min_match() { return length_; }
1884 virtual int max_match() { return length_; }
1885 virtual void AppendToText(RegExpText* text);
1886 void AddElement(TextElement elm) {
1887 elements_.Add(elm);
1888 length_ += elm.length();
1889 };
1890 ZoneList<TextElement>* elements() { return &elements_; }
1891 private:
1892 ZoneList<TextElement> elements_;
1893 int length_;
1894};
1895
1896
1897class RegExpQuantifier: public RegExpTree {
1898 public:
Leon Clarkee46be812010-01-19 14:06:41 +00001899 enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
1900 RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
1901 : body_(body),
1902 min_(min),
Steve Blocka7e24c12009-10-30 11:49:00 +00001903 max_(max),
Leon Clarkee46be812010-01-19 14:06:41 +00001904 min_match_(min * body->min_match()),
1905 type_(type) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001906 if (max > 0 && body->max_match() > kInfinity / max) {
1907 max_match_ = kInfinity;
1908 } else {
1909 max_match_ = max * body->max_match();
1910 }
1911 }
1912 virtual void* Accept(RegExpVisitor* visitor, void* data);
1913 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1914 RegExpNode* on_success);
1915 static RegExpNode* ToNode(int min,
1916 int max,
1917 bool is_greedy,
1918 RegExpTree* body,
1919 RegExpCompiler* compiler,
1920 RegExpNode* on_success,
1921 bool not_at_start = false);
1922 virtual RegExpQuantifier* AsQuantifier();
1923 virtual Interval CaptureRegisters();
1924 virtual bool IsQuantifier();
1925 virtual int min_match() { return min_match_; }
1926 virtual int max_match() { return max_match_; }
1927 int min() { return min_; }
1928 int max() { return max_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001929 bool is_possessive() { return type_ == POSSESSIVE; }
1930 bool is_non_greedy() { return type_ == NON_GREEDY; }
1931 bool is_greedy() { return type_ == GREEDY; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001932 RegExpTree* body() { return body_; }
1933 private:
Leon Clarkee46be812010-01-19 14:06:41 +00001934 RegExpTree* body_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001935 int min_;
1936 int max_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001937 int min_match_;
1938 int max_match_;
Leon Clarkee46be812010-01-19 14:06:41 +00001939 Type type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001940};
1941
1942
1943class RegExpCapture: public RegExpTree {
1944 public:
1945 explicit RegExpCapture(RegExpTree* body, int index)
1946 : body_(body), index_(index) { }
1947 virtual void* Accept(RegExpVisitor* visitor, void* data);
1948 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1949 RegExpNode* on_success);
1950 static RegExpNode* ToNode(RegExpTree* body,
1951 int index,
1952 RegExpCompiler* compiler,
1953 RegExpNode* on_success);
1954 virtual RegExpCapture* AsCapture();
1955 virtual bool IsAnchored();
1956 virtual Interval CaptureRegisters();
1957 virtual bool IsCapture();
1958 virtual int min_match() { return body_->min_match(); }
1959 virtual int max_match() { return body_->max_match(); }
1960 RegExpTree* body() { return body_; }
1961 int index() { return index_; }
1962 static int StartRegister(int index) { return index * 2; }
1963 static int EndRegister(int index) { return index * 2 + 1; }
1964 private:
1965 RegExpTree* body_;
1966 int index_;
1967};
1968
1969
1970class RegExpLookahead: public RegExpTree {
1971 public:
1972 RegExpLookahead(RegExpTree* body,
1973 bool is_positive,
1974 int capture_count,
1975 int capture_from)
1976 : body_(body),
1977 is_positive_(is_positive),
1978 capture_count_(capture_count),
1979 capture_from_(capture_from) { }
1980
1981 virtual void* Accept(RegExpVisitor* visitor, void* data);
1982 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1983 RegExpNode* on_success);
1984 virtual RegExpLookahead* AsLookahead();
1985 virtual Interval CaptureRegisters();
1986 virtual bool IsLookahead();
1987 virtual bool IsAnchored();
1988 virtual int min_match() { return 0; }
1989 virtual int max_match() { return 0; }
1990 RegExpTree* body() { return body_; }
1991 bool is_positive() { return is_positive_; }
1992 int capture_count() { return capture_count_; }
1993 int capture_from() { return capture_from_; }
1994 private:
1995 RegExpTree* body_;
1996 bool is_positive_;
1997 int capture_count_;
1998 int capture_from_;
1999};
2000
2001
2002class RegExpBackReference: public RegExpTree {
2003 public:
2004 explicit RegExpBackReference(RegExpCapture* capture)
2005 : capture_(capture) { }
2006 virtual void* Accept(RegExpVisitor* visitor, void* data);
2007 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2008 RegExpNode* on_success);
2009 virtual RegExpBackReference* AsBackReference();
2010 virtual bool IsBackReference();
2011 virtual int min_match() { return 0; }
2012 virtual int max_match() { return capture_->max_match(); }
2013 int index() { return capture_->index(); }
2014 RegExpCapture* capture() { return capture_; }
2015 private:
2016 RegExpCapture* capture_;
2017};
2018
2019
2020class RegExpEmpty: public RegExpTree {
2021 public:
2022 RegExpEmpty() { }
2023 virtual void* Accept(RegExpVisitor* visitor, void* data);
2024 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2025 RegExpNode* on_success);
2026 virtual RegExpEmpty* AsEmpty();
2027 virtual bool IsEmpty();
2028 virtual int min_match() { return 0; }
2029 virtual int max_match() { return 0; }
2030 static RegExpEmpty* GetInstance() { return &kInstance; }
2031 private:
2032 static RegExpEmpty kInstance;
2033};
2034
2035
2036// ----------------------------------------------------------------------------
2037// Basic visitor
2038// - leaf node visitors are abstract.
2039
2040class AstVisitor BASE_EMBEDDED {
2041 public:
2042 AstVisitor() : stack_overflow_(false) { }
2043 virtual ~AstVisitor() { }
2044
Steve Block6ded16b2010-05-10 14:33:55 +01002045 // Stack overflow check and dynamic dispatch.
2046 void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
Steve Blocka7e24c12009-10-30 11:49:00 +00002047
Steve Block6ded16b2010-05-10 14:33:55 +01002048 // Iteration left-to-right.
Steve Block3ce2e202009-11-05 08:53:23 +00002049 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
Steve Blocka7e24c12009-10-30 11:49:00 +00002050 virtual void VisitStatements(ZoneList<Statement*>* statements);
2051 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
2052
2053 // Stack overflow tracking support.
2054 bool HasStackOverflow() const { return stack_overflow_; }
Steve Block6ded16b2010-05-10 14:33:55 +01002055 bool CheckStackOverflow();
Steve Blocka7e24c12009-10-30 11:49:00 +00002056
2057 // If a stack-overflow exception is encountered when visiting a
2058 // node, calling SetStackOverflow will make sure that the visitor
2059 // bails out without visiting more nodes.
2060 void SetStackOverflow() { stack_overflow_ = true; }
2061
Steve Blocka7e24c12009-10-30 11:49:00 +00002062 // Individual nodes
2063#define DEF_VISIT(type) \
2064 virtual void Visit##type(type* node) = 0;
2065 AST_NODE_LIST(DEF_VISIT)
2066#undef DEF_VISIT
2067
2068 private:
2069 bool stack_overflow_;
2070};
2071
2072
Steve Block6ded16b2010-05-10 14:33:55 +01002073class CopyAstVisitor : public AstVisitor {
2074 public:
2075 Expression* DeepCopyExpr(Expression* expr);
2076
2077 Statement* DeepCopyStmt(Statement* stmt);
2078
2079 private:
2080 ZoneList<Expression*>* DeepCopyExprList(ZoneList<Expression*>* expressions);
2081
2082 ZoneList<Statement*>* DeepCopyStmtList(ZoneList<Statement*>* statements);
2083
2084 // AST node visit functions.
2085#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
2086 AST_NODE_LIST(DECLARE_VISIT)
2087#undef DECLARE_VISIT
2088
2089 // Holds the result of copying an expression.
2090 Expression* expr_;
2091 // Holds the result of copying a statement.
2092 Statement* stmt_;
2093};
2094
Steve Blocka7e24c12009-10-30 11:49:00 +00002095} } // namespace v8::internal
2096
2097#endif // V8_AST_H_