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/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 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1100 | 1100 |
| 1101 VisitForEffect(stmt->assign_each()); | 1101 VisitForEffect(stmt->assign_each()); |
| 1102 Visit(stmt->body()); | 1102 Visit(stmt->body()); |
| 1103 loop_builder.JumpToHeader(); | 1103 loop_builder.JumpToHeader(); |
| 1104 loop_builder.EndLoop(); | 1104 loop_builder.EndLoop(); |
| 1105 } | 1105 } |
| 1106 | 1106 |
| 1107 | 1107 |
| 1108 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { | 1108 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { |
| 1109 TryCatchBuilder try_control_builder(builder()); | 1109 TryCatchBuilder try_control_builder(builder()); |
| 1110 Register no_reg; | |
| 1110 | 1111 |
| 1111 // Preserve the context in a dedicated register, so that it can be restored | 1112 // Preserve the context in a dedicated register, so that it can be restored |
| 1112 // when the handler is entered by the stack-unwinding machinery. | 1113 // when the handler is entered by the stack-unwinding machinery. |
| 1113 // TODO(mstarzinger): Be smarter about register allocation. | 1114 // TODO(mstarzinger): Be smarter about register allocation. |
| 1114 Register context = register_allocator()->NewRegister(); | 1115 Register context = register_allocator()->NewRegister(); |
| 1115 | 1116 |
| 1116 // Evaluate the try-block inside a control scope. This simulates a handler | 1117 // Evaluate the try-block inside a control scope. This simulates a handler |
| 1117 // that is intercepting 'throw' control commands. | 1118 // that is intercepting 'throw' control commands. |
| 1118 try_control_builder.BeginTry(context); | 1119 try_control_builder.BeginTry(context); |
| 1119 { | 1120 { |
| 1120 ControlScopeForTryCatch scope(this, &try_control_builder); | 1121 ControlScopeForTryCatch scope(this, &try_control_builder); |
| 1121 Visit(stmt->try_block()); | 1122 Visit(stmt->try_block()); |
| 1122 } | 1123 } |
| 1123 try_control_builder.EndTry(); | 1124 try_control_builder.EndTry(); |
| 1124 | 1125 |
| 1125 // Clear message object as we enter the catch block. | |
| 1126 // TODO(mstarzinger): Implement this! | |
| 1127 | |
| 1128 // Create a catch scope that binds the exception. | 1126 // Create a catch scope that binds the exception. |
| 1129 VisitNewLocalCatchContext(stmt->variable()); | 1127 VisitNewLocalCatchContext(stmt->variable()); |
| 1128 builder()->StoreAccumulatorInRegister(context); | |
| 1129 | |
| 1130 // Clear message object as we enter the catch block. | |
| 1131 builder()->CallRuntime(Runtime::kInterpreterClearPendingMessage, no_reg, 0); | |
| 1132 | |
| 1133 // Load the catch context into the accumulator. | |
| 1134 builder()->LoadAccumulatorWithRegister(context); | |
| 1130 | 1135 |
| 1131 // Evaluate the catch-block. | 1136 // Evaluate the catch-block. |
| 1132 VisitInScope(stmt->catch_block(), stmt->scope()); | 1137 VisitInScope(stmt->catch_block(), stmt->scope()); |
| 1133 try_control_builder.EndCatch(); | 1138 try_control_builder.EndCatch(); |
| 1134 } | 1139 } |
| 1135 | 1140 |
| 1136 | 1141 |
| 1137 void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { | 1142 void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { |
| 1138 TryFinallyBuilder try_control_builder(builder()); | 1143 TryFinallyBuilder try_control_builder(builder()); |
| 1144 Register no_reg; | |
| 1139 | 1145 |
| 1140 // We keep a record of all paths that enter the finally-block to be able to | 1146 // We keep a record of all paths that enter the finally-block to be able to |
| 1141 // dispatch to the correct continuation point after the statements in the | 1147 // dispatch to the correct continuation point after the statements in the |
| 1142 // finally-block have been evaluated. | 1148 // finally-block have been evaluated. |
| 1143 // | 1149 // |
| 1144 // The try-finally construct can enter the finally-block in three ways: | 1150 // The try-finally construct can enter the finally-block in three ways: |
| 1145 // 1. By exiting the try-block normally, falling through at the end. | 1151 // 1. By exiting the try-block normally, falling through at the end. |
| 1146 // 2. By exiting the try-block with a function-local control flow transfer | 1152 // 2. By exiting the try-block with a function-local control flow transfer |
| 1147 // (i.e. through break/continue/return statements). | 1153 // (i.e. through break/continue/return statements). |
| 1148 // 3. By exiting the try-block with a thrown exception. | 1154 // 3. By exiting the try-block with a thrown exception. |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1169 Visit(stmt->try_block()); | 1175 Visit(stmt->try_block()); |
| 1170 } | 1176 } |
| 1171 try_control_builder.EndTry(); | 1177 try_control_builder.EndTry(); |
| 1172 | 1178 |
| 1173 // Record fall-through and exception cases. | 1179 // Record fall-through and exception cases. |
| 1174 commands.RecordFallThroughPath(); | 1180 commands.RecordFallThroughPath(); |
| 1175 try_control_builder.LeaveTry(); | 1181 try_control_builder.LeaveTry(); |
| 1176 try_control_builder.BeginHandler(); | 1182 try_control_builder.BeginHandler(); |
| 1177 commands.RecordHandlerReThrowPath(); | 1183 commands.RecordHandlerReThrowPath(); |
| 1178 | 1184 |
| 1185 // Pending message object is saved on entry. | |
| 1179 try_control_builder.BeginFinally(); | 1186 try_control_builder.BeginFinally(); |
| 1187 Register message = context; // Reuse register. | |
| 1188 builder() | |
| 1189 ->CallRuntime(Runtime::kInterpreterGetPendingMessage, no_reg, 0) | |
| 1190 .StoreAccumulatorInRegister(message); | |
| 1180 | 1191 |
| 1181 // Clear message object as we enter the finally block. | 1192 // Clear message object as we enter the finally block. |
| 1182 // TODO(mstarzinger): Implement this! | 1193 builder()->CallRuntime(Runtime::kInterpreterClearPendingMessage, no_reg, 0); |
|
rmcilroy
2016/02/01 20:57:14
Could we make InterpreterGetPendingMessage also cl
Michael Starzinger
2016/02/02 09:41:43
Done. I made kInterpreterClearPendingMessage retur
| |
| 1183 | 1194 |
| 1184 // Evaluate the finally-block. | 1195 // Evaluate the finally-block. |
| 1185 Visit(stmt->finally_block()); | 1196 Visit(stmt->finally_block()); |
| 1186 try_control_builder.EndFinally(); | 1197 try_control_builder.EndFinally(); |
| 1187 | 1198 |
| 1199 // Pending message object is restored on exit. | |
| 1200 builder()->CallRuntime(Runtime::kInterpreterSetPendingMessage, message, 1); | |
| 1201 | |
| 1188 // Dynamic dispatch after the finally-block. | 1202 // Dynamic dispatch after the finally-block. |
| 1189 commands.ApplyDeferredCommands(); | 1203 commands.ApplyDeferredCommands(); |
| 1190 } | 1204 } |
| 1191 | 1205 |
| 1192 | 1206 |
| 1193 void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { | 1207 void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { |
| 1194 UNIMPLEMENTED(); | 1208 UNIMPLEMENTED(); |
| 1195 } | 1209 } |
| 1196 | 1210 |
| 1197 | 1211 |
| (...skipping 1308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2506 } | 2520 } |
| 2507 | 2521 |
| 2508 | 2522 |
| 2509 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2523 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 2510 return info()->feedback_vector()->GetIndex(slot); | 2524 return info()->feedback_vector()->GetIndex(slot); |
| 2511 } | 2525 } |
| 2512 | 2526 |
| 2513 } // namespace interpreter | 2527 } // namespace interpreter |
| 2514 } // namespace internal | 2528 } // namespace internal |
| 2515 } // namespace v8 | 2529 } // namespace v8 |
| OLD | NEW |