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 #include "src/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
11 #include "src/compiler/machine-operator.h" | 11 #include "src/compiler/machine-operator.h" |
12 #include "src/compiler/node-matchers.h" | 12 #include "src/compiler/node-matchers.h" |
13 #include "src/compiler/node-properties.h" | 13 #include "src/compiler/node-properties.h" |
14 #include "src/compiler/operator-properties.h" | 14 #include "src/compiler/operator-properties.h" |
15 #include "src/full-codegen.h" | 15 #include "src/full-codegen.h" |
16 #include "src/parser.h" | 16 #include "src/parser.h" |
17 #include "src/scopes.h" | 17 #include "src/scopes.h" |
18 | 18 |
19 namespace v8 { | 19 namespace v8 { |
20 namespace internal { | 20 namespace internal { |
21 namespace compiler { | 21 namespace compiler { |
22 | 22 |
23 | 23 |
| 24 // Each expression in the AST is evaluated in a specific context. This context |
| 25 // decides how the evaluation result is passed up the visitor. |
| 26 class AstGraphBuilder::AstContext BASE_EMBEDDED { |
| 27 public: |
| 28 bool IsEffect() const { return kind_ == Expression::kEffect; } |
| 29 bool IsValue() const { return kind_ == Expression::kValue; } |
| 30 bool IsTest() const { return kind_ == Expression::kTest; } |
| 31 |
| 32 // Determines how to combine the frame state with the value |
| 33 // that is about to be plugged into this AstContext. |
| 34 OutputFrameStateCombine GetStateCombine() { |
| 35 return IsEffect() ? OutputFrameStateCombine::Ignore() |
| 36 : OutputFrameStateCombine::Push(); |
| 37 } |
| 38 |
| 39 // Plug a node into this expression context. Call this function in tail |
| 40 // position in the Visit functions for expressions. |
| 41 virtual void ProduceValue(Node* value) = 0; |
| 42 |
| 43 // Unplugs a node from this expression context. Call this to retrieve the |
| 44 // result of another Visit function that already plugged the context. |
| 45 virtual Node* ConsumeValue() = 0; |
| 46 |
| 47 // Shortcut for "context->ProduceValue(context->ConsumeValue())". |
| 48 void ReplaceValue() { ProduceValue(ConsumeValue()); } |
| 49 |
| 50 protected: |
| 51 AstContext(AstGraphBuilder* owner, Expression::Context kind); |
| 52 virtual ~AstContext(); |
| 53 |
| 54 AstGraphBuilder* owner() const { return owner_; } |
| 55 Environment* environment() const { return owner_->environment(); } |
| 56 |
| 57 // We want to be able to assert, in a context-specific way, that the stack |
| 58 // height makes sense when the context is filled. |
| 59 #ifdef DEBUG |
| 60 int original_height_; |
| 61 #endif |
| 62 |
| 63 private: |
| 64 Expression::Context kind_; |
| 65 AstGraphBuilder* owner_; |
| 66 AstContext* outer_; |
| 67 }; |
| 68 |
| 69 |
| 70 // Context to evaluate expression for its side effects only. |
| 71 class AstGraphBuilder::AstEffectContext FINAL : public AstContext { |
| 72 public: |
| 73 explicit AstEffectContext(AstGraphBuilder* owner) |
| 74 : AstContext(owner, Expression::kEffect) {} |
| 75 ~AstEffectContext() FINAL; |
| 76 void ProduceValue(Node* value) FINAL; |
| 77 Node* ConsumeValue() FINAL; |
| 78 }; |
| 79 |
| 80 |
| 81 // Context to evaluate expression for its value (and side effects). |
| 82 class AstGraphBuilder::AstValueContext FINAL : public AstContext { |
| 83 public: |
| 84 explicit AstValueContext(AstGraphBuilder* owner) |
| 85 : AstContext(owner, Expression::kValue) {} |
| 86 ~AstValueContext() FINAL; |
| 87 void ProduceValue(Node* value) FINAL; |
| 88 Node* ConsumeValue() FINAL; |
| 89 }; |
| 90 |
| 91 |
| 92 // Context to evaluate expression for a condition value (and side effects). |
| 93 class AstGraphBuilder::AstTestContext FINAL : public AstContext { |
| 94 public: |
| 95 explicit AstTestContext(AstGraphBuilder* owner) |
| 96 : AstContext(owner, Expression::kTest) {} |
| 97 ~AstTestContext() FINAL; |
| 98 void ProduceValue(Node* value) FINAL; |
| 99 Node* ConsumeValue() FINAL; |
| 100 }; |
| 101 |
| 102 |
| 103 // Scoped class tracking context objects created by the visitor. Represents |
| 104 // mutations of the context chain within the function body and allows to |
| 105 // change the current {scope} and {context} during visitation. |
| 106 class AstGraphBuilder::ContextScope BASE_EMBEDDED { |
| 107 public: |
| 108 ContextScope(AstGraphBuilder* owner, Scope* scope, Node* context) |
| 109 : owner_(owner), |
| 110 next_(owner->execution_context()), |
| 111 outer_(owner->current_context()), |
| 112 scope_(scope) { |
| 113 owner_->set_execution_context(this); // Push. |
| 114 owner_->set_current_context(context); |
| 115 } |
| 116 |
| 117 ~ContextScope() { |
| 118 owner_->set_execution_context(next_); // Pop. |
| 119 owner_->set_current_context(outer_); |
| 120 } |
| 121 |
| 122 // Current scope during visitation. |
| 123 Scope* scope() const { return scope_; } |
| 124 |
| 125 private: |
| 126 AstGraphBuilder* owner_; |
| 127 ContextScope* next_; |
| 128 Node* outer_; |
| 129 Scope* scope_; |
| 130 }; |
| 131 |
| 132 |
24 // Scoped class tracking control statements entered by the visitor. There are | 133 // Scoped class tracking control statements entered by the visitor. There are |
25 // different types of statements participating in this stack to properly track | 134 // different types of statements participating in this stack to properly track |
26 // local as well as non-local control flow: | 135 // local as well as non-local control flow: |
27 // - IterationStatement : Allows proper 'break' and 'continue' behavior. | 136 // - IterationStatement : Allows proper 'break' and 'continue' behavior. |
28 // - BreakableStatement : Allows 'break' from block and switch statements. | 137 // - BreakableStatement : Allows 'break' from block and switch statements. |
29 // - TryCatchStatement : Intercepts 'throw' and implicit exceptional edges. | 138 // - TryCatchStatement : Intercepts 'throw' and implicit exceptional edges. |
30 // - TryFinallyStatement: Intercepts 'break', 'continue', 'throw' and 'return'. | 139 // - TryFinallyStatement: Intercepts 'break', 'continue', 'throw' and 'return'. |
31 class AstGraphBuilder::ControlScope BASE_EMBEDDED { | 140 class AstGraphBuilder::ControlScope BASE_EMBEDDED { |
32 public: | 141 public: |
33 ControlScope(AstGraphBuilder* builder, int stack_delta) | 142 ControlScope(AstGraphBuilder* builder, int stack_delta) |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 Node* AstGraphBuilder::AstValueContext::ConsumeValue() { | 643 Node* AstGraphBuilder::AstValueContext::ConsumeValue() { |
535 return environment()->Pop(); | 644 return environment()->Pop(); |
536 } | 645 } |
537 | 646 |
538 | 647 |
539 Node* AstGraphBuilder::AstTestContext::ConsumeValue() { | 648 Node* AstGraphBuilder::AstTestContext::ConsumeValue() { |
540 return environment()->Pop(); | 649 return environment()->Pop(); |
541 } | 650 } |
542 | 651 |
543 | 652 |
| 653 Scope* AstGraphBuilder::current_scope() const { |
| 654 return execution_context_->scope(); |
| 655 } |
| 656 |
| 657 |
544 void AstGraphBuilder::ControlScope::PerformCommand(Command command, | 658 void AstGraphBuilder::ControlScope::PerformCommand(Command command, |
545 Statement* target, | 659 Statement* target, |
546 Node* value) { | 660 Node* value) { |
547 Environment* env = environment()->CopyAsUnreachable(); | 661 Environment* env = environment()->CopyAsUnreachable(); |
548 ControlScope* current = this; | 662 ControlScope* current = this; |
549 while (current != NULL) { | 663 while (current != NULL) { |
550 if (current->Execute(command, target, value)) break; | 664 if (current->Execute(command, target, value)) break; |
551 environment()->Drop(current->stack_delta()); | 665 environment()->Drop(current->stack_delta()); |
552 current = current->next_; | 666 current = current->next_; |
553 } | 667 } |
(...skipping 2452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3006 Node* dead_node = graph()->NewNode(common()->Dead()); | 3120 Node* dead_node = graph()->NewNode(common()->Dead()); |
3007 dead_control_.set(dead_node); | 3121 dead_control_.set(dead_node); |
3008 return dead_node; | 3122 return dead_node; |
3009 } | 3123 } |
3010 return dead_control_.get(); | 3124 return dead_control_.get(); |
3011 } | 3125 } |
3012 | 3126 |
3013 } // namespace compiler | 3127 } // namespace compiler |
3014 } // namespace internal | 3128 } // namespace internal |
3015 } // namespace v8 | 3129 } // namespace v8 |
OLD | NEW |