Chromium Code Reviews| 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/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
| 10 #include "src/interpreter/bytecode-register-allocator.h" | 10 #include "src/interpreter/bytecode-register-allocator.h" |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 288 Statement* statement_; | 288 Statement* statement_; |
| 289 LoopBuilder* loop_builder_; | 289 LoopBuilder* loop_builder_; |
| 290 }; | 290 }; |
| 291 | 291 |
| 292 // Scoped class for enabling 'throw' in try-catch constructs. | 292 // Scoped class for enabling 'throw' in try-catch constructs. |
| 293 class BytecodeGenerator::ControlScopeForTryCatch final | 293 class BytecodeGenerator::ControlScopeForTryCatch final |
| 294 : public BytecodeGenerator::ControlScope { | 294 : public BytecodeGenerator::ControlScope { |
| 295 public: | 295 public: |
| 296 ControlScopeForTryCatch(BytecodeGenerator* generator, | 296 ControlScopeForTryCatch(BytecodeGenerator* generator, |
| 297 TryCatchBuilder* try_catch_builder) | 297 TryCatchBuilder* try_catch_builder) |
| 298 : ControlScope(generator) { | 298 : ControlScope(generator) {} |
| 299 generator->try_catch_nesting_level_++; | 299 virtual ~ControlScopeForTryCatch() {} |
|
Michael Starzinger
2016/07/12 14:11:12
nit: Class is final, implicit destructor is good e
| |
| 300 } | |
| 301 virtual ~ControlScopeForTryCatch() { | |
| 302 generator()->try_catch_nesting_level_--; | |
| 303 } | |
| 304 | 300 |
| 305 protected: | 301 protected: |
| 306 bool Execute(Command command, Statement* statement) override { | 302 bool Execute(Command command, Statement* statement) override { |
| 307 switch (command) { | 303 switch (command) { |
| 308 case CMD_BREAK: | 304 case CMD_BREAK: |
| 309 case CMD_CONTINUE: | 305 case CMD_CONTINUE: |
| 310 case CMD_RETURN: | 306 case CMD_RETURN: |
| 311 break; | 307 break; |
| 312 case CMD_RETHROW: | 308 case CMD_RETHROW: |
| 313 generator()->builder()->ReThrow(); | 309 generator()->builder()->ReThrow(); |
| 314 return true; | 310 return true; |
| 315 } | 311 } |
| 316 return false; | 312 return false; |
| 317 } | 313 } |
| 318 }; | 314 }; |
| 319 | 315 |
| 320 // Scoped class for enabling control flow through try-finally constructs. | 316 // Scoped class for enabling control flow through try-finally constructs. |
| 321 class BytecodeGenerator::ControlScopeForTryFinally final | 317 class BytecodeGenerator::ControlScopeForTryFinally final |
| 322 : public BytecodeGenerator::ControlScope { | 318 : public BytecodeGenerator::ControlScope { |
| 323 public: | 319 public: |
| 324 ControlScopeForTryFinally(BytecodeGenerator* generator, | 320 ControlScopeForTryFinally(BytecodeGenerator* generator, |
| 325 TryFinallyBuilder* try_finally_builder, | 321 TryFinallyBuilder* try_finally_builder, |
| 326 DeferredCommands* commands) | 322 DeferredCommands* commands) |
| 327 : ControlScope(generator), | 323 : ControlScope(generator), |
| 328 try_finally_builder_(try_finally_builder), | 324 try_finally_builder_(try_finally_builder), |
| 329 commands_(commands) { | 325 commands_(commands) {} |
| 330 generator->try_finally_nesting_level_++; | 326 virtual ~ControlScopeForTryFinally() {} |
|
Michael Starzinger
2016/07/12 14:11:12
nit: Class is final, implicit destructor is good e
| |
| 331 } | |
| 332 virtual ~ControlScopeForTryFinally() { | |
| 333 generator()->try_finally_nesting_level_--; | |
| 334 } | |
| 335 | 327 |
| 336 protected: | 328 protected: |
| 337 bool Execute(Command command, Statement* statement) override { | 329 bool Execute(Command command, Statement* statement) override { |
| 338 switch (command) { | 330 switch (command) { |
| 339 case CMD_BREAK: | 331 case CMD_BREAK: |
| 340 case CMD_CONTINUE: | 332 case CMD_CONTINUE: |
| 341 case CMD_RETURN: | 333 case CMD_RETURN: |
| 342 case CMD_RETHROW: | 334 case CMD_RETHROW: |
| 343 commands_->RecordCommand(command, statement); | 335 commands_->RecordCommand(command, statement); |
| 344 try_finally_builder_->LeaveTry(); | 336 try_finally_builder_->LeaveTry(); |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 550 info->scope()->num_stack_slots(), info->literal(), | 542 info->scope()->num_stack_slots(), info->literal(), |
| 551 info->SourcePositionRecordingMode())), | 543 info->SourcePositionRecordingMode())), |
| 552 info_(info), | 544 info_(info), |
| 553 scope_(info->scope()), | 545 scope_(info->scope()), |
| 554 globals_(0, info->zone()), | 546 globals_(0, info->zone()), |
| 555 execution_control_(nullptr), | 547 execution_control_(nullptr), |
| 556 execution_context_(nullptr), | 548 execution_context_(nullptr), |
| 557 execution_result_(nullptr), | 549 execution_result_(nullptr), |
| 558 register_allocator_(nullptr), | 550 register_allocator_(nullptr), |
| 559 generator_resume_points_(info->literal()->yield_count(), info->zone()), | 551 generator_resume_points_(info->literal()->yield_count(), info->zone()), |
| 560 generator_state_(), | 552 generator_state_() { |
| 561 try_catch_nesting_level_(0), | |
| 562 try_finally_nesting_level_(0) { | |
| 563 InitializeAstVisitor(isolate()); | 553 InitializeAstVisitor(isolate()); |
| 564 } | 554 } |
| 565 | 555 |
| 566 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() { | 556 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() { |
| 567 // Initialize the incoming context. | 557 // Initialize the incoming context. |
| 568 ContextScope incoming_context(this, scope(), false); | 558 ContextScope incoming_context(this, scope(), false); |
| 569 | 559 |
| 570 // Initialize control scope. | 560 // Initialize control scope. |
| 571 ControlScopeForTopLevel control(this); | 561 ControlScopeForTopLevel control(this); |
| 572 | 562 |
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1182 VisitForAccumulatorValue(stmt->result_done()); | 1172 VisitForAccumulatorValue(stmt->result_done()); |
| 1183 loop_builder.BreakIfTrue(); | 1173 loop_builder.BreakIfTrue(); |
| 1184 | 1174 |
| 1185 VisitForEffect(stmt->assign_each()); | 1175 VisitForEffect(stmt->assign_each()); |
| 1186 VisitIterationBody(stmt, &loop_builder); | 1176 VisitIterationBody(stmt, &loop_builder); |
| 1187 loop_builder.JumpToHeader(); | 1177 loop_builder.JumpToHeader(); |
| 1188 loop_builder.EndLoop(); | 1178 loop_builder.EndLoop(); |
| 1189 } | 1179 } |
| 1190 | 1180 |
| 1191 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { | 1181 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { |
| 1192 TryCatchBuilder try_control_builder(builder()); | 1182 TryCatchBuilder try_control_builder(builder(), stmt->catch_predicted()); |
| 1193 Register no_reg; | 1183 Register no_reg; |
| 1194 | 1184 |
| 1195 // Preserve the context in a dedicated register, so that it can be restored | 1185 // Preserve the context in a dedicated register, so that it can be restored |
| 1196 // when the handler is entered by the stack-unwinding machinery. | 1186 // when the handler is entered by the stack-unwinding machinery. |
| 1197 // TODO(mstarzinger): Be smarter about register allocation. | 1187 // TODO(mstarzinger): Be smarter about register allocation. |
| 1198 Register context = register_allocator()->NewRegister(); | 1188 Register context = register_allocator()->NewRegister(); |
| 1199 builder()->MoveRegister(Register::current_context(), context); | 1189 builder()->MoveRegister(Register::current_context(), context); |
| 1200 | 1190 |
| 1201 // Evaluate the try-block inside a control scope. This simulates a handler | 1191 // Evaluate the try-block inside a control scope. This simulates a handler |
| 1202 // that is intercepting 'throw' control commands. | 1192 // that is intercepting 'throw' control commands. |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1218 | 1208 |
| 1219 // Load the catch context into the accumulator. | 1209 // Load the catch context into the accumulator. |
| 1220 builder()->LoadAccumulatorWithRegister(context); | 1210 builder()->LoadAccumulatorWithRegister(context); |
| 1221 | 1211 |
| 1222 // Evaluate the catch-block. | 1212 // Evaluate the catch-block. |
| 1223 VisitInScope(stmt->catch_block(), stmt->scope()); | 1213 VisitInScope(stmt->catch_block(), stmt->scope()); |
| 1224 try_control_builder.EndCatch(); | 1214 try_control_builder.EndCatch(); |
| 1225 } | 1215 } |
| 1226 | 1216 |
| 1227 void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { | 1217 void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { |
| 1228 TryFinallyBuilder try_control_builder(builder(), IsInsideTryCatch()); | 1218 TryFinallyBuilder try_control_builder(builder(), stmt->catch_predicted()); |
| 1229 Register no_reg; | 1219 Register no_reg; |
| 1230 | 1220 |
| 1231 // We keep a record of all paths that enter the finally-block to be able to | 1221 // We keep a record of all paths that enter the finally-block to be able to |
| 1232 // dispatch to the correct continuation point after the statements in the | 1222 // dispatch to the correct continuation point after the statements in the |
| 1233 // finally-block have been evaluated. | 1223 // finally-block have been evaluated. |
| 1234 // | 1224 // |
| 1235 // The try-finally construct can enter the finally-block in three ways: | 1225 // The try-finally construct can enter the finally-block in three ways: |
| 1236 // 1. By exiting the try-block normally, falling through at the end. | 1226 // 1. By exiting the try-block normally, falling through at the end. |
| 1237 // 2. By exiting the try-block with a function-local control flow transfer | 1227 // 2. By exiting the try-block with a function-local control flow transfer |
| 1238 // (i.e. through break/continue/return statements). | 1228 // (i.e. through break/continue/return statements). |
| (...skipping 1933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3172 return execution_context()->scope()->language_mode(); | 3162 return execution_context()->scope()->language_mode(); |
| 3173 } | 3163 } |
| 3174 | 3164 |
| 3175 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3165 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 3176 return TypeFeedbackVector::GetIndex(slot); | 3166 return TypeFeedbackVector::GetIndex(slot); |
| 3177 } | 3167 } |
| 3178 | 3168 |
| 3179 } // namespace interpreter | 3169 } // namespace interpreter |
| 3180 } // namespace internal | 3170 } // namespace internal |
| 3181 } // namespace v8 | 3171 } // namespace v8 |
| OLD | NEW |