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