blob: b56205f9a6779cb9703a82c1ca5c7a4779d8a4c4 [file] [log] [blame]
Ben Murdoch85b71792012-04-11 18:30:58 +01001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_AST_H_
29#define V8_AST_H_
30
Ben Murdoch85b71792012-04-11 18:30:58 +010031#include "allocation.h"
32#include "execution.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000033#include "factory.h"
Steve Block3ce2e202009-11-05 08:53:23 +000034#include "jsregexp.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000035#include "runtime.h"
Ben Murdoch69a99ed2011-11-30 16:03:39 +000036#include "small-pointer-list.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000037#include "token.h"
38#include "variables.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000039
40namespace v8 {
41namespace internal {
42
43// The abstract syntax tree is an intermediate, light-weight
44// representation of the parsed JavaScript code suitable for
45// compilation to native code.
46
47// Nodes are allocated in a separate zone, which allows faster
48// allocation and constant-time deallocation of the entire syntax
49// tree.
50
51
52// ----------------------------------------------------------------------------
53// Nodes of the abstract syntax tree. Only concrete classes are
54// enumerated here.
55
56#define STATEMENT_NODE_LIST(V) \
57 V(Block) \
58 V(ExpressionStatement) \
59 V(EmptyStatement) \
60 V(IfStatement) \
61 V(ContinueStatement) \
62 V(BreakStatement) \
63 V(ReturnStatement) \
Ben Murdoch69a99ed2011-11-30 16:03:39 +000064 V(WithStatement) \
Steve Blocka7e24c12009-10-30 11:49:00 +000065 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) \
Steve Blocka7e24c12009-10-30 11:49:00 +000083 V(Assignment) \
84 V(Throw) \
85 V(Property) \
86 V(Call) \
87 V(CallNew) \
88 V(CallRuntime) \
89 V(UnaryOperation) \
90 V(CountOperation) \
91 V(BinaryOperation) \
92 V(CompareOperation) \
Ben Murdoch85b71792012-04-11 18:30:58 +010093 V(CompareToNull) \
Steve Blocka7e24c12009-10-30 11:49:00 +000094 V(ThisFunction)
95
96#define AST_NODE_LIST(V) \
Ben Murdoch85b71792012-04-11 18:30:58 +010097 V(Declaration) \
Steve Blocka7e24c12009-10-30 11:49:00 +000098 STATEMENT_NODE_LIST(V) \
99 EXPRESSION_NODE_LIST(V)
100
101// Forward declarations
Ben Murdoch85b71792012-04-11 18:30:58 +0100102class BitVector;
103class DefinitionInfo;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100104class MaterializedLiteral;
105class TargetCollector;
106class TypeFeedbackOracle;
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
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100119#define DECLARE_NODE_TYPE(type) \
120 virtual void Accept(AstVisitor* v); \
Ben Murdoch85b71792012-04-11 18:30:58 +0100121 virtual AstNode::Type node_type() const { return AstNode::k##type; } \
122 virtual type* As##type() { return this; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100123
124
Steve Blocka7e24c12009-10-30 11:49:00 +0000125class AstNode: public ZoneObject {
126 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100127#define DECLARE_TYPE_ENUM(type) k##type,
128 enum Type {
129 AST_NODE_LIST(DECLARE_TYPE_ENUM)
130 kInvalid = -1
131 };
132#undef DECLARE_TYPE_ENUM
Steve Blocka7e24c12009-10-30 11:49:00 +0000133
Ben Murdochb0fe1622011-05-05 13:52:32 +0100134 static const int kNoNumber = -1;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100135 static const int kFunctionEntryId = 2; // Using 0 could disguise errors.
Ben Murdoch589d6972011-11-30 16:04:58 +0000136 // This AST id identifies the point after the declarations have been
137 // visited. We need it to capture the environment effects of declarations
138 // that emit code (function declarations).
139 static const int kDeclarationsId = 3;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100140
Ben Murdoch85b71792012-04-11 18:30:58 +0100141 // Override ZoneObject's new to count allocated AST nodes.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000142 void* operator new(size_t size, Zone* zone) {
Ben Murdoch85b71792012-04-11 18:30:58 +0100143 Isolate* isolate = zone->isolate();
144 isolate->set_ast_node_count(isolate->ast_node_count() + 1);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000145 return zone->New(static_cast<int>(size));
Steve Block44f0eee2011-05-26 01:26:41 +0100146 }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100147
Ben Murdoch85b71792012-04-11 18:30:58 +0100148 AstNode() {}
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000149
Ben Murdochf87a2032010-10-22 12:50:53 +0100150 virtual ~AstNode() { }
151
152 virtual void Accept(AstVisitor* v) = 0;
153 virtual Type node_type() const { return kInvalid; }
154
155 // Type testing & conversion functions overridden by concrete subclasses.
156#define DECLARE_NODE_FUNCTIONS(type) \
Ben Murdoch85b71792012-04-11 18:30:58 +0100157 virtual type* As##type() { return NULL; }
Ben Murdochf87a2032010-10-22 12:50:53 +0100158 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
159#undef DECLARE_NODE_FUNCTIONS
160
Steve Blocka7e24c12009-10-30 11:49:00 +0000161 virtual Statement* AsStatement() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000162 virtual Expression* AsExpression() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000163 virtual TargetCollector* AsTargetCollector() { return NULL; }
164 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
165 virtual IterationStatement* AsIterationStatement() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000166 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100167
Ben Murdoch85b71792012-04-11 18:30:58 +0100168 // True if the node is simple enough for us to inline calls containing it.
169 virtual bool IsInlineable() const = 0;
170
171 static int Count() { return Isolate::Current()->ast_node_count(); }
172 static void ResetIds() { Isolate::Current()->set_ast_node_id(0); }
173
Ben Murdochb0fe1622011-05-05 13:52:32 +0100174 protected:
Ben Murdoch85b71792012-04-11 18:30:58 +0100175 static unsigned GetNextId(Isolate* isolate) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000176 return ReserveIdRange(isolate, 1);
Steve Block44f0eee2011-05-26 01:26:41 +0100177 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000178
Ben Murdoch85b71792012-04-11 18:30:58 +0100179 static unsigned ReserveIdRange(Isolate* isolate, int n) {
180 unsigned tmp = isolate->ast_node_id();
Steve Block44f0eee2011-05-26 01:26:41 +0100181 isolate->set_ast_node_id(tmp + n);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100182 return tmp;
183 }
184
185 private:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000186 // Hidden to prevent accidental usage. It would have to load the
187 // current zone from the TLS.
188 void* operator new(size_t size);
Steve Block44f0eee2011-05-26 01:26:41 +0100189
190 friend class CaseClause; // Generates AST IDs.
Steve Blocka7e24c12009-10-30 11:49:00 +0000191};
192
193
194class Statement: public AstNode {
195 public:
196 Statement() : statement_pos_(RelocInfo::kNoPosition) {}
197
198 virtual Statement* AsStatement() { return this; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000199
Ben Murdoch85b71792012-04-11 18:30:58 +0100200 virtual Assignment* StatementAsSimpleAssignment() { return NULL; }
201 virtual CountOperation* StatementAsCountOperation() { return NULL; }
202
Steve Blocka7e24c12009-10-30 11:49:00 +0000203 bool IsEmpty() { return AsEmptyStatement() != NULL; }
204
205 void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
206 int statement_pos() const { return statement_pos_; }
207
208 private:
209 int statement_pos_;
210};
211
212
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000213class SmallMapList {
214 public:
215 SmallMapList() {}
216 explicit SmallMapList(int capacity) : list_(capacity) {}
217
218 void Reserve(int capacity) { list_.Reserve(capacity); }
219 void Clear() { list_.Clear(); }
220
221 bool is_empty() const { return list_.is_empty(); }
222 int length() const { return list_.length(); }
223
224 void Add(Handle<Map> handle) {
225 list_.Add(handle.location());
226 }
227
228 Handle<Map> at(int i) const {
229 return Handle<Map>(list_.at(i));
230 }
231
232 Handle<Map> first() const { return at(0); }
233 Handle<Map> last() const { return at(length() - 1); }
234
235 private:
236 // The list stores pointers to Map*, that is Map**, so it's GC safe.
237 SmallPointerList<Map*> list_;
238
239 DISALLOW_COPY_AND_ASSIGN(SmallMapList);
240};
241
242
Steve Blocka7e24c12009-10-30 11:49:00 +0000243class Expression: public AstNode {
244 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100245 enum Context {
246 // Not assigned a context yet, or else will not be visited during
247 // code generation.
248 kUninitialized,
249 // Evaluated for its side effects.
250 kEffect,
251 // Evaluated for its value (and side effects).
252 kValue,
253 // Evaluated for control flow (and side effects).
254 kTest
255 };
256
Ben Murdoch85b71792012-04-11 18:30:58 +0100257 explicit Expression(Isolate* isolate)
258 : id_(GetNextId(isolate)),
259 test_id_(GetNextId(isolate)) {}
260
Ben Murdoch8b112d22011-06-08 16:22:53 +0100261 virtual int position() const {
262 UNREACHABLE();
263 return 0;
264 }
Leon Clarke4515c472010-02-03 11:58:03 +0000265
Steve Blocka7e24c12009-10-30 11:49:00 +0000266 virtual Expression* AsExpression() { return this; }
267
Ben Murdoch85b71792012-04-11 18:30:58 +0100268 virtual bool IsTrivial() { return false; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000269 virtual bool IsValidLeftHandSide() { return false; }
270
Ben Murdochb0fe1622011-05-05 13:52:32 +0100271 // Helpers for ToBoolean conversion.
272 virtual bool ToBooleanIsTrue() { return false; }
273 virtual bool ToBooleanIsFalse() { return false; }
274
Leon Clarkee46be812010-01-19 14:06:41 +0000275 // Symbols that cannot be parsed as array indices are considered property
276 // names. We do not treat symbols that can be array indexes as property
277 // names because [] for string objects is handled only by keyed ICs.
278 virtual bool IsPropertyName() { return false; }
279
Ben Murdoch85b71792012-04-11 18:30:58 +0100280 // Mark the expression as being compiled as an expression
281 // statement. This is used to transform postfix increments to
282 // (faster) prefix increments.
283 virtual void MarkAsStatement() { /* do nothing */ }
284
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100285 // True iff the result can be safely overwritten (to avoid allocation).
286 // False for operations that can return one of their operands.
287 virtual bool ResultOverwriteAllowed() { return false; }
288
289 // True iff the expression is a literal represented as a smi.
Ben Murdoch85b71792012-04-11 18:30:58 +0100290 virtual bool IsSmiLiteral() { return false; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100291
Ben Murdochb0fe1622011-05-05 13:52:32 +0100292 // Type feedback information for assignments and properties.
293 virtual bool IsMonomorphic() {
294 UNREACHABLE();
295 return false;
296 }
Ben Murdoch85b71792012-04-11 18:30:58 +0100297 virtual bool IsArrayLength() {
298 UNREACHABLE();
299 return false;
300 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000301 virtual SmallMapList* GetReceiverTypes() {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100302 UNREACHABLE();
303 return NULL;
304 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000305 Handle<Map> GetMonomorphicReceiverType() {
306 ASSERT(IsMonomorphic());
307 SmallMapList* types = GetReceiverTypes();
308 ASSERT(types != NULL && types->length() == 1);
309 return types->at(0);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100310 }
311
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000312 unsigned id() const { return id_; }
313 unsigned test_id() const { return test_id_; }
Andrei Popescu402d9372010-02-26 13:31:12 +0000314
Steve Blocka7e24c12009-10-30 11:49:00 +0000315 private:
Ben Murdoch85b71792012-04-11 18:30:58 +0100316 unsigned id_;
317 unsigned test_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000318};
319
320
Steve Blocka7e24c12009-10-30 11:49:00 +0000321class BreakableStatement: public Statement {
322 public:
323 enum Type {
324 TARGET_FOR_ANONYMOUS,
325 TARGET_FOR_NAMED_ONLY
326 };
327
328 // The labels associated with this statement. May be NULL;
329 // if it is != NULL, guaranteed to contain at least one entry.
330 ZoneStringList* labels() const { return labels_; }
331
332 // Type testing & conversion.
333 virtual BreakableStatement* AsBreakableStatement() { return this; }
334
335 // Code generation
Ben Murdoch8b112d22011-06-08 16:22:53 +0100336 Label* break_target() { return &break_target_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000337
338 // Testers.
339 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
340
Ben Murdochb0fe1622011-05-05 13:52:32 +0100341 // Bailout support.
342 int EntryId() const { return entry_id_; }
343 int ExitId() const { return exit_id_; }
344
Steve Blocka7e24c12009-10-30 11:49:00 +0000345 protected:
Ben Murdoch85b71792012-04-11 18:30:58 +0100346 BreakableStatement(Isolate* isolate, ZoneStringList* labels, Type type);
Steve Blocka7e24c12009-10-30 11:49:00 +0000347
348 private:
349 ZoneStringList* labels_;
350 Type type_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100351 Label break_target_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100352 int entry_id_;
353 int exit_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000354};
355
356
357class Block: public BreakableStatement {
358 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100359 inline Block(Isolate* isolate,
360 ZoneStringList* labels,
361 int capacity,
362 bool is_initializer_block);
363
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100364 DECLARE_NODE_TYPE(Block)
365
Ben Murdoch85b71792012-04-11 18:30:58 +0100366 virtual Assignment* StatementAsSimpleAssignment() {
367 if (statements_.length() != 1) return NULL;
368 return statements_[0]->StatementAsSimpleAssignment();
369 }
370
371 virtual CountOperation* StatementAsCountOperation() {
372 if (statements_.length() != 1) return NULL;
373 return statements_[0]->StatementAsCountOperation();
374 }
375
376 virtual bool IsInlineable() const;
377
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100378 void AddStatement(Statement* statement) { statements_.Add(statement); }
379
380 ZoneList<Statement*>* statements() { return &statements_; }
381 bool is_initializer_block() const { return is_initializer_block_; }
382
383 Scope* block_scope() const { return block_scope_; }
384 void set_block_scope(Scope* block_scope) { block_scope_ = block_scope; }
385
Steve Blocka7e24c12009-10-30 11:49:00 +0000386 private:
387 ZoneList<Statement*> statements_;
388 bool is_initializer_block_;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000389 Scope* block_scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000390};
391
392
393class Declaration: public AstNode {
394 public:
Ben Murdoch589d6972011-11-30 16:04:58 +0000395 Declaration(VariableProxy* proxy,
Ben Murdoch85b71792012-04-11 18:30:58 +0100396 Variable::Mode mode,
397 FunctionLiteral* fun,
Ben Murdoch589d6972011-11-30 16:04:58 +0000398 Scope* scope)
Steve Blocka7e24c12009-10-30 11:49:00 +0000399 : proxy_(proxy),
400 mode_(mode),
Ben Murdoch85b71792012-04-11 18:30:58 +0100401 fun_(fun),
Ben Murdoch589d6972011-11-30 16:04:58 +0000402 scope_(scope) {
Ben Murdoch85b71792012-04-11 18:30:58 +0100403 ASSERT(mode == Variable::VAR ||
404 mode == Variable::CONST ||
405 mode == Variable::LET);
406 // At the moment there are no "const functions"'s in JavaScript...
407 ASSERT(fun == NULL || mode == Variable::VAR || mode == Variable::LET);
Steve Blocka7e24c12009-10-30 11:49:00 +0000408 }
409
Ben Murdoch85b71792012-04-11 18:30:58 +0100410 DECLARE_NODE_TYPE(Declaration)
411
412 VariableProxy* proxy() const { return proxy_; }
413 Variable::Mode mode() const { return mode_; }
414 FunctionLiteral* fun() const { return fun_; } // may be NULL
415 virtual bool IsInlineable() const;
416 Scope* scope() const { return scope_; }
417
Steve Blocka7e24c12009-10-30 11:49:00 +0000418 private:
419 VariableProxy* proxy_;
Ben Murdoch85b71792012-04-11 18:30:58 +0100420 Variable::Mode mode_;
421 FunctionLiteral* fun_;
Ben Murdoch589d6972011-11-30 16:04:58 +0000422
423 // Nested scope from which the declaration originated.
424 Scope* scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000425};
426
427
428class IterationStatement: public BreakableStatement {
429 public:
430 // Type testing & conversion.
431 virtual IterationStatement* AsIterationStatement() { return this; }
432
433 Statement* body() const { return body_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100434
435 // Bailout support.
436 int OsrEntryId() const { return osr_entry_id_; }
437 virtual int ContinueId() const = 0;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000438 virtual int StackCheckId() const = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000439
440 // Code generation
Ben Murdoch8b112d22011-06-08 16:22:53 +0100441 Label* continue_target() { return &continue_target_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000442
443 protected:
Ben Murdoch85b71792012-04-11 18:30:58 +0100444 inline IterationStatement(Isolate* isolate, ZoneStringList* labels);
Steve Blocka7e24c12009-10-30 11:49:00 +0000445
446 void Initialize(Statement* body) {
447 body_ = body;
448 }
449
450 private:
451 Statement* body_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100452 Label continue_target_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100453 int osr_entry_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000454};
455
456
Steve Block3ce2e202009-11-05 08:53:23 +0000457class DoWhileStatement: public IterationStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000458 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100459 inline DoWhileStatement(Isolate* isolate, ZoneStringList* labels);
460
Ben Murdochf87a2032010-10-22 12:50:53 +0100461 DECLARE_NODE_TYPE(DoWhileStatement)
462
Steve Block3ce2e202009-11-05 08:53:23 +0000463 void Initialize(Expression* cond, Statement* body) {
464 IterationStatement::Initialize(body);
465 cond_ = cond;
466 }
467
Steve Block3ce2e202009-11-05 08:53:23 +0000468 Expression* cond() const { return cond_; }
469
Steve Blockd0582a62009-12-15 09:54:21 +0000470 // Position where condition expression starts. We need it to make
471 // the loop's condition a breakable location.
472 int condition_position() { return condition_position_; }
473 void set_condition_position(int pos) { condition_position_ = pos; }
474
Ben Murdochb0fe1622011-05-05 13:52:32 +0100475 // Bailout support.
476 virtual int ContinueId() const { return continue_id_; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000477 virtual int StackCheckId() const { return back_edge_id_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100478 int BackEdgeId() const { return back_edge_id_; }
479
Ben Murdoch85b71792012-04-11 18:30:58 +0100480 virtual bool IsInlineable() const;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100481
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 Murdoch85b71792012-04-11 18:30:58 +0100492 inline WhileStatement(Isolate* isolate, ZoneStringList* labels);
493
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 }
Ben Murdoch85b71792012-04-11 18:30:58 +0100508 virtual bool IsInlineable() const;
Steve Block3ce2e202009-11-05 08:53:23 +0000509
Ben Murdochb0fe1622011-05-05 13:52:32 +0100510 // Bailout support.
511 virtual int ContinueId() const { return EntryId(); }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000512 virtual int StackCheckId() const { return body_id_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100513 int BodyId() const { return body_id_; }
514
Steve Block3ce2e202009-11-05 08:53:23 +0000515 private:
516 Expression* cond_;
517 // True if there is a function literal subexpression in the condition.
518 bool may_have_function_literal_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100519 int body_id_;
Steve Block3ce2e202009-11-05 08:53:23 +0000520};
521
522
523class ForStatement: public IterationStatement {
524 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100525 inline ForStatement(Isolate* isolate, ZoneStringList* labels);
526
Ben Murdochf87a2032010-10-22 12:50:53 +0100527 DECLARE_NODE_TYPE(ForStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000528
529 void Initialize(Statement* init,
530 Expression* cond,
531 Statement* next,
532 Statement* body) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000533 IterationStatement::Initialize(body);
534 init_ = init;
535 cond_ = cond;
536 next_ = next;
537 }
538
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100539 Statement* init() const { return init_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100540 Expression* cond() const { return cond_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100541 Statement* next() const { return next_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100542
Steve Blocka7e24c12009-10-30 11:49:00 +0000543 bool may_have_function_literal() const {
544 return may_have_function_literal_;
545 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100546 void set_may_have_function_literal(bool value) {
547 may_have_function_literal_ = value;
548 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000549
Ben Murdochb0fe1622011-05-05 13:52:32 +0100550 // Bailout support.
551 virtual int ContinueId() const { return continue_id_; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000552 virtual int StackCheckId() const { return body_id_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100553 int BodyId() const { return body_id_; }
554
Steve Block6ded16b2010-05-10 14:33:55 +0100555 bool is_fast_smi_loop() { return loop_variable_ != NULL; }
556 Variable* loop_variable() { return loop_variable_; }
557 void set_loop_variable(Variable* var) { loop_variable_ = var; }
Ben Murdoch85b71792012-04-11 18:30:58 +0100558 virtual bool IsInlineable() const;
Steve Block6ded16b2010-05-10 14:33:55 +0100559
Steve Blocka7e24c12009-10-30 11:49:00 +0000560 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000561 Statement* init_;
562 Expression* cond_;
563 Statement* next_;
564 // True if there is a function literal subexpression in the condition.
565 bool may_have_function_literal_;
Steve Block6ded16b2010-05-10 14:33:55 +0100566 Variable* loop_variable_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100567 int continue_id_;
568 int body_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000569};
570
571
572class ForInStatement: public IterationStatement {
573 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100574 inline ForInStatement(Isolate* isolate, ZoneStringList* labels);
575
Ben Murdochf87a2032010-10-22 12:50:53 +0100576 DECLARE_NODE_TYPE(ForInStatement)
577
Steve Blocka7e24c12009-10-30 11:49:00 +0000578 void Initialize(Expression* each, Expression* enumerable, Statement* body) {
579 IterationStatement::Initialize(body);
580 each_ = each;
581 enumerable_ = enumerable;
582 }
583
Steve Blocka7e24c12009-10-30 11:49:00 +0000584 Expression* each() const { return each_; }
585 Expression* enumerable() const { return enumerable_; }
Ben Murdoch85b71792012-04-11 18:30:58 +0100586 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000587
Ben Murdoch85b71792012-04-11 18:30:58 +0100588 // Bailout support.
589 int AssignmentId() const { return assignment_id_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100590 virtual int ContinueId() const { return EntryId(); }
Ben Murdoch85b71792012-04-11 18:30:58 +0100591 virtual int StackCheckId() const { return EntryId(); }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100592
Steve Blocka7e24c12009-10-30 11:49:00 +0000593 private:
594 Expression* each_;
595 Expression* enumerable_;
Ben Murdoch85b71792012-04-11 18:30:58 +0100596 int assignment_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000597};
598
599
600class ExpressionStatement: public Statement {
601 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100602 explicit ExpressionStatement(Expression* expression)
603 : expression_(expression) { }
604
Ben Murdochf87a2032010-10-22 12:50:53 +0100605 DECLARE_NODE_TYPE(ExpressionStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000606
Ben Murdoch85b71792012-04-11 18:30:58 +0100607 virtual bool IsInlineable() const;
608
609 virtual Assignment* StatementAsSimpleAssignment();
610 virtual CountOperation* StatementAsCountOperation();
611
Steve Blocka7e24c12009-10-30 11:49:00 +0000612 void set_expression(Expression* e) { expression_ = e; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100613 Expression* expression() const { return expression_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000614
615 private:
616 Expression* expression_;
617};
618
619
620class ContinueStatement: public Statement {
621 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100622 explicit ContinueStatement(IterationStatement* target)
623 : target_(target) { }
624
Ben Murdochf87a2032010-10-22 12:50:53 +0100625 DECLARE_NODE_TYPE(ContinueStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000626
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100627 IterationStatement* target() const { return target_; }
Ben Murdoch85b71792012-04-11 18:30:58 +0100628 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000629
630 private:
631 IterationStatement* target_;
632};
633
634
635class BreakStatement: public Statement {
636 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100637 explicit BreakStatement(BreakableStatement* target)
638 : target_(target) { }
639
Ben Murdochf87a2032010-10-22 12:50:53 +0100640 DECLARE_NODE_TYPE(BreakStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000641
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100642 BreakableStatement* target() const { return target_; }
Ben Murdoch85b71792012-04-11 18:30:58 +0100643 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000644
645 private:
646 BreakableStatement* target_;
647};
648
649
650class ReturnStatement: public Statement {
651 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100652 explicit ReturnStatement(Expression* expression)
653 : expression_(expression) { }
654
Ben Murdochf87a2032010-10-22 12:50:53 +0100655 DECLARE_NODE_TYPE(ReturnStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000656
Ben Murdochb0fe1622011-05-05 13:52:32 +0100657 Expression* expression() const { return expression_; }
Ben Murdoch85b71792012-04-11 18:30:58 +0100658 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000659
660 private:
661 Expression* expression_;
662};
663
664
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000665class WithStatement: public Statement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000666 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100667 WithStatement(Expression* expression, Statement* statement)
668 : expression_(expression), statement_(statement) { }
669
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000670 DECLARE_NODE_TYPE(WithStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000671
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100672 Expression* expression() const { return expression_; }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000673 Statement* statement() const { return statement_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000674
Ben Murdoch85b71792012-04-11 18:30:58 +0100675 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000676
677 private:
678 Expression* expression_;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000679 Statement* statement_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000680};
681
682
Steve Blocka7e24c12009-10-30 11:49:00 +0000683class CaseClause: public ZoneObject {
684 public:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000685 CaseClause(Isolate* isolate,
686 Expression* label,
687 ZoneList<Statement*>* statements,
688 int pos);
Steve Blocka7e24c12009-10-30 11:49:00 +0000689
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100690 bool is_default() const { return label_ == NULL; }
691 Expression* label() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000692 CHECK(!is_default());
693 return label_;
694 }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100695 Label* body_target() { return &body_target_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100696 ZoneList<Statement*>* statements() const { return statements_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000697
Ben Murdoch8b112d22011-06-08 16:22:53 +0100698 int position() const { return position_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100699 void set_position(int pos) { position_ = pos; }
700
Steve Block44f0eee2011-05-26 01:26:41 +0100701 int EntryId() { return entry_id_; }
Ben Murdoch257744e2011-11-30 15:57:28 +0000702 int CompareId() { return compare_id_; }
Steve Block44f0eee2011-05-26 01:26:41 +0100703
Ben Murdochb0fe1622011-05-05 13:52:32 +0100704 // Type feedback information.
705 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
706 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
707 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
708
Steve Blocka7e24c12009-10-30 11:49:00 +0000709 private:
710 Expression* label_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100711 Label body_target_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000712 ZoneList<Statement*>* statements_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100713 int position_;
Ben Murdoch85b71792012-04-11 18:30:58 +0100714 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
Ben Murdochb0fe1622011-05-05 13:52:32 +0100715 CompareTypeFeedback compare_type_;
Ben Murdoch257744e2011-11-30 15:57:28 +0000716 int compare_id_;
Steve Block44f0eee2011-05-26 01:26:41 +0100717 int entry_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000718};
719
720
721class SwitchStatement: public BreakableStatement {
722 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100723 inline SwitchStatement(Isolate* isolate, ZoneStringList* labels);
724
Ben Murdochf87a2032010-10-22 12:50:53 +0100725 DECLARE_NODE_TYPE(SwitchStatement)
726
Steve Blocka7e24c12009-10-30 11:49:00 +0000727 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
728 tag_ = tag;
729 cases_ = cases;
730 }
731
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100732 Expression* tag() const { return tag_; }
733 ZoneList<CaseClause*>* cases() const { return cases_; }
Ben Murdoch85b71792012-04-11 18:30:58 +0100734 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000735
736 private:
737 Expression* tag_;
738 ZoneList<CaseClause*>* cases_;
739};
740
741
742// If-statements always have non-null references to their then- and
743// else-parts. When parsing if-statements with no explicit else-part,
744// the parser implicitly creates an empty statement. Use the
745// HasThenStatement() and HasElseStatement() functions to check if a
746// given if-statement has a then- or an else-part containing code.
747class IfStatement: public Statement {
748 public:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100749 IfStatement(Isolate* isolate,
750 Expression* condition,
751 Statement* then_statement,
752 Statement* else_statement)
753 : condition_(condition),
754 then_statement_(then_statement),
755 else_statement_(else_statement),
756 if_id_(GetNextId(isolate)),
757 then_id_(GetNextId(isolate)),
758 else_id_(GetNextId(isolate)) {
759 }
760
Ben Murdoch85b71792012-04-11 18:30:58 +0100761 DECLARE_NODE_TYPE(IfStatement)
762
763 virtual bool IsInlineable() const;
764
765 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
766 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
767
768 Expression* condition() const { return condition_; }
769 Statement* then_statement() const { return then_statement_; }
770 Statement* else_statement() const { return else_statement_; }
771
772 int IfId() const { return if_id_; }
773 int ThenId() const { return then_id_; }
774 int ElseId() const { return else_id_; }
775
Steve Blocka7e24c12009-10-30 11:49:00 +0000776 private:
777 Expression* condition_;
778 Statement* then_statement_;
779 Statement* else_statement_;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000780 int if_id_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100781 int then_id_;
782 int else_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000783};
784
785
786// NOTE: TargetCollectors are represented as nodes to fit in the target
787// stack in the compiler; this should probably be reworked.
788class TargetCollector: public AstNode {
789 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100790 TargetCollector(): targets_(0) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000791
792 // Adds a jump target to the collector. The collector stores a pointer not
793 // a copy of the target to make binding work, so make sure not to pass in
794 // references to something on the stack.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100795 void AddTarget(Label* target);
Steve Blocka7e24c12009-10-30 11:49:00 +0000796
797 // Virtual behaviour. TargetCollectors are never part of the AST.
798 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
799 virtual TargetCollector* AsTargetCollector() { return this; }
800
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000801 ZoneList<Label*>* targets() { return &targets_; }
Ben Murdoch85b71792012-04-11 18:30:58 +0100802 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000803
804 private:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000805 ZoneList<Label*> targets_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000806};
807
808
809class TryStatement: public Statement {
810 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100811 explicit TryStatement(Block* try_block)
812 : try_block_(try_block), escaping_targets_(NULL) { }
813
Ben Murdoch8b112d22011-06-08 16:22:53 +0100814 void set_escaping_targets(ZoneList<Label*>* targets) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000815 escaping_targets_ = targets;
816 }
817
818 Block* try_block() const { return try_block_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100819 ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
Ben Murdoch85b71792012-04-11 18:30:58 +0100820 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000821
822 private:
823 Block* try_block_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100824 ZoneList<Label*>* escaping_targets_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000825};
826
827
Steve Block3ce2e202009-11-05 08:53:23 +0000828class TryCatchStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000829 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100830 TryCatchStatement(Block* try_block,
831 Scope* scope,
832 Variable* variable,
833 Block* catch_block)
834 : TryStatement(try_block),
835 scope_(scope),
836 variable_(variable),
837 catch_block_(catch_block) {
838 }
839
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100840 DECLARE_NODE_TYPE(TryCatchStatement)
841
842 Scope* scope() { return scope_; }
843 Variable* variable() { return variable_; }
844 Block* catch_block() const { return catch_block_; }
Ben Murdoch85b71792012-04-11 18:30:58 +0100845 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000846
Steve Blocka7e24c12009-10-30 11:49:00 +0000847 private:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000848 Scope* scope_;
849 Variable* variable_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000850 Block* catch_block_;
851};
852
853
Steve Block3ce2e202009-11-05 08:53:23 +0000854class TryFinallyStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000855 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100856 TryFinallyStatement(Block* try_block, Block* finally_block)
857 : TryStatement(try_block),
858 finally_block_(finally_block) { }
859
Ben Murdochf87a2032010-10-22 12:50:53 +0100860 DECLARE_NODE_TYPE(TryFinallyStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000861
862 Block* finally_block() const { return finally_block_; }
Ben Murdoch85b71792012-04-11 18:30:58 +0100863 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000864
865 private:
866 Block* finally_block_;
867};
868
869
870class DebuggerStatement: public Statement {
871 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100872 DECLARE_NODE_TYPE(DebuggerStatement)
Ben Murdoch85b71792012-04-11 18:30:58 +0100873 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000874};
875
876
877class EmptyStatement: public Statement {
878 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100879 DECLARE_NODE_TYPE(EmptyStatement)
Ben Murdochb0fe1622011-05-05 13:52:32 +0100880
Ben Murdoch85b71792012-04-11 18:30:58 +0100881 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000882};
883
884
885class Literal: public Expression {
886 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100887 Literal(Isolate* isolate, Handle<Object> handle)
888 : Expression(isolate), handle_(handle) { }
889
Ben Murdochf87a2032010-10-22 12:50:53 +0100890 DECLARE_NODE_TYPE(Literal)
891
Ben Murdoch85b71792012-04-11 18:30:58 +0100892 virtual bool IsTrivial() { return true; }
893 virtual bool IsSmiLiteral() { return handle_->IsSmi(); }
894
895 // Check if this literal is identical to the other literal.
896 bool IsIdenticalTo(const Literal* other) const {
897 return handle_.is_identical_to(other->handle_);
898 }
899
Leon Clarkee46be812010-01-19 14:06:41 +0000900 virtual bool IsPropertyName() {
901 if (handle_->IsSymbol()) {
902 uint32_t ignored;
903 return !String::cast(*handle_)->AsArrayIndex(&ignored);
904 }
905 return false;
906 }
907
Ben Murdochb0fe1622011-05-05 13:52:32 +0100908 Handle<String> AsPropertyName() {
909 ASSERT(IsPropertyName());
910 return Handle<String>::cast(handle_);
911 }
912
913 virtual bool ToBooleanIsTrue() { return handle_->ToBoolean()->IsTrue(); }
914 virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
915
Steve Blocka7e24c12009-10-30 11:49:00 +0000916 // Identity testers.
Steve Block44f0eee2011-05-26 01:26:41 +0100917 bool IsNull() const {
918 ASSERT(!handle_.is_null());
919 return handle_->IsNull();
920 }
921 bool IsTrue() const {
922 ASSERT(!handle_.is_null());
923 return handle_->IsTrue();
924 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000925 bool IsFalse() const {
Steve Block44f0eee2011-05-26 01:26:41 +0100926 ASSERT(!handle_.is_null());
927 return handle_->IsFalse();
Steve Blocka7e24c12009-10-30 11:49:00 +0000928 }
929
930 Handle<Object> handle() const { return handle_; }
Ben Murdoch85b71792012-04-11 18:30:58 +0100931 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000932
933 private:
934 Handle<Object> handle_;
935};
936
937
938// Base class for literals that needs space in the corresponding JSFunction.
939class MaterializedLiteral: public Expression {
940 public:
Ben Murdoch85b71792012-04-11 18:30:58 +0100941 MaterializedLiteral(Isolate* isolate,
942 int literal_index,
943 bool is_simple,
944 int depth)
945 : Expression(isolate),
946 literal_index_(literal_index),
947 is_simple_(is_simple),
948 depth_(depth) {}
949
Steve Blocka7e24c12009-10-30 11:49:00 +0000950 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
951
952 int literal_index() { return literal_index_; }
953
954 // A materialized literal is simple if the values consist of only
955 // constants and simple object and array literals.
956 bool is_simple() const { return is_simple_; }
957
Steve Blocka7e24c12009-10-30 11:49:00 +0000958 int depth() const { return depth_; }
Ben Murdoch85b71792012-04-11 18:30:58 +0100959 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000960
961 private:
962 int literal_index_;
963 bool is_simple_;
964 int depth_;
965};
966
967
968// An object literal has a boilerplate object that is used
969// for minimizing the work when constructing it at runtime.
970class ObjectLiteral: public MaterializedLiteral {
971 public:
972 // Property is used for passing information
973 // about an object literal's properties from the parser
974 // to the code generator.
975 class Property: public ZoneObject {
976 public:
Steve Blocka7e24c12009-10-30 11:49:00 +0000977 enum Kind {
978 CONSTANT, // Property with constant value (compile time).
979 COMPUTED, // Property with computed value (execution time).
980 MATERIALIZED_LITERAL, // Property value is a materialized literal.
981 GETTER, SETTER, // Property is an accessor function.
982 PROTOTYPE // Property is __proto__.
983 };
984
Ben Murdoch85b71792012-04-11 18:30:58 +0100985 Property(Literal* key, Expression* value);
986 Property(bool is_getter, FunctionLiteral* value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000987
988 Literal* key() { return key_; }
989 Expression* value() { return value_; }
990 Kind kind() { return kind_; }
991
Steve Blockd0582a62009-12-15 09:54:21 +0000992 bool IsCompileTimeValue();
993
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800994 void set_emit_store(bool emit_store);
995 bool emit_store();
996
Steve Blocka7e24c12009-10-30 11:49:00 +0000997 private:
998 Literal* key_;
999 Expression* value_;
1000 Kind kind_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001001 bool emit_store_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001002 };
1003
Ben Murdoch85b71792012-04-11 18:30:58 +01001004 ObjectLiteral(Isolate* isolate,
1005 Handle<FixedArray> constant_properties,
1006 ZoneList<Property*>* properties,
1007 int literal_index,
1008 bool is_simple,
1009 bool fast_elements,
1010 int depth,
1011 bool has_function)
1012 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
1013 constant_properties_(constant_properties),
1014 properties_(properties),
1015 fast_elements_(fast_elements),
1016 has_function_(has_function) {}
1017
Ben Murdochf87a2032010-10-22 12:50:53 +01001018 DECLARE_NODE_TYPE(ObjectLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00001019
1020 Handle<FixedArray> constant_properties() const {
1021 return constant_properties_;
1022 }
1023 ZoneList<Property*>* properties() const { return properties_; }
1024
Steve Block6ded16b2010-05-10 14:33:55 +01001025 bool fast_elements() const { return fast_elements_; }
1026
Steve Block44f0eee2011-05-26 01:26:41 +01001027 bool has_function() { return has_function_; }
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001028
1029 // Mark all computed expressions that are bound to a key that
1030 // is shadowed by a later occurrence of the same key. For the
1031 // marked expressions, no store code is emitted.
1032 void CalculateEmitStore();
1033
Steve Block44f0eee2011-05-26 01:26:41 +01001034 enum Flags {
1035 kNoFlags = 0,
1036 kFastElements = 1,
1037 kHasFunction = 1 << 1
1038 };
1039
Steve Blocka7e24c12009-10-30 11:49:00 +00001040 private:
1041 Handle<FixedArray> constant_properties_;
1042 ZoneList<Property*>* properties_;
Steve Block6ded16b2010-05-10 14:33:55 +01001043 bool fast_elements_;
Steve Block44f0eee2011-05-26 01:26:41 +01001044 bool has_function_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001045};
1046
1047
1048// Node for capturing a regexp literal.
1049class RegExpLiteral: public MaterializedLiteral {
1050 public:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001051 RegExpLiteral(Isolate* isolate,
1052 Handle<String> pattern,
Steve Blocka7e24c12009-10-30 11:49:00 +00001053 Handle<String> flags,
1054 int literal_index)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001055 : MaterializedLiteral(isolate, literal_index, false, 1),
Steve Blocka7e24c12009-10-30 11:49:00 +00001056 pattern_(pattern),
1057 flags_(flags) {}
1058
Ben Murdoch85b71792012-04-11 18:30:58 +01001059 DECLARE_NODE_TYPE(RegExpLiteral)
1060
1061 Handle<String> pattern() const { return pattern_; }
1062 Handle<String> flags() const { return flags_; }
1063
Steve Blocka7e24c12009-10-30 11:49:00 +00001064 private:
1065 Handle<String> pattern_;
1066 Handle<String> flags_;
1067};
1068
1069// An array literal has a literals object that is used
1070// for minimizing the work when constructing it at runtime.
1071class ArrayLiteral: public MaterializedLiteral {
1072 public:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001073 ArrayLiteral(Isolate* isolate,
1074 Handle<FixedArray> constant_elements,
Steve Blocka7e24c12009-10-30 11:49:00 +00001075 ZoneList<Expression*>* values,
1076 int literal_index,
1077 bool is_simple,
1078 int depth)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001079 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
Leon Clarkee46be812010-01-19 14:06:41 +00001080 constant_elements_(constant_elements),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001081 values_(values),
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001082 first_element_id_(ReserveIdRange(isolate, values->length())) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00001083
Ben Murdoch85b71792012-04-11 18:30:58 +01001084 DECLARE_NODE_TYPE(ArrayLiteral)
1085
1086 Handle<FixedArray> constant_elements() const { return constant_elements_; }
1087 ZoneList<Expression*>* values() const { return values_; }
1088
1089 // Return an AST id for an element that is used in simulate instructions.
1090 int GetIdForElement(int i) { return first_element_id_ + i; }
1091
Steve Blocka7e24c12009-10-30 11:49:00 +00001092 private:
Leon Clarkee46be812010-01-19 14:06:41 +00001093 Handle<FixedArray> constant_elements_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001094 ZoneList<Expression*>* values_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001095 int first_element_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001096};
1097
1098
Steve Blocka7e24c12009-10-30 11:49:00 +00001099class VariableProxy: public Expression {
1100 public:
Ben Murdoch85b71792012-04-11 18:30:58 +01001101 VariableProxy(Isolate* isolate, Variable* var);
1102
Ben Murdochf87a2032010-10-22 12:50:53 +01001103 DECLARE_NODE_TYPE(VariableProxy)
Steve Blocka7e24c12009-10-30 11:49:00 +00001104
Steve Blocka7e24c12009-10-30 11:49:00 +00001105 virtual bool IsValidLeftHandSide() {
1106 return var_ == NULL ? true : var_->IsValidLeftHandSide();
1107 }
1108
Ben Murdoch85b71792012-04-11 18:30:58 +01001109 virtual bool IsTrivial() {
1110 // Reading from a mutable variable is a side effect, but the
1111 // variable for 'this' is immutable.
1112 return is_this_ || is_trivial_;
1113 }
1114
1115 virtual bool IsInlineable() const;
1116
Steve Blocka7e24c12009-10-30 11:49:00 +00001117 bool IsVariable(Handle<String> n) {
1118 return !is_this() && name().is_identical_to(n);
1119 }
1120
Ben Murdoch589d6972011-11-30 16:04:58 +00001121 bool IsArguments() { return var_ != NULL && var_->is_arguments(); }
Steve Blocka7e24c12009-10-30 11:49:00 +00001122
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001123 Handle<String> name() const { return name_; }
1124 Variable* var() const { return var_; }
1125 bool is_this() const { return is_this_; }
Ben Murdoch85b71792012-04-11 18:30:58 +01001126 bool inside_with() const { return inside_with_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001127 int position() const { return position_; }
Steve Block6ded16b2010-05-10 14:33:55 +01001128
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001129 void MarkAsTrivial() { is_trivial_ = true; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001130
1131 // Bind this proxy to the variable var.
1132 void BindTo(Variable* var);
1133
1134 protected:
Ben Murdoch85b71792012-04-11 18:30:58 +01001135 Handle<String> name_;
1136 Variable* var_; // resolved variable, or NULL
1137 bool is_this_;
1138 bool inside_with_;
1139 bool is_trivial_;
1140 int position_;
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001141
1142 VariableProxy(Isolate* isolate,
1143 Handle<String> name,
1144 bool is_this,
Ben Murdoch85b71792012-04-11 18:30:58 +01001145 bool inside_with,
1146 int position = RelocInfo::kNoPosition);
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001147
Ben Murdoch85b71792012-04-11 18:30:58 +01001148 friend class Scope;
Steve Blocka7e24c12009-10-30 11:49:00 +00001149};
1150
1151
Steve Blocka7e24c12009-10-30 11:49:00 +00001152class Property: public Expression {
1153 public:
Ben Murdoch85b71792012-04-11 18:30:58 +01001154 Property(Isolate* isolate,
1155 Expression* obj,
1156 Expression* key,
1157 int pos)
1158 : Expression(isolate),
1159 obj_(obj),
1160 key_(key),
1161 pos_(pos),
1162 is_monomorphic_(false),
1163 is_array_length_(false),
1164 is_string_length_(false),
1165 is_string_access_(false),
1166 is_function_prototype_(false) { }
1167
Ben Murdochf87a2032010-10-22 12:50:53 +01001168 DECLARE_NODE_TYPE(Property)
Steve Blocka7e24c12009-10-30 11:49:00 +00001169
1170 virtual bool IsValidLeftHandSide() { return true; }
Ben Murdoch85b71792012-04-11 18:30:58 +01001171 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001172
1173 Expression* obj() const { return obj_; }
1174 Expression* key() const { return key_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001175 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001176
Steve Block1e0659c2011-05-24 12:43:12 +01001177 bool IsStringLength() const { return is_string_length_; }
Steve Block44f0eee2011-05-26 01:26:41 +01001178 bool IsStringAccess() const { return is_string_access_; }
Steve Block9fac8402011-05-12 15:51:54 +01001179 bool IsFunctionPrototype() const { return is_function_prototype_; }
1180
Ben Murdochb0fe1622011-05-05 13:52:32 +01001181 // Type feedback information.
1182 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1183 virtual bool IsMonomorphic() { return is_monomorphic_; }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001184 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
Ben Murdoch85b71792012-04-11 18:30:58 +01001185 virtual bool IsArrayLength() { return is_array_length_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001186
Steve Blocka7e24c12009-10-30 11:49:00 +00001187 private:
1188 Expression* obj_;
1189 Expression* key_;
1190 int pos_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001191
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001192 SmallMapList receiver_types_;
Steve Block1e0659c2011-05-24 12:43:12 +01001193 bool is_monomorphic_ : 1;
1194 bool is_array_length_ : 1;
1195 bool is_string_length_ : 1;
Steve Block44f0eee2011-05-26 01:26:41 +01001196 bool is_string_access_ : 1;
Steve Block1e0659c2011-05-24 12:43:12 +01001197 bool is_function_prototype_ : 1;
Steve Blocka7e24c12009-10-30 11:49:00 +00001198};
1199
1200
1201class Call: public Expression {
1202 public:
Ben Murdoch85b71792012-04-11 18:30:58 +01001203 Call(Isolate* isolate,
1204 Expression* expression,
1205 ZoneList<Expression*>* arguments,
1206 int pos)
1207 : Expression(isolate),
1208 expression_(expression),
1209 arguments_(arguments),
1210 pos_(pos),
1211 is_monomorphic_(false),
1212 check_type_(RECEIVER_MAP_CHECK),
1213 return_id_(GetNextId(isolate)) {
1214 }
1215
Ben Murdochf87a2032010-10-22 12:50:53 +01001216 DECLARE_NODE_TYPE(Call)
Steve Blocka7e24c12009-10-30 11:49:00 +00001217
Ben Murdoch85b71792012-04-11 18:30:58 +01001218 virtual bool IsInlineable() const;
1219
Steve Blocka7e24c12009-10-30 11:49:00 +00001220 Expression* expression() const { return expression_; }
1221 ZoneList<Expression*>* arguments() const { return arguments_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001222 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001223
Ben Murdoch257744e2011-11-30 15:57:28 +00001224 void RecordTypeFeedback(TypeFeedbackOracle* oracle,
1225 CallKind call_kind);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001226 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001227 virtual bool IsMonomorphic() { return is_monomorphic_; }
Ben Murdochb8e0da22011-05-16 14:20:40 +01001228 CheckType check_type() const { return check_type_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001229 Handle<JSFunction> target() { return target_; }
1230 Handle<JSObject> holder() { return holder_; }
1231 Handle<JSGlobalPropertyCell> cell() { return cell_; }
1232
1233 bool ComputeTarget(Handle<Map> type, Handle<String> name);
Ben Murdoch8b112d22011-06-08 16:22:53 +01001234 bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001235
1236 // Bailout support.
1237 int ReturnId() const { return return_id_; }
1238
Ben Murdochb0fe1622011-05-05 13:52:32 +01001239#ifdef DEBUG
1240 // Used to assert that the FullCodeGenerator records the return site.
1241 bool return_is_recorded_;
1242#endif
1243
Steve Blocka7e24c12009-10-30 11:49:00 +00001244 private:
1245 Expression* expression_;
1246 ZoneList<Expression*>* arguments_;
1247 int pos_;
1248
Ben Murdochb0fe1622011-05-05 13:52:32 +01001249 bool is_monomorphic_;
Ben Murdochb8e0da22011-05-16 14:20:40 +01001250 CheckType check_type_;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001251 SmallMapList receiver_types_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001252 Handle<JSFunction> target_;
1253 Handle<JSObject> holder_;
1254 Handle<JSGlobalPropertyCell> cell_;
1255
1256 int return_id_;
Steve Block44f0eee2011-05-26 01:26:41 +01001257};
Ben Murdochb0fe1622011-05-05 13:52:32 +01001258
Steve Block44f0eee2011-05-26 01:26:41 +01001259
Steve Blocka7e24c12009-10-30 11:49:00 +00001260class CallNew: public Expression {
1261 public:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001262 CallNew(Isolate* isolate,
1263 Expression* expression,
1264 ZoneList<Expression*>* arguments,
1265 int pos)
1266 : Expression(isolate),
1267 expression_(expression),
1268 arguments_(arguments),
Ben Murdoch85b71792012-04-11 18:30:58 +01001269 pos_(pos) { }
1270
1271 DECLARE_NODE_TYPE(CallNew)
1272
1273 virtual bool IsInlineable() const;
1274
1275 Expression* expression() const { return expression_; }
1276 ZoneList<Expression*>* arguments() const { return arguments_; }
1277 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001278
1279 private:
1280 Expression* expression_;
1281 ZoneList<Expression*>* arguments_;
1282 int pos_;
1283};
1284
1285
1286// The CallRuntime class does not represent any official JavaScript
1287// language construct. Instead it is used to call a C or JS function
1288// with a set of arguments. This is used from the builtins that are
1289// implemented in JavaScript (see "v8natives.js").
1290class CallRuntime: public Expression {
1291 public:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001292 CallRuntime(Isolate* isolate,
1293 Handle<String> name,
Steve Block44f0eee2011-05-26 01:26:41 +01001294 const Runtime::Function* function,
Steve Blocka7e24c12009-10-30 11:49:00 +00001295 ZoneList<Expression*>* arguments)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001296 : Expression(isolate),
1297 name_(name),
1298 function_(function),
1299 arguments_(arguments) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001300
Ben Murdoch85b71792012-04-11 18:30:58 +01001301 DECLARE_NODE_TYPE(CallRuntime)
1302
1303 virtual bool IsInlineable() const;
1304
1305 Handle<String> name() const { return name_; }
1306 const Runtime::Function* function() const { return function_; }
1307 ZoneList<Expression*>* arguments() const { return arguments_; }
1308 bool is_jsruntime() const { return function_ == NULL; }
1309
Steve Blocka7e24c12009-10-30 11:49:00 +00001310 private:
1311 Handle<String> name_;
Steve Block44f0eee2011-05-26 01:26:41 +01001312 const Runtime::Function* function_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001313 ZoneList<Expression*>* arguments_;
1314};
1315
1316
1317class UnaryOperation: public Expression {
1318 public:
Ben Murdoch85b71792012-04-11 18:30:58 +01001319 UnaryOperation(Isolate* isolate,
1320 Token::Value op,
1321 Expression* expression,
1322 int pos)
1323 : Expression(isolate), op_(op), expression_(expression), pos_(pos) {
1324 ASSERT(Token::IsUnaryOp(op));
1325 }
1326
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001327 DECLARE_NODE_TYPE(UnaryOperation)
1328
Ben Murdoch85b71792012-04-11 18:30:58 +01001329 virtual bool IsInlineable() const;
1330
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001331 virtual bool ResultOverwriteAllowed();
1332
1333 Token::Value op() const { return op_; }
1334 Expression* expression() const { return expression_; }
1335 virtual int position() const { return pos_; }
1336
Steve Blocka7e24c12009-10-30 11:49:00 +00001337 private:
1338 Token::Value op_;
1339 Expression* expression_;
Ben Murdoch257744e2011-11-30 15:57:28 +00001340 int pos_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001341};
1342
1343
1344class BinaryOperation: public Expression {
1345 public:
Ben Murdoch85b71792012-04-11 18:30:58 +01001346 BinaryOperation(Isolate* isolate,
1347 Token::Value op,
1348 Expression* left,
1349 Expression* right,
1350 int pos)
1351 : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) {
1352 ASSERT(Token::IsBinaryOp(op));
1353 right_id_ = (op == Token::AND || op == Token::OR)
1354 ? static_cast<int>(GetNextId(isolate))
1355 : AstNode::kNoNumber;
1356 }
1357
Ben Murdochf87a2032010-10-22 12:50:53 +01001358 DECLARE_NODE_TYPE(BinaryOperation)
Steve Blocka7e24c12009-10-30 11:49:00 +00001359
Ben Murdoch85b71792012-04-11 18:30:58 +01001360 virtual bool IsInlineable() const;
1361
Ben Murdochf87a2032010-10-22 12:50:53 +01001362 virtual bool ResultOverwriteAllowed();
Steve Blocka7e24c12009-10-30 11:49:00 +00001363
Steve Blocka7e24c12009-10-30 11:49:00 +00001364 Token::Value op() const { return op_; }
1365 Expression* left() const { return left_; }
1366 Expression* right() const { return right_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001367 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001368
Ben Murdochb0fe1622011-05-05 13:52:32 +01001369 // Bailout support.
1370 int RightId() const { return right_id_; }
1371
Steve Blocka7e24c12009-10-30 11:49:00 +00001372 private:
1373 Token::Value op_;
1374 Expression* left_;
1375 Expression* right_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001376 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001377 // The short-circuit logical operations have an AST ID for their
1378 // right-hand subexpression.
1379 int right_id_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001380};
1381
1382
Steve Blocka7e24c12009-10-30 11:49:00 +00001383class CountOperation: public Expression {
1384 public:
Ben Murdoch85b71792012-04-11 18:30:58 +01001385 CountOperation(Isolate* isolate,
1386 Token::Value op,
1387 bool is_prefix,
1388 Expression* expr,
1389 int pos)
1390 : Expression(isolate),
1391 op_(op),
1392 is_prefix_(is_prefix),
1393 expression_(expr),
1394 pos_(pos),
1395 assignment_id_(GetNextId(isolate)),
1396 count_id_(GetNextId(isolate)) {}
1397
Ben Murdochf87a2032010-10-22 12:50:53 +01001398 DECLARE_NODE_TYPE(CountOperation)
Steve Block6ded16b2010-05-10 14:33:55 +01001399
Steve Blocka7e24c12009-10-30 11:49:00 +00001400 bool is_prefix() const { return is_prefix_; }
1401 bool is_postfix() const { return !is_prefix_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001402
Ben Murdoch8b112d22011-06-08 16:22:53 +01001403 Token::Value op() const { return op_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001404 Token::Value binary_op() {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001405 return (op() == Token::INC) ? Token::ADD : Token::SUB;
Leon Clarkee46be812010-01-19 14:06:41 +00001406 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001407
Ben Murdoch8b112d22011-06-08 16:22:53 +01001408 Expression* expression() const { return expression_; }
1409 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001410
1411 virtual void MarkAsStatement() { is_prefix_ = true; }
1412
Ben Murdoch85b71792012-04-11 18:30:58 +01001413 virtual bool IsInlineable() const;
1414
Ben Murdoch8b112d22011-06-08 16:22:53 +01001415 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1416 virtual bool IsMonomorphic() { return is_monomorphic_; }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001417 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001418
Ben Murdochb0fe1622011-05-05 13:52:32 +01001419 // Bailout support.
1420 int AssignmentId() const { return assignment_id_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001421 int CountId() const { return count_id_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001422
Steve Blocka7e24c12009-10-30 11:49:00 +00001423 private:
Ben Murdoch8b112d22011-06-08 16:22:53 +01001424 Token::Value op_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001425 bool is_prefix_;
Ben Murdoch8b112d22011-06-08 16:22:53 +01001426 bool is_monomorphic_;
1427 Expression* expression_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001428 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001429 int assignment_id_;
Ben Murdoch8b112d22011-06-08 16:22:53 +01001430 int count_id_;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001431 SmallMapList receiver_types_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001432};
1433
1434
1435class CompareOperation: public Expression {
1436 public:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001437 CompareOperation(Isolate* isolate,
1438 Token::Value op,
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001439 Expression* left,
1440 Expression* right,
1441 int pos)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001442 : Expression(isolate),
1443 op_(op),
1444 left_(left),
1445 right_(right),
1446 pos_(pos),
1447 compare_type_(NONE) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001448 ASSERT(Token::IsCompareOp(op));
1449 }
1450
Ben Murdoch85b71792012-04-11 18:30:58 +01001451 DECLARE_NODE_TYPE(CompareOperation)
1452
1453 Token::Value op() const { return op_; }
1454 Expression* left() const { return left_; }
1455 Expression* right() const { return right_; }
1456 virtual int position() const { return pos_; }
1457
1458 virtual bool IsInlineable() const;
1459
1460 // Type feedback information.
1461 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1462 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
1463 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1464
1465 // Match special cases.
1466 bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
1467 bool IsLiteralCompareUndefined(Expression** expr);
1468
Steve Blocka7e24c12009-10-30 11:49:00 +00001469 private:
1470 Token::Value op_;
1471 Expression* left_;
1472 Expression* right_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001473 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001474
1475 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
1476 CompareTypeFeedback compare_type_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001477};
1478
1479
Ben Murdoch85b71792012-04-11 18:30:58 +01001480class CompareToNull: public Expression {
1481 public:
1482 CompareToNull(Isolate* isolate, bool is_strict, Expression* expression)
1483 : Expression(isolate), is_strict_(is_strict), expression_(expression) { }
1484
1485 DECLARE_NODE_TYPE(CompareToNull)
1486
1487 virtual bool IsInlineable() const;
1488
1489 bool is_strict() const { return is_strict_; }
1490 Token::Value op() const { return is_strict_ ? Token::EQ_STRICT : Token::EQ; }
1491 Expression* expression() const { return expression_; }
1492
1493 private:
1494 bool is_strict_;
1495 Expression* expression_;
1496};
1497
1498
Steve Blocka7e24c12009-10-30 11:49:00 +00001499class Conditional: public Expression {
1500 public:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001501 Conditional(Isolate* isolate,
1502 Expression* condition,
Steve Blocka7e24c12009-10-30 11:49:00 +00001503 Expression* then_expression,
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001504 Expression* else_expression,
1505 int then_expression_position,
1506 int else_expression_position)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001507 : Expression(isolate),
1508 condition_(condition),
Steve Blocka7e24c12009-10-30 11:49:00 +00001509 then_expression_(then_expression),
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001510 else_expression_(else_expression),
1511 then_expression_position_(then_expression_position),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001512 else_expression_position_(else_expression_position),
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001513 then_id_(GetNextId(isolate)),
Ben Murdoch85b71792012-04-11 18:30:58 +01001514 else_id_(GetNextId(isolate)) {
1515 }
1516
1517 DECLARE_NODE_TYPE(Conditional)
1518
1519 virtual bool IsInlineable() const;
1520
1521 Expression* condition() const { return condition_; }
1522 Expression* then_expression() const { return then_expression_; }
1523 Expression* else_expression() const { return else_expression_; }
1524
1525 int then_expression_position() const { return then_expression_position_; }
1526 int else_expression_position() const { return else_expression_position_; }
1527
1528 int ThenId() const { return then_id_; }
1529 int ElseId() const { return else_id_; }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001530
Steve Blocka7e24c12009-10-30 11:49:00 +00001531 private:
1532 Expression* condition_;
1533 Expression* then_expression_;
1534 Expression* else_expression_;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001535 int then_expression_position_;
1536 int else_expression_position_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001537 int then_id_;
1538 int else_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001539};
1540
1541
1542class Assignment: public Expression {
1543 public:
Ben Murdoch85b71792012-04-11 18:30:58 +01001544 Assignment(Isolate* isolate,
1545 Token::Value op,
1546 Expression* target,
1547 Expression* value,
1548 int pos);
1549
Ben Murdochf87a2032010-10-22 12:50:53 +01001550 DECLARE_NODE_TYPE(Assignment)
Steve Blocka7e24c12009-10-30 11:49:00 +00001551
Ben Murdoch85b71792012-04-11 18:30:58 +01001552 virtual bool IsInlineable() const;
1553
Steve Block6ded16b2010-05-10 14:33:55 +01001554 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1555
Steve Blocka7e24c12009-10-30 11:49:00 +00001556 Token::Value binary_op() const;
1557
1558 Token::Value op() const { return op_; }
1559 Expression* target() const { return target_; }
1560 Expression* value() const { return value_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001561 virtual int position() const { return pos_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001562 BinaryOperation* binary_operation() const { return binary_operation_; }
1563
Leon Clarkee46be812010-01-19 14:06:41 +00001564 // This check relies on the definition order of token in token.h.
1565 bool is_compound() const { return op() > Token::ASSIGN; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001566
1567 // An initialization block is a series of statments of the form
1568 // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1569 // ending of these blocks to allow for optimizations of initialization
1570 // blocks.
1571 bool starts_initialization_block() { return block_start_; }
1572 bool ends_initialization_block() { return block_end_; }
1573 void mark_block_start() { block_start_ = true; }
1574 void mark_block_end() { block_end_ = true; }
1575
Ben Murdochb0fe1622011-05-05 13:52:32 +01001576 // Type feedback information.
1577 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1578 virtual bool IsMonomorphic() { return is_monomorphic_; }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001579 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001580
1581 // Bailout support.
1582 int CompoundLoadId() const { return compound_load_id_; }
1583 int AssignmentId() const { return assignment_id_; }
1584
Steve Blocka7e24c12009-10-30 11:49:00 +00001585 private:
1586 Token::Value op_;
1587 Expression* target_;
1588 Expression* value_;
1589 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001590 BinaryOperation* binary_operation_;
1591 int compound_load_id_;
1592 int assignment_id_;
1593
Steve Blocka7e24c12009-10-30 11:49:00 +00001594 bool block_start_;
1595 bool block_end_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001596
1597 bool is_monomorphic_;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001598 SmallMapList receiver_types_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001599};
1600
1601
1602class Throw: public Expression {
1603 public:
Ben Murdoch85b71792012-04-11 18:30:58 +01001604 Throw(Isolate* isolate, Expression* exception, int pos)
1605 : Expression(isolate), exception_(exception), pos_(pos) {}
1606
Ben Murdochf87a2032010-10-22 12:50:53 +01001607 DECLARE_NODE_TYPE(Throw)
Steve Block6ded16b2010-05-10 14:33:55 +01001608
Steve Blocka7e24c12009-10-30 11:49:00 +00001609 Expression* exception() const { return exception_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001610 virtual int position() const { return pos_; }
Ben Murdoch85b71792012-04-11 18:30:58 +01001611 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001612
1613 private:
1614 Expression* exception_;
1615 int pos_;
1616};
1617
1618
1619class FunctionLiteral: public Expression {
1620 public:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001621 enum Type {
1622 ANONYMOUS_EXPRESSION,
1623 NAMED_EXPRESSION,
1624 DECLARATION
1625 };
1626
Ben Murdoch85b71792012-04-11 18:30:58 +01001627 FunctionLiteral(Isolate* isolate,
1628 Handle<String> name,
1629 Scope* scope,
1630 ZoneList<Statement*>* body,
1631 int materialized_literal_count,
1632 int expected_property_count,
1633 bool has_only_simple_this_property_assignments,
1634 Handle<FixedArray> this_property_assignments,
1635 int num_parameters,
1636 int start_position,
1637 int end_position,
1638 Type type,
1639 bool has_duplicate_parameters)
1640 : Expression(isolate),
1641 name_(name),
1642 scope_(scope),
1643 body_(body),
1644 materialized_literal_count_(materialized_literal_count),
1645 expected_property_count_(expected_property_count),
1646 has_only_simple_this_property_assignments_(
1647 has_only_simple_this_property_assignments),
1648 this_property_assignments_(this_property_assignments),
1649 num_parameters_(num_parameters),
1650 start_position_(start_position),
1651 end_position_(end_position),
1652 function_token_position_(RelocInfo::kNoPosition),
1653 inferred_name_(HEAP->empty_string()),
1654 is_expression_(type != DECLARATION),
1655 is_anonymous_(type == ANONYMOUS_EXPRESSION),
1656 pretenure_(false),
1657 has_duplicate_parameters_(has_duplicate_parameters) {
1658 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001659
Ben Murdochf87a2032010-10-22 12:50:53 +01001660 DECLARE_NODE_TYPE(FunctionLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00001661
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001662 Handle<String> name() const { return name_; }
1663 Scope* scope() const { return scope_; }
1664 ZoneList<Statement*>* body() const { return body_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001665 void set_function_token_position(int pos) { function_token_position_ = pos; }
1666 int function_token_position() const { return function_token_position_; }
Ben Murdoch85b71792012-04-11 18:30:58 +01001667 int start_position() const { return start_position_; }
1668 int end_position() const { return end_position_; }
1669 bool is_expression() const { return is_expression_; }
1670 bool is_anonymous() const { return is_anonymous_; }
1671 bool strict_mode() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001672
1673 int materialized_literal_count() { return materialized_literal_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001674 int expected_property_count() { return expected_property_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001675 bool has_only_simple_this_property_assignments() {
Ben Murdoch85b71792012-04-11 18:30:58 +01001676 return has_only_simple_this_property_assignments_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001677 }
1678 Handle<FixedArray> this_property_assignments() {
1679 return this_property_assignments_;
1680 }
Ben Murdoch85b71792012-04-11 18:30:58 +01001681 int num_parameters() { return num_parameters_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001682
1683 bool AllowsLazyCompilation();
1684
Ben Murdochf87a2032010-10-22 12:50:53 +01001685 Handle<String> debug_name() const {
1686 if (name_->length() > 0) return name_;
1687 return inferred_name();
1688 }
1689
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001690 Handle<String> inferred_name() const { return inferred_name_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001691 void set_inferred_name(Handle<String> inferred_name) {
1692 inferred_name_ = inferred_name;
1693 }
1694
Ben Murdoch85b71792012-04-11 18:30:58 +01001695 bool pretenure() { return pretenure_; }
1696 void set_pretenure(bool value) { pretenure_ = value; }
1697 virtual bool IsInlineable() const;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08001698
Ben Murdoch85b71792012-04-11 18:30:58 +01001699 bool has_duplicate_parameters() { return has_duplicate_parameters_; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001700
Steve Blocka7e24c12009-10-30 11:49:00 +00001701 private:
1702 Handle<String> name_;
1703 Scope* scope_;
1704 ZoneList<Statement*>* body_;
1705 int materialized_literal_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001706 int expected_property_count_;
Ben Murdoch85b71792012-04-11 18:30:58 +01001707 bool has_only_simple_this_property_assignments_;
1708 Handle<FixedArray> this_property_assignments_;
1709 int num_parameters_;
1710 int start_position_;
1711 int end_position_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001712 int function_token_position_;
Ben Murdoch85b71792012-04-11 18:30:58 +01001713 Handle<String> inferred_name_;
1714 bool is_expression_;
1715 bool is_anonymous_;
1716 bool pretenure_;
1717 bool has_duplicate_parameters_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001718};
1719
1720
Steve Block6ded16b2010-05-10 14:33:55 +01001721class SharedFunctionInfoLiteral: public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00001722 public:
Ben Murdoch85b71792012-04-11 18:30:58 +01001723 SharedFunctionInfoLiteral(
1724 Isolate* isolate,
1725 Handle<SharedFunctionInfo> shared_function_info)
1726 : Expression(isolate), shared_function_info_(shared_function_info) { }
1727
Ben Murdochf87a2032010-10-22 12:50:53 +01001728 DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
1729
Steve Block6ded16b2010-05-10 14:33:55 +01001730 Handle<SharedFunctionInfo> shared_function_info() const {
1731 return shared_function_info_;
1732 }
Ben Murdoch85b71792012-04-11 18:30:58 +01001733 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001734
Steve Blocka7e24c12009-10-30 11:49:00 +00001735 private:
Steve Block6ded16b2010-05-10 14:33:55 +01001736 Handle<SharedFunctionInfo> shared_function_info_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001737};
1738
1739
1740class ThisFunction: public Expression {
1741 public:
Ben Murdoch85b71792012-04-11 18:30:58 +01001742 explicit ThisFunction(Isolate* isolate) : Expression(isolate) {}
Ben Murdochf87a2032010-10-22 12:50:53 +01001743 DECLARE_NODE_TYPE(ThisFunction)
Ben Murdoch85b71792012-04-11 18:30:58 +01001744 virtual bool IsInlineable() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001745};
1746
1747
1748// ----------------------------------------------------------------------------
1749// Regular expressions
1750
1751
1752class RegExpVisitor BASE_EMBEDDED {
1753 public:
1754 virtual ~RegExpVisitor() { }
1755#define MAKE_CASE(Name) \
1756 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
1757 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
1758#undef MAKE_CASE
1759};
1760
1761
1762class RegExpTree: public ZoneObject {
1763 public:
1764 static const int kInfinity = kMaxInt;
1765 virtual ~RegExpTree() { }
1766 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
1767 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1768 RegExpNode* on_success) = 0;
1769 virtual bool IsTextElement() { return false; }
Ben Murdochf87a2032010-10-22 12:50:53 +01001770 virtual bool IsAnchoredAtStart() { return false; }
1771 virtual bool IsAnchoredAtEnd() { return false; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001772 virtual int min_match() = 0;
1773 virtual int max_match() = 0;
1774 // Returns the interval of registers used for captures within this
1775 // expression.
1776 virtual Interval CaptureRegisters() { return Interval::Empty(); }
1777 virtual void AppendToText(RegExpText* text);
Ben Murdoch589d6972011-11-30 16:04:58 +00001778 SmartArrayPointer<const char> ToString();
Steve Blocka7e24c12009-10-30 11:49:00 +00001779#define MAKE_ASTYPE(Name) \
1780 virtual RegExp##Name* As##Name(); \
1781 virtual bool Is##Name();
1782 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
1783#undef MAKE_ASTYPE
1784};
1785
1786
1787class RegExpDisjunction: public RegExpTree {
1788 public:
1789 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
1790 virtual void* Accept(RegExpVisitor* visitor, void* data);
1791 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1792 RegExpNode* on_success);
1793 virtual RegExpDisjunction* AsDisjunction();
1794 virtual Interval CaptureRegisters();
1795 virtual bool IsDisjunction();
Ben Murdochf87a2032010-10-22 12:50:53 +01001796 virtual bool IsAnchoredAtStart();
1797 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001798 virtual int min_match() { return min_match_; }
1799 virtual int max_match() { return max_match_; }
1800 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
1801 private:
1802 ZoneList<RegExpTree*>* alternatives_;
1803 int min_match_;
1804 int max_match_;
1805};
1806
1807
1808class RegExpAlternative: public RegExpTree {
1809 public:
1810 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
1811 virtual void* Accept(RegExpVisitor* visitor, void* data);
1812 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1813 RegExpNode* on_success);
1814 virtual RegExpAlternative* AsAlternative();
1815 virtual Interval CaptureRegisters();
1816 virtual bool IsAlternative();
Ben Murdochf87a2032010-10-22 12:50:53 +01001817 virtual bool IsAnchoredAtStart();
1818 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001819 virtual int min_match() { return min_match_; }
1820 virtual int max_match() { return max_match_; }
1821 ZoneList<RegExpTree*>* nodes() { return nodes_; }
1822 private:
1823 ZoneList<RegExpTree*>* nodes_;
1824 int min_match_;
1825 int max_match_;
1826};
1827
1828
1829class RegExpAssertion: public RegExpTree {
1830 public:
1831 enum Type {
1832 START_OF_LINE,
1833 START_OF_INPUT,
1834 END_OF_LINE,
1835 END_OF_INPUT,
1836 BOUNDARY,
1837 NON_BOUNDARY
1838 };
1839 explicit RegExpAssertion(Type type) : type_(type) { }
1840 virtual void* Accept(RegExpVisitor* visitor, void* data);
1841 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1842 RegExpNode* on_success);
1843 virtual RegExpAssertion* AsAssertion();
1844 virtual bool IsAssertion();
Ben Murdochf87a2032010-10-22 12:50:53 +01001845 virtual bool IsAnchoredAtStart();
1846 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00001847 virtual int min_match() { return 0; }
1848 virtual int max_match() { return 0; }
1849 Type type() { return type_; }
1850 private:
1851 Type type_;
1852};
1853
1854
1855class CharacterSet BASE_EMBEDDED {
1856 public:
1857 explicit CharacterSet(uc16 standard_set_type)
1858 : ranges_(NULL),
1859 standard_set_type_(standard_set_type) {}
1860 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
1861 : ranges_(ranges),
1862 standard_set_type_(0) {}
1863 ZoneList<CharacterRange>* ranges();
1864 uc16 standard_set_type() { return standard_set_type_; }
1865 void set_standard_set_type(uc16 special_set_type) {
1866 standard_set_type_ = special_set_type;
1867 }
1868 bool is_standard() { return standard_set_type_ != 0; }
Leon Clarkee46be812010-01-19 14:06:41 +00001869 void Canonicalize();
Steve Blocka7e24c12009-10-30 11:49:00 +00001870 private:
1871 ZoneList<CharacterRange>* ranges_;
1872 // If non-zero, the value represents a standard set (e.g., all whitespace
1873 // characters) without having to expand the ranges.
1874 uc16 standard_set_type_;
1875};
1876
1877
1878class RegExpCharacterClass: public RegExpTree {
1879 public:
1880 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
1881 : set_(ranges),
1882 is_negated_(is_negated) { }
1883 explicit RegExpCharacterClass(uc16 type)
1884 : set_(type),
1885 is_negated_(false) { }
1886 virtual void* Accept(RegExpVisitor* visitor, void* data);
1887 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1888 RegExpNode* on_success);
1889 virtual RegExpCharacterClass* AsCharacterClass();
1890 virtual bool IsCharacterClass();
1891 virtual bool IsTextElement() { return true; }
1892 virtual int min_match() { return 1; }
1893 virtual int max_match() { return 1; }
1894 virtual void AppendToText(RegExpText* text);
1895 CharacterSet character_set() { return set_; }
1896 // TODO(lrn): Remove need for complex version if is_standard that
1897 // recognizes a mangled standard set and just do { return set_.is_special(); }
1898 bool is_standard();
1899 // Returns a value representing the standard character set if is_standard()
1900 // returns true.
1901 // Currently used values are:
1902 // s : unicode whitespace
1903 // S : unicode non-whitespace
1904 // w : ASCII word character (digit, letter, underscore)
1905 // W : non-ASCII word character
1906 // d : ASCII digit
1907 // D : non-ASCII digit
1908 // . : non-unicode non-newline
1909 // * : All characters
1910 uc16 standard_type() { return set_.standard_set_type(); }
1911 ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
1912 bool is_negated() { return is_negated_; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001913
Steve Blocka7e24c12009-10-30 11:49:00 +00001914 private:
1915 CharacterSet set_;
1916 bool is_negated_;
1917};
1918
1919
1920class RegExpAtom: public RegExpTree {
1921 public:
1922 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
1923 virtual void* Accept(RegExpVisitor* visitor, void* data);
1924 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1925 RegExpNode* on_success);
1926 virtual RegExpAtom* AsAtom();
1927 virtual bool IsAtom();
1928 virtual bool IsTextElement() { return true; }
1929 virtual int min_match() { return data_.length(); }
1930 virtual int max_match() { return data_.length(); }
1931 virtual void AppendToText(RegExpText* text);
1932 Vector<const uc16> data() { return data_; }
1933 int length() { return data_.length(); }
1934 private:
1935 Vector<const uc16> data_;
1936};
1937
1938
1939class RegExpText: public RegExpTree {
1940 public:
1941 RegExpText() : elements_(2), length_(0) {}
1942 virtual void* Accept(RegExpVisitor* visitor, void* data);
1943 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1944 RegExpNode* on_success);
1945 virtual RegExpText* AsText();
1946 virtual bool IsText();
1947 virtual bool IsTextElement() { return true; }
1948 virtual int min_match() { return length_; }
1949 virtual int max_match() { return length_; }
1950 virtual void AppendToText(RegExpText* text);
1951 void AddElement(TextElement elm) {
1952 elements_.Add(elm);
1953 length_ += elm.length();
Iain Merrick9ac36c92010-09-13 15:29:50 +01001954 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001955 ZoneList<TextElement>* elements() { return &elements_; }
1956 private:
1957 ZoneList<TextElement> elements_;
1958 int length_;
1959};
1960
1961
1962class RegExpQuantifier: public RegExpTree {
1963 public:
Leon Clarkee46be812010-01-19 14:06:41 +00001964 enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
1965 RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
1966 : body_(body),
1967 min_(min),
Steve Blocka7e24c12009-10-30 11:49:00 +00001968 max_(max),
Leon Clarkee46be812010-01-19 14:06:41 +00001969 min_match_(min * body->min_match()),
1970 type_(type) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001971 if (max > 0 && body->max_match() > kInfinity / max) {
1972 max_match_ = kInfinity;
1973 } else {
1974 max_match_ = max * body->max_match();
1975 }
1976 }
1977 virtual void* Accept(RegExpVisitor* visitor, void* data);
1978 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1979 RegExpNode* on_success);
1980 static RegExpNode* ToNode(int min,
1981 int max,
1982 bool is_greedy,
1983 RegExpTree* body,
1984 RegExpCompiler* compiler,
1985 RegExpNode* on_success,
1986 bool not_at_start = false);
1987 virtual RegExpQuantifier* AsQuantifier();
1988 virtual Interval CaptureRegisters();
1989 virtual bool IsQuantifier();
1990 virtual int min_match() { return min_match_; }
1991 virtual int max_match() { return max_match_; }
1992 int min() { return min_; }
1993 int max() { return max_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001994 bool is_possessive() { return type_ == POSSESSIVE; }
1995 bool is_non_greedy() { return type_ == NON_GREEDY; }
1996 bool is_greedy() { return type_ == GREEDY; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001997 RegExpTree* body() { return body_; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001998
Steve Blocka7e24c12009-10-30 11:49:00 +00001999 private:
Leon Clarkee46be812010-01-19 14:06:41 +00002000 RegExpTree* body_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002001 int min_;
2002 int max_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002003 int min_match_;
2004 int max_match_;
Leon Clarkee46be812010-01-19 14:06:41 +00002005 Type type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002006};
2007
2008
2009class RegExpCapture: public RegExpTree {
2010 public:
2011 explicit RegExpCapture(RegExpTree* body, int index)
2012 : body_(body), index_(index) { }
2013 virtual void* Accept(RegExpVisitor* visitor, void* data);
2014 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2015 RegExpNode* on_success);
2016 static RegExpNode* ToNode(RegExpTree* body,
2017 int index,
2018 RegExpCompiler* compiler,
2019 RegExpNode* on_success);
2020 virtual RegExpCapture* AsCapture();
Ben Murdochf87a2032010-10-22 12:50:53 +01002021 virtual bool IsAnchoredAtStart();
2022 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00002023 virtual Interval CaptureRegisters();
2024 virtual bool IsCapture();
2025 virtual int min_match() { return body_->min_match(); }
2026 virtual int max_match() { return body_->max_match(); }
2027 RegExpTree* body() { return body_; }
2028 int index() { return index_; }
2029 static int StartRegister(int index) { return index * 2; }
2030 static int EndRegister(int index) { return index * 2 + 1; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002031
Steve Blocka7e24c12009-10-30 11:49:00 +00002032 private:
2033 RegExpTree* body_;
2034 int index_;
2035};
2036
2037
2038class RegExpLookahead: public RegExpTree {
2039 public:
2040 RegExpLookahead(RegExpTree* body,
2041 bool is_positive,
2042 int capture_count,
2043 int capture_from)
2044 : body_(body),
2045 is_positive_(is_positive),
2046 capture_count_(capture_count),
2047 capture_from_(capture_from) { }
2048
2049 virtual void* Accept(RegExpVisitor* visitor, void* data);
2050 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2051 RegExpNode* on_success);
2052 virtual RegExpLookahead* AsLookahead();
2053 virtual Interval CaptureRegisters();
2054 virtual bool IsLookahead();
Ben Murdochf87a2032010-10-22 12:50:53 +01002055 virtual bool IsAnchoredAtStart();
Steve Blocka7e24c12009-10-30 11:49:00 +00002056 virtual int min_match() { return 0; }
2057 virtual int max_match() { return 0; }
2058 RegExpTree* body() { return body_; }
2059 bool is_positive() { return is_positive_; }
2060 int capture_count() { return capture_count_; }
2061 int capture_from() { return capture_from_; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002062
Steve Blocka7e24c12009-10-30 11:49:00 +00002063 private:
2064 RegExpTree* body_;
2065 bool is_positive_;
2066 int capture_count_;
2067 int capture_from_;
2068};
2069
2070
2071class RegExpBackReference: public RegExpTree {
2072 public:
2073 explicit RegExpBackReference(RegExpCapture* capture)
2074 : capture_(capture) { }
2075 virtual void* Accept(RegExpVisitor* visitor, void* data);
2076 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2077 RegExpNode* on_success);
2078 virtual RegExpBackReference* AsBackReference();
2079 virtual bool IsBackReference();
2080 virtual int min_match() { return 0; }
2081 virtual int max_match() { return capture_->max_match(); }
2082 int index() { return capture_->index(); }
2083 RegExpCapture* capture() { return capture_; }
2084 private:
2085 RegExpCapture* capture_;
2086};
2087
2088
2089class RegExpEmpty: public RegExpTree {
2090 public:
2091 RegExpEmpty() { }
2092 virtual void* Accept(RegExpVisitor* visitor, void* data);
2093 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2094 RegExpNode* on_success);
2095 virtual RegExpEmpty* AsEmpty();
2096 virtual bool IsEmpty();
2097 virtual int min_match() { return 0; }
2098 virtual int max_match() { return 0; }
Ben Murdoch85b71792012-04-11 18:30:58 +01002099 static RegExpEmpty* GetInstance() { return &kInstance; }
2100 private:
2101 static RegExpEmpty kInstance;
Steve Blocka7e24c12009-10-30 11:49:00 +00002102};
2103
2104
2105// ----------------------------------------------------------------------------
2106// Basic visitor
2107// - leaf node visitors are abstract.
2108
2109class AstVisitor BASE_EMBEDDED {
2110 public:
Steve Block44f0eee2011-05-26 01:26:41 +01002111 AstVisitor() : isolate_(Isolate::Current()), stack_overflow_(false) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00002112 virtual ~AstVisitor() { }
2113
Steve Block6ded16b2010-05-10 14:33:55 +01002114 // Stack overflow check and dynamic dispatch.
2115 void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
Steve Blocka7e24c12009-10-30 11:49:00 +00002116
Steve Block6ded16b2010-05-10 14:33:55 +01002117 // Iteration left-to-right.
Steve Block3ce2e202009-11-05 08:53:23 +00002118 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
Steve Blocka7e24c12009-10-30 11:49:00 +00002119 virtual void VisitStatements(ZoneList<Statement*>* statements);
2120 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
2121
2122 // Stack overflow tracking support.
2123 bool HasStackOverflow() const { return stack_overflow_; }
Steve Block6ded16b2010-05-10 14:33:55 +01002124 bool CheckStackOverflow();
Steve Blocka7e24c12009-10-30 11:49:00 +00002125
2126 // If a stack-overflow exception is encountered when visiting a
2127 // node, calling SetStackOverflow will make sure that the visitor
2128 // bails out without visiting more nodes.
2129 void SetStackOverflow() { stack_overflow_ = true; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01002130 void ClearStackOverflow() { stack_overflow_ = false; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002131
Ben Murdochb0fe1622011-05-05 13:52:32 +01002132 // Individual AST nodes.
Steve Blocka7e24c12009-10-30 11:49:00 +00002133#define DEF_VISIT(type) \
2134 virtual void Visit##type(type* node) = 0;
2135 AST_NODE_LIST(DEF_VISIT)
2136#undef DEF_VISIT
2137
Steve Block44f0eee2011-05-26 01:26:41 +01002138 protected:
2139 Isolate* isolate() { return isolate_; }
2140
Steve Blocka7e24c12009-10-30 11:49:00 +00002141 private:
Steve Block44f0eee2011-05-26 01:26:41 +01002142 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002143 bool stack_overflow_;
2144};
2145
Steve Block44f0eee2011-05-26 01:26:41 +01002146
Steve Blocka7e24c12009-10-30 11:49:00 +00002147} } // namespace v8::internal
2148
2149#endif // V8_AST_H_