| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_COMPILER_AST_GRAPH_BUILDER_H_ | 5 #ifndef V8_COMPILER_AST_GRAPH_BUILDER_H_ |
| 6 #define V8_COMPILER_AST_GRAPH_BUILDER_H_ | 6 #define V8_COMPILER_AST_GRAPH_BUILDER_H_ |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/ast.h" | 10 #include "src/ast.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 ControlScope* execution_control() const { return execution_control_; } | 117 ControlScope* execution_control() const { return execution_control_; } |
| 118 ContextScope* execution_context() const { return execution_context_; } | 118 ContextScope* execution_context() const { return execution_context_; } |
| 119 CommonOperatorBuilder* common() const { return jsgraph_->common(); } | 119 CommonOperatorBuilder* common() const { return jsgraph_->common(); } |
| 120 CompilationInfo* info() const { return info_; } | 120 CompilationInfo* info() const { return info_; } |
| 121 StrictMode strict_mode() const; | 121 StrictMode strict_mode() const; |
| 122 JSGraph* jsgraph() { return jsgraph_; } | 122 JSGraph* jsgraph() { return jsgraph_; } |
| 123 Graph* graph() { return jsgraph_->graph(); } | 123 Graph* graph() { return jsgraph_->graph(); } |
| 124 Zone* graph_zone() { return graph()->zone(); } | 124 Zone* graph_zone() { return graph()->zone(); } |
| 125 JSOperatorBuilder* javascript() { return jsgraph_->javascript(); } | 125 JSOperatorBuilder* javascript() { return jsgraph_->javascript(); } |
| 126 ZoneVector<Handle<Object>>* globals() { return &globals_; } | 126 ZoneVector<Handle<Object>>* globals() { return &globals_; } |
| 127 inline Scope* current_scope() const; | 127 Scope* current_scope() const; |
| 128 Node* current_context() const { return current_context_; } | 128 Node* current_context() const { return current_context_; } |
| 129 Node* dead_control(); | 129 Node* dead_control(); |
| 130 Node* exit_control() const { return exit_control_; } | 130 Node* exit_control() const { return exit_control_; } |
| 131 | 131 |
| 132 void set_environment(Environment* env) { environment_ = env; } |
| 132 void set_ast_context(AstContext* ctx) { ast_context_ = ctx; } | 133 void set_ast_context(AstContext* ctx) { ast_context_ = ctx; } |
| 133 void set_execution_control(ControlScope* ctrl) { execution_control_ = ctrl; } | 134 void set_execution_control(ControlScope* ctrl) { execution_control_ = ctrl; } |
| 134 void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; } | 135 void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; } |
| 136 void set_current_context(Node* ctx) { current_context_ = ctx; } |
| 135 void set_exit_control(Node* exit) { exit_control_ = exit; } | 137 void set_exit_control(Node* exit) { exit_control_ = exit; } |
| 136 void set_current_context(Node* ctx) { current_context_ = ctx; } | |
| 137 void set_environment(Environment* env) { environment_ = env; } | |
| 138 | 138 |
| 139 // Node creation helpers. | 139 // Node creation helpers. |
| 140 Node* NewNode(const Operator* op, bool incomplete = false) { | 140 Node* NewNode(const Operator* op, bool incomplete = false) { |
| 141 return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete); | 141 return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete); |
| 142 } | 142 } |
| 143 | 143 |
| 144 Node* NewNode(const Operator* op, Node* n1) { | 144 Node* NewNode(const Operator* op, Node* n1) { |
| 145 return MakeNode(op, 1, &n1, false); | 145 return MakeNode(op, 1, &n1, false); |
| 146 } | 146 } |
| 147 | 147 |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 Zone* zone() const { return builder_->local_zone(); } | 450 Zone* zone() const { return builder_->local_zone(); } |
| 451 Graph* graph() const { return builder_->graph(); } | 451 Graph* graph() const { return builder_->graph(); } |
| 452 AstGraphBuilder* builder() const { return builder_; } | 452 AstGraphBuilder* builder() const { return builder_; } |
| 453 CommonOperatorBuilder* common() { return builder_->common(); } | 453 CommonOperatorBuilder* common() { return builder_->common(); } |
| 454 NodeVector* values() { return &values_; } | 454 NodeVector* values() { return &values_; } |
| 455 | 455 |
| 456 // Prepare environment to be used as loop header. | 456 // Prepare environment to be used as loop header. |
| 457 void PrepareForLoop(BitVector* assigned, bool is_osr = false); | 457 void PrepareForLoop(BitVector* assigned, bool is_osr = false); |
| 458 }; | 458 }; |
| 459 | 459 |
| 460 | |
| 461 // Each expression in the AST is evaluated in a specific context. This context | |
| 462 // decides how the evaluation result is passed up the visitor. | |
| 463 class AstGraphBuilder::AstContext BASE_EMBEDDED { | |
| 464 public: | |
| 465 bool IsEffect() const { return kind_ == Expression::kEffect; } | |
| 466 bool IsValue() const { return kind_ == Expression::kValue; } | |
| 467 bool IsTest() const { return kind_ == Expression::kTest; } | |
| 468 | |
| 469 // Determines how to combine the frame state with the value | |
| 470 // that is about to be plugged into this AstContext. | |
| 471 OutputFrameStateCombine GetStateCombine() { | |
| 472 return IsEffect() ? OutputFrameStateCombine::Ignore() | |
| 473 : OutputFrameStateCombine::Push(); | |
| 474 } | |
| 475 | |
| 476 // Plug a node into this expression context. Call this function in tail | |
| 477 // position in the Visit functions for expressions. | |
| 478 virtual void ProduceValue(Node* value) = 0; | |
| 479 | |
| 480 // Unplugs a node from this expression context. Call this to retrieve the | |
| 481 // result of another Visit function that already plugged the context. | |
| 482 virtual Node* ConsumeValue() = 0; | |
| 483 | |
| 484 // Shortcut for "context->ProduceValue(context->ConsumeValue())". | |
| 485 void ReplaceValue() { ProduceValue(ConsumeValue()); } | |
| 486 | |
| 487 protected: | |
| 488 AstContext(AstGraphBuilder* owner, Expression::Context kind); | |
| 489 virtual ~AstContext(); | |
| 490 | |
| 491 AstGraphBuilder* owner() const { return owner_; } | |
| 492 Environment* environment() const { return owner_->environment(); } | |
| 493 | |
| 494 // We want to be able to assert, in a context-specific way, that the stack | |
| 495 // height makes sense when the context is filled. | |
| 496 #ifdef DEBUG | |
| 497 int original_height_; | |
| 498 #endif | |
| 499 | |
| 500 private: | |
| 501 Expression::Context kind_; | |
| 502 AstGraphBuilder* owner_; | |
| 503 AstContext* outer_; | |
| 504 }; | |
| 505 | |
| 506 | |
| 507 // Context to evaluate expression for its side effects only. | |
| 508 class AstGraphBuilder::AstEffectContext FINAL : public AstContext { | |
| 509 public: | |
| 510 explicit AstEffectContext(AstGraphBuilder* owner) | |
| 511 : AstContext(owner, Expression::kEffect) {} | |
| 512 ~AstEffectContext() FINAL; | |
| 513 void ProduceValue(Node* value) FINAL; | |
| 514 Node* ConsumeValue() FINAL; | |
| 515 }; | |
| 516 | |
| 517 | |
| 518 // Context to evaluate expression for its value (and side effects). | |
| 519 class AstGraphBuilder::AstValueContext FINAL : public AstContext { | |
| 520 public: | |
| 521 explicit AstValueContext(AstGraphBuilder* owner) | |
| 522 : AstContext(owner, Expression::kValue) {} | |
| 523 ~AstValueContext() FINAL; | |
| 524 void ProduceValue(Node* value) FINAL; | |
| 525 Node* ConsumeValue() FINAL; | |
| 526 }; | |
| 527 | |
| 528 | |
| 529 // Context to evaluate expression for a condition value (and side effects). | |
| 530 class AstGraphBuilder::AstTestContext FINAL : public AstContext { | |
| 531 public: | |
| 532 explicit AstTestContext(AstGraphBuilder* owner) | |
| 533 : AstContext(owner, Expression::kTest) {} | |
| 534 ~AstTestContext() FINAL; | |
| 535 void ProduceValue(Node* value) FINAL; | |
| 536 Node* ConsumeValue() FINAL; | |
| 537 }; | |
| 538 | |
| 539 | |
| 540 // Scoped class tracking context objects created by the visitor. Represents | |
| 541 // mutations of the context chain within the function body and allows to | |
| 542 // change the current {scope} and {context} during visitation. | |
| 543 class AstGraphBuilder::ContextScope BASE_EMBEDDED { | |
| 544 public: | |
| 545 ContextScope(AstGraphBuilder* owner, Scope* scope, Node* context) | |
| 546 : owner_(owner), | |
| 547 next_(owner->execution_context()), | |
| 548 outer_(owner->current_context()), | |
| 549 scope_(scope) { | |
| 550 owner_->set_execution_context(this); // Push. | |
| 551 owner_->set_current_context(context); | |
| 552 } | |
| 553 | |
| 554 ~ContextScope() { | |
| 555 owner_->set_execution_context(next_); // Pop. | |
| 556 owner_->set_current_context(outer_); | |
| 557 } | |
| 558 | |
| 559 // Current scope during visitation. | |
| 560 Scope* scope() const { return scope_; } | |
| 561 | |
| 562 private: | |
| 563 AstGraphBuilder* owner_; | |
| 564 ContextScope* next_; | |
| 565 Node* outer_; | |
| 566 Scope* scope_; | |
| 567 }; | |
| 568 | |
| 569 Scope* AstGraphBuilder::current_scope() const { | |
| 570 return execution_context_->scope(); | |
| 571 } | |
| 572 | |
| 573 } // namespace compiler | 460 } // namespace compiler |
| 574 } // namespace internal | 461 } // namespace internal |
| 575 } // namespace v8 | 462 } // namespace v8 |
| 576 | 463 |
| 577 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ | 464 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ |
| OLD | NEW |