OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_AST_AST_H_ | 5 #ifndef V8_AST_AST_H_ |
6 #define V8_AST_AST_H_ | 6 #define V8_AST_AST_H_ |
7 | 7 |
8 #include "src/assembler.h" | 8 #include "src/assembler.h" |
9 #include "src/ast/ast-value-factory.h" | 9 #include "src/ast/ast-value-factory.h" |
10 #include "src/ast/modules.h" | 10 #include "src/ast/modules.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 V(CountOperation) \ | 84 V(CountOperation) \ |
85 V(BinaryOperation) \ | 85 V(BinaryOperation) \ |
86 V(CompareOperation) \ | 86 V(CompareOperation) \ |
87 V(Spread) \ | 87 V(Spread) \ |
88 V(ThisFunction) \ | 88 V(ThisFunction) \ |
89 V(SuperPropertyReference) \ | 89 V(SuperPropertyReference) \ |
90 V(SuperCallReference) \ | 90 V(SuperCallReference) \ |
91 V(CaseClause) \ | 91 V(CaseClause) \ |
92 V(EmptyParentheses) \ | 92 V(EmptyParentheses) \ |
93 V(DoExpression) \ | 93 V(DoExpression) \ |
94 V(RewritableAssignmentExpression) | 94 V(RewritableExpression) |
95 | 95 |
96 #define AST_NODE_LIST(V) \ | 96 #define AST_NODE_LIST(V) \ |
97 DECLARATION_NODE_LIST(V) \ | 97 DECLARATION_NODE_LIST(V) \ |
98 STATEMENT_NODE_LIST(V) \ | 98 STATEMENT_NODE_LIST(V) \ |
99 EXPRESSION_NODE_LIST(V) | 99 EXPRESSION_NODE_LIST(V) |
100 | 100 |
101 // Forward declarations | 101 // Forward declarations |
102 class AstNodeFactory; | 102 class AstNodeFactory; |
103 class AstVisitor; | 103 class AstVisitor; |
104 class Declaration; | 104 class Declaration; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 | 198 |
199 #ifdef DEBUG | 199 #ifdef DEBUG |
200 void PrettyPrint(Isolate* isolate); | 200 void PrettyPrint(Isolate* isolate); |
201 void PrettyPrint(); | 201 void PrettyPrint(); |
202 void Print(Isolate* isolate); | 202 void Print(Isolate* isolate); |
203 void Print(); | 203 void Print(); |
204 #endif // DEBUG | 204 #endif // DEBUG |
205 | 205 |
206 // Type testing & conversion functions overridden by concrete subclasses. | 206 // Type testing & conversion functions overridden by concrete subclasses. |
207 #define DECLARE_NODE_FUNCTIONS(type) \ | 207 #define DECLARE_NODE_FUNCTIONS(type) \ |
208 bool Is##type() const { return node_type() == AstNode::k##type; } \ | 208 V8_INLINE bool Is##type() const; \ |
209 type* As##type() { \ | 209 V8_INLINE type* As##type(); \ |
210 return Is##type() ? reinterpret_cast<type*>(this) : NULL; \ | 210 V8_INLINE const type* As##type() const; |
211 } \ | |
212 const type* As##type() const { \ | |
213 return Is##type() ? reinterpret_cast<const type*>(this) : NULL; \ | |
214 } | |
215 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) | 211 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) |
216 #undef DECLARE_NODE_FUNCTIONS | 212 #undef DECLARE_NODE_FUNCTIONS |
217 | 213 |
218 virtual BreakableStatement* AsBreakableStatement() { return NULL; } | 214 virtual BreakableStatement* AsBreakableStatement() { return NULL; } |
219 virtual IterationStatement* AsIterationStatement() { return NULL; } | 215 virtual IterationStatement* AsIterationStatement() { return NULL; } |
220 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; } | 216 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; } |
221 | 217 |
222 // The interface for feedback slots, with default no-op implementations for | 218 // The interface for feedback slots, with default no-op implementations for |
223 // node types which don't actually have this. Note that this is conceptually | 219 // node types which don't actually have this. Note that this is conceptually |
224 // not really nice, but multiple inheritance would introduce yet another | 220 // not really nice, but multiple inheritance would introduce yet another |
(...skipping 2254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2479 // Expression's trailing 16-bit field. | 2475 // Expression's trailing 16-bit field. |
2480 uint16_t bit_field_; | 2476 uint16_t bit_field_; |
2481 Expression* target_; | 2477 Expression* target_; |
2482 Expression* value_; | 2478 Expression* value_; |
2483 BinaryOperation* binary_operation_; | 2479 BinaryOperation* binary_operation_; |
2484 SmallMapList receiver_types_; | 2480 SmallMapList receiver_types_; |
2485 FeedbackVectorSlot slot_; | 2481 FeedbackVectorSlot slot_; |
2486 }; | 2482 }; |
2487 | 2483 |
2488 | 2484 |
2489 class RewritableAssignmentExpression : public Expression { | 2485 // The RewritableExpression class is a wrapper for AST nodes that wait |
| 2486 // for some potential rewriting. However, even if such nodes are indeed |
| 2487 // rewritten, the RewritableExpression wrapper nodes will survive in the |
| 2488 // final AST and should be just ignored, i.e., they should be treated as |
| 2489 // equivalent to the wrapped nodes. For this reason and to simplify later |
| 2490 // phases, RewritableExpressions are considered as exceptions of AST nodes |
| 2491 // in the following sense: |
| 2492 // |
| 2493 // 1. IsRewritableExpression and AsRewritableExpression behave as usual. |
| 2494 // 2. All other Is* and As* methods are practically delegated to the |
| 2495 // wrapped node, i.e. IsArrayLiteral() will return true iff the |
| 2496 // wrapped node is an array literal. |
| 2497 // |
| 2498 // Furthermore, an invariant that should be respected is that the wrapped |
| 2499 // node is not a RewritableExpression. |
| 2500 class RewritableExpression : public Expression { |
2490 public: | 2501 public: |
2491 DECLARE_NODE_TYPE(RewritableAssignmentExpression) | 2502 DECLARE_NODE_TYPE(RewritableExpression) |
2492 | 2503 |
2493 Expression* expression() { return expr_; } | 2504 Expression* expression() const { return expr_; } |
2494 bool is_rewritten() const { return is_rewritten_; } | 2505 bool is_rewritten() const { return is_rewritten_; } |
2495 | 2506 |
2496 void set_expression(Expression* e) { expr_ = e; } | |
2497 | |
2498 void Rewrite(Expression* new_expression) { | 2507 void Rewrite(Expression* new_expression) { |
2499 DCHECK(!is_rewritten()); | 2508 DCHECK(!is_rewritten()); |
2500 DCHECK_NOT_NULL(new_expression); | 2509 DCHECK_NOT_NULL(new_expression); |
| 2510 DCHECK(!new_expression->IsRewritableExpression()); |
2501 expr_ = new_expression; | 2511 expr_ = new_expression; |
2502 is_rewritten_ = true; | 2512 is_rewritten_ = true; |
2503 } | 2513 } |
2504 | 2514 |
2505 static int num_ids() { return parent_num_ids(); } | 2515 static int num_ids() { return parent_num_ids(); } |
2506 | 2516 |
2507 protected: | 2517 protected: |
2508 RewritableAssignmentExpression(Zone* zone, Expression* expression) | 2518 RewritableExpression(Zone* zone, Expression* expression) |
2509 : Expression(zone, expression->position()), | 2519 : Expression(zone, expression->position()), |
2510 is_rewritten_(false), | 2520 is_rewritten_(false), |
2511 expr_(expression) {} | 2521 expr_(expression) { |
| 2522 DCHECK(!expression->IsRewritableExpression()); |
| 2523 } |
2512 | 2524 |
2513 private: | 2525 private: |
2514 int local_id(int n) const { return base_id() + parent_num_ids() + n; } | 2526 int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
2515 | 2527 |
2516 bool is_rewritten_; | 2528 bool is_rewritten_; |
2517 Expression* expr_; | 2529 Expression* expr_; |
2518 }; | 2530 }; |
2519 | 2531 |
2520 | 2532 |
2521 class Yield final : public Expression { | 2533 class Yield final : public Expression { |
(...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3358 } | 3370 } |
3359 | 3371 |
3360 Conditional* NewConditional(Expression* condition, | 3372 Conditional* NewConditional(Expression* condition, |
3361 Expression* then_expression, | 3373 Expression* then_expression, |
3362 Expression* else_expression, | 3374 Expression* else_expression, |
3363 int position) { | 3375 int position) { |
3364 return new (local_zone_) Conditional( | 3376 return new (local_zone_) Conditional( |
3365 local_zone_, condition, then_expression, else_expression, position); | 3377 local_zone_, condition, then_expression, else_expression, position); |
3366 } | 3378 } |
3367 | 3379 |
3368 RewritableAssignmentExpression* NewRewritableAssignmentExpression( | 3380 RewritableExpression* NewRewritableExpression(Expression* expression) { |
3369 Expression* expression) { | |
3370 DCHECK_NOT_NULL(expression); | 3381 DCHECK_NOT_NULL(expression); |
3371 DCHECK(expression->IsAssignment()); | 3382 return new (local_zone_) RewritableExpression(local_zone_, expression); |
3372 return new (local_zone_) | |
3373 RewritableAssignmentExpression(local_zone_, expression); | |
3374 } | 3383 } |
3375 | 3384 |
3376 Assignment* NewAssignment(Token::Value op, | 3385 Assignment* NewAssignment(Token::Value op, |
3377 Expression* target, | 3386 Expression* target, |
3378 Expression* value, | 3387 Expression* value, |
3379 int pos) { | 3388 int pos) { |
3380 DCHECK(Token::IsAssignmentOp(op)); | 3389 DCHECK(Token::IsAssignmentOp(op)); |
3381 Assignment* assign = | 3390 Assignment* assign = |
3382 new (local_zone_) Assignment(local_zone_, op, target, value, pos); | 3391 new (local_zone_) Assignment(local_zone_, op, target, value, pos); |
3383 if (assign->is_compound()) { | 3392 if (assign->is_compound()) { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3501 // inspected. | 3510 // inspected. |
3502 // See ParseFunctionLiteral in parser.cc for preconditions. | 3511 // See ParseFunctionLiteral in parser.cc for preconditions. |
3503 Zone* local_zone_; | 3512 Zone* local_zone_; |
3504 // ZoneObjects which need to persist until scope analysis must be allocated in | 3513 // ZoneObjects which need to persist until scope analysis must be allocated in |
3505 // the parser-level zone. | 3514 // the parser-level zone. |
3506 Zone* parser_zone_; | 3515 Zone* parser_zone_; |
3507 AstValueFactory* ast_value_factory_; | 3516 AstValueFactory* ast_value_factory_; |
3508 }; | 3517 }; |
3509 | 3518 |
3510 | 3519 |
| 3520 // Type testing & conversion functions overridden by concrete subclasses. |
| 3521 // Inline functions for AstNode. |
| 3522 |
| 3523 #define DECLARE_NODE_FUNCTIONS(type) \ |
| 3524 bool AstNode::Is##type() const { \ |
| 3525 NodeType mine = node_type(); \ |
| 3526 if (mine == AstNode::kRewritableExpression && \ |
| 3527 AstNode::k##type != AstNode::kRewritableExpression) \ |
| 3528 mine = reinterpret_cast<const RewritableExpression*>(this) \ |
| 3529 ->expression() \ |
| 3530 ->node_type(); \ |
| 3531 return mine == AstNode::k##type; \ |
| 3532 } \ |
| 3533 type* AstNode::As##type() { \ |
| 3534 NodeType mine = node_type(); \ |
| 3535 AstNode* result = this; \ |
| 3536 if (mine == AstNode::kRewritableExpression && \ |
| 3537 AstNode::k##type != AstNode::kRewritableExpression) { \ |
| 3538 result = \ |
| 3539 reinterpret_cast<const RewritableExpression*>(this)->expression(); \ |
| 3540 mine = result->node_type(); \ |
| 3541 } \ |
| 3542 return mine == AstNode::k##type ? reinterpret_cast<type*>(result) : NULL; \ |
| 3543 } \ |
| 3544 const type* AstNode::As##type() const { \ |
| 3545 NodeType mine = node_type(); \ |
| 3546 const AstNode* result = this; \ |
| 3547 if (mine == AstNode::kRewritableExpression && \ |
| 3548 AstNode::k##type != AstNode::kRewritableExpression) { \ |
| 3549 result = \ |
| 3550 reinterpret_cast<const RewritableExpression*>(this)->expression(); \ |
| 3551 mine = result->node_type(); \ |
| 3552 } \ |
| 3553 return mine == AstNode::k##type ? reinterpret_cast<const type*>(result) \ |
| 3554 : NULL; \ |
| 3555 } |
| 3556 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) |
| 3557 #undef DECLARE_NODE_FUNCTIONS |
| 3558 |
| 3559 |
3511 } // namespace internal | 3560 } // namespace internal |
3512 } // namespace v8 | 3561 } // namespace v8 |
3513 | 3562 |
3514 #endif // V8_AST_AST_H_ | 3563 #endif // V8_AST_AST_H_ |
OLD | NEW |