blob: 48d0bfac066857f92b2f386903a157575f09fd82 [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_AST_H_
29#define V8_AST_H_
30
31#include "execution.h"
32#include "factory.h"
Steve Block3ce2e202009-11-05 08:53:23 +000033#include "jsregexp.h"
34#include "jump-target.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000035#include "runtime.h"
36#include "token.h"
37#include "variables.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000038
39namespace v8 {
40namespace internal {
41
42// The abstract syntax tree is an intermediate, light-weight
43// representation of the parsed JavaScript code suitable for
44// compilation to native code.
45
46// Nodes are allocated in a separate zone, which allows faster
47// allocation and constant-time deallocation of the entire syntax
48// tree.
49
50
51// ----------------------------------------------------------------------------
52// Nodes of the abstract syntax tree. Only concrete classes are
53// enumerated here.
54
55#define STATEMENT_NODE_LIST(V) \
56 V(Block) \
57 V(ExpressionStatement) \
58 V(EmptyStatement) \
59 V(IfStatement) \
60 V(ContinueStatement) \
61 V(BreakStatement) \
62 V(ReturnStatement) \
63 V(WithEnterStatement) \
64 V(WithExitStatement) \
65 V(SwitchStatement) \
Steve Block3ce2e202009-11-05 08:53:23 +000066 V(DoWhileStatement) \
67 V(WhileStatement) \
68 V(ForStatement) \
Steve Blocka7e24c12009-10-30 11:49:00 +000069 V(ForInStatement) \
Steve Block3ce2e202009-11-05 08:53:23 +000070 V(TryCatchStatement) \
71 V(TryFinallyStatement) \
Steve Blocka7e24c12009-10-30 11:49:00 +000072 V(DebuggerStatement)
73
74#define EXPRESSION_NODE_LIST(V) \
75 V(FunctionLiteral) \
76 V(FunctionBoilerplateLiteral) \
77 V(Conditional) \
78 V(Slot) \
79 V(VariableProxy) \
80 V(Literal) \
81 V(RegExpLiteral) \
82 V(ObjectLiteral) \
83 V(ArrayLiteral) \
84 V(CatchExtensionObject) \
85 V(Assignment) \
86 V(Throw) \
87 V(Property) \
88 V(Call) \
89 V(CallNew) \
90 V(CallRuntime) \
91 V(UnaryOperation) \
92 V(CountOperation) \
93 V(BinaryOperation) \
94 V(CompareOperation) \
95 V(ThisFunction)
96
97#define AST_NODE_LIST(V) \
98 V(Declaration) \
99 STATEMENT_NODE_LIST(V) \
100 EXPRESSION_NODE_LIST(V)
101
102// Forward declarations
103class TargetCollector;
104class MaterializedLiteral;
105
106#define DEF_FORWARD_DECLARATION(type) class type;
107AST_NODE_LIST(DEF_FORWARD_DECLARATION)
108#undef DEF_FORWARD_DECLARATION
109
110
111// Typedef only introduced to avoid unreadable code.
112// Please do appreciate the required space in "> >".
113typedef ZoneList<Handle<String> > ZoneStringList;
114typedef ZoneList<Handle<Object> > ZoneObjectList;
115
116
117class AstNode: public ZoneObject {
118 public:
119 virtual ~AstNode() { }
120 virtual void Accept(AstVisitor* v) = 0;
121
122 // Type testing & conversion.
123 virtual Statement* AsStatement() { return NULL; }
124 virtual ExpressionStatement* AsExpressionStatement() { return NULL; }
125 virtual EmptyStatement* AsEmptyStatement() { return NULL; }
126 virtual Expression* AsExpression() { return NULL; }
127 virtual Literal* AsLiteral() { return NULL; }
128 virtual Slot* AsSlot() { return NULL; }
129 virtual VariableProxy* AsVariableProxy() { return NULL; }
130 virtual Property* AsProperty() { return NULL; }
131 virtual Call* AsCall() { return NULL; }
132 virtual TargetCollector* AsTargetCollector() { return NULL; }
133 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
134 virtual IterationStatement* AsIterationStatement() { return NULL; }
135 virtual UnaryOperation* AsUnaryOperation() { return NULL; }
136 virtual BinaryOperation* AsBinaryOperation() { return NULL; }
137 virtual Assignment* AsAssignment() { return NULL; }
138 virtual FunctionLiteral* AsFunctionLiteral() { return NULL; }
139 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
140 virtual ObjectLiteral* AsObjectLiteral() { return NULL; }
141 virtual ArrayLiteral* AsArrayLiteral() { return NULL; }
Leon Clarkee46be812010-01-19 14:06:41 +0000142 virtual CompareOperation* AsCompareOperation() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000143};
144
145
146class Statement: public AstNode {
147 public:
148 Statement() : statement_pos_(RelocInfo::kNoPosition) {}
149
150 virtual Statement* AsStatement() { return this; }
151 virtual ReturnStatement* AsReturnStatement() { return NULL; }
152
153 bool IsEmpty() { return AsEmptyStatement() != NULL; }
154
155 void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
156 int statement_pos() const { return statement_pos_; }
157
158 private:
159 int statement_pos_;
160};
161
162
163class Expression: public AstNode {
164 public:
Steve Blockd0582a62009-12-15 09:54:21 +0000165 enum Context {
166 // Not assigned a context yet, or else will not be visited during
167 // code generation.
168 kUninitialized,
169 // Evaluated for its side effects.
170 kEffect,
171 // Evaluated for its value (and side effects).
172 kValue,
173 // Evaluated for control flow (and side effects).
174 kTest,
175 // Evaluated for control flow and side effects. Value is also
176 // needed if true.
177 kValueTest,
178 // Evaluated for control flow and side effects. Value is also
179 // needed if false.
180 kTestValue
181 };
182
Leon Clarke4515c472010-02-03 11:58:03 +0000183 static const int kNoLabel = -1;
184
185 Expression() : num_(kNoLabel) {}
186
Steve Blocka7e24c12009-10-30 11:49:00 +0000187 virtual Expression* AsExpression() { return this; }
188
Steve Blocka7e24c12009-10-30 11:49:00 +0000189 virtual bool IsValidLeftHandSide() { return false; }
190
Leon Clarkee46be812010-01-19 14:06:41 +0000191 // Symbols that cannot be parsed as array indices are considered property
192 // names. We do not treat symbols that can be array indexes as property
193 // names because [] for string objects is handled only by keyed ICs.
194 virtual bool IsPropertyName() { return false; }
195
Steve Blocka7e24c12009-10-30 11:49:00 +0000196 // Mark the expression as being compiled as an expression
197 // statement. This is used to transform postfix increments to
198 // (faster) prefix increments.
199 virtual void MarkAsStatement() { /* do nothing */ }
200
201 // Static type information for this expression.
Leon Clarkee46be812010-01-19 14:06:41 +0000202 StaticType* type() { return &type_; }
Steve Block3ce2e202009-11-05 08:53:23 +0000203
Leon Clarke4515c472010-02-03 11:58:03 +0000204 int num() { return num_; }
205
206 // AST node numbering ordered by evaluation order.
207 void set_num(int n) { num_ = n; }
208
Steve Blocka7e24c12009-10-30 11:49:00 +0000209 private:
Leon Clarkee46be812010-01-19 14:06:41 +0000210 StaticType type_;
Leon Clarke4515c472010-02-03 11:58:03 +0000211 int num_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000212};
213
214
215/**
216 * A sentinel used during pre parsing that represents some expression
217 * that is a valid left hand side without having to actually build
218 * the expression.
219 */
220class ValidLeftHandSideSentinel: public Expression {
221 public:
222 virtual bool IsValidLeftHandSide() { return true; }
223 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
224 static ValidLeftHandSideSentinel* instance() { return &instance_; }
225 private:
226 static ValidLeftHandSideSentinel instance_;
227};
228
229
230class BreakableStatement: public Statement {
231 public:
232 enum Type {
233 TARGET_FOR_ANONYMOUS,
234 TARGET_FOR_NAMED_ONLY
235 };
236
237 // The labels associated with this statement. May be NULL;
238 // if it is != NULL, guaranteed to contain at least one entry.
239 ZoneStringList* labels() const { return labels_; }
240
241 // Type testing & conversion.
242 virtual BreakableStatement* AsBreakableStatement() { return this; }
243
244 // Code generation
245 BreakTarget* break_target() { return &break_target_; }
246
247 // Testers.
248 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
249
250 protected:
251 BreakableStatement(ZoneStringList* labels, Type type)
252 : labels_(labels), type_(type) {
253 ASSERT(labels == NULL || labels->length() > 0);
254 }
255
256 private:
257 ZoneStringList* labels_;
258 Type type_;
259 BreakTarget break_target_;
260};
261
262
263class Block: public BreakableStatement {
264 public:
265 Block(ZoneStringList* labels, int capacity, bool is_initializer_block)
266 : BreakableStatement(labels, TARGET_FOR_NAMED_ONLY),
267 statements_(capacity),
268 is_initializer_block_(is_initializer_block) { }
269
270 virtual void Accept(AstVisitor* v);
271
272 void AddStatement(Statement* statement) { statements_.Add(statement); }
273
274 ZoneList<Statement*>* statements() { return &statements_; }
275 bool is_initializer_block() const { return is_initializer_block_; }
276
277 private:
278 ZoneList<Statement*> statements_;
279 bool is_initializer_block_;
280};
281
282
283class Declaration: public AstNode {
284 public:
285 Declaration(VariableProxy* proxy, Variable::Mode mode, FunctionLiteral* fun)
286 : proxy_(proxy),
287 mode_(mode),
288 fun_(fun) {
289 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
290 // At the moment there are no "const functions"'s in JavaScript...
291 ASSERT(fun == NULL || mode == Variable::VAR);
292 }
293
294 virtual void Accept(AstVisitor* v);
295
296 VariableProxy* proxy() const { return proxy_; }
297 Variable::Mode mode() const { return mode_; }
298 FunctionLiteral* fun() const { return fun_; } // may be NULL
299
300 private:
301 VariableProxy* proxy_;
302 Variable::Mode mode_;
303 FunctionLiteral* fun_;
304};
305
306
307class IterationStatement: public BreakableStatement {
308 public:
309 // Type testing & conversion.
310 virtual IterationStatement* AsIterationStatement() { return this; }
311
312 Statement* body() const { return body_; }
313
314 // Code generation
315 BreakTarget* continue_target() { return &continue_target_; }
316
317 protected:
318 explicit IterationStatement(ZoneStringList* labels)
319 : BreakableStatement(labels, TARGET_FOR_ANONYMOUS), body_(NULL) { }
320
321 void Initialize(Statement* body) {
322 body_ = body;
323 }
324
325 private:
326 Statement* body_;
327 BreakTarget continue_target_;
328};
329
330
Steve Block3ce2e202009-11-05 08:53:23 +0000331class DoWhileStatement: public IterationStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000332 public:
Steve Block3ce2e202009-11-05 08:53:23 +0000333 explicit DoWhileStatement(ZoneStringList* labels)
Steve Blockd0582a62009-12-15 09:54:21 +0000334 : IterationStatement(labels), cond_(NULL), condition_position_(-1) {
Steve Block3ce2e202009-11-05 08:53:23 +0000335 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000336
Steve Block3ce2e202009-11-05 08:53:23 +0000337 void Initialize(Expression* cond, Statement* body) {
338 IterationStatement::Initialize(body);
339 cond_ = cond;
340 }
341
342 virtual void Accept(AstVisitor* v);
343
344 Expression* cond() const { return cond_; }
345
Steve Blockd0582a62009-12-15 09:54:21 +0000346 // Position where condition expression starts. We need it to make
347 // the loop's condition a breakable location.
348 int condition_position() { return condition_position_; }
349 void set_condition_position(int pos) { condition_position_ = pos; }
350
Steve Block3ce2e202009-11-05 08:53:23 +0000351 private:
352 Expression* cond_;
Steve Blockd0582a62009-12-15 09:54:21 +0000353 int condition_position_;
Steve Block3ce2e202009-11-05 08:53:23 +0000354};
355
356
357class WhileStatement: public IterationStatement {
358 public:
359 explicit WhileStatement(ZoneStringList* labels)
Steve Blocka7e24c12009-10-30 11:49:00 +0000360 : IterationStatement(labels),
Steve Block3ce2e202009-11-05 08:53:23 +0000361 cond_(NULL),
362 may_have_function_literal_(true) {
363 }
364
365 void Initialize(Expression* cond, Statement* body) {
366 IterationStatement::Initialize(body);
367 cond_ = cond;
368 }
369
370 virtual void Accept(AstVisitor* v);
371
372 Expression* cond() const { return cond_; }
373 bool may_have_function_literal() const {
374 return may_have_function_literal_;
375 }
376
377 private:
378 Expression* cond_;
379 // True if there is a function literal subexpression in the condition.
380 bool may_have_function_literal_;
381
382 friend class AstOptimizer;
383};
384
385
386class ForStatement: public IterationStatement {
387 public:
388 explicit ForStatement(ZoneStringList* labels)
389 : IterationStatement(labels),
Steve Blocka7e24c12009-10-30 11:49:00 +0000390 init_(NULL),
391 cond_(NULL),
392 next_(NULL),
393 may_have_function_literal_(true) {
394 }
395
396 void Initialize(Statement* init,
397 Expression* cond,
398 Statement* next,
399 Statement* body) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000400 IterationStatement::Initialize(body);
401 init_ = init;
402 cond_ = cond;
403 next_ = next;
404 }
405
406 virtual void Accept(AstVisitor* v);
407
Steve Blocka7e24c12009-10-30 11:49:00 +0000408 Statement* init() const { return init_; }
409 Expression* cond() const { return cond_; }
410 Statement* next() const { return next_; }
411 bool may_have_function_literal() const {
412 return may_have_function_literal_;
413 }
414
Steve Blocka7e24c12009-10-30 11:49:00 +0000415 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000416 Statement* init_;
417 Expression* cond_;
418 Statement* next_;
419 // True if there is a function literal subexpression in the condition.
420 bool may_have_function_literal_;
421
422 friend class AstOptimizer;
423};
424
425
426class ForInStatement: public IterationStatement {
427 public:
428 explicit ForInStatement(ZoneStringList* labels)
429 : IterationStatement(labels), each_(NULL), enumerable_(NULL) { }
430
431 void Initialize(Expression* each, Expression* enumerable, Statement* body) {
432 IterationStatement::Initialize(body);
433 each_ = each;
434 enumerable_ = enumerable;
435 }
436
437 virtual void Accept(AstVisitor* v);
438
439 Expression* each() const { return each_; }
440 Expression* enumerable() const { return enumerable_; }
441
442 private:
443 Expression* each_;
444 Expression* enumerable_;
445};
446
447
448class ExpressionStatement: public Statement {
449 public:
450 explicit ExpressionStatement(Expression* expression)
451 : expression_(expression) { }
452
453 virtual void Accept(AstVisitor* v);
454
455 // Type testing & conversion.
456 virtual ExpressionStatement* AsExpressionStatement() { return this; }
457
458 void set_expression(Expression* e) { expression_ = e; }
459 Expression* expression() { return expression_; }
460
461 private:
462 Expression* expression_;
463};
464
465
466class ContinueStatement: public Statement {
467 public:
468 explicit ContinueStatement(IterationStatement* target)
469 : target_(target) { }
470
471 virtual void Accept(AstVisitor* v);
472
473 IterationStatement* target() const { return target_; }
474
475 private:
476 IterationStatement* target_;
477};
478
479
480class BreakStatement: public Statement {
481 public:
482 explicit BreakStatement(BreakableStatement* target)
483 : target_(target) { }
484
485 virtual void Accept(AstVisitor* v);
486
487 BreakableStatement* target() const { return target_; }
488
489 private:
490 BreakableStatement* target_;
491};
492
493
494class ReturnStatement: public Statement {
495 public:
496 explicit ReturnStatement(Expression* expression)
497 : expression_(expression) { }
498
499 virtual void Accept(AstVisitor* v);
500
501 // Type testing & conversion.
502 virtual ReturnStatement* AsReturnStatement() { return this; }
503
504 Expression* expression() { return expression_; }
505
506 private:
507 Expression* expression_;
508};
509
510
511class WithEnterStatement: public Statement {
512 public:
513 explicit WithEnterStatement(Expression* expression, bool is_catch_block)
514 : expression_(expression), is_catch_block_(is_catch_block) { }
515
516 virtual void Accept(AstVisitor* v);
517
518 Expression* expression() const { return expression_; }
519
520 bool is_catch_block() const { return is_catch_block_; }
521
522 private:
523 Expression* expression_;
524 bool is_catch_block_;
525};
526
527
528class WithExitStatement: public Statement {
529 public:
530 WithExitStatement() { }
531
532 virtual void Accept(AstVisitor* v);
533};
534
535
536class CaseClause: public ZoneObject {
537 public:
538 CaseClause(Expression* label, ZoneList<Statement*>* statements)
539 : label_(label), statements_(statements) { }
540
541 bool is_default() const { return label_ == NULL; }
542 Expression* label() const {
543 CHECK(!is_default());
544 return label_;
545 }
546 JumpTarget* body_target() { return &body_target_; }
547 ZoneList<Statement*>* statements() const { return statements_; }
548
549 private:
550 Expression* label_;
551 JumpTarget body_target_;
552 ZoneList<Statement*>* statements_;
553};
554
555
556class SwitchStatement: public BreakableStatement {
557 public:
558 explicit SwitchStatement(ZoneStringList* labels)
559 : BreakableStatement(labels, TARGET_FOR_ANONYMOUS),
560 tag_(NULL), cases_(NULL) { }
561
562 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
563 tag_ = tag;
564 cases_ = cases;
565 }
566
567 virtual void Accept(AstVisitor* v);
568
569 Expression* tag() const { return tag_; }
570 ZoneList<CaseClause*>* cases() const { return cases_; }
571
572 private:
573 Expression* tag_;
574 ZoneList<CaseClause*>* cases_;
575};
576
577
578// If-statements always have non-null references to their then- and
579// else-parts. When parsing if-statements with no explicit else-part,
580// the parser implicitly creates an empty statement. Use the
581// HasThenStatement() and HasElseStatement() functions to check if a
582// given if-statement has a then- or an else-part containing code.
583class IfStatement: public Statement {
584 public:
585 IfStatement(Expression* condition,
586 Statement* then_statement,
587 Statement* else_statement)
588 : condition_(condition),
589 then_statement_(then_statement),
590 else_statement_(else_statement) { }
591
592 virtual void Accept(AstVisitor* v);
593
594 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
595 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
596
597 Expression* condition() const { return condition_; }
598 Statement* then_statement() const { return then_statement_; }
599 Statement* else_statement() const { return else_statement_; }
600
601 private:
602 Expression* condition_;
603 Statement* then_statement_;
604 Statement* else_statement_;
605};
606
607
608// NOTE: TargetCollectors are represented as nodes to fit in the target
609// stack in the compiler; this should probably be reworked.
610class TargetCollector: public AstNode {
611 public:
612 explicit TargetCollector(ZoneList<BreakTarget*>* targets)
613 : targets_(targets) {
614 }
615
616 // Adds a jump target to the collector. The collector stores a pointer not
617 // a copy of the target to make binding work, so make sure not to pass in
618 // references to something on the stack.
619 void AddTarget(BreakTarget* target);
620
621 // Virtual behaviour. TargetCollectors are never part of the AST.
622 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
623 virtual TargetCollector* AsTargetCollector() { return this; }
624
625 ZoneList<BreakTarget*>* targets() { return targets_; }
626
627 private:
628 ZoneList<BreakTarget*>* targets_;
629};
630
631
632class TryStatement: public Statement {
633 public:
634 explicit TryStatement(Block* try_block)
635 : try_block_(try_block), escaping_targets_(NULL) { }
636
637 void set_escaping_targets(ZoneList<BreakTarget*>* targets) {
638 escaping_targets_ = targets;
639 }
640
641 Block* try_block() const { return try_block_; }
642 ZoneList<BreakTarget*>* escaping_targets() const { return escaping_targets_; }
643
644 private:
645 Block* try_block_;
646 ZoneList<BreakTarget*>* escaping_targets_;
647};
648
649
Steve Block3ce2e202009-11-05 08:53:23 +0000650class TryCatchStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000651 public:
Steve Block3ce2e202009-11-05 08:53:23 +0000652 TryCatchStatement(Block* try_block,
Leon Clarkee46be812010-01-19 14:06:41 +0000653 VariableProxy* catch_var,
Steve Block3ce2e202009-11-05 08:53:23 +0000654 Block* catch_block)
Steve Blocka7e24c12009-10-30 11:49:00 +0000655 : TryStatement(try_block),
656 catch_var_(catch_var),
657 catch_block_(catch_block) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000658 }
659
660 virtual void Accept(AstVisitor* v);
661
Leon Clarkee46be812010-01-19 14:06:41 +0000662 VariableProxy* catch_var() const { return catch_var_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000663 Block* catch_block() const { return catch_block_; }
664
665 private:
Leon Clarkee46be812010-01-19 14:06:41 +0000666 VariableProxy* catch_var_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000667 Block* catch_block_;
668};
669
670
Steve Block3ce2e202009-11-05 08:53:23 +0000671class TryFinallyStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000672 public:
Steve Block3ce2e202009-11-05 08:53:23 +0000673 TryFinallyStatement(Block* try_block, Block* finally_block)
Steve Blocka7e24c12009-10-30 11:49:00 +0000674 : TryStatement(try_block),
675 finally_block_(finally_block) { }
676
677 virtual void Accept(AstVisitor* v);
678
679 Block* finally_block() const { return finally_block_; }
680
681 private:
682 Block* finally_block_;
683};
684
685
686class DebuggerStatement: public Statement {
687 public:
688 virtual void Accept(AstVisitor* v);
689};
690
691
692class EmptyStatement: public Statement {
693 public:
694 virtual void Accept(AstVisitor* v);
695
696 // Type testing & conversion.
697 virtual EmptyStatement* AsEmptyStatement() { return this; }
698};
699
700
701class Literal: public Expression {
702 public:
703 explicit Literal(Handle<Object> handle) : handle_(handle) { }
704
705 virtual void Accept(AstVisitor* v);
706
707 // Type testing & conversion.
708 virtual Literal* AsLiteral() { return this; }
709
710 // Check if this literal is identical to the other literal.
711 bool IsIdenticalTo(const Literal* other) const {
712 return handle_.is_identical_to(other->handle_);
713 }
714
Leon Clarkee46be812010-01-19 14:06:41 +0000715 virtual bool IsPropertyName() {
716 if (handle_->IsSymbol()) {
717 uint32_t ignored;
718 return !String::cast(*handle_)->AsArrayIndex(&ignored);
719 }
720 return false;
721 }
722
Steve Blocka7e24c12009-10-30 11:49:00 +0000723 // Identity testers.
724 bool IsNull() const { return handle_.is_identical_to(Factory::null_value()); }
725 bool IsTrue() const { return handle_.is_identical_to(Factory::true_value()); }
726 bool IsFalse() const {
727 return handle_.is_identical_to(Factory::false_value());
728 }
729
730 Handle<Object> handle() const { return handle_; }
731
732 private:
733 Handle<Object> handle_;
734};
735
736
737// Base class for literals that needs space in the corresponding JSFunction.
738class MaterializedLiteral: public Expression {
739 public:
740 explicit MaterializedLiteral(int literal_index, bool is_simple, int depth)
741 : literal_index_(literal_index), is_simple_(is_simple), depth_(depth) {}
742
743 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
744
745 int literal_index() { return literal_index_; }
746
747 // A materialized literal is simple if the values consist of only
748 // constants and simple object and array literals.
749 bool is_simple() const { return is_simple_; }
750
Steve Blocka7e24c12009-10-30 11:49:00 +0000751 int depth() const { return depth_; }
752
753 private:
754 int literal_index_;
755 bool is_simple_;
756 int depth_;
757};
758
759
760// An object literal has a boilerplate object that is used
761// for minimizing the work when constructing it at runtime.
762class ObjectLiteral: public MaterializedLiteral {
763 public:
764 // Property is used for passing information
765 // about an object literal's properties from the parser
766 // to the code generator.
767 class Property: public ZoneObject {
768 public:
769
770 enum Kind {
771 CONSTANT, // Property with constant value (compile time).
772 COMPUTED, // Property with computed value (execution time).
773 MATERIALIZED_LITERAL, // Property value is a materialized literal.
774 GETTER, SETTER, // Property is an accessor function.
775 PROTOTYPE // Property is __proto__.
776 };
777
778 Property(Literal* key, Expression* value);
779 Property(bool is_getter, FunctionLiteral* value);
780
781 Literal* key() { return key_; }
782 Expression* value() { return value_; }
783 Kind kind() { return kind_; }
784
Steve Blockd0582a62009-12-15 09:54:21 +0000785 bool IsCompileTimeValue();
786
Steve Blocka7e24c12009-10-30 11:49:00 +0000787 private:
788 Literal* key_;
789 Expression* value_;
790 Kind kind_;
791 };
792
793 ObjectLiteral(Handle<FixedArray> constant_properties,
794 ZoneList<Property*>* properties,
795 int literal_index,
796 bool is_simple,
797 int depth)
798 : MaterializedLiteral(literal_index, is_simple, depth),
799 constant_properties_(constant_properties),
800 properties_(properties) {}
801
802 virtual ObjectLiteral* AsObjectLiteral() { return this; }
803 virtual void Accept(AstVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +0000804
805 Handle<FixedArray> constant_properties() const {
806 return constant_properties_;
807 }
808 ZoneList<Property*>* properties() const { return properties_; }
809
810 private:
811 Handle<FixedArray> constant_properties_;
812 ZoneList<Property*>* properties_;
813};
814
815
816// Node for capturing a regexp literal.
817class RegExpLiteral: public MaterializedLiteral {
818 public:
819 RegExpLiteral(Handle<String> pattern,
820 Handle<String> flags,
821 int literal_index)
822 : MaterializedLiteral(literal_index, false, 1),
823 pattern_(pattern),
824 flags_(flags) {}
825
826 virtual void Accept(AstVisitor* v);
827
828 Handle<String> pattern() const { return pattern_; }
829 Handle<String> flags() const { return flags_; }
830
831 private:
832 Handle<String> pattern_;
833 Handle<String> flags_;
834};
835
836// An array literal has a literals object that is used
837// for minimizing the work when constructing it at runtime.
838class ArrayLiteral: public MaterializedLiteral {
839 public:
Leon Clarkee46be812010-01-19 14:06:41 +0000840 ArrayLiteral(Handle<FixedArray> constant_elements,
Steve Blocka7e24c12009-10-30 11:49:00 +0000841 ZoneList<Expression*>* values,
842 int literal_index,
843 bool is_simple,
844 int depth)
845 : MaterializedLiteral(literal_index, is_simple, depth),
Leon Clarkee46be812010-01-19 14:06:41 +0000846 constant_elements_(constant_elements),
Steve Blocka7e24c12009-10-30 11:49:00 +0000847 values_(values) {}
848
849 virtual void Accept(AstVisitor* v);
850 virtual ArrayLiteral* AsArrayLiteral() { return this; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000851
Leon Clarkee46be812010-01-19 14:06:41 +0000852 Handle<FixedArray> constant_elements() const { return constant_elements_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000853 ZoneList<Expression*>* values() const { return values_; }
854
855 private:
Leon Clarkee46be812010-01-19 14:06:41 +0000856 Handle<FixedArray> constant_elements_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000857 ZoneList<Expression*>* values_;
858};
859
860
861// Node for constructing a context extension object for a catch block.
862// The catch context extension object has one property, the catch
863// variable, which should be DontDelete.
864class CatchExtensionObject: public Expression {
865 public:
866 CatchExtensionObject(Literal* key, VariableProxy* value)
867 : key_(key), value_(value) {
868 }
869
870 virtual void Accept(AstVisitor* v);
871
872 Literal* key() const { return key_; }
873 VariableProxy* value() const { return value_; }
874
875 private:
876 Literal* key_;
877 VariableProxy* value_;
878};
879
880
881class VariableProxy: public Expression {
882 public:
883 virtual void Accept(AstVisitor* v);
884
885 // Type testing & conversion
886 virtual Property* AsProperty() {
887 return var_ == NULL ? NULL : var_->AsProperty();
888 }
889 virtual VariableProxy* AsVariableProxy() { return this; }
890
891 Variable* AsVariable() {
892 return this == NULL || var_ == NULL ? NULL : var_->AsVariable();
893 }
894
895 virtual bool IsValidLeftHandSide() {
896 return var_ == NULL ? true : var_->IsValidLeftHandSide();
897 }
898
899 bool IsVariable(Handle<String> n) {
900 return !is_this() && name().is_identical_to(n);
901 }
902
903 bool IsArguments() {
904 Variable* variable = AsVariable();
905 return (variable == NULL) ? false : variable->is_arguments();
906 }
907
908 Handle<String> name() const { return name_; }
909 Variable* var() const { return var_; }
910 UseCount* var_uses() { return &var_uses_; }
911 UseCount* obj_uses() { return &obj_uses_; }
912 bool is_this() const { return is_this_; }
913 bool inside_with() const { return inside_with_; }
914
915 // Bind this proxy to the variable var.
916 void BindTo(Variable* var);
917
918 protected:
919 Handle<String> name_;
920 Variable* var_; // resolved variable, or NULL
921 bool is_this_;
922 bool inside_with_;
923
924 // VariableProxy usage info.
925 UseCount var_uses_; // uses of the variable value
926 UseCount obj_uses_; // uses of the object the variable points to
927
928 VariableProxy(Handle<String> name, bool is_this, bool inside_with);
929 explicit VariableProxy(bool is_this);
930
931 friend class Scope;
932};
933
934
935class VariableProxySentinel: public VariableProxy {
936 public:
937 virtual bool IsValidLeftHandSide() { return !is_this(); }
938 static VariableProxySentinel* this_proxy() { return &this_proxy_; }
939 static VariableProxySentinel* identifier_proxy() {
940 return &identifier_proxy_;
941 }
942
943 private:
944 explicit VariableProxySentinel(bool is_this) : VariableProxy(is_this) { }
945 static VariableProxySentinel this_proxy_;
946 static VariableProxySentinel identifier_proxy_;
947};
948
949
950class Slot: public Expression {
951 public:
952 enum Type {
953 // A slot in the parameter section on the stack. index() is
954 // the parameter index, counting left-to-right, starting at 0.
955 PARAMETER,
956
957 // A slot in the local section on the stack. index() is
958 // the variable index in the stack frame, starting at 0.
959 LOCAL,
960
961 // An indexed slot in a heap context. index() is the
962 // variable index in the context object on the heap,
963 // starting at 0. var()->scope() is the corresponding
964 // scope.
965 CONTEXT,
966
967 // A named slot in a heap context. var()->name() is the
968 // variable name in the context object on the heap,
969 // with lookup starting at the current context. index()
970 // is invalid.
Steve Blockd0582a62009-12-15 09:54:21 +0000971 LOOKUP
Steve Blocka7e24c12009-10-30 11:49:00 +0000972 };
973
974 Slot(Variable* var, Type type, int index)
975 : var_(var), type_(type), index_(index) {
976 ASSERT(var != NULL);
977 }
978
979 virtual void Accept(AstVisitor* v);
980
981 // Type testing & conversion
982 virtual Slot* AsSlot() { return this; }
983
984 // Accessors
985 Variable* var() const { return var_; }
986 Type type() const { return type_; }
987 int index() const { return index_; }
988 bool is_arguments() const { return var_->is_arguments(); }
989
990 private:
991 Variable* var_;
992 Type type_;
993 int index_;
994};
995
996
997class Property: public Expression {
998 public:
999 // Synthetic properties are property lookups introduced by the system,
1000 // to objects that aren't visible to the user. Function calls to synthetic
1001 // properties should use the global object as receiver, not the base object
1002 // of the resolved Reference.
1003 enum Type { NORMAL, SYNTHETIC };
1004 Property(Expression* obj, Expression* key, int pos, Type type = NORMAL)
1005 : obj_(obj), key_(key), pos_(pos), type_(type) { }
1006
1007 virtual void Accept(AstVisitor* v);
1008
1009 // Type testing & conversion
1010 virtual Property* AsProperty() { return this; }
1011
1012 virtual bool IsValidLeftHandSide() { return true; }
1013
1014 Expression* obj() const { return obj_; }
1015 Expression* key() const { return key_; }
1016 int position() const { return pos_; }
1017 bool is_synthetic() const { return type_ == SYNTHETIC; }
1018
1019 // Returns a property singleton property access on 'this'. Used
1020 // during preparsing.
1021 static Property* this_property() { return &this_property_; }
1022
1023 private:
1024 Expression* obj_;
1025 Expression* key_;
1026 int pos_;
1027 Type type_;
1028
1029 // Dummy property used during preparsing.
1030 static Property this_property_;
1031};
1032
1033
1034class Call: public Expression {
1035 public:
1036 Call(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1037 : expression_(expression), arguments_(arguments), pos_(pos) { }
1038
1039 virtual void Accept(AstVisitor* v);
1040
1041 // Type testing and conversion.
1042 virtual Call* AsCall() { return this; }
1043
1044 Expression* expression() const { return expression_; }
1045 ZoneList<Expression*>* arguments() const { return arguments_; }
1046 int position() { return pos_; }
1047
1048 static Call* sentinel() { return &sentinel_; }
1049
1050 private:
1051 Expression* expression_;
1052 ZoneList<Expression*>* arguments_;
1053 int pos_;
1054
1055 static Call sentinel_;
1056};
1057
1058
1059class CallNew: public Expression {
1060 public:
1061 CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1062 : expression_(expression), arguments_(arguments), pos_(pos) { }
1063
1064 virtual void Accept(AstVisitor* v);
1065
1066 Expression* expression() const { return expression_; }
1067 ZoneList<Expression*>* arguments() const { return arguments_; }
1068 int position() { return pos_; }
1069
1070 private:
1071 Expression* expression_;
1072 ZoneList<Expression*>* arguments_;
1073 int pos_;
1074};
1075
1076
1077// The CallRuntime class does not represent any official JavaScript
1078// language construct. Instead it is used to call a C or JS function
1079// with a set of arguments. This is used from the builtins that are
1080// implemented in JavaScript (see "v8natives.js").
1081class CallRuntime: public Expression {
1082 public:
1083 CallRuntime(Handle<String> name,
1084 Runtime::Function* function,
1085 ZoneList<Expression*>* arguments)
1086 : name_(name), function_(function), arguments_(arguments) { }
1087
1088 virtual void Accept(AstVisitor* v);
1089
1090 Handle<String> name() const { return name_; }
1091 Runtime::Function* function() const { return function_; }
1092 ZoneList<Expression*>* arguments() const { return arguments_; }
Steve Blockd0582a62009-12-15 09:54:21 +00001093 bool is_jsruntime() const { return function_ == NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001094
1095 private:
1096 Handle<String> name_;
1097 Runtime::Function* function_;
1098 ZoneList<Expression*>* arguments_;
1099};
1100
1101
1102class UnaryOperation: public Expression {
1103 public:
1104 UnaryOperation(Token::Value op, Expression* expression)
1105 : op_(op), expression_(expression) {
1106 ASSERT(Token::IsUnaryOp(op));
1107 }
1108
1109 virtual void Accept(AstVisitor* v);
1110
1111 // Type testing & conversion
1112 virtual UnaryOperation* AsUnaryOperation() { return this; }
1113
1114 Token::Value op() const { return op_; }
1115 Expression* expression() const { return expression_; }
1116
1117 private:
1118 Token::Value op_;
1119 Expression* expression_;
1120};
1121
1122
1123class BinaryOperation: public Expression {
1124 public:
1125 BinaryOperation(Token::Value op, Expression* left, Expression* right)
1126 : op_(op), left_(left), right_(right) {
1127 ASSERT(Token::IsBinaryOp(op));
1128 }
1129
1130 virtual void Accept(AstVisitor* v);
1131
1132 // Type testing & conversion
1133 virtual BinaryOperation* AsBinaryOperation() { return this; }
1134
1135 // True iff the result can be safely overwritten (to avoid allocation).
1136 // False for operations that can return one of their operands.
1137 bool ResultOverwriteAllowed() {
1138 switch (op_) {
1139 case Token::COMMA:
1140 case Token::OR:
1141 case Token::AND:
1142 return false;
1143 case Token::BIT_OR:
1144 case Token::BIT_XOR:
1145 case Token::BIT_AND:
1146 case Token::SHL:
1147 case Token::SAR:
1148 case Token::SHR:
1149 case Token::ADD:
1150 case Token::SUB:
1151 case Token::MUL:
1152 case Token::DIV:
1153 case Token::MOD:
1154 return true;
1155 default:
1156 UNREACHABLE();
1157 }
1158 return false;
1159 }
1160
1161 Token::Value op() const { return op_; }
1162 Expression* left() const { return left_; }
1163 Expression* right() const { return right_; }
1164
1165 private:
1166 Token::Value op_;
1167 Expression* left_;
1168 Expression* right_;
1169};
1170
1171
1172class CountOperation: public Expression {
1173 public:
1174 CountOperation(bool is_prefix, Token::Value op, Expression* expression)
1175 : is_prefix_(is_prefix), op_(op), expression_(expression) {
1176 ASSERT(Token::IsCountOp(op));
1177 }
1178
1179 virtual void Accept(AstVisitor* v);
1180
1181 bool is_prefix() const { return is_prefix_; }
1182 bool is_postfix() const { return !is_prefix_; }
1183 Token::Value op() const { return op_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001184 Token::Value binary_op() {
1185 return op_ == Token::INC ? Token::ADD : Token::SUB;
1186 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001187 Expression* expression() const { return expression_; }
1188
1189 virtual void MarkAsStatement() { is_prefix_ = true; }
1190
1191 private:
1192 bool is_prefix_;
1193 Token::Value op_;
1194 Expression* expression_;
1195};
1196
1197
1198class CompareOperation: public Expression {
1199 public:
1200 CompareOperation(Token::Value op, Expression* left, Expression* right)
Leon Clarkee46be812010-01-19 14:06:41 +00001201 : op_(op), left_(left), right_(right), is_for_loop_condition_(false) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001202 ASSERT(Token::IsCompareOp(op));
1203 }
1204
1205 virtual void Accept(AstVisitor* v);
1206
1207 Token::Value op() const { return op_; }
1208 Expression* left() const { return left_; }
1209 Expression* right() const { return right_; }
1210
Leon Clarkee46be812010-01-19 14:06:41 +00001211 // Accessors for flag whether this compare operation is hanging of a for loop.
1212 bool is_for_loop_condition() const { return is_for_loop_condition_; }
1213 void set_is_for_loop_condition() { is_for_loop_condition_ = true; }
1214
1215 // Type testing & conversion
1216 virtual CompareOperation* AsCompareOperation() { return this; }
1217
Steve Blocka7e24c12009-10-30 11:49:00 +00001218 private:
1219 Token::Value op_;
1220 Expression* left_;
1221 Expression* right_;
Leon Clarkee46be812010-01-19 14:06:41 +00001222 bool is_for_loop_condition_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001223};
1224
1225
1226class Conditional: public Expression {
1227 public:
1228 Conditional(Expression* condition,
1229 Expression* then_expression,
1230 Expression* else_expression)
1231 : condition_(condition),
1232 then_expression_(then_expression),
1233 else_expression_(else_expression) { }
1234
1235 virtual void Accept(AstVisitor* v);
1236
1237 Expression* condition() const { return condition_; }
1238 Expression* then_expression() const { return then_expression_; }
1239 Expression* else_expression() const { return else_expression_; }
1240
1241 private:
1242 Expression* condition_;
1243 Expression* then_expression_;
1244 Expression* else_expression_;
1245};
1246
1247
1248class Assignment: public Expression {
1249 public:
1250 Assignment(Token::Value op, Expression* target, Expression* value, int pos)
1251 : op_(op), target_(target), value_(value), pos_(pos),
1252 block_start_(false), block_end_(false) {
1253 ASSERT(Token::IsAssignmentOp(op));
1254 }
1255
1256 virtual void Accept(AstVisitor* v);
1257 virtual Assignment* AsAssignment() { return this; }
1258
1259 Token::Value binary_op() const;
1260
1261 Token::Value op() const { return op_; }
1262 Expression* target() const { return target_; }
1263 Expression* value() const { return value_; }
1264 int position() { return pos_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001265 // This check relies on the definition order of token in token.h.
1266 bool is_compound() const { return op() > Token::ASSIGN; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001267
1268 // An initialization block is a series of statments of the form
1269 // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1270 // ending of these blocks to allow for optimizations of initialization
1271 // blocks.
1272 bool starts_initialization_block() { return block_start_; }
1273 bool ends_initialization_block() { return block_end_; }
1274 void mark_block_start() { block_start_ = true; }
1275 void mark_block_end() { block_end_ = true; }
1276
1277 private:
1278 Token::Value op_;
1279 Expression* target_;
1280 Expression* value_;
1281 int pos_;
1282 bool block_start_;
1283 bool block_end_;
1284};
1285
1286
1287class Throw: public Expression {
1288 public:
1289 Throw(Expression* exception, int pos)
1290 : exception_(exception), pos_(pos) {}
1291
1292 virtual void Accept(AstVisitor* v);
1293 Expression* exception() const { return exception_; }
1294 int position() const { return pos_; }
1295
1296 private:
1297 Expression* exception_;
1298 int pos_;
1299};
1300
1301
1302class FunctionLiteral: public Expression {
1303 public:
1304 FunctionLiteral(Handle<String> name,
1305 Scope* scope,
1306 ZoneList<Statement*>* body,
1307 int materialized_literal_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00001308 int expected_property_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00001309 bool has_only_simple_this_property_assignments,
1310 Handle<FixedArray> this_property_assignments,
1311 int num_parameters,
1312 int start_position,
1313 int end_position,
1314 bool is_expression)
1315 : name_(name),
1316 scope_(scope),
1317 body_(body),
1318 materialized_literal_count_(materialized_literal_count),
Steve Blocka7e24c12009-10-30 11:49:00 +00001319 expected_property_count_(expected_property_count),
Steve Blocka7e24c12009-10-30 11:49:00 +00001320 has_only_simple_this_property_assignments_(
1321 has_only_simple_this_property_assignments),
1322 this_property_assignments_(this_property_assignments),
1323 num_parameters_(num_parameters),
1324 start_position_(start_position),
1325 end_position_(end_position),
1326 is_expression_(is_expression),
Steve Blocka7e24c12009-10-30 11:49:00 +00001327 function_token_position_(RelocInfo::kNoPosition),
Steve Blockd0582a62009-12-15 09:54:21 +00001328 inferred_name_(Heap::empty_string()),
Leon Clarked91b9f72010-01-27 17:25:45 +00001329 try_full_codegen_(false) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001330#ifdef DEBUG
1331 already_compiled_ = false;
1332#endif
1333 }
1334
1335 virtual void Accept(AstVisitor* v);
1336
1337 // Type testing & conversion
1338 virtual FunctionLiteral* AsFunctionLiteral() { return this; }
1339
1340 Handle<String> name() const { return name_; }
1341 Scope* scope() const { return scope_; }
1342 ZoneList<Statement*>* body() const { return body_; }
1343 void set_function_token_position(int pos) { function_token_position_ = pos; }
1344 int function_token_position() const { return function_token_position_; }
1345 int start_position() const { return start_position_; }
1346 int end_position() const { return end_position_; }
1347 bool is_expression() const { return is_expression_; }
1348
1349 int materialized_literal_count() { return materialized_literal_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001350 int expected_property_count() { return expected_property_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001351 bool has_only_simple_this_property_assignments() {
1352 return has_only_simple_this_property_assignments_;
1353 }
1354 Handle<FixedArray> this_property_assignments() {
1355 return this_property_assignments_;
1356 }
1357 int num_parameters() { return num_parameters_; }
1358
1359 bool AllowsLazyCompilation();
1360
Steve Blocka7e24c12009-10-30 11:49:00 +00001361 Handle<String> inferred_name() const { return inferred_name_; }
1362 void set_inferred_name(Handle<String> inferred_name) {
1363 inferred_name_ = inferred_name;
1364 }
1365
Leon Clarked91b9f72010-01-27 17:25:45 +00001366 bool try_full_codegen() { return try_full_codegen_; }
1367 void set_try_full_codegen(bool flag) { try_full_codegen_ = flag; }
Steve Blockd0582a62009-12-15 09:54:21 +00001368
Steve Blocka7e24c12009-10-30 11:49:00 +00001369#ifdef DEBUG
1370 void mark_as_compiled() {
1371 ASSERT(!already_compiled_);
1372 already_compiled_ = true;
1373 }
1374#endif
1375
1376 private:
1377 Handle<String> name_;
1378 Scope* scope_;
1379 ZoneList<Statement*>* body_;
1380 int materialized_literal_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001381 int expected_property_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001382 bool has_only_simple_this_property_assignments_;
1383 Handle<FixedArray> this_property_assignments_;
1384 int num_parameters_;
1385 int start_position_;
1386 int end_position_;
1387 bool is_expression_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001388 int function_token_position_;
1389 Handle<String> inferred_name_;
Leon Clarked91b9f72010-01-27 17:25:45 +00001390 bool try_full_codegen_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001391#ifdef DEBUG
1392 bool already_compiled_;
1393#endif
1394};
1395
1396
1397class FunctionBoilerplateLiteral: public Expression {
1398 public:
1399 explicit FunctionBoilerplateLiteral(Handle<JSFunction> boilerplate)
1400 : boilerplate_(boilerplate) {
1401 ASSERT(boilerplate->IsBoilerplate());
1402 }
1403
1404 Handle<JSFunction> boilerplate() const { return boilerplate_; }
1405
1406 virtual void Accept(AstVisitor* v);
1407
1408 private:
1409 Handle<JSFunction> boilerplate_;
1410};
1411
1412
1413class ThisFunction: public Expression {
1414 public:
1415 virtual void Accept(AstVisitor* v);
1416};
1417
1418
1419// ----------------------------------------------------------------------------
1420// Regular expressions
1421
1422
1423class RegExpVisitor BASE_EMBEDDED {
1424 public:
1425 virtual ~RegExpVisitor() { }
1426#define MAKE_CASE(Name) \
1427 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
1428 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
1429#undef MAKE_CASE
1430};
1431
1432
1433class RegExpTree: public ZoneObject {
1434 public:
1435 static const int kInfinity = kMaxInt;
1436 virtual ~RegExpTree() { }
1437 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
1438 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1439 RegExpNode* on_success) = 0;
1440 virtual bool IsTextElement() { return false; }
1441 virtual bool IsAnchored() { return false; }
1442 virtual int min_match() = 0;
1443 virtual int max_match() = 0;
1444 // Returns the interval of registers used for captures within this
1445 // expression.
1446 virtual Interval CaptureRegisters() { return Interval::Empty(); }
1447 virtual void AppendToText(RegExpText* text);
1448 SmartPointer<const char> ToString();
1449#define MAKE_ASTYPE(Name) \
1450 virtual RegExp##Name* As##Name(); \
1451 virtual bool Is##Name();
1452 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
1453#undef MAKE_ASTYPE
1454};
1455
1456
1457class RegExpDisjunction: public RegExpTree {
1458 public:
1459 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
1460 virtual void* Accept(RegExpVisitor* visitor, void* data);
1461 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1462 RegExpNode* on_success);
1463 virtual RegExpDisjunction* AsDisjunction();
1464 virtual Interval CaptureRegisters();
1465 virtual bool IsDisjunction();
1466 virtual bool IsAnchored();
1467 virtual int min_match() { return min_match_; }
1468 virtual int max_match() { return max_match_; }
1469 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
1470 private:
1471 ZoneList<RegExpTree*>* alternatives_;
1472 int min_match_;
1473 int max_match_;
1474};
1475
1476
1477class RegExpAlternative: public RegExpTree {
1478 public:
1479 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
1480 virtual void* Accept(RegExpVisitor* visitor, void* data);
1481 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1482 RegExpNode* on_success);
1483 virtual RegExpAlternative* AsAlternative();
1484 virtual Interval CaptureRegisters();
1485 virtual bool IsAlternative();
1486 virtual bool IsAnchored();
1487 virtual int min_match() { return min_match_; }
1488 virtual int max_match() { return max_match_; }
1489 ZoneList<RegExpTree*>* nodes() { return nodes_; }
1490 private:
1491 ZoneList<RegExpTree*>* nodes_;
1492 int min_match_;
1493 int max_match_;
1494};
1495
1496
1497class RegExpAssertion: public RegExpTree {
1498 public:
1499 enum Type {
1500 START_OF_LINE,
1501 START_OF_INPUT,
1502 END_OF_LINE,
1503 END_OF_INPUT,
1504 BOUNDARY,
1505 NON_BOUNDARY
1506 };
1507 explicit RegExpAssertion(Type type) : type_(type) { }
1508 virtual void* Accept(RegExpVisitor* visitor, void* data);
1509 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1510 RegExpNode* on_success);
1511 virtual RegExpAssertion* AsAssertion();
1512 virtual bool IsAssertion();
1513 virtual bool IsAnchored();
1514 virtual int min_match() { return 0; }
1515 virtual int max_match() { return 0; }
1516 Type type() { return type_; }
1517 private:
1518 Type type_;
1519};
1520
1521
1522class CharacterSet BASE_EMBEDDED {
1523 public:
1524 explicit CharacterSet(uc16 standard_set_type)
1525 : ranges_(NULL),
1526 standard_set_type_(standard_set_type) {}
1527 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
1528 : ranges_(ranges),
1529 standard_set_type_(0) {}
1530 ZoneList<CharacterRange>* ranges();
1531 uc16 standard_set_type() { return standard_set_type_; }
1532 void set_standard_set_type(uc16 special_set_type) {
1533 standard_set_type_ = special_set_type;
1534 }
1535 bool is_standard() { return standard_set_type_ != 0; }
Leon Clarkee46be812010-01-19 14:06:41 +00001536 void Canonicalize();
Steve Blocka7e24c12009-10-30 11:49:00 +00001537 private:
1538 ZoneList<CharacterRange>* ranges_;
1539 // If non-zero, the value represents a standard set (e.g., all whitespace
1540 // characters) without having to expand the ranges.
1541 uc16 standard_set_type_;
1542};
1543
1544
1545class RegExpCharacterClass: public RegExpTree {
1546 public:
1547 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
1548 : set_(ranges),
1549 is_negated_(is_negated) { }
1550 explicit RegExpCharacterClass(uc16 type)
1551 : set_(type),
1552 is_negated_(false) { }
1553 virtual void* Accept(RegExpVisitor* visitor, void* data);
1554 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1555 RegExpNode* on_success);
1556 virtual RegExpCharacterClass* AsCharacterClass();
1557 virtual bool IsCharacterClass();
1558 virtual bool IsTextElement() { return true; }
1559 virtual int min_match() { return 1; }
1560 virtual int max_match() { return 1; }
1561 virtual void AppendToText(RegExpText* text);
1562 CharacterSet character_set() { return set_; }
1563 // TODO(lrn): Remove need for complex version if is_standard that
1564 // recognizes a mangled standard set and just do { return set_.is_special(); }
1565 bool is_standard();
1566 // Returns a value representing the standard character set if is_standard()
1567 // returns true.
1568 // Currently used values are:
1569 // s : unicode whitespace
1570 // S : unicode non-whitespace
1571 // w : ASCII word character (digit, letter, underscore)
1572 // W : non-ASCII word character
1573 // d : ASCII digit
1574 // D : non-ASCII digit
1575 // . : non-unicode non-newline
1576 // * : All characters
1577 uc16 standard_type() { return set_.standard_set_type(); }
1578 ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
1579 bool is_negated() { return is_negated_; }
1580 private:
1581 CharacterSet set_;
1582 bool is_negated_;
1583};
1584
1585
1586class RegExpAtom: public RegExpTree {
1587 public:
1588 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
1589 virtual void* Accept(RegExpVisitor* visitor, void* data);
1590 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1591 RegExpNode* on_success);
1592 virtual RegExpAtom* AsAtom();
1593 virtual bool IsAtom();
1594 virtual bool IsTextElement() { return true; }
1595 virtual int min_match() { return data_.length(); }
1596 virtual int max_match() { return data_.length(); }
1597 virtual void AppendToText(RegExpText* text);
1598 Vector<const uc16> data() { return data_; }
1599 int length() { return data_.length(); }
1600 private:
1601 Vector<const uc16> data_;
1602};
1603
1604
1605class RegExpText: public RegExpTree {
1606 public:
1607 RegExpText() : elements_(2), length_(0) {}
1608 virtual void* Accept(RegExpVisitor* visitor, void* data);
1609 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1610 RegExpNode* on_success);
1611 virtual RegExpText* AsText();
1612 virtual bool IsText();
1613 virtual bool IsTextElement() { return true; }
1614 virtual int min_match() { return length_; }
1615 virtual int max_match() { return length_; }
1616 virtual void AppendToText(RegExpText* text);
1617 void AddElement(TextElement elm) {
1618 elements_.Add(elm);
1619 length_ += elm.length();
1620 };
1621 ZoneList<TextElement>* elements() { return &elements_; }
1622 private:
1623 ZoneList<TextElement> elements_;
1624 int length_;
1625};
1626
1627
1628class RegExpQuantifier: public RegExpTree {
1629 public:
Leon Clarkee46be812010-01-19 14:06:41 +00001630 enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
1631 RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
1632 : body_(body),
1633 min_(min),
Steve Blocka7e24c12009-10-30 11:49:00 +00001634 max_(max),
Leon Clarkee46be812010-01-19 14:06:41 +00001635 min_match_(min * body->min_match()),
1636 type_(type) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001637 if (max > 0 && body->max_match() > kInfinity / max) {
1638 max_match_ = kInfinity;
1639 } else {
1640 max_match_ = max * body->max_match();
1641 }
1642 }
1643 virtual void* Accept(RegExpVisitor* visitor, void* data);
1644 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1645 RegExpNode* on_success);
1646 static RegExpNode* ToNode(int min,
1647 int max,
1648 bool is_greedy,
1649 RegExpTree* body,
1650 RegExpCompiler* compiler,
1651 RegExpNode* on_success,
1652 bool not_at_start = false);
1653 virtual RegExpQuantifier* AsQuantifier();
1654 virtual Interval CaptureRegisters();
1655 virtual bool IsQuantifier();
1656 virtual int min_match() { return min_match_; }
1657 virtual int max_match() { return max_match_; }
1658 int min() { return min_; }
1659 int max() { return max_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001660 bool is_possessive() { return type_ == POSSESSIVE; }
1661 bool is_non_greedy() { return type_ == NON_GREEDY; }
1662 bool is_greedy() { return type_ == GREEDY; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001663 RegExpTree* body() { return body_; }
1664 private:
Leon Clarkee46be812010-01-19 14:06:41 +00001665 RegExpTree* body_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001666 int min_;
1667 int max_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001668 int min_match_;
1669 int max_match_;
Leon Clarkee46be812010-01-19 14:06:41 +00001670 Type type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001671};
1672
1673
1674class RegExpCapture: public RegExpTree {
1675 public:
1676 explicit RegExpCapture(RegExpTree* body, int index)
1677 : body_(body), index_(index) { }
1678 virtual void* Accept(RegExpVisitor* visitor, void* data);
1679 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1680 RegExpNode* on_success);
1681 static RegExpNode* ToNode(RegExpTree* body,
1682 int index,
1683 RegExpCompiler* compiler,
1684 RegExpNode* on_success);
1685 virtual RegExpCapture* AsCapture();
1686 virtual bool IsAnchored();
1687 virtual Interval CaptureRegisters();
1688 virtual bool IsCapture();
1689 virtual int min_match() { return body_->min_match(); }
1690 virtual int max_match() { return body_->max_match(); }
1691 RegExpTree* body() { return body_; }
1692 int index() { return index_; }
1693 static int StartRegister(int index) { return index * 2; }
1694 static int EndRegister(int index) { return index * 2 + 1; }
1695 private:
1696 RegExpTree* body_;
1697 int index_;
1698};
1699
1700
1701class RegExpLookahead: public RegExpTree {
1702 public:
1703 RegExpLookahead(RegExpTree* body,
1704 bool is_positive,
1705 int capture_count,
1706 int capture_from)
1707 : body_(body),
1708 is_positive_(is_positive),
1709 capture_count_(capture_count),
1710 capture_from_(capture_from) { }
1711
1712 virtual void* Accept(RegExpVisitor* visitor, void* data);
1713 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1714 RegExpNode* on_success);
1715 virtual RegExpLookahead* AsLookahead();
1716 virtual Interval CaptureRegisters();
1717 virtual bool IsLookahead();
1718 virtual bool IsAnchored();
1719 virtual int min_match() { return 0; }
1720 virtual int max_match() { return 0; }
1721 RegExpTree* body() { return body_; }
1722 bool is_positive() { return is_positive_; }
1723 int capture_count() { return capture_count_; }
1724 int capture_from() { return capture_from_; }
1725 private:
1726 RegExpTree* body_;
1727 bool is_positive_;
1728 int capture_count_;
1729 int capture_from_;
1730};
1731
1732
1733class RegExpBackReference: public RegExpTree {
1734 public:
1735 explicit RegExpBackReference(RegExpCapture* capture)
1736 : capture_(capture) { }
1737 virtual void* Accept(RegExpVisitor* visitor, void* data);
1738 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1739 RegExpNode* on_success);
1740 virtual RegExpBackReference* AsBackReference();
1741 virtual bool IsBackReference();
1742 virtual int min_match() { return 0; }
1743 virtual int max_match() { return capture_->max_match(); }
1744 int index() { return capture_->index(); }
1745 RegExpCapture* capture() { return capture_; }
1746 private:
1747 RegExpCapture* capture_;
1748};
1749
1750
1751class RegExpEmpty: public RegExpTree {
1752 public:
1753 RegExpEmpty() { }
1754 virtual void* Accept(RegExpVisitor* visitor, void* data);
1755 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1756 RegExpNode* on_success);
1757 virtual RegExpEmpty* AsEmpty();
1758 virtual bool IsEmpty();
1759 virtual int min_match() { return 0; }
1760 virtual int max_match() { return 0; }
1761 static RegExpEmpty* GetInstance() { return &kInstance; }
1762 private:
1763 static RegExpEmpty kInstance;
1764};
1765
1766
1767// ----------------------------------------------------------------------------
1768// Basic visitor
1769// - leaf node visitors are abstract.
1770
1771class AstVisitor BASE_EMBEDDED {
1772 public:
1773 AstVisitor() : stack_overflow_(false) { }
1774 virtual ~AstVisitor() { }
1775
1776 // Dispatch
1777 void Visit(AstNode* node) { node->Accept(this); }
1778
1779 // Iteration
Steve Block3ce2e202009-11-05 08:53:23 +00001780 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
Steve Blocka7e24c12009-10-30 11:49:00 +00001781 virtual void VisitStatements(ZoneList<Statement*>* statements);
1782 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
1783
1784 // Stack overflow tracking support.
1785 bool HasStackOverflow() const { return stack_overflow_; }
1786 bool CheckStackOverflow() {
1787 if (stack_overflow_) return true;
1788 StackLimitCheck check;
1789 if (!check.HasOverflowed()) return false;
1790 return (stack_overflow_ = true);
1791 }
1792
1793 // If a stack-overflow exception is encountered when visiting a
1794 // node, calling SetStackOverflow will make sure that the visitor
1795 // bails out without visiting more nodes.
1796 void SetStackOverflow() { stack_overflow_ = true; }
1797
1798
1799 // Individual nodes
1800#define DEF_VISIT(type) \
1801 virtual void Visit##type(type* node) = 0;
1802 AST_NODE_LIST(DEF_VISIT)
1803#undef DEF_VISIT
1804
1805 private:
1806 bool stack_overflow_;
1807};
1808
1809
1810} } // namespace v8::internal
1811
1812#endif // V8_AST_H_