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 Execute(Command command, Statement* statement) = 0; |
96 | 97 |
97 BytecodeGenerator* generator() const { return generator_; } | 98 BytecodeGenerator* generator() const { return generator_; } |
98 ControlScope* outer() const { return outer_; } | 99 ControlScope* outer() const { return outer_; } |
| 100 ContextScope* context() const { return context_; } |
99 | 101 |
100 private: | 102 private: |
101 BytecodeGenerator* generator_; | 103 BytecodeGenerator* generator_; |
102 ControlScope* outer_; | 104 ControlScope* outer_; |
| 105 ContextScope* context_; |
103 | 106 |
104 DISALLOW_COPY_AND_ASSIGN(ControlScope); | 107 DISALLOW_COPY_AND_ASSIGN(ControlScope); |
105 }; | 108 }; |
106 | 109 |
107 | 110 |
108 // Scoped class for enabling break inside blocks and switch blocks. | 111 // Scoped class for enabling break inside blocks and switch blocks. |
109 class BytecodeGenerator::ControlScopeForBreakable final | 112 class BytecodeGenerator::ControlScopeForBreakable final |
110 : public BytecodeGenerator::ControlScope { | 113 : public BytecodeGenerator::ControlScope { |
111 public: | 114 public: |
112 ControlScopeForBreakable(BytecodeGenerator* generator, | 115 ControlScopeForBreakable(BytecodeGenerator* generator, |
113 BreakableStatement* statement, | 116 BreakableStatement* statement, |
114 BreakableControlFlowBuilder* control_builder) | 117 BreakableControlFlowBuilder* control_builder) |
115 : ControlScope(generator), | 118 : ControlScope(generator), |
116 statement_(statement), | 119 statement_(statement), |
117 control_builder_(control_builder) {} | 120 control_builder_(control_builder) {} |
118 | 121 |
119 protected: | 122 protected: |
120 virtual bool Execute(Command command, Statement* statement) { | 123 bool Execute(Command command, Statement* statement) override { |
121 if (statement != statement_) return false; | 124 if (statement != statement_) return false; |
122 switch (command) { | 125 switch (command) { |
123 case CMD_BREAK: | 126 case CMD_BREAK: |
124 control_builder_->Break(); | 127 control_builder_->Break(); |
125 return true; | 128 return true; |
126 case CMD_CONTINUE: | 129 case CMD_CONTINUE: |
127 break; | 130 break; |
128 } | 131 } |
129 return false; | 132 return false; |
130 } | 133 } |
(...skipping 10 matching lines...) Expand all Loading... |
141 : public BytecodeGenerator::ControlScope { | 144 : public BytecodeGenerator::ControlScope { |
142 public: | 145 public: |
143 ControlScopeForIteration(BytecodeGenerator* generator, | 146 ControlScopeForIteration(BytecodeGenerator* generator, |
144 IterationStatement* statement, | 147 IterationStatement* statement, |
145 LoopBuilder* loop_builder) | 148 LoopBuilder* loop_builder) |
146 : ControlScope(generator), | 149 : ControlScope(generator), |
147 statement_(statement), | 150 statement_(statement), |
148 loop_builder_(loop_builder) {} | 151 loop_builder_(loop_builder) {} |
149 | 152 |
150 protected: | 153 protected: |
151 virtual bool Execute(Command command, Statement* statement) { | 154 bool Execute(Command command, Statement* statement) override { |
152 if (statement != statement_) return false; | 155 if (statement != statement_) return false; |
153 switch (command) { | 156 switch (command) { |
154 case CMD_BREAK: | 157 case CMD_BREAK: |
155 loop_builder_->Break(); | 158 loop_builder_->Break(); |
156 return true; | 159 return true; |
157 case CMD_CONTINUE: | 160 case CMD_CONTINUE: |
158 loop_builder_->Continue(); | 161 loop_builder_->Continue(); |
159 return true; | 162 return true; |
160 } | 163 } |
161 return false; | 164 return false; |
162 } | 165 } |
163 | 166 |
164 private: | 167 private: |
165 Statement* statement_; | 168 Statement* statement_; |
166 LoopBuilder* loop_builder_; | 169 LoopBuilder* loop_builder_; |
167 }; | 170 }; |
168 | 171 |
169 | 172 |
170 void BytecodeGenerator::ControlScope::PerformCommand(Command command, | 173 void BytecodeGenerator::ControlScope::PerformCommand(Command command, |
171 Statement* statement) { | 174 Statement* statement) { |
172 ControlScope* current = this; | 175 ControlScope* current = this; |
| 176 ContextScope* context = this->context(); |
173 do { | 177 do { |
174 if (current->Execute(command, statement)) return; | 178 if (current->Execute(command, statement)) { return; } |
175 current = current->outer(); | 179 current = current->outer(); |
| 180 if (current->context() != context) { |
| 181 // Pop context to the expected depth. |
| 182 // TODO(rmcilroy): Only emit a single context pop. |
| 183 generator()->builder()->PopContext(current->context()->reg()); |
| 184 context = current->context(); |
| 185 } |
176 } while (current != nullptr); | 186 } while (current != nullptr); |
177 UNREACHABLE(); | 187 UNREACHABLE(); |
178 } | 188 } |
179 | 189 |
180 | 190 |
181 class BytecodeGenerator::RegisterAllocationScope { | 191 class BytecodeGenerator::RegisterAllocationScope { |
182 public: | 192 public: |
183 explicit RegisterAllocationScope(BytecodeGenerator* generator) | 193 explicit RegisterAllocationScope(BytecodeGenerator* generator) |
184 : generator_(generator), | 194 : generator_(generator), |
185 outer_(generator->register_allocator()), | 195 outer_(generator->register_allocator()), |
(...skipping 2092 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2278 } | 2288 } |
2279 | 2289 |
2280 | 2290 |
2281 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2291 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
2282 return info()->feedback_vector()->GetIndex(slot); | 2292 return info()->feedback_vector()->GetIndex(slot); |
2283 } | 2293 } |
2284 | 2294 |
2285 } // namespace interpreter | 2295 } // namespace interpreter |
2286 } // namespace internal | 2296 } // namespace internal |
2287 } // namespace v8 | 2297 } // namespace v8 |
OLD | NEW |