blob: 22e096f250bc91f48f6617636402279e8343259f [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
Steve Blocka7e24c12009-10-30 11:49:00 +0000183 virtual Expression* AsExpression() { return this; }
184
185 virtual bool IsValidJSON() { return false; }
186 virtual bool IsValidLeftHandSide() { return false; }
187
Leon Clarkee46be812010-01-19 14:06:41 +0000188 // Symbols that cannot be parsed as array indices are considered property
189 // names. We do not treat symbols that can be array indexes as property
190 // names because [] for string objects is handled only by keyed ICs.
191 virtual bool IsPropertyName() { return false; }
192
Steve Blocka7e24c12009-10-30 11:49:00 +0000193 // Mark the expression as being compiled as an expression
194 // statement. This is used to transform postfix increments to
195 // (faster) prefix increments.
196 virtual void MarkAsStatement() { /* do nothing */ }
197
198 // Static type information for this expression.
Leon Clarkee46be812010-01-19 14:06:41 +0000199 StaticType* type() { return &type_; }
Steve Block3ce2e202009-11-05 08:53:23 +0000200
Steve Blocka7e24c12009-10-30 11:49:00 +0000201 private:
Leon Clarkee46be812010-01-19 14:06:41 +0000202 StaticType type_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000203};
204
205
206/**
207 * A sentinel used during pre parsing that represents some expression
208 * that is a valid left hand side without having to actually build
209 * the expression.
210 */
211class ValidLeftHandSideSentinel: public Expression {
212 public:
213 virtual bool IsValidLeftHandSide() { return true; }
214 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
215 static ValidLeftHandSideSentinel* instance() { return &instance_; }
216 private:
217 static ValidLeftHandSideSentinel instance_;
218};
219
220
221class BreakableStatement: public Statement {
222 public:
223 enum Type {
224 TARGET_FOR_ANONYMOUS,
225 TARGET_FOR_NAMED_ONLY
226 };
227
228 // The labels associated with this statement. May be NULL;
229 // if it is != NULL, guaranteed to contain at least one entry.
230 ZoneStringList* labels() const { return labels_; }
231
232 // Type testing & conversion.
233 virtual BreakableStatement* AsBreakableStatement() { return this; }
234
235 // Code generation
236 BreakTarget* break_target() { return &break_target_; }
237
238 // Testers.
239 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
240
241 protected:
242 BreakableStatement(ZoneStringList* labels, Type type)
243 : labels_(labels), type_(type) {
244 ASSERT(labels == NULL || labels->length() > 0);
245 }
246
247 private:
248 ZoneStringList* labels_;
249 Type type_;
250 BreakTarget break_target_;
251};
252
253
254class Block: public BreakableStatement {
255 public:
256 Block(ZoneStringList* labels, int capacity, bool is_initializer_block)
257 : BreakableStatement(labels, TARGET_FOR_NAMED_ONLY),
258 statements_(capacity),
259 is_initializer_block_(is_initializer_block) { }
260
261 virtual void Accept(AstVisitor* v);
262
263 void AddStatement(Statement* statement) { statements_.Add(statement); }
264
265 ZoneList<Statement*>* statements() { return &statements_; }
266 bool is_initializer_block() const { return is_initializer_block_; }
267
268 private:
269 ZoneList<Statement*> statements_;
270 bool is_initializer_block_;
271};
272
273
274class Declaration: public AstNode {
275 public:
276 Declaration(VariableProxy* proxy, Variable::Mode mode, FunctionLiteral* fun)
277 : proxy_(proxy),
278 mode_(mode),
279 fun_(fun) {
280 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
281 // At the moment there are no "const functions"'s in JavaScript...
282 ASSERT(fun == NULL || mode == Variable::VAR);
283 }
284
285 virtual void Accept(AstVisitor* v);
286
287 VariableProxy* proxy() const { return proxy_; }
288 Variable::Mode mode() const { return mode_; }
289 FunctionLiteral* fun() const { return fun_; } // may be NULL
290
291 private:
292 VariableProxy* proxy_;
293 Variable::Mode mode_;
294 FunctionLiteral* fun_;
295};
296
297
298class IterationStatement: public BreakableStatement {
299 public:
300 // Type testing & conversion.
301 virtual IterationStatement* AsIterationStatement() { return this; }
302
303 Statement* body() const { return body_; }
304
305 // Code generation
306 BreakTarget* continue_target() { return &continue_target_; }
307
308 protected:
309 explicit IterationStatement(ZoneStringList* labels)
310 : BreakableStatement(labels, TARGET_FOR_ANONYMOUS), body_(NULL) { }
311
312 void Initialize(Statement* body) {
313 body_ = body;
314 }
315
316 private:
317 Statement* body_;
318 BreakTarget continue_target_;
319};
320
321
Steve Block3ce2e202009-11-05 08:53:23 +0000322class DoWhileStatement: public IterationStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000323 public:
Steve Block3ce2e202009-11-05 08:53:23 +0000324 explicit DoWhileStatement(ZoneStringList* labels)
Steve Blockd0582a62009-12-15 09:54:21 +0000325 : IterationStatement(labels), cond_(NULL), condition_position_(-1) {
Steve Block3ce2e202009-11-05 08:53:23 +0000326 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000327
Steve Block3ce2e202009-11-05 08:53:23 +0000328 void Initialize(Expression* cond, Statement* body) {
329 IterationStatement::Initialize(body);
330 cond_ = cond;
331 }
332
333 virtual void Accept(AstVisitor* v);
334
335 Expression* cond() const { return cond_; }
336
Steve Blockd0582a62009-12-15 09:54:21 +0000337 // Position where condition expression starts. We need it to make
338 // the loop's condition a breakable location.
339 int condition_position() { return condition_position_; }
340 void set_condition_position(int pos) { condition_position_ = pos; }
341
Steve Block3ce2e202009-11-05 08:53:23 +0000342 private:
343 Expression* cond_;
Steve Blockd0582a62009-12-15 09:54:21 +0000344 int condition_position_;
Steve Block3ce2e202009-11-05 08:53:23 +0000345};
346
347
348class WhileStatement: public IterationStatement {
349 public:
350 explicit WhileStatement(ZoneStringList* labels)
Steve Blocka7e24c12009-10-30 11:49:00 +0000351 : IterationStatement(labels),
Steve Block3ce2e202009-11-05 08:53:23 +0000352 cond_(NULL),
353 may_have_function_literal_(true) {
354 }
355
356 void Initialize(Expression* cond, Statement* body) {
357 IterationStatement::Initialize(body);
358 cond_ = cond;
359 }
360
361 virtual void Accept(AstVisitor* v);
362
363 Expression* cond() const { return cond_; }
364 bool may_have_function_literal() const {
365 return may_have_function_literal_;
366 }
367
368 private:
369 Expression* cond_;
370 // True if there is a function literal subexpression in the condition.
371 bool may_have_function_literal_;
372
373 friend class AstOptimizer;
374};
375
376
377class ForStatement: public IterationStatement {
378 public:
379 explicit ForStatement(ZoneStringList* labels)
380 : IterationStatement(labels),
Steve Blocka7e24c12009-10-30 11:49:00 +0000381 init_(NULL),
382 cond_(NULL),
383 next_(NULL),
384 may_have_function_literal_(true) {
385 }
386
387 void Initialize(Statement* init,
388 Expression* cond,
389 Statement* next,
390 Statement* body) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000391 IterationStatement::Initialize(body);
392 init_ = init;
393 cond_ = cond;
394 next_ = next;
395 }
396
397 virtual void Accept(AstVisitor* v);
398
Steve Blocka7e24c12009-10-30 11:49:00 +0000399 Statement* init() const { return init_; }
400 Expression* cond() const { return cond_; }
401 Statement* next() const { return next_; }
402 bool may_have_function_literal() const {
403 return may_have_function_literal_;
404 }
405
Steve Blocka7e24c12009-10-30 11:49:00 +0000406 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000407 Statement* init_;
408 Expression* cond_;
409 Statement* next_;
410 // True if there is a function literal subexpression in the condition.
411 bool may_have_function_literal_;
412
413 friend class AstOptimizer;
414};
415
416
417class ForInStatement: public IterationStatement {
418 public:
419 explicit ForInStatement(ZoneStringList* labels)
420 : IterationStatement(labels), each_(NULL), enumerable_(NULL) { }
421
422 void Initialize(Expression* each, Expression* enumerable, Statement* body) {
423 IterationStatement::Initialize(body);
424 each_ = each;
425 enumerable_ = enumerable;
426 }
427
428 virtual void Accept(AstVisitor* v);
429
430 Expression* each() const { return each_; }
431 Expression* enumerable() const { return enumerable_; }
432
433 private:
434 Expression* each_;
435 Expression* enumerable_;
436};
437
438
439class ExpressionStatement: public Statement {
440 public:
441 explicit ExpressionStatement(Expression* expression)
442 : expression_(expression) { }
443
444 virtual void Accept(AstVisitor* v);
445
446 // Type testing & conversion.
447 virtual ExpressionStatement* AsExpressionStatement() { return this; }
448
449 void set_expression(Expression* e) { expression_ = e; }
450 Expression* expression() { return expression_; }
451
452 private:
453 Expression* expression_;
454};
455
456
457class ContinueStatement: public Statement {
458 public:
459 explicit ContinueStatement(IterationStatement* target)
460 : target_(target) { }
461
462 virtual void Accept(AstVisitor* v);
463
464 IterationStatement* target() const { return target_; }
465
466 private:
467 IterationStatement* target_;
468};
469
470
471class BreakStatement: public Statement {
472 public:
473 explicit BreakStatement(BreakableStatement* target)
474 : target_(target) { }
475
476 virtual void Accept(AstVisitor* v);
477
478 BreakableStatement* target() const { return target_; }
479
480 private:
481 BreakableStatement* target_;
482};
483
484
485class ReturnStatement: public Statement {
486 public:
487 explicit ReturnStatement(Expression* expression)
488 : expression_(expression) { }
489
490 virtual void Accept(AstVisitor* v);
491
492 // Type testing & conversion.
493 virtual ReturnStatement* AsReturnStatement() { return this; }
494
495 Expression* expression() { return expression_; }
496
497 private:
498 Expression* expression_;
499};
500
501
502class WithEnterStatement: public Statement {
503 public:
504 explicit WithEnterStatement(Expression* expression, bool is_catch_block)
505 : expression_(expression), is_catch_block_(is_catch_block) { }
506
507 virtual void Accept(AstVisitor* v);
508
509 Expression* expression() const { return expression_; }
510
511 bool is_catch_block() const { return is_catch_block_; }
512
513 private:
514 Expression* expression_;
515 bool is_catch_block_;
516};
517
518
519class WithExitStatement: public Statement {
520 public:
521 WithExitStatement() { }
522
523 virtual void Accept(AstVisitor* v);
524};
525
526
527class CaseClause: public ZoneObject {
528 public:
529 CaseClause(Expression* label, ZoneList<Statement*>* statements)
530 : label_(label), statements_(statements) { }
531
532 bool is_default() const { return label_ == NULL; }
533 Expression* label() const {
534 CHECK(!is_default());
535 return label_;
536 }
537 JumpTarget* body_target() { return &body_target_; }
538 ZoneList<Statement*>* statements() const { return statements_; }
539
540 private:
541 Expression* label_;
542 JumpTarget body_target_;
543 ZoneList<Statement*>* statements_;
544};
545
546
547class SwitchStatement: public BreakableStatement {
548 public:
549 explicit SwitchStatement(ZoneStringList* labels)
550 : BreakableStatement(labels, TARGET_FOR_ANONYMOUS),
551 tag_(NULL), cases_(NULL) { }
552
553 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
554 tag_ = tag;
555 cases_ = cases;
556 }
557
558 virtual void Accept(AstVisitor* v);
559
560 Expression* tag() const { return tag_; }
561 ZoneList<CaseClause*>* cases() const { return cases_; }
562
563 private:
564 Expression* tag_;
565 ZoneList<CaseClause*>* cases_;
566};
567
568
569// If-statements always have non-null references to their then- and
570// else-parts. When parsing if-statements with no explicit else-part,
571// the parser implicitly creates an empty statement. Use the
572// HasThenStatement() and HasElseStatement() functions to check if a
573// given if-statement has a then- or an else-part containing code.
574class IfStatement: public Statement {
575 public:
576 IfStatement(Expression* condition,
577 Statement* then_statement,
578 Statement* else_statement)
579 : condition_(condition),
580 then_statement_(then_statement),
581 else_statement_(else_statement) { }
582
583 virtual void Accept(AstVisitor* v);
584
585 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
586 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
587
588 Expression* condition() const { return condition_; }
589 Statement* then_statement() const { return then_statement_; }
590 Statement* else_statement() const { return else_statement_; }
591
592 private:
593 Expression* condition_;
594 Statement* then_statement_;
595 Statement* else_statement_;
596};
597
598
599// NOTE: TargetCollectors are represented as nodes to fit in the target
600// stack in the compiler; this should probably be reworked.
601class TargetCollector: public AstNode {
602 public:
603 explicit TargetCollector(ZoneList<BreakTarget*>* targets)
604 : targets_(targets) {
605 }
606
607 // Adds a jump target to the collector. The collector stores a pointer not
608 // a copy of the target to make binding work, so make sure not to pass in
609 // references to something on the stack.
610 void AddTarget(BreakTarget* target);
611
612 // Virtual behaviour. TargetCollectors are never part of the AST.
613 virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
614 virtual TargetCollector* AsTargetCollector() { return this; }
615
616 ZoneList<BreakTarget*>* targets() { return targets_; }
617
618 private:
619 ZoneList<BreakTarget*>* targets_;
620};
621
622
623class TryStatement: public Statement {
624 public:
625 explicit TryStatement(Block* try_block)
626 : try_block_(try_block), escaping_targets_(NULL) { }
627
628 void set_escaping_targets(ZoneList<BreakTarget*>* targets) {
629 escaping_targets_ = targets;
630 }
631
632 Block* try_block() const { return try_block_; }
633 ZoneList<BreakTarget*>* escaping_targets() const { return escaping_targets_; }
634
635 private:
636 Block* try_block_;
637 ZoneList<BreakTarget*>* escaping_targets_;
638};
639
640
Steve Block3ce2e202009-11-05 08:53:23 +0000641class TryCatchStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000642 public:
Steve Block3ce2e202009-11-05 08:53:23 +0000643 TryCatchStatement(Block* try_block,
Leon Clarkee46be812010-01-19 14:06:41 +0000644 VariableProxy* catch_var,
Steve Block3ce2e202009-11-05 08:53:23 +0000645 Block* catch_block)
Steve Blocka7e24c12009-10-30 11:49:00 +0000646 : TryStatement(try_block),
647 catch_var_(catch_var),
648 catch_block_(catch_block) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000649 }
650
651 virtual void Accept(AstVisitor* v);
652
Leon Clarkee46be812010-01-19 14:06:41 +0000653 VariableProxy* catch_var() const { return catch_var_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000654 Block* catch_block() const { return catch_block_; }
655
656 private:
Leon Clarkee46be812010-01-19 14:06:41 +0000657 VariableProxy* catch_var_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000658 Block* catch_block_;
659};
660
661
Steve Block3ce2e202009-11-05 08:53:23 +0000662class TryFinallyStatement: public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000663 public:
Steve Block3ce2e202009-11-05 08:53:23 +0000664 TryFinallyStatement(Block* try_block, Block* finally_block)
Steve Blocka7e24c12009-10-30 11:49:00 +0000665 : TryStatement(try_block),
666 finally_block_(finally_block) { }
667
668 virtual void Accept(AstVisitor* v);
669
670 Block* finally_block() const { return finally_block_; }
671
672 private:
673 Block* finally_block_;
674};
675
676
677class DebuggerStatement: public Statement {
678 public:
679 virtual void Accept(AstVisitor* v);
680};
681
682
683class EmptyStatement: public Statement {
684 public:
685 virtual void Accept(AstVisitor* v);
686
687 // Type testing & conversion.
688 virtual EmptyStatement* AsEmptyStatement() { return this; }
689};
690
691
692class Literal: public Expression {
693 public:
694 explicit Literal(Handle<Object> handle) : handle_(handle) { }
695
696 virtual void Accept(AstVisitor* v);
697
698 // Type testing & conversion.
699 virtual Literal* AsLiteral() { return this; }
700
701 // Check if this literal is identical to the other literal.
702 bool IsIdenticalTo(const Literal* other) const {
703 return handle_.is_identical_to(other->handle_);
704 }
705
706 virtual bool IsValidJSON() { return true; }
707
Leon Clarkee46be812010-01-19 14:06:41 +0000708 virtual bool IsPropertyName() {
709 if (handle_->IsSymbol()) {
710 uint32_t ignored;
711 return !String::cast(*handle_)->AsArrayIndex(&ignored);
712 }
713 return false;
714 }
715
Steve Blocka7e24c12009-10-30 11:49:00 +0000716 // Identity testers.
717 bool IsNull() const { return handle_.is_identical_to(Factory::null_value()); }
718 bool IsTrue() const { return handle_.is_identical_to(Factory::true_value()); }
719 bool IsFalse() const {
720 return handle_.is_identical_to(Factory::false_value());
721 }
722
723 Handle<Object> handle() const { return handle_; }
724
725 private:
726 Handle<Object> handle_;
727};
728
729
730// Base class for literals that needs space in the corresponding JSFunction.
731class MaterializedLiteral: public Expression {
732 public:
733 explicit MaterializedLiteral(int literal_index, bool is_simple, int depth)
734 : literal_index_(literal_index), is_simple_(is_simple), depth_(depth) {}
735
736 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
737
738 int literal_index() { return literal_index_; }
739
740 // A materialized literal is simple if the values consist of only
741 // constants and simple object and array literals.
742 bool is_simple() const { return is_simple_; }
743
744 virtual bool IsValidJSON() { return true; }
745
746 int depth() const { return depth_; }
747
748 private:
749 int literal_index_;
750 bool is_simple_;
751 int depth_;
752};
753
754
755// An object literal has a boilerplate object that is used
756// for minimizing the work when constructing it at runtime.
757class ObjectLiteral: public MaterializedLiteral {
758 public:
759 // Property is used for passing information
760 // about an object literal's properties from the parser
761 // to the code generator.
762 class Property: public ZoneObject {
763 public:
764
765 enum Kind {
766 CONSTANT, // Property with constant value (compile time).
767 COMPUTED, // Property with computed value (execution time).
768 MATERIALIZED_LITERAL, // Property value is a materialized literal.
769 GETTER, SETTER, // Property is an accessor function.
770 PROTOTYPE // Property is __proto__.
771 };
772
773 Property(Literal* key, Expression* value);
774 Property(bool is_getter, FunctionLiteral* value);
775
776 Literal* key() { return key_; }
777 Expression* value() { return value_; }
778 Kind kind() { return kind_; }
779
Steve Blockd0582a62009-12-15 09:54:21 +0000780 bool IsCompileTimeValue();
781
Steve Blocka7e24c12009-10-30 11:49:00 +0000782 private:
783 Literal* key_;
784 Expression* value_;
785 Kind kind_;
786 };
787
788 ObjectLiteral(Handle<FixedArray> constant_properties,
789 ZoneList<Property*>* properties,
790 int literal_index,
791 bool is_simple,
792 int depth)
793 : MaterializedLiteral(literal_index, is_simple, depth),
794 constant_properties_(constant_properties),
795 properties_(properties) {}
796
797 virtual ObjectLiteral* AsObjectLiteral() { return this; }
798 virtual void Accept(AstVisitor* v);
799 virtual bool IsValidJSON();
800
801 Handle<FixedArray> constant_properties() const {
802 return constant_properties_;
803 }
804 ZoneList<Property*>* properties() const { return properties_; }
805
806 private:
807 Handle<FixedArray> constant_properties_;
808 ZoneList<Property*>* properties_;
809};
810
811
812// Node for capturing a regexp literal.
813class RegExpLiteral: public MaterializedLiteral {
814 public:
815 RegExpLiteral(Handle<String> pattern,
816 Handle<String> flags,
817 int literal_index)
818 : MaterializedLiteral(literal_index, false, 1),
819 pattern_(pattern),
820 flags_(flags) {}
821
822 virtual void Accept(AstVisitor* v);
823
824 Handle<String> pattern() const { return pattern_; }
825 Handle<String> flags() const { return flags_; }
826
827 private:
828 Handle<String> pattern_;
829 Handle<String> flags_;
830};
831
832// An array literal has a literals object that is used
833// for minimizing the work when constructing it at runtime.
834class ArrayLiteral: public MaterializedLiteral {
835 public:
Leon Clarkee46be812010-01-19 14:06:41 +0000836 ArrayLiteral(Handle<FixedArray> constant_elements,
Steve Blocka7e24c12009-10-30 11:49:00 +0000837 ZoneList<Expression*>* values,
838 int literal_index,
839 bool is_simple,
840 int depth)
841 : MaterializedLiteral(literal_index, is_simple, depth),
Leon Clarkee46be812010-01-19 14:06:41 +0000842 constant_elements_(constant_elements),
Steve Blocka7e24c12009-10-30 11:49:00 +0000843 values_(values) {}
844
845 virtual void Accept(AstVisitor* v);
846 virtual ArrayLiteral* AsArrayLiteral() { return this; }
847 virtual bool IsValidJSON();
848
Leon Clarkee46be812010-01-19 14:06:41 +0000849 Handle<FixedArray> constant_elements() const { return constant_elements_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000850 ZoneList<Expression*>* values() const { return values_; }
851
852 private:
Leon Clarkee46be812010-01-19 14:06:41 +0000853 Handle<FixedArray> constant_elements_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000854 ZoneList<Expression*>* values_;
855};
856
857
858// Node for constructing a context extension object for a catch block.
859// The catch context extension object has one property, the catch
860// variable, which should be DontDelete.
861class CatchExtensionObject: public Expression {
862 public:
863 CatchExtensionObject(Literal* key, VariableProxy* value)
864 : key_(key), value_(value) {
865 }
866
867 virtual void Accept(AstVisitor* v);
868
869 Literal* key() const { return key_; }
870 VariableProxy* value() const { return value_; }
871
872 private:
873 Literal* key_;
874 VariableProxy* value_;
875};
876
877
878class VariableProxy: public Expression {
879 public:
880 virtual void Accept(AstVisitor* v);
881
882 // Type testing & conversion
883 virtual Property* AsProperty() {
884 return var_ == NULL ? NULL : var_->AsProperty();
885 }
886 virtual VariableProxy* AsVariableProxy() { return this; }
887
888 Variable* AsVariable() {
889 return this == NULL || var_ == NULL ? NULL : var_->AsVariable();
890 }
891
892 virtual bool IsValidLeftHandSide() {
893 return var_ == NULL ? true : var_->IsValidLeftHandSide();
894 }
895
896 bool IsVariable(Handle<String> n) {
897 return !is_this() && name().is_identical_to(n);
898 }
899
900 bool IsArguments() {
901 Variable* variable = AsVariable();
902 return (variable == NULL) ? false : variable->is_arguments();
903 }
904
905 Handle<String> name() const { return name_; }
906 Variable* var() const { return var_; }
907 UseCount* var_uses() { return &var_uses_; }
908 UseCount* obj_uses() { return &obj_uses_; }
909 bool is_this() const { return is_this_; }
910 bool inside_with() const { return inside_with_; }
911
912 // Bind this proxy to the variable var.
913 void BindTo(Variable* var);
914
915 protected:
916 Handle<String> name_;
917 Variable* var_; // resolved variable, or NULL
918 bool is_this_;
919 bool inside_with_;
920
921 // VariableProxy usage info.
922 UseCount var_uses_; // uses of the variable value
923 UseCount obj_uses_; // uses of the object the variable points to
924
925 VariableProxy(Handle<String> name, bool is_this, bool inside_with);
926 explicit VariableProxy(bool is_this);
927
928 friend class Scope;
929};
930
931
932class VariableProxySentinel: public VariableProxy {
933 public:
934 virtual bool IsValidLeftHandSide() { return !is_this(); }
935 static VariableProxySentinel* this_proxy() { return &this_proxy_; }
936 static VariableProxySentinel* identifier_proxy() {
937 return &identifier_proxy_;
938 }
939
940 private:
941 explicit VariableProxySentinel(bool is_this) : VariableProxy(is_this) { }
942 static VariableProxySentinel this_proxy_;
943 static VariableProxySentinel identifier_proxy_;
944};
945
946
947class Slot: public Expression {
948 public:
949 enum Type {
950 // A slot in the parameter section on the stack. index() is
951 // the parameter index, counting left-to-right, starting at 0.
952 PARAMETER,
953
954 // A slot in the local section on the stack. index() is
955 // the variable index in the stack frame, starting at 0.
956 LOCAL,
957
958 // An indexed slot in a heap context. index() is the
959 // variable index in the context object on the heap,
960 // starting at 0. var()->scope() is the corresponding
961 // scope.
962 CONTEXT,
963
964 // A named slot in a heap context. var()->name() is the
965 // variable name in the context object on the heap,
966 // with lookup starting at the current context. index()
967 // is invalid.
Steve Blockd0582a62009-12-15 09:54:21 +0000968 LOOKUP
Steve Blocka7e24c12009-10-30 11:49:00 +0000969 };
970
971 Slot(Variable* var, Type type, int index)
972 : var_(var), type_(type), index_(index) {
973 ASSERT(var != NULL);
974 }
975
976 virtual void Accept(AstVisitor* v);
977
978 // Type testing & conversion
979 virtual Slot* AsSlot() { return this; }
980
981 // Accessors
982 Variable* var() const { return var_; }
983 Type type() const { return type_; }
984 int index() const { return index_; }
985 bool is_arguments() const { return var_->is_arguments(); }
986
987 private:
988 Variable* var_;
989 Type type_;
990 int index_;
991};
992
993
994class Property: public Expression {
995 public:
996 // Synthetic properties are property lookups introduced by the system,
997 // to objects that aren't visible to the user. Function calls to synthetic
998 // properties should use the global object as receiver, not the base object
999 // of the resolved Reference.
1000 enum Type { NORMAL, SYNTHETIC };
1001 Property(Expression* obj, Expression* key, int pos, Type type = NORMAL)
1002 : obj_(obj), key_(key), pos_(pos), type_(type) { }
1003
1004 virtual void Accept(AstVisitor* v);
1005
1006 // Type testing & conversion
1007 virtual Property* AsProperty() { return this; }
1008
1009 virtual bool IsValidLeftHandSide() { return true; }
1010
1011 Expression* obj() const { return obj_; }
1012 Expression* key() const { return key_; }
1013 int position() const { return pos_; }
1014 bool is_synthetic() const { return type_ == SYNTHETIC; }
1015
1016 // Returns a property singleton property access on 'this'. Used
1017 // during preparsing.
1018 static Property* this_property() { return &this_property_; }
1019
1020 private:
1021 Expression* obj_;
1022 Expression* key_;
1023 int pos_;
1024 Type type_;
1025
1026 // Dummy property used during preparsing.
1027 static Property this_property_;
1028};
1029
1030
1031class Call: public Expression {
1032 public:
1033 Call(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1034 : expression_(expression), arguments_(arguments), pos_(pos) { }
1035
1036 virtual void Accept(AstVisitor* v);
1037
1038 // Type testing and conversion.
1039 virtual Call* AsCall() { return this; }
1040
1041 Expression* expression() const { return expression_; }
1042 ZoneList<Expression*>* arguments() const { return arguments_; }
1043 int position() { return pos_; }
1044
1045 static Call* sentinel() { return &sentinel_; }
1046
1047 private:
1048 Expression* expression_;
1049 ZoneList<Expression*>* arguments_;
1050 int pos_;
1051
1052 static Call sentinel_;
1053};
1054
1055
1056class CallNew: public Expression {
1057 public:
1058 CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1059 : expression_(expression), arguments_(arguments), pos_(pos) { }
1060
1061 virtual void Accept(AstVisitor* v);
1062
1063 Expression* expression() const { return expression_; }
1064 ZoneList<Expression*>* arguments() const { return arguments_; }
1065 int position() { return pos_; }
1066
1067 private:
1068 Expression* expression_;
1069 ZoneList<Expression*>* arguments_;
1070 int pos_;
1071};
1072
1073
1074// The CallRuntime class does not represent any official JavaScript
1075// language construct. Instead it is used to call a C or JS function
1076// with a set of arguments. This is used from the builtins that are
1077// implemented in JavaScript (see "v8natives.js").
1078class CallRuntime: public Expression {
1079 public:
1080 CallRuntime(Handle<String> name,
1081 Runtime::Function* function,
1082 ZoneList<Expression*>* arguments)
1083 : name_(name), function_(function), arguments_(arguments) { }
1084
1085 virtual void Accept(AstVisitor* v);
1086
1087 Handle<String> name() const { return name_; }
1088 Runtime::Function* function() const { return function_; }
1089 ZoneList<Expression*>* arguments() const { return arguments_; }
Steve Blockd0582a62009-12-15 09:54:21 +00001090 bool is_jsruntime() const { return function_ == NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001091
1092 private:
1093 Handle<String> name_;
1094 Runtime::Function* function_;
1095 ZoneList<Expression*>* arguments_;
1096};
1097
1098
1099class UnaryOperation: public Expression {
1100 public:
1101 UnaryOperation(Token::Value op, Expression* expression)
1102 : op_(op), expression_(expression) {
1103 ASSERT(Token::IsUnaryOp(op));
1104 }
1105
1106 virtual void Accept(AstVisitor* v);
1107
1108 // Type testing & conversion
1109 virtual UnaryOperation* AsUnaryOperation() { return this; }
1110
1111 Token::Value op() const { return op_; }
1112 Expression* expression() const { return expression_; }
1113
1114 private:
1115 Token::Value op_;
1116 Expression* expression_;
1117};
1118
1119
1120class BinaryOperation: public Expression {
1121 public:
1122 BinaryOperation(Token::Value op, Expression* left, Expression* right)
1123 : op_(op), left_(left), right_(right) {
1124 ASSERT(Token::IsBinaryOp(op));
1125 }
1126
1127 virtual void Accept(AstVisitor* v);
1128
1129 // Type testing & conversion
1130 virtual BinaryOperation* AsBinaryOperation() { return this; }
1131
1132 // True iff the result can be safely overwritten (to avoid allocation).
1133 // False for operations that can return one of their operands.
1134 bool ResultOverwriteAllowed() {
1135 switch (op_) {
1136 case Token::COMMA:
1137 case Token::OR:
1138 case Token::AND:
1139 return false;
1140 case Token::BIT_OR:
1141 case Token::BIT_XOR:
1142 case Token::BIT_AND:
1143 case Token::SHL:
1144 case Token::SAR:
1145 case Token::SHR:
1146 case Token::ADD:
1147 case Token::SUB:
1148 case Token::MUL:
1149 case Token::DIV:
1150 case Token::MOD:
1151 return true;
1152 default:
1153 UNREACHABLE();
1154 }
1155 return false;
1156 }
1157
1158 Token::Value op() const { return op_; }
1159 Expression* left() const { return left_; }
1160 Expression* right() const { return right_; }
1161
1162 private:
1163 Token::Value op_;
1164 Expression* left_;
1165 Expression* right_;
1166};
1167
1168
1169class CountOperation: public Expression {
1170 public:
1171 CountOperation(bool is_prefix, Token::Value op, Expression* expression)
1172 : is_prefix_(is_prefix), op_(op), expression_(expression) {
1173 ASSERT(Token::IsCountOp(op));
1174 }
1175
1176 virtual void Accept(AstVisitor* v);
1177
1178 bool is_prefix() const { return is_prefix_; }
1179 bool is_postfix() const { return !is_prefix_; }
1180 Token::Value op() const { return op_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001181 Token::Value binary_op() {
1182 return op_ == Token::INC ? Token::ADD : Token::SUB;
1183 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001184 Expression* expression() const { return expression_; }
1185
1186 virtual void MarkAsStatement() { is_prefix_ = true; }
1187
1188 private:
1189 bool is_prefix_;
1190 Token::Value op_;
1191 Expression* expression_;
1192};
1193
1194
1195class CompareOperation: public Expression {
1196 public:
1197 CompareOperation(Token::Value op, Expression* left, Expression* right)
Leon Clarkee46be812010-01-19 14:06:41 +00001198 : op_(op), left_(left), right_(right), is_for_loop_condition_(false) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001199 ASSERT(Token::IsCompareOp(op));
1200 }
1201
1202 virtual void Accept(AstVisitor* v);
1203
1204 Token::Value op() const { return op_; }
1205 Expression* left() const { return left_; }
1206 Expression* right() const { return right_; }
1207
Leon Clarkee46be812010-01-19 14:06:41 +00001208 // Accessors for flag whether this compare operation is hanging of a for loop.
1209 bool is_for_loop_condition() const { return is_for_loop_condition_; }
1210 void set_is_for_loop_condition() { is_for_loop_condition_ = true; }
1211
1212 // Type testing & conversion
1213 virtual CompareOperation* AsCompareOperation() { return this; }
1214
Steve Blocka7e24c12009-10-30 11:49:00 +00001215 private:
1216 Token::Value op_;
1217 Expression* left_;
1218 Expression* right_;
Leon Clarkee46be812010-01-19 14:06:41 +00001219 bool is_for_loop_condition_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001220};
1221
1222
1223class Conditional: public Expression {
1224 public:
1225 Conditional(Expression* condition,
1226 Expression* then_expression,
1227 Expression* else_expression)
1228 : condition_(condition),
1229 then_expression_(then_expression),
1230 else_expression_(else_expression) { }
1231
1232 virtual void Accept(AstVisitor* v);
1233
1234 Expression* condition() const { return condition_; }
1235 Expression* then_expression() const { return then_expression_; }
1236 Expression* else_expression() const { return else_expression_; }
1237
1238 private:
1239 Expression* condition_;
1240 Expression* then_expression_;
1241 Expression* else_expression_;
1242};
1243
1244
1245class Assignment: public Expression {
1246 public:
1247 Assignment(Token::Value op, Expression* target, Expression* value, int pos)
1248 : op_(op), target_(target), value_(value), pos_(pos),
1249 block_start_(false), block_end_(false) {
1250 ASSERT(Token::IsAssignmentOp(op));
1251 }
1252
1253 virtual void Accept(AstVisitor* v);
1254 virtual Assignment* AsAssignment() { return this; }
1255
1256 Token::Value binary_op() const;
1257
1258 Token::Value op() const { return op_; }
1259 Expression* target() const { return target_; }
1260 Expression* value() const { return value_; }
1261 int position() { return pos_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001262 // This check relies on the definition order of token in token.h.
1263 bool is_compound() const { return op() > Token::ASSIGN; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001264
1265 // An initialization block is a series of statments of the form
1266 // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1267 // ending of these blocks to allow for optimizations of initialization
1268 // blocks.
1269 bool starts_initialization_block() { return block_start_; }
1270 bool ends_initialization_block() { return block_end_; }
1271 void mark_block_start() { block_start_ = true; }
1272 void mark_block_end() { block_end_ = true; }
1273
1274 private:
1275 Token::Value op_;
1276 Expression* target_;
1277 Expression* value_;
1278 int pos_;
1279 bool block_start_;
1280 bool block_end_;
1281};
1282
1283
1284class Throw: public Expression {
1285 public:
1286 Throw(Expression* exception, int pos)
1287 : exception_(exception), pos_(pos) {}
1288
1289 virtual void Accept(AstVisitor* v);
1290 Expression* exception() const { return exception_; }
1291 int position() const { return pos_; }
1292
1293 private:
1294 Expression* exception_;
1295 int pos_;
1296};
1297
1298
1299class FunctionLiteral: public Expression {
1300 public:
1301 FunctionLiteral(Handle<String> name,
1302 Scope* scope,
1303 ZoneList<Statement*>* body,
1304 int materialized_literal_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00001305 int expected_property_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00001306 bool has_only_simple_this_property_assignments,
1307 Handle<FixedArray> this_property_assignments,
1308 int num_parameters,
1309 int start_position,
1310 int end_position,
1311 bool is_expression)
1312 : name_(name),
1313 scope_(scope),
1314 body_(body),
1315 materialized_literal_count_(materialized_literal_count),
Steve Blocka7e24c12009-10-30 11:49:00 +00001316 expected_property_count_(expected_property_count),
Steve Blocka7e24c12009-10-30 11:49:00 +00001317 has_only_simple_this_property_assignments_(
1318 has_only_simple_this_property_assignments),
1319 this_property_assignments_(this_property_assignments),
1320 num_parameters_(num_parameters),
1321 start_position_(start_position),
1322 end_position_(end_position),
1323 is_expression_(is_expression),
1324 loop_nesting_(0),
1325 function_token_position_(RelocInfo::kNoPosition),
Steve Blockd0582a62009-12-15 09:54:21 +00001326 inferred_name_(Heap::empty_string()),
Leon Clarked91b9f72010-01-27 17:25:45 +00001327 try_full_codegen_(false) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001328#ifdef DEBUG
1329 already_compiled_ = false;
1330#endif
1331 }
1332
1333 virtual void Accept(AstVisitor* v);
1334
1335 // Type testing & conversion
1336 virtual FunctionLiteral* AsFunctionLiteral() { return this; }
1337
1338 Handle<String> name() const { return name_; }
1339 Scope* scope() const { return scope_; }
1340 ZoneList<Statement*>* body() const { return body_; }
1341 void set_function_token_position(int pos) { function_token_position_ = pos; }
1342 int function_token_position() const { return function_token_position_; }
1343 int start_position() const { return start_position_; }
1344 int end_position() const { return end_position_; }
1345 bool is_expression() const { return is_expression_; }
1346
1347 int materialized_literal_count() { return materialized_literal_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001348 int expected_property_count() { return expected_property_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001349 bool has_only_simple_this_property_assignments() {
1350 return has_only_simple_this_property_assignments_;
1351 }
1352 Handle<FixedArray> this_property_assignments() {
1353 return this_property_assignments_;
1354 }
1355 int num_parameters() { return num_parameters_; }
1356
1357 bool AllowsLazyCompilation();
1358
1359 bool loop_nesting() const { return loop_nesting_; }
1360 void set_loop_nesting(int nesting) { loop_nesting_ = nesting; }
1361
1362 Handle<String> inferred_name() const { return inferred_name_; }
1363 void set_inferred_name(Handle<String> inferred_name) {
1364 inferred_name_ = inferred_name;
1365 }
1366
Leon Clarked91b9f72010-01-27 17:25:45 +00001367 bool try_full_codegen() { return try_full_codegen_; }
1368 void set_try_full_codegen(bool flag) { try_full_codegen_ = flag; }
Steve Blockd0582a62009-12-15 09:54:21 +00001369
Steve Blocka7e24c12009-10-30 11:49:00 +00001370#ifdef DEBUG
1371 void mark_as_compiled() {
1372 ASSERT(!already_compiled_);
1373 already_compiled_ = true;
1374 }
1375#endif
1376
1377 private:
1378 Handle<String> name_;
1379 Scope* scope_;
1380 ZoneList<Statement*>* body_;
1381 int materialized_literal_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001382 int expected_property_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001383 bool has_only_simple_this_property_assignments_;
1384 Handle<FixedArray> this_property_assignments_;
1385 int num_parameters_;
1386 int start_position_;
1387 int end_position_;
1388 bool is_expression_;
1389 int loop_nesting_;
1390 int function_token_position_;
1391 Handle<String> inferred_name_;
Leon Clarked91b9f72010-01-27 17:25:45 +00001392 bool try_full_codegen_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001393#ifdef DEBUG
1394 bool already_compiled_;
1395#endif
1396};
1397
1398
1399class FunctionBoilerplateLiteral: public Expression {
1400 public:
1401 explicit FunctionBoilerplateLiteral(Handle<JSFunction> boilerplate)
1402 : boilerplate_(boilerplate) {
1403 ASSERT(boilerplate->IsBoilerplate());
1404 }
1405
1406 Handle<JSFunction> boilerplate() const { return boilerplate_; }
1407
1408 virtual void Accept(AstVisitor* v);
1409
1410 private:
1411 Handle<JSFunction> boilerplate_;
1412};
1413
1414
1415class ThisFunction: public Expression {
1416 public:
1417 virtual void Accept(AstVisitor* v);
1418};
1419
1420
1421// ----------------------------------------------------------------------------
1422// Regular expressions
1423
1424
1425class RegExpVisitor BASE_EMBEDDED {
1426 public:
1427 virtual ~RegExpVisitor() { }
1428#define MAKE_CASE(Name) \
1429 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
1430 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
1431#undef MAKE_CASE
1432};
1433
1434
1435class RegExpTree: public ZoneObject {
1436 public:
1437 static const int kInfinity = kMaxInt;
1438 virtual ~RegExpTree() { }
1439 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
1440 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1441 RegExpNode* on_success) = 0;
1442 virtual bool IsTextElement() { return false; }
1443 virtual bool IsAnchored() { return false; }
1444 virtual int min_match() = 0;
1445 virtual int max_match() = 0;
1446 // Returns the interval of registers used for captures within this
1447 // expression.
1448 virtual Interval CaptureRegisters() { return Interval::Empty(); }
1449 virtual void AppendToText(RegExpText* text);
1450 SmartPointer<const char> ToString();
1451#define MAKE_ASTYPE(Name) \
1452 virtual RegExp##Name* As##Name(); \
1453 virtual bool Is##Name();
1454 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
1455#undef MAKE_ASTYPE
1456};
1457
1458
1459class RegExpDisjunction: public RegExpTree {
1460 public:
1461 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
1462 virtual void* Accept(RegExpVisitor* visitor, void* data);
1463 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1464 RegExpNode* on_success);
1465 virtual RegExpDisjunction* AsDisjunction();
1466 virtual Interval CaptureRegisters();
1467 virtual bool IsDisjunction();
1468 virtual bool IsAnchored();
1469 virtual int min_match() { return min_match_; }
1470 virtual int max_match() { return max_match_; }
1471 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
1472 private:
1473 ZoneList<RegExpTree*>* alternatives_;
1474 int min_match_;
1475 int max_match_;
1476};
1477
1478
1479class RegExpAlternative: public RegExpTree {
1480 public:
1481 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
1482 virtual void* Accept(RegExpVisitor* visitor, void* data);
1483 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1484 RegExpNode* on_success);
1485 virtual RegExpAlternative* AsAlternative();
1486 virtual Interval CaptureRegisters();
1487 virtual bool IsAlternative();
1488 virtual bool IsAnchored();
1489 virtual int min_match() { return min_match_; }
1490 virtual int max_match() { return max_match_; }
1491 ZoneList<RegExpTree*>* nodes() { return nodes_; }
1492 private:
1493 ZoneList<RegExpTree*>* nodes_;
1494 int min_match_;
1495 int max_match_;
1496};
1497
1498
1499class RegExpAssertion: public RegExpTree {
1500 public:
1501 enum Type {
1502 START_OF_LINE,
1503 START_OF_INPUT,
1504 END_OF_LINE,
1505 END_OF_INPUT,
1506 BOUNDARY,
1507 NON_BOUNDARY
1508 };
1509 explicit RegExpAssertion(Type type) : type_(type) { }
1510 virtual void* Accept(RegExpVisitor* visitor, void* data);
1511 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1512 RegExpNode* on_success);
1513 virtual RegExpAssertion* AsAssertion();
1514 virtual bool IsAssertion();
1515 virtual bool IsAnchored();
1516 virtual int min_match() { return 0; }
1517 virtual int max_match() { return 0; }
1518 Type type() { return type_; }
1519 private:
1520 Type type_;
1521};
1522
1523
1524class CharacterSet BASE_EMBEDDED {
1525 public:
1526 explicit CharacterSet(uc16 standard_set_type)
1527 : ranges_(NULL),
1528 standard_set_type_(standard_set_type) {}
1529 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
1530 : ranges_(ranges),
1531 standard_set_type_(0) {}
1532 ZoneList<CharacterRange>* ranges();
1533 uc16 standard_set_type() { return standard_set_type_; }
1534 void set_standard_set_type(uc16 special_set_type) {
1535 standard_set_type_ = special_set_type;
1536 }
1537 bool is_standard() { return standard_set_type_ != 0; }
Leon Clarkee46be812010-01-19 14:06:41 +00001538 void Canonicalize();
Steve Blocka7e24c12009-10-30 11:49:00 +00001539 private:
1540 ZoneList<CharacterRange>* ranges_;
1541 // If non-zero, the value represents a standard set (e.g., all whitespace
1542 // characters) without having to expand the ranges.
1543 uc16 standard_set_type_;
1544};
1545
1546
1547class RegExpCharacterClass: public RegExpTree {
1548 public:
1549 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
1550 : set_(ranges),
1551 is_negated_(is_negated) { }
1552 explicit RegExpCharacterClass(uc16 type)
1553 : set_(type),
1554 is_negated_(false) { }
1555 virtual void* Accept(RegExpVisitor* visitor, void* data);
1556 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1557 RegExpNode* on_success);
1558 virtual RegExpCharacterClass* AsCharacterClass();
1559 virtual bool IsCharacterClass();
1560 virtual bool IsTextElement() { return true; }
1561 virtual int min_match() { return 1; }
1562 virtual int max_match() { return 1; }
1563 virtual void AppendToText(RegExpText* text);
1564 CharacterSet character_set() { return set_; }
1565 // TODO(lrn): Remove need for complex version if is_standard that
1566 // recognizes a mangled standard set and just do { return set_.is_special(); }
1567 bool is_standard();
1568 // Returns a value representing the standard character set if is_standard()
1569 // returns true.
1570 // Currently used values are:
1571 // s : unicode whitespace
1572 // S : unicode non-whitespace
1573 // w : ASCII word character (digit, letter, underscore)
1574 // W : non-ASCII word character
1575 // d : ASCII digit
1576 // D : non-ASCII digit
1577 // . : non-unicode non-newline
1578 // * : All characters
1579 uc16 standard_type() { return set_.standard_set_type(); }
1580 ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
1581 bool is_negated() { return is_negated_; }
1582 private:
1583 CharacterSet set_;
1584 bool is_negated_;
1585};
1586
1587
1588class RegExpAtom: public RegExpTree {
1589 public:
1590 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
1591 virtual void* Accept(RegExpVisitor* visitor, void* data);
1592 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1593 RegExpNode* on_success);
1594 virtual RegExpAtom* AsAtom();
1595 virtual bool IsAtom();
1596 virtual bool IsTextElement() { return true; }
1597 virtual int min_match() { return data_.length(); }
1598 virtual int max_match() { return data_.length(); }
1599 virtual void AppendToText(RegExpText* text);
1600 Vector<const uc16> data() { return data_; }
1601 int length() { return data_.length(); }
1602 private:
1603 Vector<const uc16> data_;
1604};
1605
1606
1607class RegExpText: public RegExpTree {
1608 public:
1609 RegExpText() : elements_(2), length_(0) {}
1610 virtual void* Accept(RegExpVisitor* visitor, void* data);
1611 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1612 RegExpNode* on_success);
1613 virtual RegExpText* AsText();
1614 virtual bool IsText();
1615 virtual bool IsTextElement() { return true; }
1616 virtual int min_match() { return length_; }
1617 virtual int max_match() { return length_; }
1618 virtual void AppendToText(RegExpText* text);
1619 void AddElement(TextElement elm) {
1620 elements_.Add(elm);
1621 length_ += elm.length();
1622 };
1623 ZoneList<TextElement>* elements() { return &elements_; }
1624 private:
1625 ZoneList<TextElement> elements_;
1626 int length_;
1627};
1628
1629
1630class RegExpQuantifier: public RegExpTree {
1631 public:
Leon Clarkee46be812010-01-19 14:06:41 +00001632 enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
1633 RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
1634 : body_(body),
1635 min_(min),
Steve Blocka7e24c12009-10-30 11:49:00 +00001636 max_(max),
Leon Clarkee46be812010-01-19 14:06:41 +00001637 min_match_(min * body->min_match()),
1638 type_(type) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001639 if (max > 0 && body->max_match() > kInfinity / max) {
1640 max_match_ = kInfinity;
1641 } else {
1642 max_match_ = max * body->max_match();
1643 }
1644 }
1645 virtual void* Accept(RegExpVisitor* visitor, void* data);
1646 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1647 RegExpNode* on_success);
1648 static RegExpNode* ToNode(int min,
1649 int max,
1650 bool is_greedy,
1651 RegExpTree* body,
1652 RegExpCompiler* compiler,
1653 RegExpNode* on_success,
1654 bool not_at_start = false);
1655 virtual RegExpQuantifier* AsQuantifier();
1656 virtual Interval CaptureRegisters();
1657 virtual bool IsQuantifier();
1658 virtual int min_match() { return min_match_; }
1659 virtual int max_match() { return max_match_; }
1660 int min() { return min_; }
1661 int max() { return max_; }
Leon Clarkee46be812010-01-19 14:06:41 +00001662 bool is_possessive() { return type_ == POSSESSIVE; }
1663 bool is_non_greedy() { return type_ == NON_GREEDY; }
1664 bool is_greedy() { return type_ == GREEDY; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001665 RegExpTree* body() { return body_; }
1666 private:
Leon Clarkee46be812010-01-19 14:06:41 +00001667 RegExpTree* body_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001668 int min_;
1669 int max_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001670 int min_match_;
1671 int max_match_;
Leon Clarkee46be812010-01-19 14:06:41 +00001672 Type type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001673};
1674
1675
1676class RegExpCapture: public RegExpTree {
1677 public:
1678 explicit RegExpCapture(RegExpTree* body, int index)
1679 : body_(body), index_(index) { }
1680 virtual void* Accept(RegExpVisitor* visitor, void* data);
1681 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1682 RegExpNode* on_success);
1683 static RegExpNode* ToNode(RegExpTree* body,
1684 int index,
1685 RegExpCompiler* compiler,
1686 RegExpNode* on_success);
1687 virtual RegExpCapture* AsCapture();
1688 virtual bool IsAnchored();
1689 virtual Interval CaptureRegisters();
1690 virtual bool IsCapture();
1691 virtual int min_match() { return body_->min_match(); }
1692 virtual int max_match() { return body_->max_match(); }
1693 RegExpTree* body() { return body_; }
1694 int index() { return index_; }
1695 static int StartRegister(int index) { return index * 2; }
1696 static int EndRegister(int index) { return index * 2 + 1; }
1697 private:
1698 RegExpTree* body_;
1699 int index_;
1700};
1701
1702
1703class RegExpLookahead: public RegExpTree {
1704 public:
1705 RegExpLookahead(RegExpTree* body,
1706 bool is_positive,
1707 int capture_count,
1708 int capture_from)
1709 : body_(body),
1710 is_positive_(is_positive),
1711 capture_count_(capture_count),
1712 capture_from_(capture_from) { }
1713
1714 virtual void* Accept(RegExpVisitor* visitor, void* data);
1715 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1716 RegExpNode* on_success);
1717 virtual RegExpLookahead* AsLookahead();
1718 virtual Interval CaptureRegisters();
1719 virtual bool IsLookahead();
1720 virtual bool IsAnchored();
1721 virtual int min_match() { return 0; }
1722 virtual int max_match() { return 0; }
1723 RegExpTree* body() { return body_; }
1724 bool is_positive() { return is_positive_; }
1725 int capture_count() { return capture_count_; }
1726 int capture_from() { return capture_from_; }
1727 private:
1728 RegExpTree* body_;
1729 bool is_positive_;
1730 int capture_count_;
1731 int capture_from_;
1732};
1733
1734
1735class RegExpBackReference: public RegExpTree {
1736 public:
1737 explicit RegExpBackReference(RegExpCapture* capture)
1738 : capture_(capture) { }
1739 virtual void* Accept(RegExpVisitor* visitor, void* data);
1740 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1741 RegExpNode* on_success);
1742 virtual RegExpBackReference* AsBackReference();
1743 virtual bool IsBackReference();
1744 virtual int min_match() { return 0; }
1745 virtual int max_match() { return capture_->max_match(); }
1746 int index() { return capture_->index(); }
1747 RegExpCapture* capture() { return capture_; }
1748 private:
1749 RegExpCapture* capture_;
1750};
1751
1752
1753class RegExpEmpty: public RegExpTree {
1754 public:
1755 RegExpEmpty() { }
1756 virtual void* Accept(RegExpVisitor* visitor, void* data);
1757 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1758 RegExpNode* on_success);
1759 virtual RegExpEmpty* AsEmpty();
1760 virtual bool IsEmpty();
1761 virtual int min_match() { return 0; }
1762 virtual int max_match() { return 0; }
1763 static RegExpEmpty* GetInstance() { return &kInstance; }
1764 private:
1765 static RegExpEmpty kInstance;
1766};
1767
1768
1769// ----------------------------------------------------------------------------
1770// Basic visitor
1771// - leaf node visitors are abstract.
1772
1773class AstVisitor BASE_EMBEDDED {
1774 public:
1775 AstVisitor() : stack_overflow_(false) { }
1776 virtual ~AstVisitor() { }
1777
1778 // Dispatch
1779 void Visit(AstNode* node) { node->Accept(this); }
1780
1781 // Iteration
Steve Block3ce2e202009-11-05 08:53:23 +00001782 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
Steve Blocka7e24c12009-10-30 11:49:00 +00001783 virtual void VisitStatements(ZoneList<Statement*>* statements);
1784 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
1785
1786 // Stack overflow tracking support.
1787 bool HasStackOverflow() const { return stack_overflow_; }
1788 bool CheckStackOverflow() {
1789 if (stack_overflow_) return true;
1790 StackLimitCheck check;
1791 if (!check.HasOverflowed()) return false;
1792 return (stack_overflow_ = true);
1793 }
1794
1795 // If a stack-overflow exception is encountered when visiting a
1796 // node, calling SetStackOverflow will make sure that the visitor
1797 // bails out without visiting more nodes.
1798 void SetStackOverflow() { stack_overflow_ = true; }
1799
1800
1801 // Individual nodes
1802#define DEF_VISIT(type) \
1803 virtual void Visit##type(type* node) = 0;
1804 AST_NODE_LIST(DEF_VISIT)
1805#undef DEF_VISIT
1806
1807 private:
1808 bool stack_overflow_;
1809};
1810
1811
1812} } // namespace v8::internal
1813
1814#endif // V8_AST_H_