My favorites | Sign in
v8
Project Home Downloads Wiki Issues Source Code Search
Checkout   Browse   Changes  
Changes to /trunk/src/ast.h
r0 vs. r8 Compare: vs.  Format:
Revision r8
Go to: 
Project members, sign in to write a code review
/trunk/src/ast.h /trunk/src/ast.h   r8
Properties
 svn:eol-style
   1 native
  
Contents
  1 // Copyright 2006-2008 Google Inc. 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"
  33 #include "runtime.h"
  34 #include "token.h"
  35 #include "variables.h"
  36 #include "macro-assembler.h"
  37
  38 namespace v8 { namespace internal {
  39
  40 // The abstract syntax tree is an intermediate, light-weight
  41 // representation of the parsed JavaScript code suitable for
  42 // compilation to native code.
  43
  44 // Nodes are allocated in a separate zone, which allows faster
  45 // allocation and constant-time deallocation of the entire syntax
  46 // tree.
  47
  48
  49 // ----------------------------------------------------------------------------
  50 // Nodes of the abstract syntax tree. Only concrete classes are
  51 // enumerated here.
  52
  53 #define NODE_LIST(V) \
  54 V(Block) \
  55 V(Declaration) \
  56 V(ExpressionStatement) \
  57 V(EmptyStatement) \
  58 V(IfStatement) \
  59 V(ContinueStatement) \
  60 V(BreakStatement) \
  61 V(ReturnStatement) \
  62 V(WithEnterStatement) \
  63 V(WithExitStatement) \
  64 V(SwitchStatement) \
  65 V(LoopStatement) \
  66 V(ForInStatement) \
  67 V(TryCatch) \
  68 V(TryFinally) \
  69 V(DebuggerStatement) \
  70 V(FunctionLiteral) \
  71 V(FunctionBoilerplateLiteral) \
  72 V(Conditional) \
  73 V(Slot) \
  74 V(VariableProxy) \
  75 V(Literal) \
  76 V(RegExpLiteral) \
  77 V(ObjectLiteral) \
  78 V(ArrayLiteral) \
  79 V(Assignment) \
  80 V(Throw) \
  81 V(Property) \
  82 V(Call) \
  83 V(CallNew) \
  84 V(CallRuntime) \
  85 V(UnaryOperation) \
  86 V(CountOperation) \
  87 V(BinaryOperation) \
  88 V(CompareOperation) \
  89 V(ThisFunction)
  90
  91
  92 #define DEF_FORWARD_DECLARATION(type) class type;
  93 NODE_LIST(DEF_FORWARD_DECLARATION)
  94 #undef DEF_FORWARD_DECLARATION
  95
  96
  97 // Typedef only introduced to avoid unreadable code.
  98 // Please do appreciate the required space in "> >".
  99 typedef ZoneList<Handle<String> > ZoneStringList;
  100
  101
  102 class Node: public ZoneObject {
  103 public:
  104 Node(): statement_pos_(kNoPosition) { }
  105 virtual ~Node() { }
  106 virtual void Accept(Visitor* v) = 0;
  107
  108 // Type testing & conversion.
  109 virtual Statement* AsStatement() { return NULL; }
  110 virtual ExpressionStatement* AsExpressionStatement() { return NULL; }
  111 virtual EmptyStatement* AsEmptyStatement() { return NULL; }
  112 virtual Expression* AsExpression() { return NULL; }
  113 virtual Literal* AsLiteral() { return NULL; }
  114 virtual Slot* AsSlot() { return NULL; }
  115 virtual VariableProxy* AsVariableProxy() { return NULL; }
  116 virtual Property* AsProperty() { return NULL; }
  117 virtual Call* AsCall() { return NULL; }
  118 virtual LabelCollector* AsLabelCollector() { return NULL; }
  119 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
  120 virtual IterationStatement* AsIterationStatement() { return NULL; }
  121 virtual UnaryOperation* AsUnaryOperation() { return NULL; }
  122 virtual BinaryOperation* AsBinaryOperation() { return NULL; }
  123 virtual Assignment* AsAssignment() { return NULL; }
  124 virtual FunctionLiteral* AsFunctionLiteral() { return NULL; }
  125
  126 void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
  127 int statement_pos() const { return statement_pos_; }
  128
  129 private:
  130 int statement_pos_;
  131 };
  132
  133
  134 class Statement: public Node {
  135 public:
  136 virtual Statement* AsStatement() { return this; }
  137 virtual ReturnStatement* AsReturnStatement() { return NULL; }
  138
  139 bool IsEmpty() { return AsEmptyStatement() != NULL; }
  140 };
  141
  142
  143 class Expression: public Node {
  144 public:
  145 virtual Expression* AsExpression() { return this; }
  146
  147 virtual bool IsValidLeftHandSide() { return false; }
  148
  149 // Mark the expression as being compiled as an expression
  150 // statement. This is used to transform postfix increments to
  151 // (faster) prefix increments.
  152 virtual void MarkAsStatement() { /* do nothing */ }
  153 };
  154
  155
  156 /**
  157 * A sentinel used during pre parsing that represents some expression
  158 * that is a valid left hand side without having to actually build
  159 * the expression.
  160 */
  161 class ValidLeftHandSideSentinel: public Expression {
  162 public:
  163 virtual bool IsValidLeftHandSide() { return true; }
  164 virtual void Accept(Visitor* v) { UNREACHABLE(); }
  165 static ValidLeftHandSideSentinel* instance() { return &instance_; }
  166 private:
  167 static ValidLeftHandSideSentinel instance_;
  168 };
  169
  170
  171 class BreakableStatement: public Statement {
  172 public:
  173 enum Type {
  174 TARGET_FOR_ANONYMOUS,
  175 TARGET_FOR_NAMED_ONLY
  176 };
  177
  178 // The labels associated with this statement. May be NULL;
  179 // if it is != NULL, guaranteed to contain at least one entry.
  180 ZoneStringList* labels() const { return labels_; }
  181
  182 // Type testing & conversion.
  183 virtual BreakableStatement* AsBreakableStatement() { return this; }
  184
  185 // Code generation
  186 Label* break_target() { return &break_target_; }
  187
  188 // Used during code generation for restoring the stack when a
  189 // break/continue crosses a statement that keeps stuff on the stack.
  190 int break_stack_height() { return break_stack_height_; }
  191 void set_break_stack_height(int height) { break_stack_height_ = height; }
  192
  193 // Testers.
  194 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
  195
  196 protected:
  197 BreakableStatement(ZoneStringList* labels, Type type)
  198 : labels_(labels), type_(type) {
  199 ASSERT(labels == NULL || labels->length() > 0);
  200 }
  201
  202 private:
  203 ZoneStringList* labels_;
  204 Type type_;
  205 Label break_target_;
  206 int break_stack_height_;
  207 };
  208
  209
  210 class Block: public BreakableStatement {
  211 public:
  212 Block(ZoneStringList* labels, int capacity, bool is_initializer_block)
  213 : BreakableStatement(labels, TARGET_FOR_NAMED_ONLY),
  214 statements_(capacity),
  215 is_initializer_block_(is_initializer_block) { }
  216
  217 virtual void Accept(Visitor* v);
  218
  219 void AddStatement(Statement* statement) { statements_.Add(statement); }
  220
  221 ZoneList<Statement*>* statements() { return &statements_; }
  222 bool is_initializer_block() const { return is_initializer_block_; }
  223
  224 private:
  225 ZoneList<Statement*> statements_;
  226 bool is_initializer_block_;
  227 };
  228
  229
  230 class Declaration: public Node {
  231 public:
  232 Declaration(VariableProxy* proxy, Variable::Mode mode, FunctionLiteral* fun)
  233 : proxy_(proxy),
  234 mode_(mode),
  235 fun_(fun) {
  236 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
  237 // At the moment there are no "const functions"'s in JavaScript...
  238 ASSERT(fun == NULL || mode == Variable::VAR);
  239 }
  240
  241 virtual void Accept(Visitor* v);
  242
  243 VariableProxy* proxy() const { return proxy_; }
  244 Variable::Mode mode() const { return mode_; }
  245 FunctionLiteral* fun() const { return fun_; } // may be NULL
  246
  247 private:
  248 VariableProxy* proxy_;
  249 Variable::Mode mode_;
  250 FunctionLiteral* fun_;
  251 };
  252
  253
  254 class IterationStatement: public BreakableStatement {
  255 public:
  256 // Type testing & conversion.
  257 virtual IterationStatement* AsIterationStatement() { return this; }
  258
  259 Statement* body() const { return body_; }
  260
  261 // Code generation
  262 Label* continue_target() { return &continue_target_; }
  263
  264 protected:
  265 explicit IterationStatement(ZoneStringList* labels)
  266 : BreakableStatement(labels, TARGET_FOR_ANONYMOUS), body_(NULL) { }
  267
  268 void Initialize(Statement* body) {
  269 body_ = body;
  270 }
  271
  272 private:
  273 Statement* body_;
  274 Label continue_target_;
  275 };
  276
  277
  278 class LoopStatement: public IterationStatement {
  279 public:
  280 enum Type { DO_LOOP, FOR_LOOP, WHILE_LOOP };
  281
  282 LoopStatement(ZoneStringList* labels, Type type)
  283 : IterationStatement(labels), type_(type), init_(NULL),
  284 cond_(NULL), next_(NULL) { }
  285
  286 void Initialize(Statement* init,
  287 Expression* cond,
  288 Statement* next,
  289 Statement* body) {
  290 ASSERT(init == NULL || type_ == FOR_LOOP);
  291 ASSERT(next == NULL || type_ == FOR_LOOP);
  292 IterationStatement::Initialize(body);
  293 init_ = init;
  294 cond_ = cond;
  295 next_ = next;
  296 }
  297
  298 virtual void Accept(Visitor* v);
  299
  300 Type type() const { return type_; }
  301 Statement* init() const { return init_; }
  302 Expression* cond() const { return cond_; }
  303 Statement* next() const { return next_; }
  304
  305 #ifdef DEBUG
  306 const char* OperatorString() const;
  307 #endif
  308
  309 private:
  310 Type type_;
  311 Statement* init_;
  312 Expression* cond_;
  313 Statement* next_;
  314 };
  315
  316
  317 class ForInStatement: public IterationStatement {
  318 public:
  319 explicit ForInStatement(ZoneStringList* labels)
  320 : IterationStatement(labels), each_(NULL), enumerable_(NULL) { }
  321
  322 void Initialize(Expression* each, Expression* enumerable, Statement* body) {
  323 IterationStatement::Initialize(body);
  324 each_ = each;
  325 enumerable_ = enumerable;
  326 }
  327
  328 virtual void Accept(Visitor* v);
  329
  330 Expression* each() const { return each_; }
  331 Expression* enumerable() const { return enumerable_; }
  332
  333 private:
  334 Expression* each_;
  335 Expression* enumerable_;
  336 };
  337
  338
  339 class ExpressionStatement: public Statement {
  340 public:
  341 explicit ExpressionStatement(Expression* expression)
  342 : expression_(expression) { }
  343
  344 virtual void Accept(Visitor* v);
  345
  346 // Type testing & conversion.
  347 virtual ExpressionStatement* AsExpressionStatement() { return this; }
  348
  349 void set_expression(Expression* e) { expression_ = e; }
  350 Expression* expression() { return expression_; }
  351
  352 private:
  353 Expression* expression_;
  354 };
  355
  356
  357 class ContinueStatement: public Statement {
  358 public:
  359 explicit ContinueStatement(IterationStatement* target)
  360 : target_(target) { }
  361
  362 virtual void Accept(Visitor* v);
  363
  364 IterationStatement* target() const { return target_; }
  365
  366 private:
  367 IterationStatement* target_;
  368 };
  369
  370
  371 class BreakStatement: public Statement {
  372 public:
  373 explicit BreakStatement(BreakableStatement* target)
  374 : target_(target) { }
  375
  376 virtual void Accept(Visitor* v);
  377
  378 BreakableStatement* target() const { return target_; }
  379
  380 private:
  381 BreakableStatement* target_;
  382 };
  383
  384
  385 class ReturnStatement: public Statement {
  386 public:
  387 explicit ReturnStatement(Expression* expression)
  388 : expression_(expression) { }
  389
  390 virtual void Accept(Visitor* v);
  391
  392 // Type testing & conversion.
  393 virtual ReturnStatement* AsReturnStatement() { return this; }
  394
  395 Expression* expression() { return expression_; }
  396
  397 private:
  398 Expression* expression_;
  399 };
  400
  401
  402 class WithEnterStatement: public Statement {
  403 public:
  404 explicit WithEnterStatement(Expression* expression)
  405 : expression_(expression) { }
  406
  407 virtual void Accept(Visitor* v);
  408
  409 Expression* expression() const { return expression_; }
  410
  411 private:
  412 Expression* expression_;
  413 };
  414
  415
  416 class WithExitStatement: public Statement {
  417 public:
  418 WithExitStatement() { }
  419
  420 virtual void Accept(Visitor* v);
  421 };
  422
  423
  424 class CaseClause: public ZoneObject {
  425 public:
  426 CaseClause(Expression* label, ZoneList<Statement*>* statements)
  427 : label_(label), statements_(statements) { }
  428
  429 bool is_default() const { return label_ == NULL; }
  430 Expression* label() const {
  431 CHECK(!is_default());
  432 return label_;
  433 }
  434 ZoneList<Statement*>* statements() const { return statements_; }
  435
  436 private:
  437 Expression* label_;
  438 ZoneList<Statement*>* statements_;
  439 };
  440
  441
  442 class SwitchStatement: public BreakableStatement {
  443 public:
  444 explicit SwitchStatement(ZoneStringList* labels)
  445 : BreakableStatement(labels, TARGET_FOR_ANONYMOUS),
  446 tag_(NULL), cases_(NULL) { }
  447
  448 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
  449 tag_ = tag;
  450 cases_ = cases;
  451 }
  452
  453 virtual void Accept(Visitor* v);
  454
  455 Expression* tag() const { return tag_; }
  456 ZoneList<CaseClause*>* cases() const { return cases_; }
  457
  458 private:
  459 Expression* tag_;
  460 ZoneList<CaseClause*>* cases_;
  461 };
  462
  463
  464 // If-statements always have non-null references to their then- and
  465 // else-parts. When parsing if-statements with no explicit else-part,
  466 // the parser implicitly creates an empty statement. Use the
  467 // HasThenStatement() and HasElseStatement() functions to check if a
  468 // given if-statement has a then- or an else-part containing code.
  469 class IfStatement: public Statement {
  470 public:
  471 IfStatement(Expression* condition,
  472 Statement* then_statement,
  473 Statement* else_statement)
  474 : condition_(condition),
  475 then_statement_(then_statement),
  476 else_statement_(else_statement) { }
  477
  478 virtual void Accept(Visitor* v);
  479
  480 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
  481 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
  482
  483 Expression* condition() const { return condition_; }
  484 Statement* then_statement() const { return then_statement_; }
  485 Statement* else_statement() const { return else_statement_; }
  486
  487 private:
  488 Expression* condition_;
  489 Statement* then_statement_;
  490 Statement* else_statement_;
  491 };
  492
  493
  494 // NOTE: LabelCollectors are represented as nodes to fit in the target
  495 // stack in the compiler; this should probably be reworked.
  496 class LabelCollector: public Node {
  497 public:
  498 explicit LabelCollector(ZoneList<Label*>* labels) : labels_(labels) { }
  499
  500 // Adds a label to the collector. The collector stores a pointer not
  501 // a copy of the label to make binding work, so make sure not to
  502 // pass in references to something on the stack.
  503 void AddLabel(Label* label);
  504
  505 // Virtual behaviour. LabelCollectors are never part of the AST.
  506 virtual void Accept(Visitor* v) { UNREACHABLE(); }
  507 virtual LabelCollector* AsLabelCollector() { return this; }
  508
  509 ZoneList<Label*>* labels() { return labels_; }
  510
  511 private:
  512 ZoneList<Label*>* labels_;
  513 };
  514
  515
  516 class TryStatement: public Statement {
  517 public:
  518 explicit TryStatement(Block* try_block)
  519 : try_block_(try_block), escaping_labels_(NULL) { }
  520
  521 void set_escaping_labels(ZoneList<Label*>* labels) {
  522 escaping_labels_ = labels;
  523 }
  524
  525 Block* try_block() const { return try_block_; }
  526 ZoneList<Label*>* escaping_labels() const { return escaping_labels_; }
  527
  528 private:
  529 Block* try_block_;
  530 ZoneList<Label*>* escaping_labels_;
  531 };
  532
  533
  534 class TryCatch: public TryStatement {
  535 public:
  536 TryCatch(Block* try_block, Expression* catch_var, Block* catch_block)
  537 : TryStatement(try_block),
  538 catch_var_(catch_var),
  539 catch_block_(catch_block) {
  540 ASSERT(catch_var->AsVariableProxy() != NULL);
  541 }
  542
  543 virtual void Accept(Visitor* v);
  544
  545 Expression* catch_var() const { return catch_var_; }
  546 Block* catch_block() const { return catch_block_; }
  547
  548 private:
  549 Expression* catch_var_;
  550 Block* catch_block_;
  551 };
  552
  553
  554 class TryFinally: public TryStatement {
  555 public:
  556 TryFinally(Block* try_block, Expression* finally_var, Block* finally_block)
  557 : TryStatement(try_block),
  558 finally_var_(finally_var),
  559 finally_block_(finally_block) { }
  560
  561 virtual void Accept(Visitor* v);
  562
  563 // If the finally block is non-trivial it may be problematic to have
  564 // extra stuff on the expression stack while evaluating it. The
  565 // finally variable is used to hold the state instead of storing it
  566 // on the stack. It may be NULL in which case the state is stored on
  567 // the stack.
  568 Expression* finally_var() const { return finally_var_; }
  569
  570 Block* finally_block() const { return finally_block_; }
  571
  572 private:
  573 Expression* finally_var_;
  574 Block* finally_block_;
  575 };
  576
  577
  578 class DebuggerStatement: public Statement {
  579 public:
  580 virtual void Accept(Visitor* v);
  581 };
  582
  583
  584 class EmptyStatement: public Statement {
  585 public:
  586 virtual void Accept(Visitor* v);
  587
  588 // Type testing & conversion.
  589 virtual EmptyStatement* AsEmptyStatement() { return this; }
  590 };
  591
  592
  593 class Literal: public Expression {
  594 public:
  595 explicit Literal(Handle<Object> handle) : handle_(handle) { }
  596
  597 virtual void Accept(Visitor* v);
  598
  599 // Type testing & conversion.
  600 virtual Literal* AsLiteral() { return this; }
  601
  602 // Check if this literal is identical to the other literal.
  603 bool IsIdenticalTo(const Literal* other) const {
  604 return handle_.is_identical_to(other->handle_);
  605 }
  606
  607 // Identity testers.
  608 bool IsNull() const { return handle_.is_identical_to(Factory::null_value()); }
  609 bool IsTrue() const { return handle_.is_identical_to(Factory::true_value()); }
  610 bool IsFalse() const {
  611 return handle_.is_identical_to(Factory::false_value());
  612 }
  613
  614 Handle<Object> handle() const { return handle_; }
  615
  616 private:
  617 Handle<Object> handle_;
  618 };
  619
  620
  621 // Base class for literals that needs space in the corresponding JSFunction.
  622 class MaterializedLiteral: public Expression {
  623 public:
  624 explicit MaterializedLiteral(int literal_index)
  625 : literal_index_(literal_index) {}
  626 int literal_index() { return literal_index_; }
  627 private:
  628 int literal_index_;
  629 };
  630
  631
  632 // An object literal has a boilerplate object that is used
  633 // for minimizing the work when constructing it at runtime.
  634 class ObjectLiteral: public MaterializedLiteral {
  635 public:
  636 // Property is used for passing information
  637 // about an object literal's properties from the parser
  638 // to the code generator.
  639 class Property: public ZoneObject {
  640 public:
  641
  642 enum Kind {
  643 CONSTANT, // Property with constant value (at compile time).
  644 COMPUTED, // Property with computed value (at execution time).
  645 GETTER, SETTER, // Property is an accessor function.
  646 PROTOTYPE // Property is __proto__.
  647 };
  648
  649 Property(Literal* key, Expression* value);
  650 Property(bool is_getter, FunctionLiteral* value);
  651
  652 Literal* key() { return key_; }
  653 Expression* value() { return value_; }
  654 Kind kind() { return kind_; }
  655
  656 private:
  657 Literal* key_;
  658 Expression* value_;
  659 Kind kind_;
  660 };
  661
  662 ObjectLiteral(Handle<FixedArray> constant_properties,
  663 Expression* result,
  664 ZoneList<Property*>* properties,
  665 int literal_index)
  666 : MaterializedLiteral(literal_index),
  667 constant_properties_(constant_properties),
  668 result_(result),
  669 properties_(properties) {
  670 }
  671
  672 virtual void Accept(Visitor* v);
  673
  674 Handle<FixedArray> constant_properties() const {
  675 return constant_properties_;
  676 }
  677 Expression* result() const { return result_; }
  678 ZoneList<Property*>* properties() const { return properties_; }
  679
  680 private:
  681 Handle<FixedArray> constant_properties_;
  682 Expression* result_;
  683 ZoneList<Property*>* properties_;
  684 };
  685
  686
  687 // Node for capturing a regexp literal.
  688 class RegExpLiteral: public MaterializedLiteral {
  689 public:
  690 RegExpLiteral(Handle<String> pattern,
  691 Handle<String> flags,
  692 int literal_index)
  693 : MaterializedLiteral(literal_index),
  694 pattern_(pattern),
  695 flags_(flags) {}
  696
  697 virtual void Accept(Visitor* v);
  698
  699 Handle<String> pattern() const { return pattern_; }
  700 Handle<String> flags() const { return flags_; }
  701
  702 private:
  703 Handle<String> pattern_;
  704 Handle<String> flags_;
  705 };
  706
  707 // An array literal has a literals object that is used
  708 // used for minimizing the work when contructing it at runtime.
  709 class ArrayLiteral: public Expression {
  710 public:
  711 ArrayLiteral(Handle<FixedArray> literals,
  712 Expression* result,
  713 ZoneList<Expression*>* values)
  714 : literals_(literals), result_(result), values_(values) {
  715 }
  716
  717 virtual void Accept(Visitor* v);
  718
  719 Handle<FixedArray> literals() const { return literals_; }
  720 Expression* result() const { return result_; }
  721 ZoneList<Expression*>* values() const { return values_; }
  722
  723 private:
  724 Handle<FixedArray> literals_;
  725 Expression* result_;
  726 ZoneList<Expression*>* values_;
  727 };
  728
  729
  730 class VariableProxy: public Expression {
  731 public:
  732 virtual void Accept(Visitor* v);
  733
  734 // Type testing & conversion
  735 virtual Property* AsProperty() {
  736 return var_ == NULL ? NULL : var_->AsProperty();
  737 }
  738 virtual VariableProxy* AsVariableProxy() { return this; }
  739
  740 Variable* AsVariable() {
  741 return this == NULL || var_ == NULL ? NULL : var_->AsVariable();
  742 }
  743 virtual bool IsValidLeftHandSide() {
  744 return var_ == NULL ? true : var_->IsValidLeftHandSide();
  745 }
  746 bool IsVariable(Handle<String> n) {
  747 return !is_this() && name().is_identical_to(n);
  748 }
  749
  750 // If this assertion fails it means that some code has tried to
  751 // treat the special "this" variable as an ordinary variable with
  752 // the name "this".
  753 Handle<String> name() const { return name_; }
  754 Variable* var() const { return var_; }
  755 UseCount* var_uses() { return &var_uses_; }
  756 UseCount* obj_uses() { return &obj_uses_; }
  757 bool is_this() const { return is_this_; }
  758 bool inside_with() const { return inside_with_; }
  759
  760 // Bind this proxy to the variable var.
  761 void BindTo(Variable* var);
  762
  763 protected:
  764 Handle<String> name_;
  765 Variable* var_; // resolved variable, or NULL
  766 bool is_this_;
  767 bool inside_with_;
  768
  769 // VariableProxy usage info.
  770 UseCount var_uses_; // uses of the variable value
  771 UseCount obj_uses_; // uses of the object the variable points to
  772
  773 VariableProxy(Handle<String> name, bool is_this, bool inside_with);
  774 explicit VariableProxy(bool is_this);
  775
  776 friend class Scope;
  777 };
  778
  779
  780 class VariableProxySentinel: public VariableProxy {
  781 public:
  782 virtual bool IsValidLeftHandSide() { return !is_this(); }
  783 static VariableProxySentinel* this_proxy() { return &this_proxy_; }
  784 static VariableProxySentinel* identifier_proxy() {
  785 return &identifier_proxy_;
  786 }
  787
  788 private:
  789 explicit VariableProxySentinel(bool is_this) : VariableProxy(is_this) { }
  790 static VariableProxySentinel this_proxy_;
  791 static VariableProxySentinel identifier_proxy_;
  792 };
  793
  794
  795 class Slot: public Expression {
  796 public:
  797 enum Type {
  798 // A slot in the parameter section on the stack. index() is
  799 // the parameter index, counting left-to-right, starting at 0.
  800 PARAMETER,
  801
  802 // A slot in the local section on the stack. index() is
  803 // the variable index in the stack frame, starting at 0.
  804 LOCAL,
  805
  806 // An indexed slot in a heap context. index() is the
  807 // variable index in the context object on the heap,
  808 // starting at 0. var()->scope() is the corresponding
  809 // scope.
  810 CONTEXT,
  811
  812 // A named slot in a heap context. var()->name() is the
  813 // variable name in the context object on the heap,
  814 // with lookup starting at the current context. index()
  815 // is invalid.
  816 LOOKUP,
  817
  818 // A property in the global object. var()->name() is
  819 // the property name.
  820 GLOBAL
  821 };
  822
  823 Slot(Variable* var, Type type, int index)
  824 : var_(var), type_(type), index_(index) {
  825 ASSERT(var != NULL);
  826 }
  827
  828 virtual void Accept(Visitor* v);
  829
  830 // Type testing & conversion
  831 virtual Slot* AsSlot() { return this; }
  832
  833 // Accessors
  834 Variable* var() const { return var_; }
  835 Type type() const { return type_; }
  836 int index() const { return index_; }
  837
  838 private:
  839 Variable* var_;
  840 Type type_;
  841 int index_;
  842 };
  843
  844
  845 class Property: public Expression {
  846 public:
  847 Property(Expression* obj, Expression* key, int pos)
  848 : obj_(obj), key_(key), pos_(pos) { }
  849
  850 virtual void Accept(Visitor* v);
  851
  852 // Type testing & conversion
  853 virtual Property* AsProperty() { return this; }
  854
  855 virtual bool IsValidLeftHandSide() { return true; }
  856
  857 Expression* obj() const { return obj_; }
  858 Expression* key() const { return key_; }
  859 int position() const { return pos_; }
  860
  861 // Returns a property singleton property access on 'this'. Used
  862 // during preparsing.
  863 static Property* this_property() { return &this_property_; }
  864
  865 private:
  866 Expression* obj_;
  867 Expression* key_;
  868 int pos_;
  869
  870 // Dummy property used during preparsing
  871 static Property this_property_;
  872 };
  873
  874
  875 class Call: public Expression {
  876 public:
  877 Call(Expression* expression,
  878 ZoneList<Expression*>* arguments,
  879 bool is_eval,
  880 int pos)
  881 : expression_(expression),
  882 arguments_(arguments),
  883 is_eval_(is_eval),
  884 pos_(pos) { }
  885
  886 virtual void Accept(Visitor* v);
  887
  888 // Type testing and conversion.
  889 virtual Call* AsCall() { return this; }
  890
  891 Expression* expression() const { return expression_; }
  892 ZoneList<Expression*>* arguments() const { return arguments_; }
  893 bool is_eval() { return is_eval_; }
  894 int position() { return pos_; }
  895
  896 static Call* sentinel() { return &sentinel_; }
  897
  898 private:
  899 Expression* expression_;
  900 ZoneList<Expression*>* arguments_;
  901 bool is_eval_;
  902 int pos_;
  903
  904 static Call sentinel_;
  905 };
  906
  907
  908 class CallNew: public Call {
  909 public:
  910 CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
  911 : Call(expression, arguments, false, pos) { }
  912
  913 virtual void Accept(Visitor* v);
  914 };
  915
  916
  917 // The CallRuntime class does not represent any official JavaScript
  918 // language construct. Instead it is used to call a C or JS function
  919 // with a set of arguments. This is used from the builtins that are
  920 // implemented in JavaScript (see "v8natives.js").
  921 class CallRuntime: public Expression {
  922 public:
  923 CallRuntime(Handle<String> name,
  924 Runtime::Function* function,
  925 ZoneList<Expression*>* arguments)
  926 : name_(name), function_(function), arguments_(arguments) { }
  927
  928 virtual void Accept(Visitor* v);
  929
  930 Handle<String> name() const { return name_; }
  931 Runtime::Function* function() const { return function_; }
  932 ZoneList<Expression*>* arguments() const { return arguments_; }
  933
  934 private:
  935 Handle<String> name_;
  936 Runtime::Function* function_;
  937 ZoneList<Expression*>* arguments_;
  938 };
  939
  940
  941 class UnaryOperation: public Expression {
  942 public:
  943 UnaryOperation(Token::Value op, Expression* expression)
  944 : op_(op), expression_(expression) {
  945 ASSERT(Token::IsUnaryOp(op));
  946 }
  947
  948 virtual void Accept(Visitor* v);
  949
  950 // Type testing & conversion
  951 virtual UnaryOperation* AsUnaryOperation() { return this; }
  952
  953 Token::Value op() const { return op_; }
  954 Expression* expression() const { return expression_; }
  955
  956 private:
  957 Token::Value op_;
  958 Expression* expression_;
  959 };
  960
  961
  962 class BinaryOperation: public Expression {
  963 public:
  964 BinaryOperation(Token::Value op, Expression* left, Expression* right)
  965 : op_(op), left_(left), right_(right) {
  966 ASSERT(Token::IsBinaryOp(op));
  967 }
  968
  969 virtual void Accept(Visitor* v);
  970
  971 // Type testing & conversion
  972 virtual BinaryOperation* AsBinaryOperation() { return this; }
  973
  974 // True iff the result can be safely overwritten (to avoid allocation).
  975 // False for operations that can return one of their operands.
  976 bool ResultOverwriteAllowed() {
  977 switch (op_) {
  978 case Token::COMMA:
  979 case Token::OR:
  980 case Token::AND:
  981 return false;
  982 case Token::BIT_OR:
  983 case Token::BIT_XOR:
  984 case Token::BIT_AND:
  985 case Token::SHL:
  986 case Token::SAR:
  987 case Token::SHR:
  988 case Token::ADD:
  989 case Token::SUB:
  990 case Token::MUL:
  991 case Token::DIV:
  992 case Token::MOD:
  993 return true;
  994 default:
  995 UNREACHABLE();
  996 }
  997 return false;
  998 }
  999
  1000 Token::Value op() const { return op_; }
  1001 Expression* left() const { return left_; }
  1002 Expression* right() const { return right_; }
  1003
  1004 private:
  1005 Token::Value op_;
  1006 Expression* left_;
  1007 Expression* right_;
  1008 };
  1009
  1010
  1011 class CountOperation: public Expression {
  1012 public:
  1013 CountOperation(bool is_prefix, Token::Value op, Expression* expression)
  1014 : is_prefix_(is_prefix), op_(op), expression_(expression) {
  1015 ASSERT(Token::IsCountOp(op));
  1016 }
  1017
  1018 virtual void Accept(Visitor* v);
  1019
  1020 bool is_prefix() const { return is_prefix_; }
  1021 bool is_postfix() const { return !is_prefix_; }
  1022 Token::Value op() const { return op_; }
  1023 Expression* expression() const { return expression_; }
  1024
  1025 virtual void MarkAsStatement() { is_prefix_ = true; }
  1026
  1027 private:
  1028 bool is_prefix_;
  1029 Token::Value op_;
  1030 Expression* expression_;
  1031 };
  1032
  1033
  1034 class CompareOperation: public Expression {
  1035 public:
  1036 CompareOperation(Token::Value op, Expression* left, Expression* right)
  1037 : op_(op), left_(left), right_(right) {
  1038 ASSERT(Token::IsCompareOp(op));
  1039 }
  1040
  1041 virtual void Accept(Visitor* v);
  1042
  1043 Token::Value op() const { return op_; }
  1044 Expression* left() const { return left_; }
  1045 Expression* right() const { return right_; }
  1046
  1047 private:
  1048 Token::Value op_;
  1049 Expression* left_;
  1050 Expression* right_;
  1051 };
  1052
  1053
  1054 class Conditional: public Expression {
  1055 public:
  1056 Conditional(Expression* condition,
  1057 Expression* then_expression,
  1058 Expression* else_expression)
  1059 : condition_(condition),
  1060 then_expression_(then_expression),
  1061 else_expression_(else_expression) { }
  1062
  1063 virtual void Accept(Visitor* v);
  1064
  1065 Expression* condition() const { return condition_; }
  1066 Expression* then_expression() const { return then_expression_; }
  1067 Expression* else_expression() const { return else_expression_; }
  1068
  1069 private:
  1070 Expression* condition_;
  1071 Expression* then_expression_;
  1072 Expression* else_expression_;
  1073 };
  1074
  1075
  1076 class Assignment: public Expression {
  1077 public:
  1078 Assignment(Token::Value op, Expression* target, Expression* value, int pos)
  1079 : op_(op), target_(target), value_(value), pos_(pos) {
  1080 ASSERT(Token::IsAssignmentOp(op));
  1081 }
  1082
  1083 virtual void Accept(Visitor* v);
  1084 virtual Assignment* AsAssignment() { return this; }
  1085
  1086 Token::Value binary_op() const;
  1087
  1088 Token::Value op() const { return op_; }
  1089 Expression* target() const { return target_; }
  1090 Expression* value() const { return value_; }
  1091 int position() { return pos_; }
  1092
  1093 private:
  1094 Token::Value op_;
  1095 Expression* target_;
  1096 Expression* value_;
  1097 int pos_;
  1098 };
  1099
  1100
  1101 class Throw: public Expression {
  1102 public:
  1103 Throw(Expression* exception, int pos)
  1104 : exception_(exception), pos_(pos) {}
  1105
  1106 virtual void Accept(Visitor* v);
  1107 Expression* exception() const { return exception_; }
  1108 int position() const { return pos_; }
  1109
  1110 private:
  1111 Expression* exception_;
  1112 int pos_;
  1113 };
  1114
  1115
  1116 class FunctionLiteral: public Expression {
  1117 public:
  1118 FunctionLiteral(Handle<String> name,
  1119 Scope* scope,
  1120 ZoneList<Statement*>* body,
  1121 int materialized_literal_count,
  1122 int expected_property_count,
  1123 int num_parameters,
  1124 int start_position,
  1125 int end_position,
  1126 bool is_expression)
  1127 : name_(name),
  1128 scope_(scope),
  1129 body_(body),
  1130 materialized_literal_count_(materialized_literal_count),
  1131 expected_property_count_(expected_property_count),
  1132 num_parameters_(num_parameters),
  1133 start_position_(start_position),
  1134 end_position_(end_position),
  1135 is_expression_(is_expression),
  1136 function_token_position_(kNoPosition) {
  1137 }
  1138
  1139 virtual void Accept(Visitor* v);
  1140
  1141 // Type testing & conversion
  1142 virtual FunctionLiteral* AsFunctionLiteral() { return this; }
  1143
  1144 Handle<String> name() const { return name_; }
  1145 Scope* scope() const { return scope_; }
  1146 ZoneList<Statement*>* body() const { return body_; }
  1147 void set_function_token_position(int pos) { function_token_position_ = pos; }
  1148 int function_token_position() const { return function_token_position_; }
  1149 int start_position() const { return start_position_; }
  1150 int end_position() const { return end_position_; }
  1151 bool is_expression() const { return is_expression_; }
  1152
  1153 int materialized_literal_count() { return materialized_literal_count_; }
  1154 int expected_property_count() { return expected_property_count_; }
  1155 int num_parameters() { return num_parameters_; }
  1156
  1157 bool AllowsLazyCompilation();
  1158
  1159 private:
  1160 Handle<String> name_;
  1161 Scope* scope_;
  1162 ZoneList<Statement*>* body_;
  1163 int materialized_literal_count_;
  1164 int expected_property_count_;
  1165 int num_parameters_;
  1166 int start_position_;
  1167 int end_position_;
  1168 bool is_expression_;
  1169 int function_token_position_;
  1170 };
  1171
  1172
  1173 class FunctionBoilerplateLiteral: public Expression {
  1174 public:
  1175 explicit FunctionBoilerplateLiteral(Handle<JSFunction> boilerplate)
  1176 : boilerplate_(boilerplate) {
  1177 ASSERT(boilerplate->IsBoilerplate());
  1178 }
  1179
  1180 Handle<JSFunction> boilerplate() const { return boilerplate_; }
  1181
  1182 virtual void Accept(Visitor* v);
  1183
  1184 private:
  1185 Handle<JSFunction> boilerplate_;
  1186 };
  1187
  1188
  1189 class ThisFunction: public Expression {
  1190 public:
  1191 virtual void Accept(Visitor* v);
  1192 };
  1193
  1194
  1195 // ----------------------------------------------------------------------------
  1196 // Basic visitor
  1197 // - leaf node visitors are abstract.
  1198
  1199 class Visitor BASE_EMBEDDED {
  1200 public:
  1201 Visitor() : stack_overflow_(false) { }
  1202 virtual ~Visitor() { }
  1203
  1204 // Dispatch
  1205 void Visit(Node* node) { node->Accept(this); }
  1206
  1207 // Iteration
  1208 virtual void VisitStatements(ZoneList<Statement*>* statements);
  1209 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
  1210
  1211 // Stack overflow tracking support.
  1212 bool HasStackOverflow() const { return stack_overflow_; }
  1213 bool CheckStackOverflow() {
  1214 if (stack_overflow_) return true;
  1215 StackLimitCheck check;
  1216 if (!check.HasOverflowed()) return false;
  1217 return (stack_overflow_ = true);
  1218 }
  1219
  1220 // If a stack-overflow exception is encountered when visiting a
  1221 // node, calling SetStackOverflow will make sure that the visitor
  1222 // bails out without visiting more nodes.
  1223 void SetStackOverflow() { stack_overflow_ = true; }
  1224
  1225
  1226 // Individual nodes
  1227 #define DEF_VISIT(type) \
  1228 virtual void Visit##type(type* node) = 0;
  1229 NODE_LIST(DEF_VISIT)
  1230 #undef DEF_VISIT
  1231
  1232 private:
  1233 bool stack_overflow_;
  1234 };
  1235
  1236
  1237 } } // namespace v8::internal
  1238
  1239 #endif // V8_AST_H_
Powered by Google Project Hosting