blob: b827302ebd82da0878281f69fce2ffb490110494 [file] [log] [blame]
Ben Murdochc7cc0282012-03-05 14:35:55 +00001// Copyright 2012 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 Murdochc7cc0282012-03-05 14:35:55 +000031#include "v8.h"
32
33#include "assembler.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000034#include "factory.h"
Ben Murdochc7cc0282012-03-05 14:35:55 +000035#include "isolate.h"
Steve Block3ce2e202009-11-05 08:53:23 +000036#include "jsregexp.h"
Ben Murdochc7cc0282012-03-05 14:35:55 +000037#include "list-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000038#include "runtime.h"
Ben Murdoch69a99ed2011-11-30 16:03:39 +000039#include "small-pointer-list.h"
Ben Murdochc7cc0282012-03-05 14:35:55 +000040#include "smart-array-pointer.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000041#include "token.h"
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +010042#include "utils.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000043#include "variables.h"
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +010044#include "interface.h"
Ben Murdochc7cc0282012-03-05 14:35:55 +000045#include "zone-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000046
47namespace v8 {
48namespace internal {
49
50// The abstract syntax tree is an intermediate, light-weight
51// representation of the parsed JavaScript code suitable for
52// compilation to native code.
53
54// Nodes are allocated in a separate zone, which allows faster
55// allocation and constant-time deallocation of the entire syntax
56// tree.
57
58
59// ----------------------------------------------------------------------------
60// Nodes of the abstract syntax tree. Only concrete classes are
61// enumerated here.
62
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +010063#define DECLARATION_NODE_LIST(V) \
64 V(VariableDeclaration) \
65 V(FunctionDeclaration) \
66 V(ModuleDeclaration) \
67 V(ImportDeclaration) \
68 V(ExportDeclaration) \
69
70#define MODULE_NODE_LIST(V) \
71 V(ModuleLiteral) \
72 V(ModuleVariable) \
73 V(ModulePath) \
74 V(ModuleUrl)
75
Steve Blocka7e24c12009-10-30 11:49:00 +000076#define STATEMENT_NODE_LIST(V) \
77 V(Block) \
78 V(ExpressionStatement) \
79 V(EmptyStatement) \
80 V(IfStatement) \
81 V(ContinueStatement) \
82 V(BreakStatement) \
83 V(ReturnStatement) \
Ben Murdoch69a99ed2011-11-30 16:03:39 +000084 V(WithStatement) \
Steve Blocka7e24c12009-10-30 11:49:00 +000085 V(SwitchStatement) \
Steve Block3ce2e202009-11-05 08:53:23 +000086 V(DoWhileStatement) \
87 V(WhileStatement) \
88 V(ForStatement) \
Steve Blocka7e24c12009-10-30 11:49:00 +000089 V(ForInStatement) \
Steve Block3ce2e202009-11-05 08:53:23 +000090 V(TryCatchStatement) \
91 V(TryFinallyStatement) \
Steve Blocka7e24c12009-10-30 11:49:00 +000092 V(DebuggerStatement)
93
94#define EXPRESSION_NODE_LIST(V) \
95 V(FunctionLiteral) \
Steve Block6ded16b2010-05-10 14:33:55 +010096 V(SharedFunctionInfoLiteral) \
Steve Blocka7e24c12009-10-30 11:49:00 +000097 V(Conditional) \
Steve Blocka7e24c12009-10-30 11:49:00 +000098 V(VariableProxy) \
99 V(Literal) \
100 V(RegExpLiteral) \
101 V(ObjectLiteral) \
102 V(ArrayLiteral) \
Steve Blocka7e24c12009-10-30 11:49:00 +0000103 V(Assignment) \
104 V(Throw) \
105 V(Property) \
106 V(Call) \
107 V(CallNew) \
108 V(CallRuntime) \
109 V(UnaryOperation) \
110 V(CountOperation) \
111 V(BinaryOperation) \
112 V(CompareOperation) \
113 V(ThisFunction)
114
115#define AST_NODE_LIST(V) \
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100116 DECLARATION_NODE_LIST(V) \
117 MODULE_NODE_LIST(V) \
Steve Blocka7e24c12009-10-30 11:49:00 +0000118 STATEMENT_NODE_LIST(V) \
119 EXPRESSION_NODE_LIST(V)
120
121// Forward declarations
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100122class AstConstructionVisitor;
123template<class> class AstNodeFactory;
Ben Murdochc7cc0282012-03-05 14:35:55 +0000124class AstVisitor;
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100125class Declaration;
126class Module;
Ben Murdochc7cc0282012-03-05 14:35:55 +0000127class BreakableStatement;
128class Expression;
129class IterationStatement;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100130class MaterializedLiteral;
Ben Murdochc7cc0282012-03-05 14:35:55 +0000131class Statement;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100132class TargetCollector;
133class TypeFeedbackOracle;
Steve Blocka7e24c12009-10-30 11:49:00 +0000134
Ben Murdochc7cc0282012-03-05 14:35:55 +0000135class RegExpAlternative;
136class RegExpAssertion;
137class RegExpAtom;
138class RegExpBackReference;
139class RegExpCapture;
140class RegExpCharacterClass;
141class RegExpCompiler;
142class RegExpDisjunction;
143class RegExpEmpty;
144class RegExpLookahead;
145class RegExpQuantifier;
146class RegExpText;
147
Steve Blocka7e24c12009-10-30 11:49:00 +0000148#define DEF_FORWARD_DECLARATION(type) class type;
149AST_NODE_LIST(DEF_FORWARD_DECLARATION)
150#undef DEF_FORWARD_DECLARATION
151
152
153// Typedef only introduced to avoid unreadable code.
154// Please do appreciate the required space in "> >".
155typedef ZoneList<Handle<String> > ZoneStringList;
156typedef ZoneList<Handle<Object> > ZoneObjectList;
157
158
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100159#define DECLARE_NODE_TYPE(type) \
160 virtual void Accept(AstVisitor* v); \
161 virtual AstNode::Type node_type() const { return AstNode::k##type; }
162
163
164enum AstPropertiesFlag {
165 kDontInline,
166 kDontOptimize,
167 kDontSelfOptimize,
168 kDontSoftInline
169};
170
171
172class AstProperties BASE_EMBEDDED {
173 public:
174 class Flags : public EnumSet<AstPropertiesFlag, int> {};
175
176 AstProperties() : node_count_(0) { }
177
178 Flags* flags() { return &flags_; }
179 int node_count() { return node_count_; }
180 void add_node_count(int count) { node_count_ += count; }
181
182 private:
183 Flags flags_;
184 int node_count_;
185};
186
187
Steve Blocka7e24c12009-10-30 11:49:00 +0000188class AstNode: public ZoneObject {
189 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100190#define DECLARE_TYPE_ENUM(type) k##type,
191 enum Type {
192 AST_NODE_LIST(DECLARE_TYPE_ENUM)
193 kInvalid = -1
194 };
195#undef DECLARE_TYPE_ENUM
Steve Blocka7e24c12009-10-30 11:49:00 +0000196
Ben Murdochb0fe1622011-05-05 13:52:32 +0100197 static const int kNoNumber = -1;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100198 static const int kFunctionEntryId = 2; // Using 0 could disguise errors.
Ben Murdoch589d6972011-11-30 16:04:58 +0000199 // This AST id identifies the point after the declarations have been
200 // visited. We need it to capture the environment effects of declarations
201 // that emit code (function declarations).
202 static const int kDeclarationsId = 3;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100203
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000204 void* operator new(size_t size, Zone* zone) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000205 return zone->New(static_cast<int>(size));
Steve Block44f0eee2011-05-26 01:26:41 +0100206 }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100207
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100208 AstNode() { }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000209
Ben Murdochf87a2032010-10-22 12:50:53 +0100210 virtual ~AstNode() { }
211
212 virtual void Accept(AstVisitor* v) = 0;
213 virtual Type node_type() const { return kInvalid; }
214
215 // Type testing & conversion functions overridden by concrete subclasses.
216#define DECLARE_NODE_FUNCTIONS(type) \
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000217 bool Is##type() { return node_type() == AstNode::k##type; } \
218 type* As##type() { return Is##type() ? reinterpret_cast<type*>(this) : NULL; }
Ben Murdochf87a2032010-10-22 12:50:53 +0100219 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
220#undef DECLARE_NODE_FUNCTIONS
221
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100222 virtual Declaration* AsDeclaration() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000223 virtual Statement* AsStatement() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000224 virtual Expression* AsExpression() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000225 virtual TargetCollector* AsTargetCollector() { return NULL; }
226 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
227 virtual IterationStatement* AsIterationStatement() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000228 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100229
Ben Murdochb0fe1622011-05-05 13:52:32 +0100230 protected:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100231 static int GetNextId(Isolate* isolate) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000232 return ReserveIdRange(isolate, 1);
Steve Block44f0eee2011-05-26 01:26:41 +0100233 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000234
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100235 static int ReserveIdRange(Isolate* isolate, int n) {
236 int tmp = isolate->ast_node_id();
Steve Block44f0eee2011-05-26 01:26:41 +0100237 isolate->set_ast_node_id(tmp + n);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100238 return tmp;
239 }
240
241 private:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000242 // Hidden to prevent accidental usage. It would have to load the
243 // current zone from the TLS.
244 void* operator new(size_t size);
Steve Block44f0eee2011-05-26 01:26:41 +0100245
246 friend class CaseClause; // Generates AST IDs.
Steve Blocka7e24c12009-10-30 11:49:00 +0000247};
248
249
250class Statement: public AstNode {
251 public:
252 Statement() : statement_pos_(RelocInfo::kNoPosition) {}
253
254 virtual Statement* AsStatement() { return this; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000255
256 bool IsEmpty() { return AsEmptyStatement() != NULL; }
257
258 void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
259 int statement_pos() const { return statement_pos_; }
260
261 private:
262 int statement_pos_;
263};
264
265
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000266class SmallMapList {
267 public:
268 SmallMapList() {}
269 explicit SmallMapList(int capacity) : list_(capacity) {}
270
271 void Reserve(int capacity) { list_.Reserve(capacity); }
272 void Clear() { list_.Clear(); }
273
274 bool is_empty() const { return list_.is_empty(); }
275 int length() const { return list_.length(); }
276
277 void Add(Handle<Map> handle) {
278 list_.Add(handle.location());
279 }
280
281 Handle<Map> at(int i) const {
282 return Handle<Map>(list_.at(i));
283 }
284
285 Handle<Map> first() const { return at(0); }
286 Handle<Map> last() const { return at(length() - 1); }
287
288 private:
289 // The list stores pointers to Map*, that is Map**, so it's GC safe.
290 SmallPointerList<Map*> list_;
291
292 DISALLOW_COPY_AND_ASSIGN(SmallMapList);
293};
294
295
Steve Blocka7e24c12009-10-30 11:49:00 +0000296class Expression: public AstNode {
297 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100298 enum Context {
299 // Not assigned a context yet, or else will not be visited during
300 // code generation.
301 kUninitialized,
302 // Evaluated for its side effects.
303 kEffect,
304 // Evaluated for its value (and side effects).
305 kValue,
306 // Evaluated for control flow (and side effects).
307 kTest
308 };
309
Ben Murdoch8b112d22011-06-08 16:22:53 +0100310 virtual int position() const {
311 UNREACHABLE();
312 return 0;
313 }
Leon Clarke4515c472010-02-03 11:58:03 +0000314
Steve Blocka7e24c12009-10-30 11:49:00 +0000315 virtual Expression* AsExpression() { return this; }
316
Steve Blocka7e24c12009-10-30 11:49:00 +0000317 virtual bool IsValidLeftHandSide() { return false; }
318
Ben Murdochb0fe1622011-05-05 13:52:32 +0100319 // Helpers for ToBoolean conversion.
320 virtual bool ToBooleanIsTrue() { return false; }
321 virtual bool ToBooleanIsFalse() { return false; }
322
Leon Clarkee46be812010-01-19 14:06:41 +0000323 // Symbols that cannot be parsed as array indices are considered property
324 // names. We do not treat symbols that can be array indexes as property
325 // names because [] for string objects is handled only by keyed ICs.
326 virtual bool IsPropertyName() { return false; }
327
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100328 // True iff the result can be safely overwritten (to avoid allocation).
329 // False for operations that can return one of their operands.
330 virtual bool ResultOverwriteAllowed() { return false; }
331
332 // True iff the expression is a literal represented as a smi.
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000333 bool IsSmiLiteral();
334
335 // True iff the expression is a string literal.
336 bool IsStringLiteral();
337
338 // True iff the expression is the null literal.
339 bool IsNullLiteral();
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100340
Ben Murdochb0fe1622011-05-05 13:52:32 +0100341 // Type feedback information for assignments and properties.
342 virtual bool IsMonomorphic() {
343 UNREACHABLE();
344 return false;
345 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000346 virtual SmallMapList* GetReceiverTypes() {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100347 UNREACHABLE();
348 return NULL;
349 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000350 Handle<Map> GetMonomorphicReceiverType() {
351 ASSERT(IsMonomorphic());
352 SmallMapList* types = GetReceiverTypes();
353 ASSERT(types != NULL && types->length() == 1);
354 return types->at(0);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100355 }
356
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000357 unsigned id() const { return id_; }
358 unsigned test_id() const { return test_id_; }
Andrei Popescu402d9372010-02-26 13:31:12 +0000359
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100360 protected:
361 explicit Expression(Isolate* isolate)
362 : id_(GetNextId(isolate)),
363 test_id_(GetNextId(isolate)) {}
364
Steve Blocka7e24c12009-10-30 11:49:00 +0000365 private:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100366 int id_;
367 int test_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000368};
369
370
Steve Blocka7e24c12009-10-30 11:49:00 +0000371class BreakableStatement: public Statement {
372 public:
373 enum Type {
374 TARGET_FOR_ANONYMOUS,
375 TARGET_FOR_NAMED_ONLY
376 };
377
378 // The labels associated with this statement. May be NULL;
379 // if it is != NULL, guaranteed to contain at least one entry.
380 ZoneStringList* labels() const { return labels_; }
381
382 // Type testing & conversion.
383 virtual BreakableStatement* AsBreakableStatement() { return this; }
384
385 // Code generation
Ben Murdoch8b112d22011-06-08 16:22:53 +0100386 Label* break_target() { return &break_target_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000387
388 // Testers.
389 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
390
Ben Murdochb0fe1622011-05-05 13:52:32 +0100391 // Bailout support.
392 int EntryId() const { return entry_id_; }
393 int ExitId() const { return exit_id_; }
394
Steve Blocka7e24c12009-10-30 11:49:00 +0000395 protected:
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000396 BreakableStatement(Isolate* isolate, ZoneStringList* labels, Type type)
397 : labels_(labels),
398 type_(type),
399 entry_id_(GetNextId(isolate)),
400 exit_id_(GetNextId(isolate)) {
401 ASSERT(labels == NULL || labels->length() > 0);
402 }
403
Steve Blocka7e24c12009-10-30 11:49:00 +0000404
405 private:
406 ZoneStringList* labels_;
407 Type type_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100408 Label break_target_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100409 int entry_id_;
410 int exit_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000411};
412
413
414class Block: public BreakableStatement {
415 public:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100416 DECLARE_NODE_TYPE(Block)
417
418 void AddStatement(Statement* statement) { statements_.Add(statement); }
419
420 ZoneList<Statement*>* statements() { return &statements_; }
421 bool is_initializer_block() const { return is_initializer_block_; }
422
423 Scope* block_scope() const { return block_scope_; }
424 void set_block_scope(Scope* block_scope) { block_scope_ = block_scope; }
425
426 protected:
427 template<class> friend class AstNodeFactory;
428
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000429 Block(Isolate* isolate,
430 ZoneStringList* labels,
431 int capacity,
432 bool is_initializer_block)
433 : BreakableStatement(isolate, labels, TARGET_FOR_NAMED_ONLY),
434 statements_(capacity),
435 is_initializer_block_(is_initializer_block),
436 block_scope_(NULL) {
437 }
438
Steve Blocka7e24c12009-10-30 11:49:00 +0000439 private:
440 ZoneList<Statement*> statements_;
441 bool is_initializer_block_;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000442 Scope* block_scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000443};
444
445
446class Declaration: public AstNode {
447 public:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100448 VariableProxy* proxy() const { return proxy_; }
449 VariableMode mode() const { return mode_; }
450 Scope* scope() const { return scope_; }
451 virtual InitializationFlag initialization() const = 0;
452 virtual bool IsInlineable() const;
453
454 virtual Declaration* AsDeclaration() { return this; }
455
456 protected:
Ben Murdoch589d6972011-11-30 16:04:58 +0000457 Declaration(VariableProxy* proxy,
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000458 VariableMode mode,
Ben Murdoch589d6972011-11-30 16:04:58 +0000459 Scope* scope)
Steve Blocka7e24c12009-10-30 11:49:00 +0000460 : proxy_(proxy),
461 mode_(mode),
Ben Murdoch589d6972011-11-30 16:04:58 +0000462 scope_(scope) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000463 ASSERT(mode == VAR ||
464 mode == CONST ||
465 mode == CONST_HARMONY ||
466 mode == LET);
Steve Blocka7e24c12009-10-30 11:49:00 +0000467 }
468
Steve Blocka7e24c12009-10-30 11:49:00 +0000469 private:
470 VariableProxy* proxy_;
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000471 VariableMode mode_;
Ben Murdoch589d6972011-11-30 16:04:58 +0000472
473 // Nested scope from which the declaration originated.
474 Scope* scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000475};
476
477
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100478class VariableDeclaration: public Declaration {
479 public:
480 DECLARE_NODE_TYPE(VariableDeclaration)
481
482 virtual InitializationFlag initialization() const {
483 return mode() == VAR ? kCreatedInitialized : kNeedsInitialization;
484 }
485
486 protected:
487 template<class> friend class AstNodeFactory;
488
489 VariableDeclaration(VariableProxy* proxy,
490 VariableMode mode,
491 Scope* scope)
492 : Declaration(proxy, mode, scope) {
493 }
494};
495
496
497class FunctionDeclaration: public Declaration {
498 public:
499 DECLARE_NODE_TYPE(FunctionDeclaration)
500
501 FunctionLiteral* fun() const { return fun_; }
502 virtual InitializationFlag initialization() const {
503 return kCreatedInitialized;
504 }
505 virtual bool IsInlineable() const;
506
507 protected:
508 template<class> friend class AstNodeFactory;
509
510 FunctionDeclaration(VariableProxy* proxy,
511 VariableMode mode,
512 FunctionLiteral* fun,
513 Scope* scope)
514 : Declaration(proxy, mode, scope),
515 fun_(fun) {
516 // At the moment there are no "const functions" in JavaScript...
517 ASSERT(mode == VAR || mode == LET);
518 ASSERT(fun != NULL);
519 }
520
521 private:
522 FunctionLiteral* fun_;
523};
524
525
526class ModuleDeclaration: public Declaration {
527 public:
528 DECLARE_NODE_TYPE(ModuleDeclaration)
529
530 Module* module() const { return module_; }
531 virtual InitializationFlag initialization() const {
532 return kCreatedInitialized;
533 }
534
535 protected:
536 template<class> friend class AstNodeFactory;
537
538 ModuleDeclaration(VariableProxy* proxy,
539 Module* module,
540 Scope* scope)
541 : Declaration(proxy, LET, scope),
542 module_(module) {
543 }
544
545 private:
546 Module* module_;
547};
548
549
550class ImportDeclaration: public Declaration {
551 public:
552 DECLARE_NODE_TYPE(ImportDeclaration)
553
554 Module* module() const { return module_; }
555 virtual InitializationFlag initialization() const {
556 return kCreatedInitialized;
557 }
558
559 protected:
560 template<class> friend class AstNodeFactory;
561
562 ImportDeclaration(VariableProxy* proxy,
563 Module* module,
564 Scope* scope)
565 : Declaration(proxy, LET, scope),
566 module_(module) {
567 }
568
569 private:
570 Module* module_;
571};
572
573
574class ExportDeclaration: public Declaration {
575 public:
576 DECLARE_NODE_TYPE(ExportDeclaration)
577
578 virtual InitializationFlag initialization() const {
579 return kCreatedInitialized;
580 }
581
582 protected:
583 template<class> friend class AstNodeFactory;
584
585 ExportDeclaration(VariableProxy* proxy,
586 Scope* scope)
587 : Declaration(proxy, LET, scope) {
588 }
589};
590
591
592class Module: public AstNode {
593 public:
594 Interface* interface() const { return interface_; }
595
596 protected:
597 Module() : interface_(Interface::NewModule()) {}
598 explicit Module(Interface* interface) : interface_(interface) {}
599
600 private:
601 Interface* interface_;
602};
603
604
605class ModuleLiteral: public Module {
606 public:
607 DECLARE_NODE_TYPE(ModuleLiteral)
608
609 Block* body() const { return body_; }
610
611 protected:
612 template<class> friend class AstNodeFactory;
613
614 ModuleLiteral(Block* body, Interface* interface)
615 : Module(interface),
616 body_(body) {
617 }
618
619 private:
620 Block* body_;
621};
622
623
624class ModuleVariable: public Module {
625 public:
626 DECLARE_NODE_TYPE(ModuleVariable)
627
628 VariableProxy* proxy() const { return proxy_; }
629
630 protected:
631 template<class> friend class AstNodeFactory;
632
633 inline explicit ModuleVariable(VariableProxy* proxy);
634
635 private:
636 VariableProxy* proxy_;
637};
638
639
640class ModulePath: public Module {
641 public:
642 DECLARE_NODE_TYPE(ModulePath)
643
644 Module* module() const { return module_; }
645 Handle<String> name() const { return name_; }
646
647 protected:
648 template<class> friend class AstNodeFactory;
649
650 ModulePath(Module* module, Handle<String> name)
651 : module_(module),
652 name_(name) {
653 }
654
655 private:
656 Module* module_;
657 Handle<String> name_;
658};
659
660
661class ModuleUrl: public Module {
662 public:
663 DECLARE_NODE_TYPE(ModuleUrl)
664
665 Handle<String> url() const { return url_; }
666
667 protected:
668 template<class> friend class AstNodeFactory;
669
670 explicit ModuleUrl(Handle<String> url) : url_(url) {
671 }
672
673 private:
674 Handle<String> url_;
675};
676
677
Steve Blocka7e24c12009-10-30 11:49:00 +0000678class IterationStatement: public BreakableStatement {
679 public:
680 // Type testing & conversion.
681 virtual IterationStatement* AsIterationStatement() { return this; }
682
683 Statement* body() const { return body_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100684
685 // Bailout support.
686 int OsrEntryId() const { return osr_entry_id_; }
687 virtual int ContinueId() const = 0;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000688 virtual int StackCheckId() const = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000689
690 // Code generation
Ben Murdoch8b112d22011-06-08 16:22:53 +0100691 Label* continue_target() { return &continue_target_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000692
693 protected:
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000694 IterationStatement(Isolate* isolate, ZoneStringList* labels)
695 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
696 body_(NULL),
697 osr_entry_id_(GetNextId(isolate)) {
698 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000699
700 void Initialize(Statement* body) {
701 body_ = body;
702 }
703
704 private:
705 Statement* body_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100706 Label continue_target_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100707 int osr_entry_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000708};
709
710
Steve Block3ce2e202009-11-05 08:53:23 +0000711class DoWhileStatement: public IterationStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000712 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100713 DECLARE_NODE_TYPE(DoWhileStatement)
714
Steve Block3ce2e202009-11-05 08:53:23 +0000715 void Initialize(Expression* cond, Statement* body) {
716 IterationStatement::Initialize(body);
717 cond_ = cond;
718 }
719
Steve Block3ce2e202009-11-05 08:53:23 +0000720 Expression* cond() const { return cond_; }
721
Steve Blockd0582a62009-12-15 09:54:21 +0000722 // Position where condition expression starts. We need it to make
723 // the loop's condition a breakable location.
724 int condition_position() { return condition_position_; }
725 void set_condition_position(int pos) { condition_position_ = pos; }
726
Ben Murdochb0fe1622011-05-05 13:52:32 +0100727 // Bailout support.
728 virtual int ContinueId() const { return continue_id_; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000729 virtual int StackCheckId() const { return back_edge_id_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100730 int BackEdgeId() const { return back_edge_id_; }
731
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100732 protected:
733 template<class> friend class AstNodeFactory;
734
735 DoWhileStatement(Isolate* isolate, ZoneStringList* labels)
736 : IterationStatement(isolate, labels),
737 cond_(NULL),
738 condition_position_(-1),
739 continue_id_(GetNextId(isolate)),
740 back_edge_id_(GetNextId(isolate)) {
741 }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100742
Steve Block3ce2e202009-11-05 08:53:23 +0000743 private:
744 Expression* cond_;
Steve Blockd0582a62009-12-15 09:54:21 +0000745 int condition_position_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100746 int continue_id_;
747 int back_edge_id_;
Steve Block3ce2e202009-11-05 08:53:23 +0000748};
749
750
751class WhileStatement: public IterationStatement {
752 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100753 DECLARE_NODE_TYPE(WhileStatement)
754
Steve Block3ce2e202009-11-05 08:53:23 +0000755 void Initialize(Expression* cond, Statement* body) {
756 IterationStatement::Initialize(body);
757 cond_ = cond;
758 }
759
Steve Block3ce2e202009-11-05 08:53:23 +0000760 Expression* cond() const { return cond_; }
761 bool may_have_function_literal() const {
762 return may_have_function_literal_;
763 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100764 void set_may_have_function_literal(bool value) {
765 may_have_function_literal_ = value;
766 }
Steve Block3ce2e202009-11-05 08:53:23 +0000767
Ben Murdochb0fe1622011-05-05 13:52:32 +0100768 // Bailout support.
769 virtual int ContinueId() const { return EntryId(); }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000770 virtual int StackCheckId() const { return body_id_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100771 int BodyId() const { return body_id_; }
772
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100773 protected:
774 template<class> friend class AstNodeFactory;
775
776 WhileStatement(Isolate* isolate, ZoneStringList* labels)
777 : IterationStatement(isolate, labels),
778 cond_(NULL),
779 may_have_function_literal_(true),
780 body_id_(GetNextId(isolate)) {
781 }
782
Steve Block3ce2e202009-11-05 08:53:23 +0000783 private:
784 Expression* cond_;
785 // True if there is a function literal subexpression in the condition.
786 bool may_have_function_literal_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100787 int body_id_;
Steve Block3ce2e202009-11-05 08:53:23 +0000788};
789
790
791class ForStatement: public IterationStatement {
792 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100793 DECLARE_NODE_TYPE(ForStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000794
795 void Initialize(Statement* init,
796 Expression* cond,
797 Statement* next,
798 Statement* body) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000799 IterationStatement::Initialize(body);
800 init_ = init;
801 cond_ = cond;
802 next_ = next;
803 }
804
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100805 Statement* init() const { return init_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100806 Expression* cond() const { return cond_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100807 Statement* next() const { return next_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100808
Steve Blocka7e24c12009-10-30 11:49:00 +0000809 bool may_have_function_literal() const {
810 return may_have_function_literal_;
811 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100812 void set_may_have_function_literal(bool value) {
813 may_have_function_literal_ = value;
814 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000815
Ben Murdochb0fe1622011-05-05 13:52:32 +0100816 // Bailout support.
817 virtual int ContinueId() const { return continue_id_; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000818 virtual int StackCheckId() const { return body_id_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100819 int BodyId() const { return body_id_; }
820
Steve Block6ded16b2010-05-10 14:33:55 +0100821 bool is_fast_smi_loop() { return loop_variable_ != NULL; }
822 Variable* loop_variable() { return loop_variable_; }
823 void set_loop_variable(Variable* var) { loop_variable_ = var; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100824
825 protected:
826 template<class> friend class AstNodeFactory;
827
828 ForStatement(Isolate* isolate, ZoneStringList* labels)
829 : IterationStatement(isolate, labels),
830 init_(NULL),
831 cond_(NULL),
832 next_(NULL),
833 may_have_function_literal_(true),
834 loop_variable_(NULL),
835 continue_id_(GetNextId(isolate)),
836 body_id_(GetNextId(isolate)) {
837 }
Steve Block6ded16b2010-05-10 14:33:55 +0100838
Steve Blocka7e24c12009-10-30 11:49:00 +0000839 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000840 Statement* init_;
841 Expression* cond_;
842 Statement* next_;
843 // True if there is a function literal subexpression in the condition.
844 bool may_have_function_literal_;
Steve Block6ded16b2010-05-10 14:33:55 +0100845 Variable* loop_variable_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100846 int continue_id_;
847 int body_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000848};
849
850
851class ForInStatement: public IterationStatement {
852 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100853 DECLARE_NODE_TYPE(ForInStatement)
854
Steve Blocka7e24c12009-10-30 11:49:00 +0000855 void Initialize(Expression* each, Expression* enumerable, Statement* body) {
856 IterationStatement::Initialize(body);
857 each_ = each;
858 enumerable_ = enumerable;
859 }
860
Steve Blocka7e24c12009-10-30 11:49:00 +0000861 Expression* each() const { return each_; }
862 Expression* enumerable() const { return enumerable_; }
863
Ben Murdochb0fe1622011-05-05 13:52:32 +0100864 virtual int ContinueId() const { return EntryId(); }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100865 virtual int StackCheckId() const { return body_id_; }
866 int BodyId() const { return body_id_; }
867 int PrepareId() const { return prepare_id_; }
868
869 protected:
870 template<class> friend class AstNodeFactory;
871
872 ForInStatement(Isolate* isolate, ZoneStringList* labels)
873 : IterationStatement(isolate, labels),
874 each_(NULL),
875 enumerable_(NULL),
876 body_id_(GetNextId(isolate)),
877 prepare_id_(GetNextId(isolate)) {
878 }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100879
Steve Blocka7e24c12009-10-30 11:49:00 +0000880 private:
881 Expression* each_;
882 Expression* enumerable_;
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100883 int body_id_;
884 int prepare_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000885};
886
887
888class ExpressionStatement: public Statement {
889 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100890 DECLARE_NODE_TYPE(ExpressionStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000891
892 void set_expression(Expression* e) { expression_ = e; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100893 Expression* expression() const { return expression_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000894
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100895 protected:
896 template<class> friend class AstNodeFactory;
897
898 explicit ExpressionStatement(Expression* expression)
899 : expression_(expression) { }
900
Steve Blocka7e24c12009-10-30 11:49:00 +0000901 private:
902 Expression* expression_;
903};
904
905
906class ContinueStatement: public Statement {
907 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100908 DECLARE_NODE_TYPE(ContinueStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000909
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100910 IterationStatement* target() const { return target_; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100911
912 protected:
913 template<class> friend class AstNodeFactory;
914
915 explicit ContinueStatement(IterationStatement* target)
916 : target_(target) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000917
918 private:
919 IterationStatement* target_;
920};
921
922
923class BreakStatement: public Statement {
924 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100925 DECLARE_NODE_TYPE(BreakStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000926
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100927 BreakableStatement* target() const { return target_; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100928
929 protected:
930 template<class> friend class AstNodeFactory;
931
932 explicit BreakStatement(BreakableStatement* target)
933 : target_(target) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000934
935 private:
936 BreakableStatement* target_;
937};
938
939
940class ReturnStatement: public Statement {
941 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100942 DECLARE_NODE_TYPE(ReturnStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000943
Ben Murdochb0fe1622011-05-05 13:52:32 +0100944 Expression* expression() const { return expression_; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100945
946 protected:
947 template<class> friend class AstNodeFactory;
948
949 explicit ReturnStatement(Expression* expression)
950 : expression_(expression) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000951
952 private:
953 Expression* expression_;
954};
955
956
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000957class WithStatement: public Statement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000958 public:
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000959 DECLARE_NODE_TYPE(WithStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000960
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100961 Expression* expression() const { return expression_; }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000962 Statement* statement() const { return statement_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000963
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100964 protected:
965 template<class> friend class AstNodeFactory;
966
967 WithStatement(Expression* expression, Statement* statement)
968 : expression_(expression),
969 statement_(statement) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000970
971 private:
972 Expression* expression_;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000973 Statement* statement_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000974};
975
976
Steve Blocka7e24c12009-10-30 11:49:00 +0000977class CaseClause: public ZoneObject {
978 public:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000979 CaseClause(Isolate* isolate,
980 Expression* label,
981 ZoneList<Statement*>* statements,
982 int pos);
Steve Blocka7e24c12009-10-30 11:49:00 +0000983
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100984 bool is_default() const { return label_ == NULL; }
985 Expression* label() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000986 CHECK(!is_default());
987 return label_;
988 }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100989 Label* body_target() { return &body_target_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100990 ZoneList<Statement*>* statements() const { return statements_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000991
Ben Murdoch8b112d22011-06-08 16:22:53 +0100992 int position() const { return position_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100993 void set_position(int pos) { position_ = pos; }
994
Steve Block44f0eee2011-05-26 01:26:41 +0100995 int EntryId() { return entry_id_; }
Ben Murdoch257744e2011-11-30 15:57:28 +0000996 int CompareId() { return compare_id_; }
Steve Block44f0eee2011-05-26 01:26:41 +0100997
Ben Murdochb0fe1622011-05-05 13:52:32 +0100998 // Type feedback information.
999 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1000 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001001 bool IsSymbolCompare() { return compare_type_ == SYMBOL_ONLY; }
1002 bool IsStringCompare() { return compare_type_ == STRING_ONLY; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001003 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1004
Steve Blocka7e24c12009-10-30 11:49:00 +00001005 private:
1006 Expression* label_;
Ben Murdoch8b112d22011-06-08 16:22:53 +01001007 Label body_target_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001008 ZoneList<Statement*>* statements_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001009 int position_;
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001010 enum CompareTypeFeedback {
1011 NONE,
1012 SMI_ONLY,
1013 SYMBOL_ONLY,
1014 STRING_ONLY,
1015 OBJECT_ONLY
1016 };
Ben Murdochb0fe1622011-05-05 13:52:32 +01001017 CompareTypeFeedback compare_type_;
Ben Murdoch257744e2011-11-30 15:57:28 +00001018 int compare_id_;
Steve Block44f0eee2011-05-26 01:26:41 +01001019 int entry_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001020};
1021
1022
1023class SwitchStatement: public BreakableStatement {
1024 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001025 DECLARE_NODE_TYPE(SwitchStatement)
1026
Steve Blocka7e24c12009-10-30 11:49:00 +00001027 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
1028 tag_ = tag;
1029 cases_ = cases;
1030 }
1031
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001032 Expression* tag() const { return tag_; }
1033 ZoneList<CaseClause*>* cases() const { return cases_; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001034
1035 protected:
1036 template<class> friend class AstNodeFactory;
1037
1038 SwitchStatement(Isolate* isolate, ZoneStringList* labels)
1039 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
1040 tag_(NULL),
1041 cases_(NULL) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001042
1043 private:
1044 Expression* tag_;
1045 ZoneList<CaseClause*>* cases_;
1046};
1047
1048
1049// If-statements always have non-null references to their then- and
1050// else-parts. When parsing if-statements with no explicit else-part,
1051// the parser implicitly creates an empty statement. Use the
1052// HasThenStatement() and HasElseStatement() functions to check if a
1053// given if-statement has a then- or an else-part containing code.
1054class IfStatement: public Statement {
1055 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001056 DECLARE_NODE_TYPE(IfStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +00001057
1058 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
1059 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
1060
1061 Expression* condition() const { return condition_; }
1062 Statement* then_statement() const { return then_statement_; }
1063 Statement* else_statement() const { return else_statement_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001064
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001065 int IfId() const { return if_id_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001066 int ThenId() const { return then_id_; }
1067 int ElseId() const { return else_id_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001068
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001069 protected:
1070 template<class> friend class AstNodeFactory;
1071
1072 IfStatement(Isolate* isolate,
1073 Expression* condition,
1074 Statement* then_statement,
1075 Statement* else_statement)
1076 : condition_(condition),
1077 then_statement_(then_statement),
1078 else_statement_(else_statement),
1079 if_id_(GetNextId(isolate)),
1080 then_id_(GetNextId(isolate)),
1081 else_id_(GetNextId(isolate)) {
1082 }
1083
Steve Blocka7e24c12009-10-30 11:49:00 +00001084 private:
1085 Expression* condition_;
1086 Statement* then_statement_;
1087 Statement* else_statement_;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001088 int if_id_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001089 int then_id_;
1090 int else_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001091};
1092
1093
1094// NOTE: TargetCollectors are represented as nodes to fit in the target
1095// stack in the compiler; this should probably be reworked.
1096class TargetCollector: public AstNode {
1097 public:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001098 TargetCollector() : targets_(0) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001099
1100 // Adds a jump target to the collector. The collector stores a pointer not
1101 // a copy of the target to make binding work, so make sure not to pass in
1102 // references to something on the stack.
Ben Murdoch8b112d22011-06-08 16:22:53 +01001103 void AddTarget(Label* target);
Steve Blocka7e24c12009-10-30 11:49:00 +00001104
1105 // Virtual behaviour. TargetCollectors are never part of the AST.
1106 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
1107 virtual TargetCollector* AsTargetCollector() { return this; }
1108
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001109 ZoneList<Label*>* targets() { return &targets_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001110
1111 private:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001112 ZoneList<Label*> targets_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001113};
1114
1115
1116class TryStatement: public Statement {
1117 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +01001118 void set_escaping_targets(ZoneList<Label*>* targets) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001119 escaping_targets_ = targets;
1120 }
1121
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001122 int index() const { return index_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001123 Block* try_block() const { return try_block_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001124 ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001125
1126 protected:
1127 TryStatement(int index, Block* try_block)
1128 : index_(index),
1129 try_block_(try_block),
1130 escaping_targets_(NULL) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001131
1132 private:
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001133 // Unique (per-function) index of this handler. This is not an AST ID.
1134 int index_;
1135
Steve Blocka7e24c12009-10-30 11:49:00 +00001136 Block* try_block_;
Ben Murdoch8b112d22011-06-08 16:22:53 +01001137 ZoneList<Label*>* escaping_targets_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001138};
1139
1140
Steve Block3ce2e202009-11-05 08:53:23 +00001141class TryCatchStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +00001142 public:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001143 DECLARE_NODE_TYPE(TryCatchStatement)
1144
1145 Scope* scope() { return scope_; }
1146 Variable* variable() { return variable_; }
1147 Block* catch_block() const { return catch_block_; }
1148
1149 protected:
1150 template<class> friend class AstNodeFactory;
1151
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001152 TryCatchStatement(int index,
1153 Block* try_block,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001154 Scope* scope,
1155 Variable* variable,
Steve Block3ce2e202009-11-05 08:53:23 +00001156 Block* catch_block)
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001157 : TryStatement(index, try_block),
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001158 scope_(scope),
1159 variable_(variable),
Steve Blocka7e24c12009-10-30 11:49:00 +00001160 catch_block_(catch_block) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001161 }
1162
Steve Blocka7e24c12009-10-30 11:49:00 +00001163 private:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001164 Scope* scope_;
1165 Variable* variable_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001166 Block* catch_block_;
1167};
1168
1169
Steve Block3ce2e202009-11-05 08:53:23 +00001170class TryFinallyStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +00001171 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001172 DECLARE_NODE_TYPE(TryFinallyStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +00001173
1174 Block* finally_block() const { return finally_block_; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001175
1176 protected:
1177 template<class> friend class AstNodeFactory;
1178
1179 TryFinallyStatement(int index, Block* try_block, Block* finally_block)
1180 : TryStatement(index, try_block),
1181 finally_block_(finally_block) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001182
1183 private:
1184 Block* finally_block_;
1185};
1186
1187
1188class DebuggerStatement: public Statement {
1189 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001190 DECLARE_NODE_TYPE(DebuggerStatement)
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001191
1192 protected:
1193 template<class> friend class AstNodeFactory;
1194
1195 DebuggerStatement() {}
Steve Blocka7e24c12009-10-30 11:49:00 +00001196};
1197
1198
1199class EmptyStatement: public Statement {
1200 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001201 DECLARE_NODE_TYPE(EmptyStatement)
Ben Murdochb0fe1622011-05-05 13:52:32 +01001202
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001203 protected:
1204 template<class> friend class AstNodeFactory;
1205
1206 EmptyStatement() {}
Steve Blocka7e24c12009-10-30 11:49:00 +00001207};
1208
1209
1210class Literal: public Expression {
1211 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001212 DECLARE_NODE_TYPE(Literal)
1213
Leon Clarkee46be812010-01-19 14:06:41 +00001214 virtual bool IsPropertyName() {
1215 if (handle_->IsSymbol()) {
1216 uint32_t ignored;
1217 return !String::cast(*handle_)->AsArrayIndex(&ignored);
1218 }
1219 return false;
1220 }
1221
Ben Murdochb0fe1622011-05-05 13:52:32 +01001222 Handle<String> AsPropertyName() {
1223 ASSERT(IsPropertyName());
1224 return Handle<String>::cast(handle_);
1225 }
1226
1227 virtual bool ToBooleanIsTrue() { return handle_->ToBoolean()->IsTrue(); }
1228 virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
1229
Steve Blocka7e24c12009-10-30 11:49:00 +00001230 // Identity testers.
Steve Block44f0eee2011-05-26 01:26:41 +01001231 bool IsNull() const {
1232 ASSERT(!handle_.is_null());
1233 return handle_->IsNull();
1234 }
1235 bool IsTrue() const {
1236 ASSERT(!handle_.is_null());
1237 return handle_->IsTrue();
1238 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001239 bool IsFalse() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001240 ASSERT(!handle_.is_null());
1241 return handle_->IsFalse();
Steve Blocka7e24c12009-10-30 11:49:00 +00001242 }
1243
1244 Handle<Object> handle() const { return handle_; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001245
1246 // Support for using Literal as a HashMap key. NOTE: Currently, this works
1247 // only for string and number literals!
1248 uint32_t Hash() { return ToString()->Hash(); }
1249
1250 static bool Match(void* literal1, void* literal2) {
1251 Handle<String> s1 = static_cast<Literal*>(literal1)->ToString();
1252 Handle<String> s2 = static_cast<Literal*>(literal2)->ToString();
1253 return s1->Equals(*s2);
1254 }
1255
1256 protected:
1257 template<class> friend class AstNodeFactory;
1258
1259 Literal(Isolate* isolate, Handle<Object> handle)
1260 : Expression(isolate),
1261 handle_(handle) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001262
1263 private:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001264 Handle<String> ToString();
1265
Steve Blocka7e24c12009-10-30 11:49:00 +00001266 Handle<Object> handle_;
1267};
1268
1269
1270// Base class for literals that needs space in the corresponding JSFunction.
1271class MaterializedLiteral: public Expression {
1272 public:
Steve Blocka7e24c12009-10-30 11:49:00 +00001273 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
1274
1275 int literal_index() { return literal_index_; }
1276
1277 // A materialized literal is simple if the values consist of only
1278 // constants and simple object and array literals.
1279 bool is_simple() const { return is_simple_; }
1280
Steve Blocka7e24c12009-10-30 11:49:00 +00001281 int depth() const { return depth_; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001282
1283 protected:
1284 MaterializedLiteral(Isolate* isolate,
1285 int literal_index,
1286 bool is_simple,
1287 int depth)
1288 : Expression(isolate),
1289 literal_index_(literal_index),
1290 is_simple_(is_simple),
1291 depth_(depth) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00001292
1293 private:
1294 int literal_index_;
1295 bool is_simple_;
1296 int depth_;
1297};
1298
1299
1300// An object literal has a boilerplate object that is used
1301// for minimizing the work when constructing it at runtime.
1302class ObjectLiteral: public MaterializedLiteral {
1303 public:
1304 // Property is used for passing information
1305 // about an object literal's properties from the parser
1306 // to the code generator.
1307 class Property: public ZoneObject {
1308 public:
Steve Blocka7e24c12009-10-30 11:49:00 +00001309 enum Kind {
1310 CONSTANT, // Property with constant value (compile time).
1311 COMPUTED, // Property with computed value (execution time).
1312 MATERIALIZED_LITERAL, // Property value is a materialized literal.
1313 GETTER, SETTER, // Property is an accessor function.
1314 PROTOTYPE // Property is __proto__.
1315 };
1316
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001317 Property(Literal* key, Expression* value, Isolate* isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001318
1319 Literal* key() { return key_; }
1320 Expression* value() { return value_; }
1321 Kind kind() { return kind_; }
1322
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001323 // Type feedback information.
1324 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1325 bool IsMonomorphic() { return !receiver_type_.is_null(); }
1326 Handle<Map> GetReceiverType() { return receiver_type_; }
1327
Steve Blockd0582a62009-12-15 09:54:21 +00001328 bool IsCompileTimeValue();
1329
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001330 void set_emit_store(bool emit_store);
1331 bool emit_store();
1332
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001333 protected:
1334 template<class> friend class AstNodeFactory;
1335
1336 Property(bool is_getter, FunctionLiteral* value);
1337 void set_key(Literal* key) { key_ = key; }
1338
Steve Blocka7e24c12009-10-30 11:49:00 +00001339 private:
1340 Literal* key_;
1341 Expression* value_;
1342 Kind kind_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001343 bool emit_store_;
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001344 Handle<Map> receiver_type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001345 };
1346
Ben Murdochf87a2032010-10-22 12:50:53 +01001347 DECLARE_NODE_TYPE(ObjectLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00001348
1349 Handle<FixedArray> constant_properties() const {
1350 return constant_properties_;
1351 }
1352 ZoneList<Property*>* properties() const { return properties_; }
1353
Steve Block6ded16b2010-05-10 14:33:55 +01001354 bool fast_elements() const { return fast_elements_; }
1355
Steve Block44f0eee2011-05-26 01:26:41 +01001356 bool has_function() { return has_function_; }
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001357
1358 // Mark all computed expressions that are bound to a key that
1359 // is shadowed by a later occurrence of the same key. For the
1360 // marked expressions, no store code is emitted.
1361 void CalculateEmitStore();
1362
Steve Block44f0eee2011-05-26 01:26:41 +01001363 enum Flags {
1364 kNoFlags = 0,
1365 kFastElements = 1,
1366 kHasFunction = 1 << 1
1367 };
1368
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001369 struct Accessors: public ZoneObject {
1370 Accessors() : getter(NULL), setter(NULL) { }
1371 Expression* getter;
1372 Expression* setter;
1373 };
1374
1375 protected:
1376 template<class> friend class AstNodeFactory;
1377
1378 ObjectLiteral(Isolate* isolate,
1379 Handle<FixedArray> constant_properties,
1380 ZoneList<Property*>* properties,
1381 int literal_index,
1382 bool is_simple,
1383 bool fast_elements,
1384 int depth,
1385 bool has_function)
1386 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
1387 constant_properties_(constant_properties),
1388 properties_(properties),
1389 fast_elements_(fast_elements),
1390 has_function_(has_function) {}
1391
Steve Blocka7e24c12009-10-30 11:49:00 +00001392 private:
1393 Handle<FixedArray> constant_properties_;
1394 ZoneList<Property*>* properties_;
Steve Block6ded16b2010-05-10 14:33:55 +01001395 bool fast_elements_;
Steve Block44f0eee2011-05-26 01:26:41 +01001396 bool has_function_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001397};
1398
1399
1400// Node for capturing a regexp literal.
1401class RegExpLiteral: public MaterializedLiteral {
1402 public:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001403 DECLARE_NODE_TYPE(RegExpLiteral)
1404
1405 Handle<String> pattern() const { return pattern_; }
1406 Handle<String> flags() const { return flags_; }
1407
1408 protected:
1409 template<class> friend class AstNodeFactory;
1410
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001411 RegExpLiteral(Isolate* isolate,
1412 Handle<String> pattern,
Steve Blocka7e24c12009-10-30 11:49:00 +00001413 Handle<String> flags,
1414 int literal_index)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001415 : MaterializedLiteral(isolate, literal_index, false, 1),
Steve Blocka7e24c12009-10-30 11:49:00 +00001416 pattern_(pattern),
1417 flags_(flags) {}
1418
Steve Blocka7e24c12009-10-30 11:49:00 +00001419 private:
1420 Handle<String> pattern_;
1421 Handle<String> flags_;
1422};
1423
1424// An array literal has a literals object that is used
1425// for minimizing the work when constructing it at runtime.
1426class ArrayLiteral: public MaterializedLiteral {
1427 public:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001428 DECLARE_NODE_TYPE(ArrayLiteral)
1429
1430 Handle<FixedArray> constant_elements() const { return constant_elements_; }
1431 ZoneList<Expression*>* values() const { return values_; }
1432
1433 // Return an AST id for an element that is used in simulate instructions.
1434 int GetIdForElement(int i) { return first_element_id_ + i; }
1435
1436 protected:
1437 template<class> friend class AstNodeFactory;
1438
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001439 ArrayLiteral(Isolate* isolate,
1440 Handle<FixedArray> constant_elements,
Steve Blocka7e24c12009-10-30 11:49:00 +00001441 ZoneList<Expression*>* values,
1442 int literal_index,
1443 bool is_simple,
1444 int depth)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001445 : MaterializedLiteral(isolate, literal_index, is_simple, depth),
Leon Clarkee46be812010-01-19 14:06:41 +00001446 constant_elements_(constant_elements),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001447 values_(values),
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001448 first_element_id_(ReserveIdRange(isolate, values->length())) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00001449
Steve Blocka7e24c12009-10-30 11:49:00 +00001450 private:
Leon Clarkee46be812010-01-19 14:06:41 +00001451 Handle<FixedArray> constant_elements_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001452 ZoneList<Expression*>* values_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001453 int first_element_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001454};
1455
1456
Steve Blocka7e24c12009-10-30 11:49:00 +00001457class VariableProxy: public Expression {
1458 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001459 DECLARE_NODE_TYPE(VariableProxy)
Steve Blocka7e24c12009-10-30 11:49:00 +00001460
Steve Blocka7e24c12009-10-30 11:49:00 +00001461 virtual bool IsValidLeftHandSide() {
1462 return var_ == NULL ? true : var_->IsValidLeftHandSide();
1463 }
1464
1465 bool IsVariable(Handle<String> n) {
1466 return !is_this() && name().is_identical_to(n);
1467 }
1468
Ben Murdoch589d6972011-11-30 16:04:58 +00001469 bool IsArguments() { return var_ != NULL && var_->is_arguments(); }
Steve Blocka7e24c12009-10-30 11:49:00 +00001470
Ben Murdochc7cc0282012-03-05 14:35:55 +00001471 bool IsLValue() {
1472 return is_lvalue_;
1473 }
1474
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001475 Handle<String> name() const { return name_; }
1476 Variable* var() const { return var_; }
1477 bool is_this() const { return is_this_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001478 int position() const { return position_; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001479 Interface* interface() const { return interface_; }
1480
Steve Block6ded16b2010-05-10 14:33:55 +01001481
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001482 void MarkAsTrivial() { is_trivial_ = true; }
Ben Murdochc7cc0282012-03-05 14:35:55 +00001483 void MarkAsLValue() { is_lvalue_ = true; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001484
1485 // Bind this proxy to the variable var.
1486 void BindTo(Variable* var);
1487
1488 protected:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001489 template<class> friend class AstNodeFactory;
1490
1491 VariableProxy(Isolate* isolate, Variable* var);
1492
1493 VariableProxy(Isolate* isolate,
1494 Handle<String> name,
1495 bool is_this,
1496 int position,
1497 Interface* interface);
1498
Steve Blocka7e24c12009-10-30 11:49:00 +00001499 Handle<String> name_;
1500 Variable* var_; // resolved variable, or NULL
1501 bool is_this_;
Steve Block6ded16b2010-05-10 14:33:55 +01001502 bool is_trivial_;
Ben Murdochc7cc0282012-03-05 14:35:55 +00001503 // True if this variable proxy is being used in an assignment
1504 // or with a increment/decrement operator.
1505 bool is_lvalue_;
Ben Murdoch8b112d22011-06-08 16:22:53 +01001506 int position_;
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001507 Interface* interface_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001508};
1509
1510
Steve Blocka7e24c12009-10-30 11:49:00 +00001511class Property: public Expression {
1512 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001513 DECLARE_NODE_TYPE(Property)
Steve Blocka7e24c12009-10-30 11:49:00 +00001514
1515 virtual bool IsValidLeftHandSide() { return true; }
1516
1517 Expression* obj() const { return obj_; }
1518 Expression* key() const { return key_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001519 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001520
Steve Block1e0659c2011-05-24 12:43:12 +01001521 bool IsStringLength() const { return is_string_length_; }
Steve Block44f0eee2011-05-26 01:26:41 +01001522 bool IsStringAccess() const { return is_string_access_; }
Steve Block9fac8402011-05-12 15:51:54 +01001523 bool IsFunctionPrototype() const { return is_function_prototype_; }
1524
Ben Murdochb0fe1622011-05-05 13:52:32 +01001525 // Type feedback information.
1526 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1527 virtual bool IsMonomorphic() { return is_monomorphic_; }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001528 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001529 bool IsArrayLength() { return is_array_length_; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001530 bool IsUninitialized() { return is_uninitialized_; }
1531
1532 protected:
1533 template<class> friend class AstNodeFactory;
1534
1535 Property(Isolate* isolate,
1536 Expression* obj,
1537 Expression* key,
1538 int pos)
1539 : Expression(isolate),
1540 obj_(obj),
1541 key_(key),
1542 pos_(pos),
1543 is_monomorphic_(false),
1544 is_uninitialized_(false),
1545 is_array_length_(false),
1546 is_string_length_(false),
1547 is_string_access_(false),
1548 is_function_prototype_(false) { }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001549
Steve Blocka7e24c12009-10-30 11:49:00 +00001550 private:
1551 Expression* obj_;
1552 Expression* key_;
1553 int pos_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001554
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001555 SmallMapList receiver_types_;
Steve Block1e0659c2011-05-24 12:43:12 +01001556 bool is_monomorphic_ : 1;
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001557 bool is_uninitialized_ : 1;
Steve Block1e0659c2011-05-24 12:43:12 +01001558 bool is_array_length_ : 1;
1559 bool is_string_length_ : 1;
Steve Block44f0eee2011-05-26 01:26:41 +01001560 bool is_string_access_ : 1;
Steve Block1e0659c2011-05-24 12:43:12 +01001561 bool is_function_prototype_ : 1;
Steve Blocka7e24c12009-10-30 11:49:00 +00001562};
1563
1564
1565class Call: public Expression {
1566 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001567 DECLARE_NODE_TYPE(Call)
Steve Blocka7e24c12009-10-30 11:49:00 +00001568
1569 Expression* expression() const { return expression_; }
1570 ZoneList<Expression*>* arguments() const { return arguments_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001571 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001572
Ben Murdoch257744e2011-11-30 15:57:28 +00001573 void RecordTypeFeedback(TypeFeedbackOracle* oracle,
1574 CallKind call_kind);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001575 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001576 virtual bool IsMonomorphic() { return is_monomorphic_; }
Ben Murdochb8e0da22011-05-16 14:20:40 +01001577 CheckType check_type() const { return check_type_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001578 Handle<JSFunction> target() { return target_; }
1579 Handle<JSObject> holder() { return holder_; }
1580 Handle<JSGlobalPropertyCell> cell() { return cell_; }
1581
1582 bool ComputeTarget(Handle<Map> type, Handle<String> name);
Ben Murdoch8b112d22011-06-08 16:22:53 +01001583 bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001584
1585 // Bailout support.
1586 int ReturnId() const { return return_id_; }
1587
Ben Murdochb0fe1622011-05-05 13:52:32 +01001588#ifdef DEBUG
1589 // Used to assert that the FullCodeGenerator records the return site.
1590 bool return_is_recorded_;
1591#endif
1592
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001593 protected:
1594 template<class> friend class AstNodeFactory;
1595
1596 Call(Isolate* isolate,
1597 Expression* expression,
1598 ZoneList<Expression*>* arguments,
1599 int pos)
1600 : Expression(isolate),
1601 expression_(expression),
1602 arguments_(arguments),
1603 pos_(pos),
1604 is_monomorphic_(false),
1605 check_type_(RECEIVER_MAP_CHECK),
1606 return_id_(GetNextId(isolate)) { }
1607
Steve Blocka7e24c12009-10-30 11:49:00 +00001608 private:
1609 Expression* expression_;
1610 ZoneList<Expression*>* arguments_;
1611 int pos_;
1612
Ben Murdochb0fe1622011-05-05 13:52:32 +01001613 bool is_monomorphic_;
Ben Murdochb8e0da22011-05-16 14:20:40 +01001614 CheckType check_type_;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001615 SmallMapList receiver_types_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001616 Handle<JSFunction> target_;
1617 Handle<JSObject> holder_;
1618 Handle<JSGlobalPropertyCell> cell_;
1619
1620 int return_id_;
Steve Block44f0eee2011-05-26 01:26:41 +01001621};
Ben Murdochb0fe1622011-05-05 13:52:32 +01001622
Steve Block44f0eee2011-05-26 01:26:41 +01001623
Steve Blocka7e24c12009-10-30 11:49:00 +00001624class CallNew: public Expression {
1625 public:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001626 DECLARE_NODE_TYPE(CallNew)
1627
1628 Expression* expression() const { return expression_; }
1629 ZoneList<Expression*>* arguments() const { return arguments_; }
1630 virtual int position() const { return pos_; }
1631
1632 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1633 virtual bool IsMonomorphic() { return is_monomorphic_; }
1634 Handle<JSFunction> target() { return target_; }
1635
1636 // Bailout support.
1637 int ReturnId() const { return return_id_; }
1638
1639 protected:
1640 template<class> friend class AstNodeFactory;
1641
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001642 CallNew(Isolate* isolate,
1643 Expression* expression,
1644 ZoneList<Expression*>* arguments,
1645 int pos)
1646 : Expression(isolate),
1647 expression_(expression),
1648 arguments_(arguments),
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001649 pos_(pos),
1650 is_monomorphic_(false),
1651 return_id_(GetNextId(isolate)) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001652
1653 private:
1654 Expression* expression_;
1655 ZoneList<Expression*>* arguments_;
1656 int pos_;
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001657
1658 bool is_monomorphic_;
1659 Handle<JSFunction> target_;
1660
1661 int return_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001662};
1663
1664
1665// The CallRuntime class does not represent any official JavaScript
1666// language construct. Instead it is used to call a C or JS function
1667// with a set of arguments. This is used from the builtins that are
1668// implemented in JavaScript (see "v8natives.js").
1669class CallRuntime: public Expression {
1670 public:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001671 DECLARE_NODE_TYPE(CallRuntime)
1672
1673 Handle<String> name() const { return name_; }
1674 const Runtime::Function* function() const { return function_; }
1675 ZoneList<Expression*>* arguments() const { return arguments_; }
1676 bool is_jsruntime() const { return function_ == NULL; }
1677
1678 protected:
1679 template<class> friend class AstNodeFactory;
1680
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001681 CallRuntime(Isolate* isolate,
1682 Handle<String> name,
Steve Block44f0eee2011-05-26 01:26:41 +01001683 const Runtime::Function* function,
Steve Blocka7e24c12009-10-30 11:49:00 +00001684 ZoneList<Expression*>* arguments)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001685 : Expression(isolate),
1686 name_(name),
1687 function_(function),
1688 arguments_(arguments) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001689
Steve Blocka7e24c12009-10-30 11:49:00 +00001690 private:
1691 Handle<String> name_;
Steve Block44f0eee2011-05-26 01:26:41 +01001692 const Runtime::Function* function_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001693 ZoneList<Expression*>* arguments_;
1694};
1695
1696
1697class UnaryOperation: public Expression {
1698 public:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001699 DECLARE_NODE_TYPE(UnaryOperation)
1700
1701 virtual bool ResultOverwriteAllowed();
1702
1703 Token::Value op() const { return op_; }
1704 Expression* expression() const { return expression_; }
1705 virtual int position() const { return pos_; }
1706
1707 int MaterializeTrueId() { return materialize_true_id_; }
1708 int MaterializeFalseId() { return materialize_false_id_; }
1709
1710 protected:
1711 template<class> friend class AstNodeFactory;
1712
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001713 UnaryOperation(Isolate* isolate,
1714 Token::Value op,
1715 Expression* expression,
1716 int pos)
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001717 : Expression(isolate),
1718 op_(op),
1719 expression_(expression),
1720 pos_(pos),
1721 materialize_true_id_(AstNode::kNoNumber),
1722 materialize_false_id_(AstNode::kNoNumber) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001723 ASSERT(Token::IsUnaryOp(op));
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001724 if (op == Token::NOT) {
1725 materialize_true_id_ = GetNextId(isolate);
1726 materialize_false_id_ = GetNextId(isolate);
1727 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001728 }
1729
Steve Blocka7e24c12009-10-30 11:49:00 +00001730 private:
1731 Token::Value op_;
1732 Expression* expression_;
Ben Murdoch257744e2011-11-30 15:57:28 +00001733 int pos_;
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001734
1735 // For unary not (Token::NOT), the AST ids where true and false will
1736 // actually be materialized, respectively.
1737 int materialize_true_id_;
1738 int materialize_false_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001739};
1740
1741
1742class BinaryOperation: public Expression {
1743 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001744 DECLARE_NODE_TYPE(BinaryOperation)
Steve Blocka7e24c12009-10-30 11:49:00 +00001745
Ben Murdochf87a2032010-10-22 12:50:53 +01001746 virtual bool ResultOverwriteAllowed();
Steve Blocka7e24c12009-10-30 11:49:00 +00001747
Steve Blocka7e24c12009-10-30 11:49:00 +00001748 Token::Value op() const { return op_; }
1749 Expression* left() const { return left_; }
1750 Expression* right() const { return right_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001751 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001752
Ben Murdochb0fe1622011-05-05 13:52:32 +01001753 // Bailout support.
1754 int RightId() const { return right_id_; }
1755
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001756 protected:
1757 template<class> friend class AstNodeFactory;
1758
1759 BinaryOperation(Isolate* isolate,
1760 Token::Value op,
1761 Expression* left,
1762 Expression* right,
1763 int pos)
1764 : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) {
1765 ASSERT(Token::IsBinaryOp(op));
1766 right_id_ = (op == Token::AND || op == Token::OR)
1767 ? GetNextId(isolate)
1768 : AstNode::kNoNumber;
1769 }
1770
Steve Blocka7e24c12009-10-30 11:49:00 +00001771 private:
1772 Token::Value op_;
1773 Expression* left_;
1774 Expression* right_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001775 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001776 // The short-circuit logical operations have an AST ID for their
1777 // right-hand subexpression.
1778 int right_id_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001779};
1780
1781
Steve Blocka7e24c12009-10-30 11:49:00 +00001782class CountOperation: public Expression {
1783 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001784 DECLARE_NODE_TYPE(CountOperation)
Steve Block6ded16b2010-05-10 14:33:55 +01001785
Steve Blocka7e24c12009-10-30 11:49:00 +00001786 bool is_prefix() const { return is_prefix_; }
1787 bool is_postfix() const { return !is_prefix_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001788
Ben Murdoch8b112d22011-06-08 16:22:53 +01001789 Token::Value op() const { return op_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001790 Token::Value binary_op() {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001791 return (op() == Token::INC) ? Token::ADD : Token::SUB;
Leon Clarkee46be812010-01-19 14:06:41 +00001792 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001793
Ben Murdoch8b112d22011-06-08 16:22:53 +01001794 Expression* expression() const { return expression_; }
1795 virtual int position() const { return pos_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001796
1797 virtual void MarkAsStatement() { is_prefix_ = true; }
1798
Ben Murdoch8b112d22011-06-08 16:22:53 +01001799 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1800 virtual bool IsMonomorphic() { return is_monomorphic_; }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001801 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001802
Ben Murdochb0fe1622011-05-05 13:52:32 +01001803 // Bailout support.
1804 int AssignmentId() const { return assignment_id_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001805 int CountId() const { return count_id_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001806
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001807 protected:
1808 template<class> friend class AstNodeFactory;
1809
1810 CountOperation(Isolate* isolate,
1811 Token::Value op,
1812 bool is_prefix,
1813 Expression* expr,
1814 int pos)
1815 : Expression(isolate),
1816 op_(op),
1817 is_prefix_(is_prefix),
1818 expression_(expr),
1819 pos_(pos),
1820 assignment_id_(GetNextId(isolate)),
1821 count_id_(GetNextId(isolate)) {}
1822
Steve Blocka7e24c12009-10-30 11:49:00 +00001823 private:
Ben Murdoch8b112d22011-06-08 16:22:53 +01001824 Token::Value op_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001825 bool is_prefix_;
Ben Murdoch8b112d22011-06-08 16:22:53 +01001826 bool is_monomorphic_;
1827 Expression* expression_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001828 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001829 int assignment_id_;
Ben Murdoch8b112d22011-06-08 16:22:53 +01001830 int count_id_;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001831 SmallMapList receiver_types_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001832};
1833
1834
1835class CompareOperation: public Expression {
1836 public:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001837 DECLARE_NODE_TYPE(CompareOperation)
1838
1839 Token::Value op() const { return op_; }
1840 Expression* left() const { return left_; }
1841 Expression* right() const { return right_; }
1842 virtual int position() const { return pos_; }
1843
1844 // Type feedback information.
1845 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1846 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
1847 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1848
1849 // Match special cases.
1850 bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
1851 bool IsLiteralCompareUndefined(Expression** expr);
1852 bool IsLiteralCompareNull(Expression** expr);
1853
1854 protected:
1855 template<class> friend class AstNodeFactory;
1856
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001857 CompareOperation(Isolate* isolate,
1858 Token::Value op,
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001859 Expression* left,
1860 Expression* right,
1861 int pos)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001862 : Expression(isolate),
1863 op_(op),
1864 left_(left),
1865 right_(right),
1866 pos_(pos),
1867 compare_type_(NONE) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001868 ASSERT(Token::IsCompareOp(op));
1869 }
1870
Steve Blocka7e24c12009-10-30 11:49:00 +00001871 private:
1872 Token::Value op_;
1873 Expression* left_;
1874 Expression* right_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001875 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001876
1877 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
1878 CompareTypeFeedback compare_type_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001879};
1880
1881
Steve Blocka7e24c12009-10-30 11:49:00 +00001882class Conditional: public Expression {
1883 public:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001884 DECLARE_NODE_TYPE(Conditional)
1885
1886 Expression* condition() const { return condition_; }
1887 Expression* then_expression() const { return then_expression_; }
1888 Expression* else_expression() const { return else_expression_; }
1889
1890 int then_expression_position() const { return then_expression_position_; }
1891 int else_expression_position() const { return else_expression_position_; }
1892
1893 int ThenId() const { return then_id_; }
1894 int ElseId() const { return else_id_; }
1895
1896 protected:
1897 template<class> friend class AstNodeFactory;
1898
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001899 Conditional(Isolate* isolate,
1900 Expression* condition,
Steve Blocka7e24c12009-10-30 11:49:00 +00001901 Expression* then_expression,
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001902 Expression* else_expression,
1903 int then_expression_position,
1904 int else_expression_position)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001905 : Expression(isolate),
1906 condition_(condition),
Steve Blocka7e24c12009-10-30 11:49:00 +00001907 then_expression_(then_expression),
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001908 else_expression_(else_expression),
1909 then_expression_position_(then_expression_position),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001910 else_expression_position_(else_expression_position),
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001911 then_id_(GetNextId(isolate)),
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001912 else_id_(GetNextId(isolate)) { }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001913
Steve Blocka7e24c12009-10-30 11:49:00 +00001914 private:
1915 Expression* condition_;
1916 Expression* then_expression_;
1917 Expression* else_expression_;
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001918 int then_expression_position_;
1919 int else_expression_position_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001920 int then_id_;
1921 int else_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001922};
1923
1924
1925class Assignment: public Expression {
1926 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001927 DECLARE_NODE_TYPE(Assignment)
Steve Blocka7e24c12009-10-30 11:49:00 +00001928
Steve Block6ded16b2010-05-10 14:33:55 +01001929 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1930
Steve Blocka7e24c12009-10-30 11:49:00 +00001931 Token::Value binary_op() const;
1932
1933 Token::Value op() const { return op_; }
1934 Expression* target() const { return target_; }
1935 Expression* value() const { return value_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001936 virtual int position() const { return pos_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001937 BinaryOperation* binary_operation() const { return binary_operation_; }
1938
Leon Clarkee46be812010-01-19 14:06:41 +00001939 // This check relies on the definition order of token in token.h.
1940 bool is_compound() const { return op() > Token::ASSIGN; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001941
1942 // An initialization block is a series of statments of the form
1943 // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1944 // ending of these blocks to allow for optimizations of initialization
1945 // blocks.
1946 bool starts_initialization_block() { return block_start_; }
1947 bool ends_initialization_block() { return block_end_; }
1948 void mark_block_start() { block_start_ = true; }
1949 void mark_block_end() { block_end_ = true; }
1950
Ben Murdochb0fe1622011-05-05 13:52:32 +01001951 // Type feedback information.
1952 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1953 virtual bool IsMonomorphic() { return is_monomorphic_; }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001954 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001955
1956 // Bailout support.
1957 int CompoundLoadId() const { return compound_load_id_; }
1958 int AssignmentId() const { return assignment_id_; }
1959
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001960 protected:
1961 template<class> friend class AstNodeFactory;
1962
1963 Assignment(Isolate* isolate,
1964 Token::Value op,
1965 Expression* target,
1966 Expression* value,
1967 int pos);
1968
1969 template<class Visitor>
1970 void Init(Isolate* isolate, AstNodeFactory<Visitor>* factory) {
1971 ASSERT(Token::IsAssignmentOp(op_));
1972 if (is_compound()) {
1973 binary_operation_ =
1974 factory->NewBinaryOperation(binary_op(), target_, value_, pos_ + 1);
1975 compound_load_id_ = GetNextId(isolate);
1976 }
1977 }
1978
Steve Blocka7e24c12009-10-30 11:49:00 +00001979 private:
1980 Token::Value op_;
1981 Expression* target_;
1982 Expression* value_;
1983 int pos_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001984 BinaryOperation* binary_operation_;
1985 int compound_load_id_;
1986 int assignment_id_;
1987
Steve Blocka7e24c12009-10-30 11:49:00 +00001988 bool block_start_;
1989 bool block_end_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001990
1991 bool is_monomorphic_;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001992 SmallMapList receiver_types_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001993};
1994
1995
1996class Throw: public Expression {
1997 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001998 DECLARE_NODE_TYPE(Throw)
Steve Block6ded16b2010-05-10 14:33:55 +01001999
Steve Blocka7e24c12009-10-30 11:49:00 +00002000 Expression* exception() const { return exception_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01002001 virtual int position() const { return pos_; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002002
2003 protected:
2004 template<class> friend class AstNodeFactory;
2005
2006 Throw(Isolate* isolate, Expression* exception, int pos)
2007 : Expression(isolate), exception_(exception), pos_(pos) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00002008
2009 private:
2010 Expression* exception_;
2011 int pos_;
2012};
2013
2014
2015class FunctionLiteral: public Expression {
2016 public:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002017 enum Type {
2018 ANONYMOUS_EXPRESSION,
2019 NAMED_EXPRESSION,
2020 DECLARATION
2021 };
2022
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002023 enum ParameterFlag {
2024 kNoDuplicateParameters = 0,
2025 kHasDuplicateParameters = 1
2026 };
2027
2028 enum IsFunctionFlag {
2029 kGlobalOrEval,
2030 kIsFunction
2031 };
Steve Blocka7e24c12009-10-30 11:49:00 +00002032
Ben Murdochf87a2032010-10-22 12:50:53 +01002033 DECLARE_NODE_TYPE(FunctionLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00002034
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002035 Handle<String> name() const { return name_; }
2036 Scope* scope() const { return scope_; }
2037 ZoneList<Statement*>* body() const { return body_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002038 void set_function_token_position(int pos) { function_token_position_ = pos; }
2039 int function_token_position() const { return function_token_position_; }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002040 int start_position() const;
2041 int end_position() const;
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002042 int SourceSize() const { return end_position() - start_position(); }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002043 bool is_expression() const { return IsExpression::decode(bitfield_); }
2044 bool is_anonymous() const { return IsAnonymous::decode(bitfield_); }
2045 bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; }
2046 LanguageMode language_mode() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00002047
2048 int materialized_literal_count() { return materialized_literal_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002049 int expected_property_count() { return expected_property_count_; }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002050 int handler_count() { return handler_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002051 bool has_only_simple_this_property_assignments() {
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002052 return HasOnlySimpleThisPropertyAssignments::decode(bitfield_);
Steve Blocka7e24c12009-10-30 11:49:00 +00002053 }
2054 Handle<FixedArray> this_property_assignments() {
2055 return this_property_assignments_;
2056 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002057 int parameter_count() { return parameter_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002058
2059 bool AllowsLazyCompilation();
2060
Ben Murdochf87a2032010-10-22 12:50:53 +01002061 Handle<String> debug_name() const {
2062 if (name_->length() > 0) return name_;
2063 return inferred_name();
2064 }
2065
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002066 Handle<String> inferred_name() const { return inferred_name_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002067 void set_inferred_name(Handle<String> inferred_name) {
2068 inferred_name_ = inferred_name;
2069 }
2070
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002071 bool pretenure() { return Pretenure::decode(bitfield_); }
2072 void set_pretenure() { bitfield_ |= Pretenure::encode(true); }
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002073
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002074 bool has_duplicate_parameters() {
2075 return HasDuplicateParameters::decode(bitfield_);
2076 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002077
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002078 bool is_function() { return IsFunction::decode(bitfield_) == kIsFunction; }
2079
2080 int ast_node_count() { return ast_properties_.node_count(); }
2081 AstProperties::Flags* flags() { return ast_properties_.flags(); }
2082 void set_ast_properties(AstProperties* ast_properties) {
2083 ast_properties_ = *ast_properties;
2084 }
2085
2086 protected:
2087 template<class> friend class AstNodeFactory;
2088
2089 FunctionLiteral(Isolate* isolate,
2090 Handle<String> name,
2091 Scope* scope,
2092 ZoneList<Statement*>* body,
2093 int materialized_literal_count,
2094 int expected_property_count,
2095 int handler_count,
2096 bool has_only_simple_this_property_assignments,
2097 Handle<FixedArray> this_property_assignments,
2098 int parameter_count,
2099 Type type,
2100 ParameterFlag has_duplicate_parameters,
2101 IsFunctionFlag is_function)
2102 : Expression(isolate),
2103 name_(name),
2104 scope_(scope),
2105 body_(body),
2106 this_property_assignments_(this_property_assignments),
2107 inferred_name_(isolate->factory()->empty_string()),
2108 materialized_literal_count_(materialized_literal_count),
2109 expected_property_count_(expected_property_count),
2110 handler_count_(handler_count),
2111 parameter_count_(parameter_count),
2112 function_token_position_(RelocInfo::kNoPosition) {
2113 bitfield_ =
2114 HasOnlySimpleThisPropertyAssignments::encode(
2115 has_only_simple_this_property_assignments) |
2116 IsExpression::encode(type != DECLARATION) |
2117 IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) |
2118 Pretenure::encode(false) |
2119 HasDuplicateParameters::encode(has_duplicate_parameters) |
2120 IsFunction::encode(is_function);
2121 }
2122
Steve Blocka7e24c12009-10-30 11:49:00 +00002123 private:
2124 Handle<String> name_;
2125 Scope* scope_;
2126 ZoneList<Statement*>* body_;
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002127 Handle<FixedArray> this_property_assignments_;
2128 Handle<String> inferred_name_;
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002129 AstProperties ast_properties_;
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002130
Steve Blocka7e24c12009-10-30 11:49:00 +00002131 int materialized_literal_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002132 int expected_property_count_;
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002133 int handler_count_;
2134 int parameter_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002135 int function_token_position_;
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002136
2137 unsigned bitfield_;
2138 class HasOnlySimpleThisPropertyAssignments: public BitField<bool, 0, 1> {};
2139 class IsExpression: public BitField<bool, 1, 1> {};
2140 class IsAnonymous: public BitField<bool, 2, 1> {};
2141 class Pretenure: public BitField<bool, 3, 1> {};
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002142 class HasDuplicateParameters: public BitField<ParameterFlag, 4, 1> {};
2143 class IsFunction: public BitField<IsFunctionFlag, 5, 1> {};
Steve Blocka7e24c12009-10-30 11:49:00 +00002144};
2145
2146
Steve Block6ded16b2010-05-10 14:33:55 +01002147class SharedFunctionInfoLiteral: public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00002148 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01002149 DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
2150
Steve Block6ded16b2010-05-10 14:33:55 +01002151 Handle<SharedFunctionInfo> shared_function_info() const {
2152 return shared_function_info_;
2153 }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002154
2155 protected:
2156 template<class> friend class AstNodeFactory;
2157
2158 SharedFunctionInfoLiteral(
2159 Isolate* isolate,
2160 Handle<SharedFunctionInfo> shared_function_info)
2161 : Expression(isolate),
2162 shared_function_info_(shared_function_info) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00002163
Steve Blocka7e24c12009-10-30 11:49:00 +00002164 private:
Steve Block6ded16b2010-05-10 14:33:55 +01002165 Handle<SharedFunctionInfo> shared_function_info_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002166};
2167
2168
2169class ThisFunction: public Expression {
2170 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01002171 DECLARE_NODE_TYPE(ThisFunction)
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002172
2173 protected:
2174 template<class> friend class AstNodeFactory;
2175
2176 explicit ThisFunction(Isolate* isolate): Expression(isolate) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00002177};
2178
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002179#undef DECLARE_NODE_TYPE
2180
Steve Blocka7e24c12009-10-30 11:49:00 +00002181
2182// ----------------------------------------------------------------------------
2183// Regular expressions
2184
2185
2186class RegExpVisitor BASE_EMBEDDED {
2187 public:
2188 virtual ~RegExpVisitor() { }
2189#define MAKE_CASE(Name) \
2190 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
2191 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
2192#undef MAKE_CASE
2193};
2194
2195
2196class RegExpTree: public ZoneObject {
2197 public:
2198 static const int kInfinity = kMaxInt;
2199 virtual ~RegExpTree() { }
2200 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
2201 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2202 RegExpNode* on_success) = 0;
2203 virtual bool IsTextElement() { return false; }
Ben Murdochf87a2032010-10-22 12:50:53 +01002204 virtual bool IsAnchoredAtStart() { return false; }
2205 virtual bool IsAnchoredAtEnd() { return false; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002206 virtual int min_match() = 0;
2207 virtual int max_match() = 0;
2208 // Returns the interval of registers used for captures within this
2209 // expression.
2210 virtual Interval CaptureRegisters() { return Interval::Empty(); }
2211 virtual void AppendToText(RegExpText* text);
Ben Murdoch589d6972011-11-30 16:04:58 +00002212 SmartArrayPointer<const char> ToString();
Steve Blocka7e24c12009-10-30 11:49:00 +00002213#define MAKE_ASTYPE(Name) \
2214 virtual RegExp##Name* As##Name(); \
2215 virtual bool Is##Name();
2216 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
2217#undef MAKE_ASTYPE
2218};
2219
2220
2221class RegExpDisjunction: public RegExpTree {
2222 public:
2223 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
2224 virtual void* Accept(RegExpVisitor* visitor, void* data);
2225 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2226 RegExpNode* on_success);
2227 virtual RegExpDisjunction* AsDisjunction();
2228 virtual Interval CaptureRegisters();
2229 virtual bool IsDisjunction();
Ben Murdochf87a2032010-10-22 12:50:53 +01002230 virtual bool IsAnchoredAtStart();
2231 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00002232 virtual int min_match() { return min_match_; }
2233 virtual int max_match() { return max_match_; }
2234 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
2235 private:
2236 ZoneList<RegExpTree*>* alternatives_;
2237 int min_match_;
2238 int max_match_;
2239};
2240
2241
2242class RegExpAlternative: public RegExpTree {
2243 public:
2244 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
2245 virtual void* Accept(RegExpVisitor* visitor, void* data);
2246 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2247 RegExpNode* on_success);
2248 virtual RegExpAlternative* AsAlternative();
2249 virtual Interval CaptureRegisters();
2250 virtual bool IsAlternative();
Ben Murdochf87a2032010-10-22 12:50:53 +01002251 virtual bool IsAnchoredAtStart();
2252 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00002253 virtual int min_match() { return min_match_; }
2254 virtual int max_match() { return max_match_; }
2255 ZoneList<RegExpTree*>* nodes() { return nodes_; }
2256 private:
2257 ZoneList<RegExpTree*>* nodes_;
2258 int min_match_;
2259 int max_match_;
2260};
2261
2262
2263class RegExpAssertion: public RegExpTree {
2264 public:
2265 enum Type {
2266 START_OF_LINE,
2267 START_OF_INPUT,
2268 END_OF_LINE,
2269 END_OF_INPUT,
2270 BOUNDARY,
2271 NON_BOUNDARY
2272 };
2273 explicit RegExpAssertion(Type type) : type_(type) { }
2274 virtual void* Accept(RegExpVisitor* visitor, void* data);
2275 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2276 RegExpNode* on_success);
2277 virtual RegExpAssertion* AsAssertion();
2278 virtual bool IsAssertion();
Ben Murdochf87a2032010-10-22 12:50:53 +01002279 virtual bool IsAnchoredAtStart();
2280 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00002281 virtual int min_match() { return 0; }
2282 virtual int max_match() { return 0; }
2283 Type type() { return type_; }
2284 private:
2285 Type type_;
2286};
2287
2288
2289class CharacterSet BASE_EMBEDDED {
2290 public:
2291 explicit CharacterSet(uc16 standard_set_type)
2292 : ranges_(NULL),
2293 standard_set_type_(standard_set_type) {}
2294 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
2295 : ranges_(ranges),
2296 standard_set_type_(0) {}
2297 ZoneList<CharacterRange>* ranges();
2298 uc16 standard_set_type() { return standard_set_type_; }
2299 void set_standard_set_type(uc16 special_set_type) {
2300 standard_set_type_ = special_set_type;
2301 }
2302 bool is_standard() { return standard_set_type_ != 0; }
Leon Clarkee46be812010-01-19 14:06:41 +00002303 void Canonicalize();
Steve Blocka7e24c12009-10-30 11:49:00 +00002304 private:
2305 ZoneList<CharacterRange>* ranges_;
2306 // If non-zero, the value represents a standard set (e.g., all whitespace
2307 // characters) without having to expand the ranges.
2308 uc16 standard_set_type_;
2309};
2310
2311
2312class RegExpCharacterClass: public RegExpTree {
2313 public:
2314 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
2315 : set_(ranges),
2316 is_negated_(is_negated) { }
2317 explicit RegExpCharacterClass(uc16 type)
2318 : set_(type),
2319 is_negated_(false) { }
2320 virtual void* Accept(RegExpVisitor* visitor, void* data);
2321 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2322 RegExpNode* on_success);
2323 virtual RegExpCharacterClass* AsCharacterClass();
2324 virtual bool IsCharacterClass();
2325 virtual bool IsTextElement() { return true; }
2326 virtual int min_match() { return 1; }
2327 virtual int max_match() { return 1; }
2328 virtual void AppendToText(RegExpText* text);
2329 CharacterSet character_set() { return set_; }
2330 // TODO(lrn): Remove need for complex version if is_standard that
2331 // recognizes a mangled standard set and just do { return set_.is_special(); }
2332 bool is_standard();
2333 // Returns a value representing the standard character set if is_standard()
2334 // returns true.
2335 // Currently used values are:
2336 // s : unicode whitespace
2337 // S : unicode non-whitespace
2338 // w : ASCII word character (digit, letter, underscore)
2339 // W : non-ASCII word character
2340 // d : ASCII digit
2341 // D : non-ASCII digit
2342 // . : non-unicode non-newline
2343 // * : All characters
2344 uc16 standard_type() { return set_.standard_set_type(); }
2345 ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
2346 bool is_negated() { return is_negated_; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002347
Steve Blocka7e24c12009-10-30 11:49:00 +00002348 private:
2349 CharacterSet set_;
2350 bool is_negated_;
2351};
2352
2353
2354class RegExpAtom: public RegExpTree {
2355 public:
2356 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
2357 virtual void* Accept(RegExpVisitor* visitor, void* data);
2358 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2359 RegExpNode* on_success);
2360 virtual RegExpAtom* AsAtom();
2361 virtual bool IsAtom();
2362 virtual bool IsTextElement() { return true; }
2363 virtual int min_match() { return data_.length(); }
2364 virtual int max_match() { return data_.length(); }
2365 virtual void AppendToText(RegExpText* text);
2366 Vector<const uc16> data() { return data_; }
2367 int length() { return data_.length(); }
2368 private:
2369 Vector<const uc16> data_;
2370};
2371
2372
2373class RegExpText: public RegExpTree {
2374 public:
2375 RegExpText() : elements_(2), length_(0) {}
2376 virtual void* Accept(RegExpVisitor* visitor, void* data);
2377 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2378 RegExpNode* on_success);
2379 virtual RegExpText* AsText();
2380 virtual bool IsText();
2381 virtual bool IsTextElement() { return true; }
2382 virtual int min_match() { return length_; }
2383 virtual int max_match() { return length_; }
2384 virtual void AppendToText(RegExpText* text);
2385 void AddElement(TextElement elm) {
2386 elements_.Add(elm);
2387 length_ += elm.length();
Iain Merrick9ac36c92010-09-13 15:29:50 +01002388 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002389 ZoneList<TextElement>* elements() { return &elements_; }
2390 private:
2391 ZoneList<TextElement> elements_;
2392 int length_;
2393};
2394
2395
2396class RegExpQuantifier: public RegExpTree {
2397 public:
Leon Clarkee46be812010-01-19 14:06:41 +00002398 enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
2399 RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
2400 : body_(body),
2401 min_(min),
Steve Blocka7e24c12009-10-30 11:49:00 +00002402 max_(max),
Leon Clarkee46be812010-01-19 14:06:41 +00002403 min_match_(min * body->min_match()),
2404 type_(type) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002405 if (max > 0 && body->max_match() > kInfinity / max) {
2406 max_match_ = kInfinity;
2407 } else {
2408 max_match_ = max * body->max_match();
2409 }
2410 }
2411 virtual void* Accept(RegExpVisitor* visitor, void* data);
2412 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2413 RegExpNode* on_success);
2414 static RegExpNode* ToNode(int min,
2415 int max,
2416 bool is_greedy,
2417 RegExpTree* body,
2418 RegExpCompiler* compiler,
2419 RegExpNode* on_success,
2420 bool not_at_start = false);
2421 virtual RegExpQuantifier* AsQuantifier();
2422 virtual Interval CaptureRegisters();
2423 virtual bool IsQuantifier();
2424 virtual int min_match() { return min_match_; }
2425 virtual int max_match() { return max_match_; }
2426 int min() { return min_; }
2427 int max() { return max_; }
Leon Clarkee46be812010-01-19 14:06:41 +00002428 bool is_possessive() { return type_ == POSSESSIVE; }
2429 bool is_non_greedy() { return type_ == NON_GREEDY; }
2430 bool is_greedy() { return type_ == GREEDY; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002431 RegExpTree* body() { return body_; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002432
Steve Blocka7e24c12009-10-30 11:49:00 +00002433 private:
Leon Clarkee46be812010-01-19 14:06:41 +00002434 RegExpTree* body_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002435 int min_;
2436 int max_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002437 int min_match_;
2438 int max_match_;
Leon Clarkee46be812010-01-19 14:06:41 +00002439 Type type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002440};
2441
2442
2443class RegExpCapture: public RegExpTree {
2444 public:
2445 explicit RegExpCapture(RegExpTree* body, int index)
2446 : body_(body), index_(index) { }
2447 virtual void* Accept(RegExpVisitor* visitor, void* data);
2448 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2449 RegExpNode* on_success);
2450 static RegExpNode* ToNode(RegExpTree* body,
2451 int index,
2452 RegExpCompiler* compiler,
2453 RegExpNode* on_success);
2454 virtual RegExpCapture* AsCapture();
Ben Murdochf87a2032010-10-22 12:50:53 +01002455 virtual bool IsAnchoredAtStart();
2456 virtual bool IsAnchoredAtEnd();
Steve Blocka7e24c12009-10-30 11:49:00 +00002457 virtual Interval CaptureRegisters();
2458 virtual bool IsCapture();
2459 virtual int min_match() { return body_->min_match(); }
2460 virtual int max_match() { return body_->max_match(); }
2461 RegExpTree* body() { return body_; }
2462 int index() { return index_; }
2463 static int StartRegister(int index) { return index * 2; }
2464 static int EndRegister(int index) { return index * 2 + 1; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002465
Steve Blocka7e24c12009-10-30 11:49:00 +00002466 private:
2467 RegExpTree* body_;
2468 int index_;
2469};
2470
2471
2472class RegExpLookahead: public RegExpTree {
2473 public:
2474 RegExpLookahead(RegExpTree* body,
2475 bool is_positive,
2476 int capture_count,
2477 int capture_from)
2478 : body_(body),
2479 is_positive_(is_positive),
2480 capture_count_(capture_count),
2481 capture_from_(capture_from) { }
2482
2483 virtual void* Accept(RegExpVisitor* visitor, void* data);
2484 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2485 RegExpNode* on_success);
2486 virtual RegExpLookahead* AsLookahead();
2487 virtual Interval CaptureRegisters();
2488 virtual bool IsLookahead();
Ben Murdochf87a2032010-10-22 12:50:53 +01002489 virtual bool IsAnchoredAtStart();
Steve Blocka7e24c12009-10-30 11:49:00 +00002490 virtual int min_match() { return 0; }
2491 virtual int max_match() { return 0; }
2492 RegExpTree* body() { return body_; }
2493 bool is_positive() { return is_positive_; }
2494 int capture_count() { return capture_count_; }
2495 int capture_from() { return capture_from_; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002496
Steve Blocka7e24c12009-10-30 11:49:00 +00002497 private:
2498 RegExpTree* body_;
2499 bool is_positive_;
2500 int capture_count_;
2501 int capture_from_;
2502};
2503
2504
2505class RegExpBackReference: public RegExpTree {
2506 public:
2507 explicit RegExpBackReference(RegExpCapture* capture)
2508 : capture_(capture) { }
2509 virtual void* Accept(RegExpVisitor* visitor, void* data);
2510 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2511 RegExpNode* on_success);
2512 virtual RegExpBackReference* AsBackReference();
2513 virtual bool IsBackReference();
2514 virtual int min_match() { return 0; }
2515 virtual int max_match() { return capture_->max_match(); }
2516 int index() { return capture_->index(); }
2517 RegExpCapture* capture() { return capture_; }
2518 private:
2519 RegExpCapture* capture_;
2520};
2521
2522
2523class RegExpEmpty: public RegExpTree {
2524 public:
2525 RegExpEmpty() { }
2526 virtual void* Accept(RegExpVisitor* visitor, void* data);
2527 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2528 RegExpNode* on_success);
2529 virtual RegExpEmpty* AsEmpty();
2530 virtual bool IsEmpty();
2531 virtual int min_match() { return 0; }
2532 virtual int max_match() { return 0; }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002533 static RegExpEmpty* GetInstance() {
2534 static RegExpEmpty* instance = ::new RegExpEmpty();
2535 return instance;
2536 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002537};
2538
2539
2540// ----------------------------------------------------------------------------
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002541// Out-of-line inline constructors (to side-step cyclic dependencies).
2542
2543inline ModuleVariable::ModuleVariable(VariableProxy* proxy)
2544 : Module(proxy->interface()),
2545 proxy_(proxy) {
2546}
2547
2548
2549// ----------------------------------------------------------------------------
Steve Blocka7e24c12009-10-30 11:49:00 +00002550// Basic visitor
2551// - leaf node visitors are abstract.
2552
2553class AstVisitor BASE_EMBEDDED {
2554 public:
Steve Block44f0eee2011-05-26 01:26:41 +01002555 AstVisitor() : isolate_(Isolate::Current()), stack_overflow_(false) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00002556 virtual ~AstVisitor() { }
2557
Steve Block6ded16b2010-05-10 14:33:55 +01002558 // Stack overflow check and dynamic dispatch.
2559 void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
Steve Blocka7e24c12009-10-30 11:49:00 +00002560
Steve Block6ded16b2010-05-10 14:33:55 +01002561 // Iteration left-to-right.
Steve Block3ce2e202009-11-05 08:53:23 +00002562 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
Steve Blocka7e24c12009-10-30 11:49:00 +00002563 virtual void VisitStatements(ZoneList<Statement*>* statements);
2564 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
2565
2566 // Stack overflow tracking support.
2567 bool HasStackOverflow() const { return stack_overflow_; }
Steve Block6ded16b2010-05-10 14:33:55 +01002568 bool CheckStackOverflow();
Steve Blocka7e24c12009-10-30 11:49:00 +00002569
2570 // If a stack-overflow exception is encountered when visiting a
2571 // node, calling SetStackOverflow will make sure that the visitor
2572 // bails out without visiting more nodes.
2573 void SetStackOverflow() { stack_overflow_ = true; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01002574 void ClearStackOverflow() { stack_overflow_ = false; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002575
Ben Murdochb0fe1622011-05-05 13:52:32 +01002576 // Individual AST nodes.
Steve Blocka7e24c12009-10-30 11:49:00 +00002577#define DEF_VISIT(type) \
2578 virtual void Visit##type(type* node) = 0;
2579 AST_NODE_LIST(DEF_VISIT)
2580#undef DEF_VISIT
2581
Steve Block44f0eee2011-05-26 01:26:41 +01002582 protected:
2583 Isolate* isolate() { return isolate_; }
2584
Steve Blocka7e24c12009-10-30 11:49:00 +00002585 private:
Steve Block44f0eee2011-05-26 01:26:41 +01002586 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002587 bool stack_overflow_;
2588};
2589
Steve Block44f0eee2011-05-26 01:26:41 +01002590
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002591// ----------------------------------------------------------------------------
2592// Construction time visitor.
2593
2594class AstConstructionVisitor BASE_EMBEDDED {
2595 public:
2596 AstConstructionVisitor() { }
2597
2598 AstProperties* ast_properties() { return &properties_; }
2599
2600 private:
2601 template<class> friend class AstNodeFactory;
2602
2603 // Node visitors.
2604#define DEF_VISIT(type) \
2605 void Visit##type(type* node);
2606 AST_NODE_LIST(DEF_VISIT)
2607#undef DEF_VISIT
2608
2609 void increase_node_count() { properties_.add_node_count(1); }
2610 void add_flag(AstPropertiesFlag flag) { properties_.flags()->Add(flag); }
2611
2612 AstProperties properties_;
2613};
2614
2615
2616class AstNullVisitor BASE_EMBEDDED {
2617 public:
2618 // Node visitors.
2619#define DEF_VISIT(type) \
2620 void Visit##type(type* node) {}
2621 AST_NODE_LIST(DEF_VISIT)
2622#undef DEF_VISIT
2623};
2624
2625
2626
2627// ----------------------------------------------------------------------------
2628// AstNode factory
2629
2630template<class Visitor>
2631class AstNodeFactory BASE_EMBEDDED {
2632 public:
2633 explicit AstNodeFactory(Isolate* isolate)
2634 : isolate_(isolate),
2635 zone_(isolate_->zone()) { }
2636
2637 Visitor* visitor() { return &visitor_; }
2638
2639#define VISIT_AND_RETURN(NodeType, node) \
2640 visitor_.Visit##NodeType((node)); \
2641 return node;
2642
2643 VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
2644 VariableMode mode,
2645 Scope* scope) {
2646 VariableDeclaration* decl =
2647 new(zone_) VariableDeclaration(proxy, mode, scope);
2648 VISIT_AND_RETURN(VariableDeclaration, decl)
2649 }
2650
2651 FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy,
2652 VariableMode mode,
2653 FunctionLiteral* fun,
2654 Scope* scope) {
2655 FunctionDeclaration* decl =
2656 new(zone_) FunctionDeclaration(proxy, mode, fun, scope);
2657 VISIT_AND_RETURN(FunctionDeclaration, decl)
2658 }
2659
2660 ModuleDeclaration* NewModuleDeclaration(VariableProxy* proxy,
2661 Module* module,
2662 Scope* scope) {
2663 ModuleDeclaration* decl =
2664 new(zone_) ModuleDeclaration(proxy, module, scope);
2665 VISIT_AND_RETURN(ModuleDeclaration, decl)
2666 }
2667
2668 ImportDeclaration* NewImportDeclaration(VariableProxy* proxy,
2669 Module* module,
2670 Scope* scope) {
2671 ImportDeclaration* decl =
2672 new(zone_) ImportDeclaration(proxy, module, scope);
2673 VISIT_AND_RETURN(ImportDeclaration, decl)
2674 }
2675
2676 ExportDeclaration* NewExportDeclaration(VariableProxy* proxy,
2677 Scope* scope) {
2678 ExportDeclaration* decl =
2679 new(zone_) ExportDeclaration(proxy, scope);
2680 VISIT_AND_RETURN(ExportDeclaration, decl)
2681 }
2682
2683 ModuleLiteral* NewModuleLiteral(Block* body, Interface* interface) {
2684 ModuleLiteral* module = new(zone_) ModuleLiteral(body, interface);
2685 VISIT_AND_RETURN(ModuleLiteral, module)
2686 }
2687
2688 ModuleVariable* NewModuleVariable(VariableProxy* proxy) {
2689 ModuleVariable* module = new(zone_) ModuleVariable(proxy);
2690 VISIT_AND_RETURN(ModuleVariable, module)
2691 }
2692
2693 ModulePath* NewModulePath(Module* origin, Handle<String> name) {
2694 ModulePath* module = new(zone_) ModulePath(origin, name);
2695 VISIT_AND_RETURN(ModulePath, module)
2696 }
2697
2698 ModuleUrl* NewModuleUrl(Handle<String> url) {
2699 ModuleUrl* module = new(zone_) ModuleUrl(url);
2700 VISIT_AND_RETURN(ModuleUrl, module)
2701 }
2702
2703 Block* NewBlock(ZoneStringList* labels,
2704 int capacity,
2705 bool is_initializer_block) {
2706 Block* block = new(zone_) Block(
2707 isolate_, labels, capacity, is_initializer_block);
2708 VISIT_AND_RETURN(Block, block)
2709 }
2710
2711#define STATEMENT_WITH_LABELS(NodeType) \
2712 NodeType* New##NodeType(ZoneStringList* labels) { \
2713 NodeType* stmt = new(zone_) NodeType(isolate_, labels); \
2714 VISIT_AND_RETURN(NodeType, stmt); \
2715 }
2716 STATEMENT_WITH_LABELS(DoWhileStatement)
2717 STATEMENT_WITH_LABELS(WhileStatement)
2718 STATEMENT_WITH_LABELS(ForStatement)
2719 STATEMENT_WITH_LABELS(ForInStatement)
2720 STATEMENT_WITH_LABELS(SwitchStatement)
2721#undef STATEMENT_WITH_LABELS
2722
2723 ExpressionStatement* NewExpressionStatement(Expression* expression) {
2724 ExpressionStatement* stmt = new(zone_) ExpressionStatement(expression);
2725 VISIT_AND_RETURN(ExpressionStatement, stmt)
2726 }
2727
2728 ContinueStatement* NewContinueStatement(IterationStatement* target) {
2729 ContinueStatement* stmt = new(zone_) ContinueStatement(target);
2730 VISIT_AND_RETURN(ContinueStatement, stmt)
2731 }
2732
2733 BreakStatement* NewBreakStatement(BreakableStatement* target) {
2734 BreakStatement* stmt = new(zone_) BreakStatement(target);
2735 VISIT_AND_RETURN(BreakStatement, stmt)
2736 }
2737
2738 ReturnStatement* NewReturnStatement(Expression* expression) {
2739 ReturnStatement* stmt = new(zone_) ReturnStatement(expression);
2740 VISIT_AND_RETURN(ReturnStatement, stmt)
2741 }
2742
2743 WithStatement* NewWithStatement(Expression* expression,
2744 Statement* statement) {
2745 WithStatement* stmt = new(zone_) WithStatement(expression, statement);
2746 VISIT_AND_RETURN(WithStatement, stmt)
2747 }
2748
2749 IfStatement* NewIfStatement(Expression* condition,
2750 Statement* then_statement,
2751 Statement* else_statement) {
2752 IfStatement* stmt = new(zone_) IfStatement(
2753 isolate_, condition, then_statement, else_statement);
2754 VISIT_AND_RETURN(IfStatement, stmt)
2755 }
2756
2757 TryCatchStatement* NewTryCatchStatement(int index,
2758 Block* try_block,
2759 Scope* scope,
2760 Variable* variable,
2761 Block* catch_block) {
2762 TryCatchStatement* stmt = new(zone_) TryCatchStatement(
2763 index, try_block, scope, variable, catch_block);
2764 VISIT_AND_RETURN(TryCatchStatement, stmt)
2765 }
2766
2767 TryFinallyStatement* NewTryFinallyStatement(int index,
2768 Block* try_block,
2769 Block* finally_block) {
2770 TryFinallyStatement* stmt =
2771 new(zone_) TryFinallyStatement(index, try_block, finally_block);
2772 VISIT_AND_RETURN(TryFinallyStatement, stmt)
2773 }
2774
2775 DebuggerStatement* NewDebuggerStatement() {
2776 DebuggerStatement* stmt = new(zone_) DebuggerStatement();
2777 VISIT_AND_RETURN(DebuggerStatement, stmt)
2778 }
2779
2780 EmptyStatement* NewEmptyStatement() {
2781 return new(zone_) EmptyStatement();
2782 }
2783
2784 Literal* NewLiteral(Handle<Object> handle) {
2785 Literal* lit = new(zone_) Literal(isolate_, handle);
2786 VISIT_AND_RETURN(Literal, lit)
2787 }
2788
2789 Literal* NewNumberLiteral(double number) {
2790 return NewLiteral(isolate_->factory()->NewNumber(number, TENURED));
2791 }
2792
2793 ObjectLiteral* NewObjectLiteral(
2794 Handle<FixedArray> constant_properties,
2795 ZoneList<ObjectLiteral::Property*>* properties,
2796 int literal_index,
2797 bool is_simple,
2798 bool fast_elements,
2799 int depth,
2800 bool has_function) {
2801 ObjectLiteral* lit = new(zone_) ObjectLiteral(
2802 isolate_, constant_properties, properties, literal_index,
2803 is_simple, fast_elements, depth, has_function);
2804 VISIT_AND_RETURN(ObjectLiteral, lit)
2805 }
2806
2807 ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter,
2808 FunctionLiteral* value) {
2809 ObjectLiteral::Property* prop =
2810 new(zone_) ObjectLiteral::Property(is_getter, value);
2811 prop->set_key(NewLiteral(value->name()));
2812 return prop; // Not an AST node, will not be visited.
2813 }
2814
2815 RegExpLiteral* NewRegExpLiteral(Handle<String> pattern,
2816 Handle<String> flags,
2817 int literal_index) {
2818 RegExpLiteral* lit =
2819 new(zone_) RegExpLiteral(isolate_, pattern, flags, literal_index);
2820 VISIT_AND_RETURN(RegExpLiteral, lit);
2821 }
2822
2823 ArrayLiteral* NewArrayLiteral(Handle<FixedArray> constant_elements,
2824 ZoneList<Expression*>* values,
2825 int literal_index,
2826 bool is_simple,
2827 int depth) {
2828 ArrayLiteral* lit = new(zone_) ArrayLiteral(
2829 isolate_, constant_elements, values, literal_index, is_simple, depth);
2830 VISIT_AND_RETURN(ArrayLiteral, lit)
2831 }
2832
2833 VariableProxy* NewVariableProxy(Variable* var) {
2834 VariableProxy* proxy = new(zone_) VariableProxy(isolate_, var);
2835 VISIT_AND_RETURN(VariableProxy, proxy)
2836 }
2837
2838 VariableProxy* NewVariableProxy(Handle<String> name,
2839 bool is_this,
2840 int position = RelocInfo::kNoPosition,
2841 Interface* interface =
2842 Interface::NewValue()) {
2843 VariableProxy* proxy =
2844 new(zone_) VariableProxy(isolate_, name, is_this, position, interface);
2845 VISIT_AND_RETURN(VariableProxy, proxy)
2846 }
2847
2848 Property* NewProperty(Expression* obj, Expression* key, int pos) {
2849 Property* prop = new(zone_) Property(isolate_, obj, key, pos);
2850 VISIT_AND_RETURN(Property, prop)
2851 }
2852
2853 Call* NewCall(Expression* expression,
2854 ZoneList<Expression*>* arguments,
2855 int pos) {
2856 Call* call = new(zone_) Call(isolate_, expression, arguments, pos);
2857 VISIT_AND_RETURN(Call, call)
2858 }
2859
2860 CallNew* NewCallNew(Expression* expression,
2861 ZoneList<Expression*>* arguments,
2862 int pos) {
2863 CallNew* call = new(zone_) CallNew(isolate_, expression, arguments, pos);
2864 VISIT_AND_RETURN(CallNew, call)
2865 }
2866
2867 CallRuntime* NewCallRuntime(Handle<String> name,
2868 const Runtime::Function* function,
2869 ZoneList<Expression*>* arguments) {
2870 CallRuntime* call =
2871 new(zone_) CallRuntime(isolate_, name, function, arguments);
2872 VISIT_AND_RETURN(CallRuntime, call)
2873 }
2874
2875 UnaryOperation* NewUnaryOperation(Token::Value op,
2876 Expression* expression,
2877 int pos) {
2878 UnaryOperation* node =
2879 new(zone_) UnaryOperation(isolate_, op, expression, pos);
2880 VISIT_AND_RETURN(UnaryOperation, node)
2881 }
2882
2883 BinaryOperation* NewBinaryOperation(Token::Value op,
2884 Expression* left,
2885 Expression* right,
2886 int pos) {
2887 BinaryOperation* node =
2888 new(zone_) BinaryOperation(isolate_, op, left, right, pos);
2889 VISIT_AND_RETURN(BinaryOperation, node)
2890 }
2891
2892 CountOperation* NewCountOperation(Token::Value op,
2893 bool is_prefix,
2894 Expression* expr,
2895 int pos) {
2896 CountOperation* node =
2897 new(zone_) CountOperation(isolate_, op, is_prefix, expr, pos);
2898 VISIT_AND_RETURN(CountOperation, node)
2899 }
2900
2901 CompareOperation* NewCompareOperation(Token::Value op,
2902 Expression* left,
2903 Expression* right,
2904 int pos) {
2905 CompareOperation* node =
2906 new(zone_) CompareOperation(isolate_, op, left, right, pos);
2907 VISIT_AND_RETURN(CompareOperation, node)
2908 }
2909
2910 Conditional* NewConditional(Expression* condition,
2911 Expression* then_expression,
2912 Expression* else_expression,
2913 int then_expression_position,
2914 int else_expression_position) {
2915 Conditional* cond = new(zone_) Conditional(
2916 isolate_, condition, then_expression, else_expression,
2917 then_expression_position, else_expression_position);
2918 VISIT_AND_RETURN(Conditional, cond)
2919 }
2920
2921 Assignment* NewAssignment(Token::Value op,
2922 Expression* target,
2923 Expression* value,
2924 int pos) {
2925 Assignment* assign =
2926 new(zone_) Assignment(isolate_, op, target, value, pos);
2927 assign->Init(isolate_, this);
2928 VISIT_AND_RETURN(Assignment, assign)
2929 }
2930
2931 Throw* NewThrow(Expression* exception, int pos) {
2932 Throw* t = new(zone_) Throw(isolate_, exception, pos);
2933 VISIT_AND_RETURN(Throw, t)
2934 }
2935
2936 FunctionLiteral* NewFunctionLiteral(
2937 Handle<String> name,
2938 Scope* scope,
2939 ZoneList<Statement*>* body,
2940 int materialized_literal_count,
2941 int expected_property_count,
2942 int handler_count,
2943 bool has_only_simple_this_property_assignments,
2944 Handle<FixedArray> this_property_assignments,
2945 int parameter_count,
2946 FunctionLiteral::ParameterFlag has_duplicate_parameters,
2947 FunctionLiteral::Type type,
2948 FunctionLiteral::IsFunctionFlag is_function) {
2949 FunctionLiteral* lit = new(zone_) FunctionLiteral(
2950 isolate_, name, scope, body,
2951 materialized_literal_count, expected_property_count, handler_count,
2952 has_only_simple_this_property_assignments, this_property_assignments,
2953 parameter_count, type, has_duplicate_parameters, is_function);
2954 // Top-level literal doesn't count for the AST's properties.
2955 if (is_function == FunctionLiteral::kIsFunction) {
2956 visitor_.VisitFunctionLiteral(lit);
2957 }
2958 return lit;
2959 }
2960
2961 SharedFunctionInfoLiteral* NewSharedFunctionInfoLiteral(
2962 Handle<SharedFunctionInfo> shared_function_info) {
2963 SharedFunctionInfoLiteral* lit =
2964 new(zone_) SharedFunctionInfoLiteral(isolate_, shared_function_info);
2965 VISIT_AND_RETURN(SharedFunctionInfoLiteral, lit)
2966 }
2967
2968 ThisFunction* NewThisFunction() {
2969 ThisFunction* fun = new(zone_) ThisFunction(isolate_);
2970 VISIT_AND_RETURN(ThisFunction, fun)
2971 }
2972
2973#undef VISIT_AND_RETURN
2974
2975 private:
2976 Isolate* isolate_;
2977 Zone* zone_;
2978 Visitor visitor_;
2979};
2980
2981
Steve Blocka7e24c12009-10-30 11:49:00 +00002982} } // namespace v8::internal
2983
2984#endif // V8_AST_H_