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