OLD | NEW |
---|---|
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
9 #include "src/interpreter/bytecode-register-allocator.h" | 9 #include "src/interpreter/bytecode-register-allocator.h" |
10 #include "src/interpreter/control-flow-builders.h" | 10 #include "src/interpreter/control-flow-builders.h" |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 int depth_; | 74 int depth_; |
75 bool should_pop_context_; | 75 bool should_pop_context_; |
76 }; | 76 }; |
77 | 77 |
78 | 78 |
79 // Scoped class for tracking control statements entered by the | 79 // Scoped class for tracking control statements entered by the |
80 // visitor. The pattern derives AstGraphBuilder::ControlScope. | 80 // visitor. The pattern derives AstGraphBuilder::ControlScope. |
81 class BytecodeGenerator::ControlScope BASE_EMBEDDED { | 81 class BytecodeGenerator::ControlScope BASE_EMBEDDED { |
82 public: | 82 public: |
83 explicit ControlScope(BytecodeGenerator* generator) | 83 explicit ControlScope(BytecodeGenerator* generator) |
84 : generator_(generator), outer_(generator->execution_control()) { | 84 : generator_(generator), outer_(generator->execution_control()), |
85 context_(generator->execution_context()) { | |
85 generator_->set_execution_control(this); | 86 generator_->set_execution_control(this); |
86 } | 87 } |
87 virtual ~ControlScope() { generator_->set_execution_control(outer()); } | 88 virtual ~ControlScope() { generator_->set_execution_control(outer()); } |
88 | 89 |
89 void Break(Statement* stmt) { PerformCommand(CMD_BREAK, stmt); } | 90 void Break(Statement* stmt) { PerformCommand(CMD_BREAK, stmt); } |
90 void Continue(Statement* stmt) { PerformCommand(CMD_CONTINUE, stmt); } | 91 void Continue(Statement* stmt) { PerformCommand(CMD_CONTINUE, stmt); } |
91 | 92 |
92 protected: | 93 protected: |
93 enum Command { CMD_BREAK, CMD_CONTINUE }; | 94 enum Command { CMD_BREAK, CMD_CONTINUE }; |
94 void PerformCommand(Command command, Statement* statement); | 95 void PerformCommand(Command command, Statement* statement); |
95 virtual bool Execute(Command command, Statement* statement) = 0; | 96 virtual bool ShouldExecute(Command command, Statement* statement) = 0; |
97 virtual void Execute(Command command) = 0; | |
96 | 98 |
97 BytecodeGenerator* generator() const { return generator_; } | 99 BytecodeGenerator* generator() const { return generator_; } |
98 ControlScope* outer() const { return outer_; } | 100 ControlScope* outer() const { return outer_; } |
101 ContextScope* context() const { return context_; } | |
99 | 102 |
100 private: | 103 private: |
101 BytecodeGenerator* generator_; | 104 BytecodeGenerator* generator_; |
102 ControlScope* outer_; | 105 ControlScope* outer_; |
106 ContextScope* context_; | |
103 | 107 |
104 DISALLOW_COPY_AND_ASSIGN(ControlScope); | 108 DISALLOW_COPY_AND_ASSIGN(ControlScope); |
105 }; | 109 }; |
106 | 110 |
107 | 111 |
108 // Scoped class for enabling break inside blocks and switch blocks. | 112 // Scoped class for enabling break inside blocks and switch blocks. |
109 class BytecodeGenerator::ControlScopeForBreakable final | 113 class BytecodeGenerator::ControlScopeForBreakable final |
110 : public BytecodeGenerator::ControlScope { | 114 : public BytecodeGenerator::ControlScope { |
111 public: | 115 public: |
112 ControlScopeForBreakable(BytecodeGenerator* generator, | 116 ControlScopeForBreakable(BytecodeGenerator* generator, |
113 BreakableStatement* statement, | 117 BreakableStatement* statement, |
114 BreakableControlFlowBuilder* control_builder) | 118 BreakableControlFlowBuilder* control_builder) |
115 : ControlScope(generator), | 119 : ControlScope(generator), |
116 statement_(statement), | 120 statement_(statement), |
117 control_builder_(control_builder) {} | 121 control_builder_(control_builder) {} |
118 | 122 |
119 protected: | 123 protected: |
120 virtual bool Execute(Command command, Statement* statement) { | 124 bool ShouldExecute(Command command, Statement* statement) override { |
121 if (statement != statement_) return false; | 125 if (statement != statement_) return false; |
126 return command == CMD_BREAK; | |
127 } | |
128 | |
129 void Execute(Command command) override { | |
122 switch (command) { | 130 switch (command) { |
123 case CMD_BREAK: | 131 case CMD_BREAK: |
124 control_builder_->Break(); | 132 control_builder_->Break(); |
125 return true; | 133 break; |
126 case CMD_CONTINUE: | 134 case CMD_CONTINUE: |
135 UNREACHABLE(); | |
127 break; | 136 break; |
128 } | 137 } |
129 return false; | |
130 } | 138 } |
131 | 139 |
132 private: | 140 private: |
133 Statement* statement_; | 141 Statement* statement_; |
134 BreakableControlFlowBuilder* control_builder_; | 142 BreakableControlFlowBuilder* control_builder_; |
135 }; | 143 }; |
136 | 144 |
137 | 145 |
138 // Scoped class for enabling 'break' and 'continue' in iteration | 146 // Scoped class for enabling 'break' and 'continue' in iteration |
139 // constructs, e.g. do...while, while..., for... | 147 // constructs, e.g. do...while, while..., for... |
140 class BytecodeGenerator::ControlScopeForIteration final | 148 class BytecodeGenerator::ControlScopeForIteration final |
141 : public BytecodeGenerator::ControlScope { | 149 : public BytecodeGenerator::ControlScope { |
142 public: | 150 public: |
143 ControlScopeForIteration(BytecodeGenerator* generator, | 151 ControlScopeForIteration(BytecodeGenerator* generator, |
144 IterationStatement* statement, | 152 IterationStatement* statement, |
145 LoopBuilder* loop_builder) | 153 LoopBuilder* loop_builder) |
146 : ControlScope(generator), | 154 : ControlScope(generator), |
147 statement_(statement), | 155 statement_(statement), |
148 loop_builder_(loop_builder) {} | 156 loop_builder_(loop_builder) {} |
149 | 157 |
150 protected: | 158 protected: |
151 virtual bool Execute(Command command, Statement* statement) { | 159 bool ShouldExecute(Command command, Statement* statement) override { |
152 if (statement != statement_) return false; | 160 if (statement != statement_) return false; |
161 return command == CMD_BREAK || command == CMD_CONTINUE; | |
162 } | |
163 | |
164 void Execute(Command command) override { | |
153 switch (command) { | 165 switch (command) { |
154 case CMD_BREAK: | 166 case CMD_BREAK: |
155 loop_builder_->Break(); | 167 loop_builder_->Break(); |
156 return true; | 168 break; |
157 case CMD_CONTINUE: | 169 case CMD_CONTINUE: |
158 loop_builder_->Continue(); | 170 loop_builder_->Continue(); |
159 return true; | 171 break; |
160 } | 172 } |
161 return false; | |
162 } | 173 } |
163 | 174 |
164 private: | 175 private: |
165 Statement* statement_; | 176 Statement* statement_; |
166 LoopBuilder* loop_builder_; | 177 LoopBuilder* loop_builder_; |
167 }; | 178 }; |
168 | 179 |
169 | 180 |
170 void BytecodeGenerator::ControlScope::PerformCommand(Command command, | 181 void BytecodeGenerator::ControlScope::PerformCommand(Command command, |
171 Statement* statement) { | 182 Statement* statement) { |
172 ControlScope* current = this; | 183 ControlScope* current = this; |
173 do { | 184 do { |
174 if (current->Execute(command, statement)) return; | 185 if (current->ShouldExecute(command, statement)) { |
Michael Starzinger
2016/01/21 13:25:20
As discussed offline: How would you feel about goi
rmcilroy
2016/01/22 11:46:08
Done.
| |
186 if (current->context() != this->context()) { | |
187 // Pop context to the expected depth. | |
188 generator()->builder()->PopContext(current->context()->reg()); | |
189 } | |
190 current->Execute(command); | |
191 return; | |
192 } | |
175 current = current->outer(); | 193 current = current->outer(); |
176 } while (current != nullptr); | 194 } while (current != nullptr); |
177 UNREACHABLE(); | 195 UNREACHABLE(); |
178 } | 196 } |
179 | 197 |
180 | 198 |
181 class BytecodeGenerator::RegisterAllocationScope { | 199 class BytecodeGenerator::RegisterAllocationScope { |
182 public: | 200 public: |
183 explicit RegisterAllocationScope(BytecodeGenerator* generator) | 201 explicit RegisterAllocationScope(BytecodeGenerator* generator) |
184 : generator_(generator), | 202 : generator_(generator), |
(...skipping 2028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2213 } | 2231 } |
2214 | 2232 |
2215 | 2233 |
2216 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2234 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
2217 return info()->feedback_vector()->GetIndex(slot); | 2235 return info()->feedback_vector()->GetIndex(slot); |
2218 } | 2236 } |
2219 | 2237 |
2220 } // namespace interpreter | 2238 } // namespace interpreter |
2221 } // namespace internal | 2239 } // namespace internal |
2222 } // namespace v8 | 2240 } // namespace v8 |
OLD | NEW |