blob: ba422fdaf38dbfadc51dd55559525b5571375059 [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) \
Steve Blocka7e24c12009-10-30 11:49:00 +000078 V(VariableProxy) \
79 V(Literal) \
80 V(RegExpLiteral) \
81 V(ObjectLiteral) \
82 V(ArrayLiteral) \
83 V(CatchExtensionObject) \
84 V(Assignment) \
85 V(Throw) \
86 V(Property) \
87 V(Call) \
88 V(CallNew) \
89 V(CallRuntime) \
90 V(UnaryOperation) \
Kristian Monsen80d68ea2010-09-08 11:05:35 +010091 V(IncrementOperation) \
Steve Blocka7e24c12009-10-30 11:49:00 +000092 V(CountOperation) \
93 V(BinaryOperation) \
94 V(CompareOperation) \
Kristian Monsen80d68ea2010-09-08 11:05:35 +010095 V(CompareToNull) \
Steve Blocka7e24c12009-10-30 11:49:00 +000096 V(ThisFunction)
97
98#define AST_NODE_LIST(V) \
99 V(Declaration) \
100 STATEMENT_NODE_LIST(V) \
101 EXPRESSION_NODE_LIST(V)
102
103// Forward declarations
Steve Block6ded16b2010-05-10 14:33:55 +0100104class BitVector;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100105class DefinitionInfo;
106class MaterializedLiteral;
107class TargetCollector;
108class TypeFeedbackOracle;
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 Murdochb0fe1622011-05-05 13:52:32 +0100136 static const int kNoNumber = -1;
137
138 AstNode() : id_(GetNextId()) { count_++; }
139
Ben Murdochf87a2032010-10-22 12:50:53 +0100140 virtual ~AstNode() { }
141
142 virtual void Accept(AstVisitor* v) = 0;
143 virtual Type node_type() const { return kInvalid; }
144
145 // Type testing & conversion functions overridden by concrete subclasses.
146#define DECLARE_NODE_FUNCTIONS(type) \
147 virtual type* As##type() { return NULL; }
148 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
149#undef DECLARE_NODE_FUNCTIONS
150
Steve Blocka7e24c12009-10-30 11:49:00 +0000151 virtual Statement* AsStatement() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000152 virtual Expression* AsExpression() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000153 virtual TargetCollector* AsTargetCollector() { return NULL; }
154 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
155 virtual IterationStatement* AsIterationStatement() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000156 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100157 virtual Slot* AsSlot() { return NULL; }
158
159 // True if the node is simple enough for us to inline calls containing it.
160 virtual bool IsInlineable() const { return false; }
161
162 static int Count() { return count_; }
163 static void ResetIds() { current_id_ = 0; }
164 unsigned id() const { return id_; }
165
166 protected:
167 static unsigned GetNextId() { return current_id_++; }
168 static unsigned ReserveIdRange(int n) {
169 unsigned tmp = current_id_;
170 current_id_ += n;
171 return tmp;
172 }
173
174 private:
175 static unsigned current_id_;
176 static unsigned count_;
177 unsigned id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000178};
179
180
181class Statement: public AstNode {
182 public:
183 Statement() : statement_pos_(RelocInfo::kNoPosition) {}
184
185 virtual Statement* AsStatement() { return this; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000186
Steve Block6ded16b2010-05-10 14:33:55 +0100187 virtual Assignment* StatementAsSimpleAssignment() { return NULL; }
188 virtual CountOperation* StatementAsCountOperation() { return NULL; }
189
Steve Blocka7e24c12009-10-30 11:49:00 +0000190 bool IsEmpty() { return AsEmptyStatement() != NULL; }
191
192 void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
193 int statement_pos() const { return statement_pos_; }
194
195 private:
196 int statement_pos_;
197};
198
199
200class Expression: public AstNode {
201 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100202 enum Context {
203 // Not assigned a context yet, or else will not be visited during
204 // code generation.
205 kUninitialized,
206 // Evaluated for its side effects.
207 kEffect,
208 // Evaluated for its value (and side effects).
209 kValue,
210 // Evaluated for control flow (and side effects).
211 kTest
212 };
213
Steve Block6ded16b2010-05-10 14:33:55 +0100214 Expression() : bitfields_(0) {}
Leon Clarke4515c472010-02-03 11:58:03 +0000215
Steve Blocka7e24c12009-10-30 11:49:00 +0000216 virtual Expression* AsExpression() { return this; }
217
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100218 virtual bool IsTrivial() { return false; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000219 virtual bool IsValidLeftHandSide() { return false; }
220
Ben Murdochb0fe1622011-05-05 13:52:32 +0100221 // Helpers for ToBoolean conversion.
222 virtual bool ToBooleanIsTrue() { return false; }
223 virtual bool ToBooleanIsFalse() { return false; }
224
Leon Clarkee46be812010-01-19 14:06:41 +0000225 // Symbols that cannot be parsed as array indices are considered property
226 // names. We do not treat symbols that can be array indexes as property
227 // names because [] for string objects is handled only by keyed ICs.
228 virtual bool IsPropertyName() { return false; }
229
Steve Blocka7e24c12009-10-30 11:49:00 +0000230 // Mark the expression as being compiled as an expression
231 // statement. This is used to transform postfix increments to
232 // (faster) prefix increments.
233 virtual void MarkAsStatement() { /* do nothing */ }
234
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100235 // True iff the result can be safely overwritten (to avoid allocation).
236 // False for operations that can return one of their operands.
237 virtual bool ResultOverwriteAllowed() { return false; }
238
239 // True iff the expression is a literal represented as a smi.
240 virtual bool IsSmiLiteral() { return false; }
241
Ben Murdochb0fe1622011-05-05 13:52:32 +0100242 // Type feedback information for assignments and properties.
243 virtual bool IsMonomorphic() {
244 UNREACHABLE();
245 return false;
246 }
247 virtual bool IsArrayLength() {
248 UNREACHABLE();
249 return false;
250 }
251 virtual ZoneMapList* GetReceiverTypes() {
252 UNREACHABLE();
253 return NULL;
254 }
255 virtual Handle<Map> GetMonomorphicReceiverType() {
256 UNREACHABLE();
257 return Handle<Map>();
258 }
259
Steve Blocka7e24c12009-10-30 11:49:00 +0000260 // Static type information for this expression.
Leon Clarkee46be812010-01-19 14:06:41 +0000261 StaticType* type() { return &type_; }
Steve Block3ce2e202009-11-05 08:53:23 +0000262
Steve Block6ded16b2010-05-10 14:33:55 +0100263 // True if the expression is a loop condition.
264 bool is_loop_condition() const {
265 return LoopConditionField::decode(bitfields_);
266 }
267 void set_is_loop_condition(bool flag) {
268 bitfields_ = (bitfields_ & ~LoopConditionField::mask()) |
269 LoopConditionField::encode(flag);
270 }
Leon Clarke4515c472010-02-03 11:58:03 +0000271
Steve Block6ded16b2010-05-10 14:33:55 +0100272 // The value of the expression is guaranteed to be a smi, because the
273 // top operation is a bit operation with a mask, or a shift.
274 bool GuaranteedSmiResult();
Leon Clarke4515c472010-02-03 11:58:03 +0000275
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100276 // AST analysis results.
277 void CopyAnalysisResultsFrom(Expression* other);
Andrei Popescu402d9372010-02-26 13:31:12 +0000278
Steve Block6ded16b2010-05-10 14:33:55 +0100279 // True if the expression rooted at this node can be compiled by the
280 // side-effect free compiler.
281 bool side_effect_free() { return SideEffectFreeField::decode(bitfields_); }
282 void set_side_effect_free(bool is_side_effect_free) {
283 bitfields_ &= ~SideEffectFreeField::mask();
284 bitfields_ |= SideEffectFreeField::encode(is_side_effect_free);
285 }
286
287 // Will the use of this expression treat -0 the same as 0 in all cases?
288 // If so, we can return 0 instead of -0 if we want to, to optimize code.
289 bool no_negative_zero() { return NoNegativeZeroField::decode(bitfields_); }
290 void set_no_negative_zero(bool no_negative_zero) {
291 bitfields_ &= ~NoNegativeZeroField::mask();
292 bitfields_ |= NoNegativeZeroField::encode(no_negative_zero);
293 }
294
295 // Will ToInt32 (ECMA 262-3 9.5) or ToUint32 (ECMA 262-3 9.6)
296 // be applied to the value of this expression?
297 // If so, we may be able to optimize the calculation of the value.
298 bool to_int32() { return ToInt32Field::decode(bitfields_); }
299 void set_to_int32(bool to_int32) {
300 bitfields_ &= ~ToInt32Field::mask();
301 bitfields_ |= ToInt32Field::encode(to_int32);
302 }
303
304 // How many bitwise logical or shift operators are used in this expression?
305 int num_bit_ops() { return NumBitOpsField::decode(bitfields_); }
306 void set_num_bit_ops(int num_bit_ops) {
307 bitfields_ &= ~NumBitOpsField::mask();
308 num_bit_ops = Min(num_bit_ops, kMaxNumBitOps);
309 bitfields_ |= NumBitOpsField::encode(num_bit_ops);
Andrei Popescu402d9372010-02-26 13:31:12 +0000310 }
311
Steve Blocka7e24c12009-10-30 11:49:00 +0000312 private:
Steve Block6ded16b2010-05-10 14:33:55 +0100313 static const int kMaxNumBitOps = (1 << 5) - 1;
314
315 uint32_t bitfields_;
Leon Clarkee46be812010-01-19 14:06:41 +0000316 StaticType type_;
Steve Block6ded16b2010-05-10 14:33:55 +0100317
318 // Using template BitField<type, start, size>.
319 class SideEffectFreeField : public BitField<bool, 0, 1> {};
320 class NoNegativeZeroField : public BitField<bool, 1, 1> {};
321 class ToInt32Field : public BitField<bool, 2, 1> {};
322 class NumBitOpsField : public BitField<int, 3, 5> {};
323 class LoopConditionField: public BitField<bool, 8, 1> {};
Steve Blocka7e24c12009-10-30 11:49:00 +0000324};
325
326
327/**
328 * A sentinel used during pre parsing that represents some expression
329 * that is a valid left hand side without having to actually build
330 * the expression.
331 */
332class ValidLeftHandSideSentinel: public Expression {
333 public:
334 virtual bool IsValidLeftHandSide() { return true; }
335 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
336 static ValidLeftHandSideSentinel* instance() { return &instance_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100337
Steve Blocka7e24c12009-10-30 11:49:00 +0000338 private:
339 static ValidLeftHandSideSentinel instance_;
340};
341
342
343class BreakableStatement: public Statement {
344 public:
345 enum Type {
346 TARGET_FOR_ANONYMOUS,
347 TARGET_FOR_NAMED_ONLY
348 };
349
350 // The labels associated with this statement. May be NULL;
351 // if it is != NULL, guaranteed to contain at least one entry.
352 ZoneStringList* labels() const { return labels_; }
353
354 // Type testing & conversion.
355 virtual BreakableStatement* AsBreakableStatement() { return this; }
356
357 // Code generation
358 BreakTarget* break_target() { return &break_target_; }
359
360 // Testers.
361 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
362
Ben Murdochb0fe1622011-05-05 13:52:32 +0100363 // Bailout support.
364 int EntryId() const { return entry_id_; }
365 int ExitId() const { return exit_id_; }
366
Steve Blocka7e24c12009-10-30 11:49:00 +0000367 protected:
Kristian Monsen25f61362010-05-21 11:50:48 +0100368 inline BreakableStatement(ZoneStringList* labels, Type type);
Steve Blocka7e24c12009-10-30 11:49:00 +0000369
370 private:
371 ZoneStringList* labels_;
372 Type type_;
373 BreakTarget break_target_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100374 int entry_id_;
375 int exit_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000376};
377
378
379class Block: public BreakableStatement {
380 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100381 inline Block(ZoneStringList* labels, int capacity, bool is_initializer_block);
Steve Blocka7e24c12009-10-30 11:49:00 +0000382
Ben Murdochf87a2032010-10-22 12:50:53 +0100383 DECLARE_NODE_TYPE(Block)
Steve Block6ded16b2010-05-10 14:33:55 +0100384
385 virtual Assignment* StatementAsSimpleAssignment() {
386 if (statements_.length() != 1) return NULL;
387 return statements_[0]->StatementAsSimpleAssignment();
388 }
389
390 virtual CountOperation* StatementAsCountOperation() {
391 if (statements_.length() != 1) return NULL;
392 return statements_[0]->StatementAsCountOperation();
393 }
394
Ben Murdochb0fe1622011-05-05 13:52:32 +0100395 virtual bool IsInlineable() const;
396
Steve Blocka7e24c12009-10-30 11:49:00 +0000397 void AddStatement(Statement* statement) { statements_.Add(statement); }
398
399 ZoneList<Statement*>* statements() { return &statements_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100400 bool is_initializer_block() const { return is_initializer_block_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000401
402 private:
403 ZoneList<Statement*> statements_;
404 bool is_initializer_block_;
405};
406
407
408class Declaration: public AstNode {
409 public:
410 Declaration(VariableProxy* proxy, Variable::Mode mode, FunctionLiteral* fun)
411 : proxy_(proxy),
412 mode_(mode),
413 fun_(fun) {
414 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
415 // At the moment there are no "const functions"'s in JavaScript...
416 ASSERT(fun == NULL || mode == Variable::VAR);
417 }
418
Ben Murdochf87a2032010-10-22 12:50:53 +0100419 DECLARE_NODE_TYPE(Declaration)
Steve Blocka7e24c12009-10-30 11:49:00 +0000420
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100421 VariableProxy* proxy() const { return proxy_; }
422 Variable::Mode mode() const { return mode_; }
423 FunctionLiteral* fun() const { return fun_; } // may be NULL
Steve Blocka7e24c12009-10-30 11:49:00 +0000424
425 private:
426 VariableProxy* proxy_;
427 Variable::Mode mode_;
428 FunctionLiteral* fun_;
429};
430
431
432class IterationStatement: public BreakableStatement {
433 public:
434 // Type testing & conversion.
435 virtual IterationStatement* AsIterationStatement() { return this; }
436
437 Statement* body() const { return body_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100438
439 // Bailout support.
440 int OsrEntryId() const { return osr_entry_id_; }
441 virtual int ContinueId() const = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000442
443 // Code generation
444 BreakTarget* continue_target() { return &continue_target_; }
445
446 protected:
Kristian Monsen25f61362010-05-21 11:50:48 +0100447 explicit inline IterationStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000448
449 void Initialize(Statement* body) {
450 body_ = body;
451 }
452
453 private:
454 Statement* body_;
455 BreakTarget continue_target_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100456 int osr_entry_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000457};
458
459
Steve Block3ce2e202009-11-05 08:53:23 +0000460class DoWhileStatement: public IterationStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000461 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100462 explicit inline DoWhileStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000463
Ben Murdochf87a2032010-10-22 12:50:53 +0100464 DECLARE_NODE_TYPE(DoWhileStatement)
465
Steve Block3ce2e202009-11-05 08:53:23 +0000466 void Initialize(Expression* cond, Statement* body) {
467 IterationStatement::Initialize(body);
468 cond_ = cond;
469 }
470
Steve Block3ce2e202009-11-05 08:53:23 +0000471 Expression* cond() const { return cond_; }
472
Steve Blockd0582a62009-12-15 09:54:21 +0000473 // Position where condition expression starts. We need it to make
474 // the loop's condition a breakable location.
475 int condition_position() { return condition_position_; }
476 void set_condition_position(int pos) { condition_position_ = pos; }
477
Ben Murdochb0fe1622011-05-05 13:52:32 +0100478 // Bailout support.
479 virtual int ContinueId() const { return continue_id_; }
480 int BackEdgeId() const { return back_edge_id_; }
481
Steve Block3ce2e202009-11-05 08:53:23 +0000482 private:
483 Expression* cond_;
Steve Blockd0582a62009-12-15 09:54:21 +0000484 int condition_position_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100485 int continue_id_;
486 int back_edge_id_;
Steve Block3ce2e202009-11-05 08:53:23 +0000487};
488
489
490class WhileStatement: public IterationStatement {
491 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100492 explicit inline WhileStatement(ZoneStringList* labels);
Steve Block3ce2e202009-11-05 08:53:23 +0000493
Ben Murdochf87a2032010-10-22 12:50:53 +0100494 DECLARE_NODE_TYPE(WhileStatement)
495
Steve Block3ce2e202009-11-05 08:53:23 +0000496 void Initialize(Expression* cond, Statement* body) {
497 IterationStatement::Initialize(body);
498 cond_ = cond;
499 }
500
Steve Block3ce2e202009-11-05 08:53:23 +0000501 Expression* cond() const { return cond_; }
502 bool may_have_function_literal() const {
503 return may_have_function_literal_;
504 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100505 void set_may_have_function_literal(bool value) {
506 may_have_function_literal_ = value;
507 }
Steve Block3ce2e202009-11-05 08:53:23 +0000508
Ben Murdochb0fe1622011-05-05 13:52:32 +0100509 // Bailout support.
510 virtual int ContinueId() const { return EntryId(); }
511 int BodyId() const { return body_id_; }
512
Steve Block3ce2e202009-11-05 08:53:23 +0000513 private:
514 Expression* cond_;
515 // True if there is a function literal subexpression in the condition.
516 bool may_have_function_literal_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100517 int body_id_;
Steve Block3ce2e202009-11-05 08:53:23 +0000518};
519
520
521class ForStatement: public IterationStatement {
522 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100523 explicit inline ForStatement(ZoneStringList* labels);
Steve Block6ded16b2010-05-10 14:33:55 +0100524
Ben Murdochf87a2032010-10-22 12:50:53 +0100525 DECLARE_NODE_TYPE(ForStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000526
527 void Initialize(Statement* init,
528 Expression* cond,
529 Statement* next,
530 Statement* body) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000531 IterationStatement::Initialize(body);
532 init_ = init;
533 cond_ = cond;
534 next_ = next;
535 }
536
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100537 Statement* init() const { return init_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100538 Expression* cond() const { return cond_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100539 Statement* next() const { return next_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100540
Steve Blocka7e24c12009-10-30 11:49:00 +0000541 bool may_have_function_literal() const {
542 return may_have_function_literal_;
543 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100544 void set_may_have_function_literal(bool value) {
545 may_have_function_literal_ = value;
546 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000547
Ben Murdochb0fe1622011-05-05 13:52:32 +0100548 // Bailout support.
549 virtual int ContinueId() const { return continue_id_; }
550 int BodyId() const { return body_id_; }
551
Steve Block6ded16b2010-05-10 14:33:55 +0100552 bool is_fast_smi_loop() { return loop_variable_ != NULL; }
553 Variable* loop_variable() { return loop_variable_; }
554 void set_loop_variable(Variable* var) { loop_variable_ = var; }
555
Steve Blocka7e24c12009-10-30 11:49:00 +0000556 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000557 Statement* init_;
558 Expression* cond_;
559 Statement* next_;
560 // True if there is a function literal subexpression in the condition.
561 bool may_have_function_literal_;
Steve Block6ded16b2010-05-10 14:33:55 +0100562 Variable* loop_variable_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100563 int continue_id_;
564 int body_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000565};
566
567
568class ForInStatement: public IterationStatement {
569 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100570 explicit inline ForInStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000571
Ben Murdochf87a2032010-10-22 12:50:53 +0100572 DECLARE_NODE_TYPE(ForInStatement)
573
Steve Blocka7e24c12009-10-30 11:49:00 +0000574 void Initialize(Expression* each, Expression* enumerable, Statement* body) {
575 IterationStatement::Initialize(body);
576 each_ = each;
577 enumerable_ = enumerable;
578 }
579
Steve Blocka7e24c12009-10-30 11:49:00 +0000580 Expression* each() const { return each_; }
581 Expression* enumerable() const { return enumerable_; }
582
Ben Murdochb0fe1622011-05-05 13:52:32 +0100583 // Bailout support.
584 int AssignmentId() const { return assignment_id_; }
585 virtual int ContinueId() const { return EntryId(); }
586
Steve Blocka7e24c12009-10-30 11:49:00 +0000587 private:
588 Expression* each_;
589 Expression* enumerable_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100590 int assignment_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000591};
592
593
594class ExpressionStatement: public Statement {
595 public:
596 explicit ExpressionStatement(Expression* expression)
597 : expression_(expression) { }
598
Ben Murdochf87a2032010-10-22 12:50:53 +0100599 DECLARE_NODE_TYPE(ExpressionStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000600
Ben Murdochb0fe1622011-05-05 13:52:32 +0100601 virtual bool IsInlineable() const;
602
Steve Block6ded16b2010-05-10 14:33:55 +0100603 virtual Assignment* StatementAsSimpleAssignment();
604 virtual CountOperation* StatementAsCountOperation();
605
Steve Blocka7e24c12009-10-30 11:49:00 +0000606 void set_expression(Expression* e) { expression_ = e; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100607 Expression* expression() const { return expression_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000608
609 private:
610 Expression* expression_;
611};
612
613
614class ContinueStatement: public Statement {
615 public:
616 explicit ContinueStatement(IterationStatement* target)
617 : target_(target) { }
618
Ben Murdochf87a2032010-10-22 12:50:53 +0100619 DECLARE_NODE_TYPE(ContinueStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000620
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100621 IterationStatement* target() const { return target_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000622
623 private:
624 IterationStatement* target_;
625};
626
627
628class BreakStatement: public Statement {
629 public:
630 explicit BreakStatement(BreakableStatement* target)
631 : target_(target) { }
632
Ben Murdochf87a2032010-10-22 12:50:53 +0100633 DECLARE_NODE_TYPE(BreakStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000634
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100635 BreakableStatement* target() const { return target_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000636
637 private:
638 BreakableStatement* target_;
639};
640
641
642class ReturnStatement: public Statement {
643 public:
644 explicit ReturnStatement(Expression* expression)
645 : expression_(expression) { }
646
Ben Murdochf87a2032010-10-22 12:50:53 +0100647 DECLARE_NODE_TYPE(ReturnStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000648
Ben Murdochb0fe1622011-05-05 13:52:32 +0100649 Expression* expression() const { return expression_; }
650 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000651
652 private:
653 Expression* expression_;
654};
655
656
657class WithEnterStatement: public Statement {
658 public:
659 explicit WithEnterStatement(Expression* expression, bool is_catch_block)
660 : expression_(expression), is_catch_block_(is_catch_block) { }
661
Ben Murdochf87a2032010-10-22 12:50:53 +0100662 DECLARE_NODE_TYPE(WithEnterStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000663
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100664 Expression* expression() const { return expression_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000665
666 bool is_catch_block() const { return is_catch_block_; }
667
668 private:
669 Expression* expression_;
670 bool is_catch_block_;
671};
672
673
674class WithExitStatement: public Statement {
675 public:
676 WithExitStatement() { }
677
Ben Murdochf87a2032010-10-22 12:50:53 +0100678 DECLARE_NODE_TYPE(WithExitStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000679};
680
681
682class CaseClause: public ZoneObject {
683 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100684 CaseClause(Expression* label, ZoneList<Statement*>* statements, int pos);
Steve Blocka7e24c12009-10-30 11:49:00 +0000685
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100686 bool is_default() const { return label_ == NULL; }
687 Expression* label() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000688 CHECK(!is_default());
689 return label_;
690 }
691 JumpTarget* body_target() { return &body_target_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100692 ZoneList<Statement*>* statements() const { return statements_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000693
Ben Murdochb0fe1622011-05-05 13:52:32 +0100694 int position() { return position_; }
695 void set_position(int pos) { position_ = pos; }
696
697 // Type feedback information.
698 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
699 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
700 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
701
Steve Blocka7e24c12009-10-30 11:49:00 +0000702 private:
703 Expression* label_;
704 JumpTarget body_target_;
705 ZoneList<Statement*>* statements_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100706 int position_;
707 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
708 CompareTypeFeedback compare_type_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000709};
710
711
712class SwitchStatement: public BreakableStatement {
713 public:
Kristian Monsen25f61362010-05-21 11:50:48 +0100714 explicit inline SwitchStatement(ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000715
Ben Murdochf87a2032010-10-22 12:50:53 +0100716 DECLARE_NODE_TYPE(SwitchStatement)
717
Steve Blocka7e24c12009-10-30 11:49:00 +0000718 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
719 tag_ = tag;
720 cases_ = cases;
721 }
722
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100723 Expression* tag() const { return tag_; }
724 ZoneList<CaseClause*>* cases() const { return cases_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000725
726 private:
727 Expression* tag_;
728 ZoneList<CaseClause*>* cases_;
729};
730
731
732// If-statements always have non-null references to their then- and
733// else-parts. When parsing if-statements with no explicit else-part,
734// the parser implicitly creates an empty statement. Use the
735// HasThenStatement() and HasElseStatement() functions to check if a
736// given if-statement has a then- or an else-part containing code.
737class IfStatement: public Statement {
738 public:
739 IfStatement(Expression* condition,
740 Statement* then_statement,
741 Statement* else_statement)
742 : condition_(condition),
743 then_statement_(then_statement),
Ben Murdochb0fe1622011-05-05 13:52:32 +0100744 else_statement_(else_statement),
745 then_id_(GetNextId()),
746 else_id_(GetNextId()) {
747 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000748
Ben Murdochf87a2032010-10-22 12:50:53 +0100749 DECLARE_NODE_TYPE(IfStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000750
Ben Murdochb0fe1622011-05-05 13:52:32 +0100751 virtual bool IsInlineable() const;
752
Steve Blocka7e24c12009-10-30 11:49:00 +0000753 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
754 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
755
756 Expression* condition() const { return condition_; }
757 Statement* then_statement() const { return then_statement_; }
758 Statement* else_statement() const { return else_statement_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100759
760 int ThenId() const { return then_id_; }
761 int ElseId() const { return else_id_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000762
763 private:
764 Expression* condition_;
765 Statement* then_statement_;
766 Statement* else_statement_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100767 int then_id_;
768 int else_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000769};
770
771
772// NOTE: TargetCollectors are represented as nodes to fit in the target
773// stack in the compiler; this should probably be reworked.
774class TargetCollector: public AstNode {
775 public:
776 explicit TargetCollector(ZoneList<BreakTarget*>* targets)
777 : targets_(targets) {
778 }
779
780 // Adds a jump target to the collector. The collector stores a pointer not
781 // a copy of the target to make binding work, so make sure not to pass in
782 // references to something on the stack.
783 void AddTarget(BreakTarget* target);
784
785 // Virtual behaviour. TargetCollectors are never part of the AST.
786 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
787 virtual TargetCollector* AsTargetCollector() { return this; }
788
789 ZoneList<BreakTarget*>* targets() { return targets_; }
790
791 private:
792 ZoneList<BreakTarget*>* targets_;
793};
794
795
796class TryStatement: public Statement {
797 public:
798 explicit TryStatement(Block* try_block)
799 : try_block_(try_block), escaping_targets_(NULL) { }
800
801 void set_escaping_targets(ZoneList<BreakTarget*>* targets) {
802 escaping_targets_ = targets;
803 }
804
805 Block* try_block() const { return try_block_; }
806 ZoneList<BreakTarget*>* escaping_targets() const { return escaping_targets_; }
807
808 private:
809 Block* try_block_;
810 ZoneList<BreakTarget*>* escaping_targets_;
811};
812
813
Steve Block3ce2e202009-11-05 08:53:23 +0000814class TryCatchStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000815 public:
Steve Block3ce2e202009-11-05 08:53:23 +0000816 TryCatchStatement(Block* try_block,
Leon Clarkee46be812010-01-19 14:06:41 +0000817 VariableProxy* catch_var,
Steve Block3ce2e202009-11-05 08:53:23 +0000818 Block* catch_block)
Steve Blocka7e24c12009-10-30 11:49:00 +0000819 : TryStatement(try_block),
820 catch_var_(catch_var),
821 catch_block_(catch_block) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000822 }
823
Ben Murdochf87a2032010-10-22 12:50:53 +0100824 DECLARE_NODE_TYPE(TryCatchStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000825
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100826 VariableProxy* catch_var() const { return catch_var_; }
827 Block* catch_block() const { return catch_block_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000828
829 private:
Leon Clarkee46be812010-01-19 14:06:41 +0000830 VariableProxy* catch_var_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000831 Block* catch_block_;
832};
833
834
Steve Block3ce2e202009-11-05 08:53:23 +0000835class TryFinallyStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000836 public:
Steve Block3ce2e202009-11-05 08:53:23 +0000837 TryFinallyStatement(Block* try_block, Block* finally_block)
Steve Blocka7e24c12009-10-30 11:49:00 +0000838 : TryStatement(try_block),
839 finally_block_(finally_block) { }
840
Ben Murdochf87a2032010-10-22 12:50:53 +0100841 DECLARE_NODE_TYPE(TryFinallyStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000842
843 Block* finally_block() const { return finally_block_; }
844
845 private:
846 Block* finally_block_;
847};
848
849
850class DebuggerStatement: public Statement {
851 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100852 DECLARE_NODE_TYPE(DebuggerStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000853};
854
855
856class EmptyStatement: public Statement {
857 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100858 DECLARE_NODE_TYPE(EmptyStatement)
Ben Murdochb0fe1622011-05-05 13:52:32 +0100859
860 virtual bool IsInlineable() const { return true; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000861};
862
863
864class Literal: public Expression {
865 public:
866 explicit Literal(Handle<Object> handle) : handle_(handle) { }
867
Ben Murdochf87a2032010-10-22 12:50:53 +0100868 DECLARE_NODE_TYPE(Literal)
869
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100870 virtual bool IsTrivial() { return true; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100871 virtual bool IsInlineable() const { return true; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100872 virtual bool IsSmiLiteral() { return handle_->IsSmi(); }
Steve Blocka7e24c12009-10-30 11:49:00 +0000873
Steve Blocka7e24c12009-10-30 11:49:00 +0000874 // Check if this literal is identical to the other literal.
875 bool IsIdenticalTo(const Literal* other) const {
876 return handle_.is_identical_to(other->handle_);
877 }
878
Leon Clarkee46be812010-01-19 14:06:41 +0000879 virtual bool IsPropertyName() {
880 if (handle_->IsSymbol()) {
881 uint32_t ignored;
882 return !String::cast(*handle_)->AsArrayIndex(&ignored);
883 }
884 return false;
885 }
886
Ben Murdochb0fe1622011-05-05 13:52:32 +0100887 Handle<String> AsPropertyName() {
888 ASSERT(IsPropertyName());
889 return Handle<String>::cast(handle_);
890 }
891
892 virtual bool ToBooleanIsTrue() { return handle_->ToBoolean()->IsTrue(); }
893 virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
894
Steve Blocka7e24c12009-10-30 11:49:00 +0000895 // Identity testers.
896 bool IsNull() const { return handle_.is_identical_to(Factory::null_value()); }
897 bool IsTrue() const { return handle_.is_identical_to(Factory::true_value()); }
898 bool IsFalse() const {
899 return handle_.is_identical_to(Factory::false_value());
900 }
901
902 Handle<Object> handle() const { return handle_; }
903
904 private:
905 Handle<Object> handle_;
906};
907
908
909// Base class for literals that needs space in the corresponding JSFunction.
910class MaterializedLiteral: public Expression {
911 public:
912 explicit MaterializedLiteral(int literal_index, bool is_simple, int depth)
913 : literal_index_(literal_index), is_simple_(is_simple), depth_(depth) {}
914
915 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
916
917 int literal_index() { return literal_index_; }
918
919 // A materialized literal is simple if the values consist of only
920 // constants and simple object and array literals.
921 bool is_simple() const { return is_simple_; }
922
Steve Blocka7e24c12009-10-30 11:49:00 +0000923 int depth() const { return depth_; }
924
925 private:
926 int literal_index_;
927 bool is_simple_;
928 int depth_;
929};
930
931
932// An object literal has a boilerplate object that is used
933// for minimizing the work when constructing it at runtime.
934class ObjectLiteral: public MaterializedLiteral {
935 public:
936 // Property is used for passing information
937 // about an object literal's properties from the parser
938 // to the code generator.
939 class Property: public ZoneObject {
940 public:
Steve Blocka7e24c12009-10-30 11:49:00 +0000941 enum Kind {
942 CONSTANT, // Property with constant value (compile time).
943 COMPUTED, // Property with computed value (execution time).
944 MATERIALIZED_LITERAL, // Property value is a materialized literal.
945 GETTER, SETTER, // Property is an accessor function.
946 PROTOTYPE // Property is __proto__.
947 };
948
949 Property(Literal* key, Expression* value);
950 Property(bool is_getter, FunctionLiteral* value);
951
952 Literal* key() { return key_; }
953 Expression* value() { return value_; }
954 Kind kind() { return kind_; }
955
Steve Blockd0582a62009-12-15 09:54:21 +0000956 bool IsCompileTimeValue();
957
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800958 void set_emit_store(bool emit_store);
959 bool emit_store();
960
Steve Blocka7e24c12009-10-30 11:49:00 +0000961 private:
962 Literal* key_;
963 Expression* value_;
964 Kind kind_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800965 bool emit_store_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000966 };
967
968 ObjectLiteral(Handle<FixedArray> constant_properties,
969 ZoneList<Property*>* properties,
970 int literal_index,
971 bool is_simple,
Steve Block6ded16b2010-05-10 14:33:55 +0100972 bool fast_elements,
Steve Blocka7e24c12009-10-30 11:49:00 +0000973 int depth)
974 : MaterializedLiteral(literal_index, is_simple, depth),
975 constant_properties_(constant_properties),
Steve Block6ded16b2010-05-10 14:33:55 +0100976 properties_(properties),
977 fast_elements_(fast_elements) {}
Steve Blocka7e24c12009-10-30 11:49:00 +0000978
Ben Murdochf87a2032010-10-22 12:50:53 +0100979 DECLARE_NODE_TYPE(ObjectLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +0000980
981 Handle<FixedArray> constant_properties() const {
982 return constant_properties_;
983 }
984 ZoneList<Property*>* properties() const { return properties_; }
985
Steve Block6ded16b2010-05-10 14:33:55 +0100986 bool fast_elements() const { return fast_elements_; }
987
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800988
989 // Mark all computed expressions that are bound to a key that
990 // is shadowed by a later occurrence of the same key. For the
991 // marked expressions, no store code is emitted.
992 void CalculateEmitStore();
993
Steve Blocka7e24c12009-10-30 11:49:00 +0000994 private:
995 Handle<FixedArray> constant_properties_;
996 ZoneList<Property*>* properties_;
Steve Block6ded16b2010-05-10 14:33:55 +0100997 bool fast_elements_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000998};
999
1000
1001// Node for capturing a regexp literal.
1002class RegExpLiteral: public MaterializedLiteral {
1003 public:
1004 RegExpLiteral(Handle<String> pattern,
1005 Handle<String> flags,
1006 int literal_index)
1007 : MaterializedLiteral(literal_index, false, 1),
1008 pattern_(pattern),
1009 flags_(flags) {}
1010
Ben Murdochf87a2032010-10-22 12:50:53 +01001011 DECLARE_NODE_TYPE(RegExpLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00001012
1013 Handle<String> pattern() const { return pattern_; }
1014 Handle<String> flags() const { return flags_; }
1015
1016 private:
1017 Handle<String> pattern_;
1018 Handle<String> flags_;
1019};
1020
1021// An array literal has a literals object that is used
1022// for minimizing the work when constructing it at runtime.
1023class ArrayLiteral: public MaterializedLiteral {
1024 public:
Leon Clarkee46be812010-01-19 14:06:41 +00001025 ArrayLiteral(Handle<FixedArray> constant_elements,
Steve Blocka7e24c12009-10-30 11:49:00 +00001026 ZoneList<Expression*>* values,
1027 int literal_index,
1028 bool is_simple,
1029 int depth)
1030 : MaterializedLiteral(literal_index, is_simple, depth),
Leon Clarkee46be812010-01-19 14:06:41 +00001031 constant_elements_(constant_elements),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001032 values_(values),
1033 first_element_id_(ReserveIdRange(values->length())) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00001034
Ben Murdochf87a2032010-10-22 12:50:53 +01001035 DECLARE_NODE_TYPE(ArrayLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00001036
Leon Clarkee46be812010-01-19 14:06:41 +00001037 Handle<FixedArray> constant_elements() const { return constant_elements_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001038 ZoneList<Expression*>* values() const { return values_; }
1039
Ben Murdochb0fe1622011-05-05 13:52:32 +01001040 // Return an AST id for an element that is used in simulate instructions.
1041 int GetIdForElement(int i) { return first_element_id_ + i; }
1042
Steve Blocka7e24c12009-10-30 11:49:00 +00001043 private:
Leon Clarkee46be812010-01-19 14:06:41 +00001044 Handle<FixedArray> constant_elements_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001045 ZoneList<Expression*>* values_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001046 int first_element_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001047};
1048
1049
1050// Node for constructing a context extension object for a catch block.
1051// The catch context extension object has one property, the catch
1052// variable, which should be DontDelete.
1053class CatchExtensionObject: public Expression {
1054 public:
1055 CatchExtensionObject(Literal* key, VariableProxy* value)
1056 : key_(key), value_(value) {
1057 }
1058
Ben Murdochf87a2032010-10-22 12:50:53 +01001059 DECLARE_NODE_TYPE(CatchExtensionObject)
Steve Blocka7e24c12009-10-30 11:49:00 +00001060
1061 Literal* key() const { return key_; }
1062 VariableProxy* value() const { return value_; }
1063
1064 private:
1065 Literal* key_;
1066 VariableProxy* value_;
1067};
1068
1069
1070class VariableProxy: public Expression {
1071 public:
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001072 explicit VariableProxy(Variable* var);
1073
Ben Murdochf87a2032010-10-22 12:50:53 +01001074 DECLARE_NODE_TYPE(VariableProxy)
Steve Blocka7e24c12009-10-30 11:49:00 +00001075
1076 // Type testing & conversion
1077 virtual Property* AsProperty() {
1078 return var_ == NULL ? NULL : var_->AsProperty();
1079 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001080
Steve Blocka7e24c12009-10-30 11:49:00 +00001081 Variable* AsVariable() {
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001082 if (this == NULL || var_ == NULL) return NULL;
1083 Expression* rewrite = var_->rewrite();
1084 if (rewrite == NULL || rewrite->AsSlot() != NULL) return var_;
1085 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +00001086 }
1087
1088 virtual bool IsValidLeftHandSide() {
1089 return var_ == NULL ? true : var_->IsValidLeftHandSide();
1090 }
1091
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001092 virtual bool IsTrivial() {
1093 // Reading from a mutable variable is a side effect, but the
1094 // variable for 'this' is immutable.
1095 return is_this_ || is_trivial_;
Andrei Popescu402d9372010-02-26 13:31:12 +00001096 }
1097
Ben Murdochb0fe1622011-05-05 13:52:32 +01001098 virtual bool IsInlineable() const;
1099
Steve Blocka7e24c12009-10-30 11:49:00 +00001100 bool IsVariable(Handle<String> n) {
1101 return !is_this() && name().is_identical_to(n);
1102 }
1103
1104 bool IsArguments() {
1105 Variable* variable = AsVariable();
1106 return (variable == NULL) ? false : variable->is_arguments();
1107 }
1108
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001109 Handle<String> name() const { return name_; }
1110 Variable* var() const { return var_; }
1111 bool is_this() const { return is_this_; }
1112 bool inside_with() const { return inside_with_; }
Steve Block6ded16b2010-05-10 14:33:55 +01001113
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001114 void MarkAsTrivial() { is_trivial_ = true; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001115
1116 // Bind this proxy to the variable var.
1117 void BindTo(Variable* var);
1118
1119 protected:
1120 Handle<String> name_;
1121 Variable* var_; // resolved variable, or NULL
1122 bool is_this_;
1123 bool inside_with_;
Steve Block6ded16b2010-05-10 14:33:55 +01001124 bool is_trivial_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001125
1126 VariableProxy(Handle<String> name, bool is_this, bool inside_with);
1127 explicit VariableProxy(bool is_this);
1128
1129 friend class Scope;
1130};
1131
1132
1133class VariableProxySentinel: public VariableProxy {
1134 public:
1135 virtual bool IsValidLeftHandSide() { return !is_this(); }
1136 static VariableProxySentinel* this_proxy() { return &this_proxy_; }
1137 static VariableProxySentinel* identifier_proxy() {
1138 return &identifier_proxy_;
1139 }
1140
1141 private:
1142 explicit VariableProxySentinel(bool is_this) : VariableProxy(is_this) { }
1143 static VariableProxySentinel this_proxy_;
1144 static VariableProxySentinel identifier_proxy_;
1145};
1146
1147
1148class Slot: public Expression {
1149 public:
1150 enum Type {
1151 // A slot in the parameter section on the stack. index() is
1152 // the parameter index, counting left-to-right, starting at 0.
1153 PARAMETER,
1154
1155 // A slot in the local section on the stack. index() is
1156 // the variable index in the stack frame, starting at 0.
1157 LOCAL,
1158
1159 // An indexed slot in a heap context. index() is the
1160 // variable index in the context object on the heap,
1161 // starting at 0. var()->scope() is the corresponding
1162 // scope.
1163 CONTEXT,
1164
1165 // A named slot in a heap context. var()->name() is the
1166 // variable name in the context object on the heap,
1167 // with lookup starting at the current context. index()
1168 // is invalid.
Steve Blockd0582a62009-12-15 09:54:21 +00001169 LOOKUP
Steve Blocka7e24c12009-10-30 11:49:00 +00001170 };
1171
1172 Slot(Variable* var, Type type, int index)
1173 : var_(var), type_(type), index_(index) {
1174 ASSERT(var != NULL);
1175 }
1176
Ben Murdochb0fe1622011-05-05 13:52:32 +01001177 virtual void Accept(AstVisitor* v);
1178
1179 virtual Slot* AsSlot() { return this; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001180
Steve Block6ded16b2010-05-10 14:33:55 +01001181 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)
Ben Murdochb0fe1622011-05-05 13:52:32 +01001204 : obj_(obj),
1205 key_(key),
1206 pos_(pos),
1207 type_(type),
1208 is_monomorphic_(false),
1209 receiver_types_(NULL),
1210 is_array_length_(false),
Steve Block9fac8402011-05-12 15:51:54 +01001211 is_function_prototype_(false),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001212 is_arguments_access_(false) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001213
Ben Murdochf87a2032010-10-22 12:50:53 +01001214 DECLARE_NODE_TYPE(Property)
Steve Blocka7e24c12009-10-30 11:49:00 +00001215
1216 virtual bool IsValidLeftHandSide() { return true; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001217 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001218
1219 Expression* obj() const { return obj_; }
1220 Expression* key() const { return key_; }
1221 int position() const { return pos_; }
1222 bool is_synthetic() const { return type_ == SYNTHETIC; }
1223
Steve Block9fac8402011-05-12 15:51:54 +01001224 bool IsFunctionPrototype() const { return is_function_prototype_; }
1225
Ben Murdochb0fe1622011-05-05 13:52:32 +01001226 // Marks that this is actually an argument rewritten to a keyed property
1227 // accessing the argument through the arguments shadow object.
1228 void set_is_arguments_access(bool is_arguments_access) {
1229 is_arguments_access_ = is_arguments_access;
1230 }
1231 bool is_arguments_access() const { return is_arguments_access_; }
1232
1233 // Type feedback information.
1234 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1235 virtual bool IsMonomorphic() { return is_monomorphic_; }
1236 virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
1237 virtual bool IsArrayLength() { return is_array_length_; }
1238 virtual Handle<Map> GetMonomorphicReceiverType() {
1239 return monomorphic_receiver_type_;
1240 }
1241
Steve Blocka7e24c12009-10-30 11:49:00 +00001242 // Returns a property singleton property access on 'this'. Used
1243 // during preparsing.
1244 static Property* this_property() { return &this_property_; }
1245
1246 private:
1247 Expression* obj_;
1248 Expression* key_;
1249 int pos_;
1250 Type type_;
1251
Ben Murdochb0fe1622011-05-05 13:52:32 +01001252 bool is_monomorphic_;
1253 ZoneMapList* receiver_types_;
1254 bool is_array_length_;
Steve Block9fac8402011-05-12 15:51:54 +01001255 bool is_function_prototype_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001256 bool is_arguments_access_;
1257 Handle<Map> monomorphic_receiver_type_;
1258
Steve Blocka7e24c12009-10-30 11:49:00 +00001259 // Dummy property used during preparsing.
1260 static Property this_property_;
1261};
1262
1263
1264class Call: public Expression {
1265 public:
1266 Call(Expression* expression, ZoneList<Expression*>* arguments, int pos)
Ben Murdochb0fe1622011-05-05 13:52:32 +01001267 : expression_(expression),
1268 arguments_(arguments),
1269 pos_(pos),
1270 is_monomorphic_(false),
1271 receiver_types_(NULL),
1272 return_id_(GetNextId()) {
1273 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001274
Ben Murdochf87a2032010-10-22 12:50:53 +01001275 DECLARE_NODE_TYPE(Call)
Steve Blocka7e24c12009-10-30 11:49:00 +00001276
Ben Murdochb0fe1622011-05-05 13:52:32 +01001277 virtual bool IsInlineable() const;
1278
Steve Blocka7e24c12009-10-30 11:49:00 +00001279 Expression* expression() const { return expression_; }
1280 ZoneList<Expression*>* arguments() const { return arguments_; }
1281 int position() { return pos_; }
1282
Ben Murdochb0fe1622011-05-05 13:52:32 +01001283 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1284 virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
1285 virtual bool IsMonomorphic() { return is_monomorphic_; }
1286 Handle<JSFunction> target() { return target_; }
1287 Handle<JSObject> holder() { return holder_; }
1288 Handle<JSGlobalPropertyCell> cell() { return cell_; }
1289
1290 bool ComputeTarget(Handle<Map> type, Handle<String> name);
1291 bool ComputeGlobalTarget(Handle<GlobalObject> global, Handle<String> name);
1292
1293 // Bailout support.
1294 int ReturnId() const { return return_id_; }
1295
Steve Blocka7e24c12009-10-30 11:49:00 +00001296 static Call* sentinel() { return &sentinel_; }
1297
Ben Murdochb0fe1622011-05-05 13:52:32 +01001298#ifdef DEBUG
1299 // Used to assert that the FullCodeGenerator records the return site.
1300 bool return_is_recorded_;
1301#endif
1302
Steve Blocka7e24c12009-10-30 11:49:00 +00001303 private:
1304 Expression* expression_;
1305 ZoneList<Expression*>* arguments_;
1306 int pos_;
1307
Ben Murdochb0fe1622011-05-05 13:52:32 +01001308 bool is_monomorphic_;
1309 ZoneMapList* receiver_types_;
1310 Handle<JSFunction> target_;
1311 Handle<JSObject> holder_;
1312 Handle<JSGlobalPropertyCell> cell_;
1313
1314 int return_id_;
1315
Steve Blocka7e24c12009-10-30 11:49:00 +00001316 static Call sentinel_;
1317};
1318
1319
1320class CallNew: public Expression {
1321 public:
1322 CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1323 : expression_(expression), arguments_(arguments), pos_(pos) { }
1324
Ben Murdochf87a2032010-10-22 12:50:53 +01001325 DECLARE_NODE_TYPE(CallNew)
Steve Blocka7e24c12009-10-30 11:49:00 +00001326
Ben Murdochb0fe1622011-05-05 13:52:32 +01001327 virtual bool IsInlineable() const;
1328
Steve Blocka7e24c12009-10-30 11:49:00 +00001329 Expression* expression() const { return expression_; }
1330 ZoneList<Expression*>* arguments() const { return arguments_; }
1331 int position() { return pos_; }
1332
1333 private:
1334 Expression* expression_;
1335 ZoneList<Expression*>* arguments_;
1336 int pos_;
1337};
1338
1339
1340// The CallRuntime class does not represent any official JavaScript
1341// language construct. Instead it is used to call a C or JS function
1342// with a set of arguments. This is used from the builtins that are
1343// implemented in JavaScript (see "v8natives.js").
1344class CallRuntime: public Expression {
1345 public:
1346 CallRuntime(Handle<String> name,
1347 Runtime::Function* function,
1348 ZoneList<Expression*>* arguments)
1349 : name_(name), function_(function), arguments_(arguments) { }
1350
Ben Murdochf87a2032010-10-22 12:50:53 +01001351 DECLARE_NODE_TYPE(CallRuntime)
Steve Blocka7e24c12009-10-30 11:49:00 +00001352
Ben Murdochb0fe1622011-05-05 13:52:32 +01001353 virtual bool IsInlineable() const;
1354
Steve Blocka7e24c12009-10-30 11:49:00 +00001355 Handle<String> name() const { return name_; }
1356 Runtime::Function* function() const { return function_; }
1357 ZoneList<Expression*>* arguments() const { return arguments_; }
Steve Blockd0582a62009-12-15 09:54:21 +00001358 bool is_jsruntime() const { return function_ == NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001359
1360 private:
1361 Handle<String> name_;
1362 Runtime::Function* function_;
1363 ZoneList<Expression*>* arguments_;
1364};
1365
1366
1367class UnaryOperation: public Expression {
1368 public:
1369 UnaryOperation(Token::Value op, Expression* expression)
1370 : op_(op), expression_(expression) {
1371 ASSERT(Token::IsUnaryOp(op));
1372 }
1373
Ben Murdochf87a2032010-10-22 12:50:53 +01001374 DECLARE_NODE_TYPE(UnaryOperation)
Steve Blocka7e24c12009-10-30 11:49:00 +00001375
Ben Murdochb0fe1622011-05-05 13:52:32 +01001376 virtual bool IsInlineable() const;
1377
Ben Murdochf87a2032010-10-22 12:50:53 +01001378 virtual bool ResultOverwriteAllowed();
Steve Blocka7e24c12009-10-30 11:49:00 +00001379
1380 Token::Value op() const { return op_; }
1381 Expression* expression() const { return expression_; }
1382
1383 private:
1384 Token::Value op_;
1385 Expression* expression_;
1386};
1387
1388
1389class BinaryOperation: public Expression {
1390 public:
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001391 BinaryOperation(Token::Value op,
1392 Expression* left,
1393 Expression* right,
1394 int pos)
Ben Murdochb0fe1622011-05-05 13:52:32 +01001395 : op_(op), left_(left), right_(right), pos_(pos), is_smi_only_(false) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001396 ASSERT(Token::IsBinaryOp(op));
Ben Murdochb0fe1622011-05-05 13:52:32 +01001397 right_id_ = (op == Token::AND || op == Token::OR)
Steve Block9fac8402011-05-12 15:51:54 +01001398 ? static_cast<int>(GetNextId())
Ben Murdochb0fe1622011-05-05 13:52:32 +01001399 : AstNode::kNoNumber;
Steve Blocka7e24c12009-10-30 11:49:00 +00001400 }
1401
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001402 // Create the binary operation corresponding to a compound assignment.
1403 explicit BinaryOperation(Assignment* assignment);
Steve Block6ded16b2010-05-10 14:33:55 +01001404
Ben Murdochf87a2032010-10-22 12:50:53 +01001405 DECLARE_NODE_TYPE(BinaryOperation)
Steve Blocka7e24c12009-10-30 11:49:00 +00001406
Ben Murdochb0fe1622011-05-05 13:52:32 +01001407 virtual bool IsInlineable() const;
1408
Ben Murdochf87a2032010-10-22 12:50:53 +01001409 virtual bool ResultOverwriteAllowed();
Steve Blocka7e24c12009-10-30 11:49:00 +00001410
Steve Blocka7e24c12009-10-30 11:49:00 +00001411 Token::Value op() const { return op_; }
1412 Expression* left() const { return left_; }
1413 Expression* right() const { return right_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001414 int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001415
Ben Murdochb0fe1622011-05-05 13:52:32 +01001416 // Type feedback information.
1417 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1418 bool IsSmiOnly() const { return is_smi_only_; }
1419
1420 // Bailout support.
1421 int RightId() const { return right_id_; }
1422
Steve Blocka7e24c12009-10-30 11:49:00 +00001423 private:
1424 Token::Value op_;
1425 Expression* left_;
1426 Expression* right_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001427 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001428 bool is_smi_only_;
1429 // The short-circuit logical operations have an AST ID for their
1430 // right-hand subexpression.
1431 int right_id_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001432};
1433
1434
1435class IncrementOperation: public Expression {
1436 public:
1437 IncrementOperation(Token::Value op, Expression* expr)
1438 : op_(op), expression_(expr) {
1439 ASSERT(Token::IsCountOp(op));
1440 }
1441
Ben Murdochf87a2032010-10-22 12:50:53 +01001442 DECLARE_NODE_TYPE(IncrementOperation)
1443
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001444 Token::Value op() const { return op_; }
1445 bool is_increment() { return op_ == Token::INC; }
1446 Expression* expression() const { return expression_; }
1447
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001448 private:
1449 Token::Value op_;
1450 Expression* expression_;
1451 int pos_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001452};
1453
1454
1455class CountOperation: public Expression {
1456 public:
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001457 CountOperation(bool is_prefix, IncrementOperation* increment, int pos)
Ben Murdochb0fe1622011-05-05 13:52:32 +01001458 : is_prefix_(is_prefix), increment_(increment), pos_(pos),
1459 assignment_id_(GetNextId()) {
1460 }
Steve Block6ded16b2010-05-10 14:33:55 +01001461
Ben Murdochf87a2032010-10-22 12:50:53 +01001462 DECLARE_NODE_TYPE(CountOperation)
Steve Block6ded16b2010-05-10 14:33:55 +01001463
Steve Blocka7e24c12009-10-30 11:49:00 +00001464 bool is_prefix() const { return is_prefix_; }
1465 bool is_postfix() const { return !is_prefix_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001466
1467 Token::Value op() const { return increment_->op(); }
Leon Clarkee46be812010-01-19 14:06:41 +00001468 Token::Value binary_op() {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001469 return (op() == Token::INC) ? Token::ADD : Token::SUB;
Leon Clarkee46be812010-01-19 14:06:41 +00001470 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001471
1472 Expression* expression() const { return increment_->expression(); }
1473 IncrementOperation* increment() const { return increment_; }
1474 int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001475
1476 virtual void MarkAsStatement() { is_prefix_ = true; }
1477
Ben Murdochb0fe1622011-05-05 13:52:32 +01001478 virtual bool IsInlineable() const;
1479
1480 // Bailout support.
1481 int AssignmentId() const { return assignment_id_; }
1482
Steve Blocka7e24c12009-10-30 11:49:00 +00001483 private:
1484 bool is_prefix_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001485 IncrementOperation* increment_;
1486 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001487 int assignment_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001488};
1489
1490
1491class CompareOperation: public Expression {
1492 public:
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001493 CompareOperation(Token::Value op,
1494 Expression* left,
1495 Expression* right,
1496 int pos)
Ben Murdochb0fe1622011-05-05 13:52:32 +01001497 : op_(op), left_(left), right_(right), pos_(pos), compare_type_(NONE) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001498 ASSERT(Token::IsCompareOp(op));
1499 }
1500
Ben Murdochf87a2032010-10-22 12:50:53 +01001501 DECLARE_NODE_TYPE(CompareOperation)
Steve Blocka7e24c12009-10-30 11:49:00 +00001502
1503 Token::Value op() const { return op_; }
1504 Expression* left() const { return left_; }
1505 Expression* right() const { return right_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001506 int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001507
Ben Murdochb0fe1622011-05-05 13:52:32 +01001508 virtual bool IsInlineable() const;
1509
1510 // Type feedback information.
1511 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1512 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
1513 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1514
Steve Blocka7e24c12009-10-30 11:49:00 +00001515 private:
1516 Token::Value op_;
1517 Expression* left_;
1518 Expression* right_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001519 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001520
1521 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
1522 CompareTypeFeedback compare_type_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001523};
1524
1525
1526class CompareToNull: public Expression {
1527 public:
1528 CompareToNull(bool is_strict, Expression* expression)
1529 : is_strict_(is_strict), expression_(expression) { }
1530
Ben Murdochf87a2032010-10-22 12:50:53 +01001531 DECLARE_NODE_TYPE(CompareToNull)
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001532
Ben Murdochb0fe1622011-05-05 13:52:32 +01001533 virtual bool IsInlineable() const;
1534
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001535 bool is_strict() const { return is_strict_; }
1536 Token::Value op() const { return is_strict_ ? Token::EQ_STRICT : Token::EQ; }
1537 Expression* expression() const { return expression_; }
1538
1539 private:
1540 bool is_strict_;
1541 Expression* expression_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001542};
1543
1544
1545class Conditional: public Expression {
1546 public:
1547 Conditional(Expression* condition,
1548 Expression* then_expression,
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001549 Expression* else_expression,
1550 int then_expression_position,
1551 int else_expression_position)
Steve Blocka7e24c12009-10-30 11:49:00 +00001552 : condition_(condition),
1553 then_expression_(then_expression),
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001554 else_expression_(else_expression),
1555 then_expression_position_(then_expression_position),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001556 else_expression_position_(else_expression_position),
1557 then_id_(GetNextId()),
1558 else_id_(GetNextId()) {
1559 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001560
Ben Murdochf87a2032010-10-22 12:50:53 +01001561 DECLARE_NODE_TYPE(Conditional)
Steve Blocka7e24c12009-10-30 11:49:00 +00001562
Ben Murdochb0fe1622011-05-05 13:52:32 +01001563 virtual bool IsInlineable() const;
1564
Steve Blocka7e24c12009-10-30 11:49:00 +00001565 Expression* condition() const { return condition_; }
1566 Expression* then_expression() const { return then_expression_; }
1567 Expression* else_expression() const { return else_expression_; }
1568
Ben Murdochb0fe1622011-05-05 13:52:32 +01001569 int then_expression_position() const { return then_expression_position_; }
1570 int else_expression_position() const { return else_expression_position_; }
1571
1572 int ThenId() const { return then_id_; }
1573 int ElseId() const { return else_id_; }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001574
Steve Blocka7e24c12009-10-30 11:49:00 +00001575 private:
1576 Expression* condition_;
1577 Expression* then_expression_;
1578 Expression* else_expression_;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001579 int then_expression_position_;
1580 int else_expression_position_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001581 int then_id_;
1582 int else_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001583};
1584
1585
1586class Assignment: public Expression {
1587 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +01001588 Assignment(Token::Value op, Expression* target, Expression* value, int pos);
Steve Blocka7e24c12009-10-30 11:49:00 +00001589
Ben Murdochf87a2032010-10-22 12:50:53 +01001590 DECLARE_NODE_TYPE(Assignment)
Steve Blocka7e24c12009-10-30 11:49:00 +00001591
Ben Murdochb0fe1622011-05-05 13:52:32 +01001592 virtual bool IsInlineable() const;
1593
Steve Block6ded16b2010-05-10 14:33:55 +01001594 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1595
Steve Blocka7e24c12009-10-30 11:49:00 +00001596 Token::Value binary_op() const;
1597
1598 Token::Value op() const { return op_; }
1599 Expression* target() const { return target_; }
1600 Expression* value() const { return value_; }
1601 int position() { return pos_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001602 BinaryOperation* binary_operation() const { return binary_operation_; }
1603
Leon Clarkee46be812010-01-19 14:06:41 +00001604 // This check relies on the definition order of token in token.h.
1605 bool is_compound() const { return op() > Token::ASSIGN; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001606
1607 // An initialization block is a series of statments of the form
1608 // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1609 // ending of these blocks to allow for optimizations of initialization
1610 // blocks.
1611 bool starts_initialization_block() { return block_start_; }
1612 bool ends_initialization_block() { return block_end_; }
1613 void mark_block_start() { block_start_ = true; }
1614 void mark_block_end() { block_end_ = true; }
1615
Ben Murdochb0fe1622011-05-05 13:52:32 +01001616 // Type feedback information.
1617 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1618 virtual bool IsMonomorphic() { return is_monomorphic_; }
1619 virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
1620 virtual Handle<Map> GetMonomorphicReceiverType() {
1621 return monomorphic_receiver_type_;
1622 }
1623
1624 // Bailout support.
1625 int CompoundLoadId() const { return compound_load_id_; }
1626 int AssignmentId() const { return assignment_id_; }
1627
Steve Blocka7e24c12009-10-30 11:49:00 +00001628 private:
1629 Token::Value op_;
1630 Expression* target_;
1631 Expression* value_;
1632 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001633 BinaryOperation* binary_operation_;
1634 int compound_load_id_;
1635 int assignment_id_;
1636
Steve Blocka7e24c12009-10-30 11:49:00 +00001637 bool block_start_;
1638 bool block_end_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001639
1640 bool is_monomorphic_;
1641 ZoneMapList* receiver_types_;
1642 Handle<Map> monomorphic_receiver_type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001643};
1644
1645
1646class Throw: public Expression {
1647 public:
1648 Throw(Expression* exception, int pos)
1649 : exception_(exception), pos_(pos) {}
1650
Ben Murdochf87a2032010-10-22 12:50:53 +01001651 DECLARE_NODE_TYPE(Throw)
Steve Block6ded16b2010-05-10 14:33:55 +01001652
Steve Blocka7e24c12009-10-30 11:49:00 +00001653 Expression* exception() const { return exception_; }
1654 int position() const { return pos_; }
1655
1656 private:
1657 Expression* exception_;
1658 int pos_;
1659};
1660
1661
1662class FunctionLiteral: public Expression {
1663 public:
1664 FunctionLiteral(Handle<String> name,
1665 Scope* scope,
1666 ZoneList<Statement*>* body,
1667 int materialized_literal_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00001668 int expected_property_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00001669 bool has_only_simple_this_property_assignments,
1670 Handle<FixedArray> this_property_assignments,
1671 int num_parameters,
1672 int start_position,
1673 int end_position,
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001674 bool is_expression,
1675 bool contains_loops)
Steve Blocka7e24c12009-10-30 11:49:00 +00001676 : name_(name),
1677 scope_(scope),
1678 body_(body),
1679 materialized_literal_count_(materialized_literal_count),
Steve Blocka7e24c12009-10-30 11:49:00 +00001680 expected_property_count_(expected_property_count),
Steve Blocka7e24c12009-10-30 11:49:00 +00001681 has_only_simple_this_property_assignments_(
1682 has_only_simple_this_property_assignments),
1683 this_property_assignments_(this_property_assignments),
1684 num_parameters_(num_parameters),
1685 start_position_(start_position),
1686 end_position_(end_position),
1687 is_expression_(is_expression),
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001688 contains_loops_(contains_loops),
Steve Blocka7e24c12009-10-30 11:49:00 +00001689 function_token_position_(RelocInfo::kNoPosition),
Steve Blockd0582a62009-12-15 09:54:21 +00001690 inferred_name_(Heap::empty_string()),
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08001691 try_full_codegen_(false),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001692 pretenure_(false) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001693
Ben Murdochf87a2032010-10-22 12:50:53 +01001694 DECLARE_NODE_TYPE(FunctionLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00001695
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001696 Handle<String> name() const { return name_; }
1697 Scope* scope() const { return scope_; }
1698 ZoneList<Statement*>* body() const { return body_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001699 void set_function_token_position(int pos) { function_token_position_ = pos; }
1700 int function_token_position() const { return function_token_position_; }
1701 int start_position() const { return start_position_; }
1702 int end_position() const { return end_position_; }
1703 bool is_expression() const { return is_expression_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001704 bool contains_loops() const { return contains_loops_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001705
1706 int materialized_literal_count() { return materialized_literal_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001707 int expected_property_count() { return expected_property_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001708 bool has_only_simple_this_property_assignments() {
1709 return has_only_simple_this_property_assignments_;
1710 }
1711 Handle<FixedArray> this_property_assignments() {
1712 return this_property_assignments_;
1713 }
1714 int num_parameters() { return num_parameters_; }
1715
1716 bool AllowsLazyCompilation();
Ben Murdochb0fe1622011-05-05 13:52:32 +01001717 bool AllowOptimize();
Steve Blocka7e24c12009-10-30 11:49:00 +00001718
Ben Murdochf87a2032010-10-22 12:50:53 +01001719 Handle<String> debug_name() const {
1720 if (name_->length() > 0) return name_;
1721 return inferred_name();
1722 }
1723
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001724 Handle<String> inferred_name() const { return inferred_name_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001725 void set_inferred_name(Handle<String> inferred_name) {
1726 inferred_name_ = inferred_name;
1727 }
1728
Leon Clarked91b9f72010-01-27 17:25:45 +00001729 bool try_full_codegen() { return try_full_codegen_; }
1730 void set_try_full_codegen(bool flag) { try_full_codegen_ = flag; }
Steve Blockd0582a62009-12-15 09:54:21 +00001731
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08001732 bool pretenure() { return pretenure_; }
1733 void set_pretenure(bool value) { pretenure_ = value; }
1734
Steve Blocka7e24c12009-10-30 11:49:00 +00001735 private:
1736 Handle<String> name_;
1737 Scope* scope_;
1738 ZoneList<Statement*>* body_;
1739 int materialized_literal_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001740 int expected_property_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001741 bool has_only_simple_this_property_assignments_;
1742 Handle<FixedArray> this_property_assignments_;
1743 int num_parameters_;
1744 int start_position_;
1745 int end_position_;
1746 bool is_expression_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001747 bool contains_loops_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001748 int function_token_position_;
1749 Handle<String> inferred_name_;
Leon Clarked91b9f72010-01-27 17:25:45 +00001750 bool try_full_codegen_;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08001751 bool pretenure_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001752};
1753
1754
Steve Block6ded16b2010-05-10 14:33:55 +01001755class SharedFunctionInfoLiteral: public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00001756 public:
Steve Block6ded16b2010-05-10 14:33:55 +01001757 explicit SharedFunctionInfoLiteral(
1758 Handle<SharedFunctionInfo> shared_function_info)
1759 : shared_function_info_(shared_function_info) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001760
Ben Murdochf87a2032010-10-22 12:50:53 +01001761 DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
1762
Steve Block6ded16b2010-05-10 14:33:55 +01001763 Handle<SharedFunctionInfo> shared_function_info() const {
1764 return shared_function_info_;
1765 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001766
Steve Blocka7e24c12009-10-30 11:49:00 +00001767 private:
Steve Block6ded16b2010-05-10 14:33:55 +01001768 Handle<SharedFunctionInfo> shared_function_info_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001769};
1770
1771
1772class ThisFunction: public Expression {
1773 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001774 DECLARE_NODE_TYPE(ThisFunction)
Steve Blocka7e24c12009-10-30 11:49:00 +00001775};
1776
1777
1778// ----------------------------------------------------------------------------
1779// Regular expressions
1780
1781
1782class RegExpVisitor BASE_EMBEDDED {
1783 public:
1784 virtual ~RegExpVisitor() { }
1785#define MAKE_CASE(Name) \
1786 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
1787 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
1788#undef MAKE_CASE
1789};
1790
1791
1792class RegExpTree: public ZoneObject {
1793 public:
1794 static const int kInfinity = kMaxInt;
1795 virtual ~RegExpTree() { }
1796 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
1797 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1798 RegExpNode* on_success) = 0;
1799 virtual bool IsTextElement() { return false; }
Ben Murdochf87a2032010-10-22 12:50:53 +01001800 virtual bool IsAnchoredAtStart() { return false; }
1801 virtual bool IsAnchoredAtEnd() { return false; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001802 virtual int min_match() = 0;
1803 virtual int max_match() = 0;
1804 // Returns the interval of registers used for captures within this
1805 // expression.
1806 virtual Interval CaptureRegisters() { return Interval::Empty(); }
1807 virtual void AppendToText(RegExpText* text);
1808 SmartPointer<const char> ToString();
1809#define MAKE_ASTYPE(Name) \
1810 virtual RegExp##Name* As##Name(); \
1811 virtual bool Is##Name();
1812 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
1813#undef MAKE_ASTYPE
1814};
1815
1816
1817class RegExpDisjunction: public RegExpTree {
1818 public:
1819 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
1820 virtual void* Accept(RegExpVisitor* visitor, void* data);
1821 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1822 RegExpNode* on_success);
1823 virtual RegExpDisjunction* AsDisjunction();
1824 virtual Interval CaptureRegisters();
1825 virtual bool IsDisjunction();
Ben Murdochf87a2032010-10-22 12:50:53 +01001826 virtual bool IsAnchoredAtStart();
1827 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001828 virtual int min_match() { return min_match_; }
1829 virtual int max_match() { return max_match_; }
1830 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
1831 private:
1832 ZoneList<RegExpTree*>* alternatives_;
1833 int min_match_;
1834 int max_match_;
1835};
1836
1837
1838class RegExpAlternative: public RegExpTree {
1839 public:
1840 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
1841 virtual void* Accept(RegExpVisitor* visitor, void* data);
1842 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1843 RegExpNode* on_success);
1844 virtual RegExpAlternative* AsAlternative();
1845 virtual Interval CaptureRegisters();
1846 virtual bool IsAlternative();
Ben Murdochf87a2032010-10-22 12:50:53 +01001847 virtual bool IsAnchoredAtStart();
1848 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001849 virtual int min_match() { return min_match_; }
1850 virtual int max_match() { return max_match_; }
1851 ZoneList<RegExpTree*>* nodes() { return nodes_; }
1852 private:
1853 ZoneList<RegExpTree*>* nodes_;
1854 int min_match_;
1855 int max_match_;
1856};
1857
1858
1859class RegExpAssertion: public RegExpTree {
1860 public:
1861 enum Type {
1862 START_OF_LINE,
1863 START_OF_INPUT,
1864 END_OF_LINE,
1865 END_OF_INPUT,
1866 BOUNDARY,
1867 NON_BOUNDARY
1868 };
1869 explicit RegExpAssertion(Type type) : type_(type) { }
1870 virtual void* Accept(RegExpVisitor* visitor, void* data);
1871 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1872 RegExpNode* on_success);
1873 virtual RegExpAssertion* AsAssertion();
1874 virtual bool IsAssertion();
Ben Murdochf87a2032010-10-22 12:50:53 +01001875 virtual bool IsAnchoredAtStart();
1876 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001877 virtual int min_match() { return 0; }
1878 virtual int max_match() { return 0; }
1879 Type type() { return type_; }
1880 private:
1881 Type type_;
1882};
1883
1884
1885class CharacterSet BASE_EMBEDDED {
1886 public:
1887 explicit CharacterSet(uc16 standard_set_type)
1888 : ranges_(NULL),
1889 standard_set_type_(standard_set_type) {}
1890 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
1891 : ranges_(ranges),
1892 standard_set_type_(0) {}
1893 ZoneList<CharacterRange>* ranges();
1894 uc16 standard_set_type() { return standard_set_type_; }
1895 void set_standard_set_type(uc16 special_set_type) {
1896 standard_set_type_ = special_set_type;
1897 }
1898 bool is_standard() { return standard_set_type_ != 0; }
Leon Clarkee46be812010-01-19 14:06:41 +00001899 void Canonicalize();
Steve Blocka7e24c12009-10-30 11:49:00 +00001900 private:
1901 ZoneList<CharacterRange>* ranges_;
1902 // If non-zero, the value represents a standard set (e.g., all whitespace
1903 // characters) without having to expand the ranges.
1904 uc16 standard_set_type_;
1905};
1906
1907
1908class RegExpCharacterClass: public RegExpTree {
1909 public:
1910 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
1911 : set_(ranges),
1912 is_negated_(is_negated) { }
1913 explicit RegExpCharacterClass(uc16 type)
1914 : set_(type),
1915 is_negated_(false) { }
1916 virtual void* Accept(RegExpVisitor* visitor, void* data);
1917 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1918 RegExpNode* on_success);
1919 virtual RegExpCharacterClass* AsCharacterClass();
1920 virtual bool IsCharacterClass();
1921 virtual bool IsTextElement() { return true; }
1922 virtual int min_match() { return 1; }
1923 virtual int max_match() { return 1; }
1924 virtual void AppendToText(RegExpText* text);
1925 CharacterSet character_set() { return set_; }
1926 // TODO(lrn): Remove need for complex version if is_standard that
1927 // recognizes a mangled standard set and just do { return set_.is_special(); }
1928 bool is_standard();
1929 // Returns a value representing the standard character set if is_standard()
1930 // returns true.
1931 // Currently used values are:
1932 // s : unicode whitespace
1933 // S : unicode non-whitespace
1934 // w : ASCII word character (digit, letter, underscore)
1935 // W : non-ASCII word character
1936 // d : ASCII digit
1937 // D : non-ASCII digit
1938 // . : non-unicode non-newline
1939 // * : All characters
1940 uc16 standard_type() { return set_.standard_set_type(); }
1941 ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
1942 bool is_negated() { return is_negated_; }
1943 private:
1944 CharacterSet set_;
1945 bool is_negated_;
1946};
1947
1948
1949class RegExpAtom: public RegExpTree {
1950 public:
1951 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
1952 virtual void* Accept(RegExpVisitor* visitor, void* data);
1953 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1954 RegExpNode* on_success);
1955 virtual RegExpAtom* AsAtom();
1956 virtual bool IsAtom();
1957 virtual bool IsTextElement() { return true; }
1958 virtual int min_match() { return data_.length(); }
1959 virtual int max_match() { return data_.length(); }
1960 virtual void AppendToText(RegExpText* text);
1961 Vector<const uc16> data() { return data_; }
1962 int length() { return data_.length(); }
1963 private:
1964 Vector<const uc16> data_;
1965};
1966
1967
1968class RegExpText: public RegExpTree {
1969 public:
1970 RegExpText() : elements_(2), length_(0) {}
1971 virtual void* Accept(RegExpVisitor* visitor, void* data);
1972 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1973 RegExpNode* on_success);
1974 virtual RegExpText* AsText();
1975 virtual bool IsText();
1976 virtual bool IsTextElement() { return true; }
1977 virtual int min_match() { return length_; }
1978 virtual int max_match() { return length_; }
1979 virtual void AppendToText(RegExpText* text);
1980 void AddElement(TextElement elm) {
1981 elements_.Add(elm);
1982 length_ += elm.length();
Iain Merrick9ac36c92010-09-13 15:29:50 +01001983 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001984 ZoneList<TextElement>* elements() { return &elements_; }
1985 private:
1986 ZoneList<TextElement> elements_;
1987 int length_;
1988};
1989
1990
1991class RegExpQuantifier: public RegExpTree {
1992 public:
Leon Clarkee46be812010-01-19 14:06:41 +00001993 enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
1994 RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
1995 : body_(body),
1996 min_(min),
Steve Blocka7e24c12009-10-30 11:49:00 +00001997 max_(max),
Leon Clarkee46be812010-01-19 14:06:41 +00001998 min_match_(min * body->min_match()),
1999 type_(type) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002000 if (max > 0 && body->max_match() > kInfinity / max) {
2001 max_match_ = kInfinity;
2002 } else {
2003 max_match_ = max * body->max_match();
2004 }
2005 }
2006 virtual void* Accept(RegExpVisitor* visitor, void* data);
2007 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2008 RegExpNode* on_success);
2009 static RegExpNode* ToNode(int min,
2010 int max,
2011 bool is_greedy,
2012 RegExpTree* body,
2013 RegExpCompiler* compiler,
2014 RegExpNode* on_success,
2015 bool not_at_start = false);
2016 virtual RegExpQuantifier* AsQuantifier();
2017 virtual Interval CaptureRegisters();
2018 virtual bool IsQuantifier();
2019 virtual int min_match() { return min_match_; }
2020 virtual int max_match() { return max_match_; }
2021 int min() { return min_; }
2022 int max() { return max_; }
Leon Clarkee46be812010-01-19 14:06:41 +00002023 bool is_possessive() { return type_ == POSSESSIVE; }
2024 bool is_non_greedy() { return type_ == NON_GREEDY; }
2025 bool is_greedy() { return type_ == GREEDY; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002026 RegExpTree* body() { return body_; }
2027 private:
Leon Clarkee46be812010-01-19 14:06:41 +00002028 RegExpTree* body_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002029 int min_;
2030 int max_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002031 int min_match_;
2032 int max_match_;
Leon Clarkee46be812010-01-19 14:06:41 +00002033 Type type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002034};
2035
2036
2037class RegExpCapture: public RegExpTree {
2038 public:
2039 explicit RegExpCapture(RegExpTree* body, int index)
2040 : body_(body), index_(index) { }
2041 virtual void* Accept(RegExpVisitor* visitor, void* data);
2042 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2043 RegExpNode* on_success);
2044 static RegExpNode* ToNode(RegExpTree* body,
2045 int index,
2046 RegExpCompiler* compiler,
2047 RegExpNode* on_success);
2048 virtual RegExpCapture* AsCapture();
Ben Murdochf87a2032010-10-22 12:50:53 +01002049 virtual bool IsAnchoredAtStart();
2050 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00002051 virtual Interval CaptureRegisters();
2052 virtual bool IsCapture();
2053 virtual int min_match() { return body_->min_match(); }
2054 virtual int max_match() { return body_->max_match(); }
2055 RegExpTree* body() { return body_; }
2056 int index() { return index_; }
2057 static int StartRegister(int index) { return index * 2; }
2058 static int EndRegister(int index) { return index * 2 + 1; }
2059 private:
2060 RegExpTree* body_;
2061 int index_;
2062};
2063
2064
2065class RegExpLookahead: public RegExpTree {
2066 public:
2067 RegExpLookahead(RegExpTree* body,
2068 bool is_positive,
2069 int capture_count,
2070 int capture_from)
2071 : body_(body),
2072 is_positive_(is_positive),
2073 capture_count_(capture_count),
2074 capture_from_(capture_from) { }
2075
2076 virtual void* Accept(RegExpVisitor* visitor, void* data);
2077 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2078 RegExpNode* on_success);
2079 virtual RegExpLookahead* AsLookahead();
2080 virtual Interval CaptureRegisters();
2081 virtual bool IsLookahead();
Ben Murdochf87a2032010-10-22 12:50:53 +01002082 virtual bool IsAnchoredAtStart();
Steve Blocka7e24c12009-10-30 11:49:00 +00002083 virtual int min_match() { return 0; }
2084 virtual int max_match() { return 0; }
2085 RegExpTree* body() { return body_; }
2086 bool is_positive() { return is_positive_; }
2087 int capture_count() { return capture_count_; }
2088 int capture_from() { return capture_from_; }
2089 private:
2090 RegExpTree* body_;
2091 bool is_positive_;
2092 int capture_count_;
2093 int capture_from_;
2094};
2095
2096
2097class RegExpBackReference: public RegExpTree {
2098 public:
2099 explicit RegExpBackReference(RegExpCapture* capture)
2100 : capture_(capture) { }
2101 virtual void* Accept(RegExpVisitor* visitor, void* data);
2102 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2103 RegExpNode* on_success);
2104 virtual RegExpBackReference* AsBackReference();
2105 virtual bool IsBackReference();
2106 virtual int min_match() { return 0; }
2107 virtual int max_match() { return capture_->max_match(); }
2108 int index() { return capture_->index(); }
2109 RegExpCapture* capture() { return capture_; }
2110 private:
2111 RegExpCapture* capture_;
2112};
2113
2114
2115class RegExpEmpty: public RegExpTree {
2116 public:
2117 RegExpEmpty() { }
2118 virtual void* Accept(RegExpVisitor* visitor, void* data);
2119 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2120 RegExpNode* on_success);
2121 virtual RegExpEmpty* AsEmpty();
2122 virtual bool IsEmpty();
2123 virtual int min_match() { return 0; }
2124 virtual int max_match() { return 0; }
2125 static RegExpEmpty* GetInstance() { return &kInstance; }
2126 private:
2127 static RegExpEmpty kInstance;
2128};
2129
2130
2131// ----------------------------------------------------------------------------
2132// Basic visitor
2133// - leaf node visitors are abstract.
2134
2135class AstVisitor BASE_EMBEDDED {
2136 public:
2137 AstVisitor() : stack_overflow_(false) { }
2138 virtual ~AstVisitor() { }
2139
Steve Block6ded16b2010-05-10 14:33:55 +01002140 // Stack overflow check and dynamic dispatch.
2141 void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
Steve Blocka7e24c12009-10-30 11:49:00 +00002142
Steve Block6ded16b2010-05-10 14:33:55 +01002143 // Iteration left-to-right.
Steve Block3ce2e202009-11-05 08:53:23 +00002144 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
Steve Blocka7e24c12009-10-30 11:49:00 +00002145 virtual void VisitStatements(ZoneList<Statement*>* statements);
2146 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
2147
2148 // Stack overflow tracking support.
2149 bool HasStackOverflow() const { return stack_overflow_; }
Steve Block6ded16b2010-05-10 14:33:55 +01002150 bool CheckStackOverflow();
Steve Blocka7e24c12009-10-30 11:49:00 +00002151
2152 // If a stack-overflow exception is encountered when visiting a
2153 // node, calling SetStackOverflow will make sure that the visitor
2154 // bails out without visiting more nodes.
2155 void SetStackOverflow() { stack_overflow_ = true; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01002156 void ClearStackOverflow() { stack_overflow_ = false; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002157
Ben Murdochb0fe1622011-05-05 13:52:32 +01002158 // Nodes not appearing in the AST, including slots.
2159 virtual void VisitSlot(Slot* node) { UNREACHABLE(); }
2160
2161 // Individual AST nodes.
Steve Blocka7e24c12009-10-30 11:49:00 +00002162#define DEF_VISIT(type) \
2163 virtual void Visit##type(type* node) = 0;
2164 AST_NODE_LIST(DEF_VISIT)
2165#undef DEF_VISIT
2166
2167 private:
2168 bool stack_overflow_;
2169};
2170
Steve Blocka7e24c12009-10-30 11:49:00 +00002171} } // namespace v8::internal
2172
2173#endif // V8_AST_H_