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/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/interpreter/control-flow-builders.h" | 8 #include "src/interpreter/control-flow-builders.h" |
9 #include "src/objects.h" | 9 #include "src/objects.h" |
10 #include "src/parser.h" | 10 #include "src/parser.h" |
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 // TODO(rmcilroy): Perform check for uninitialized legacy const, const and | 953 // TODO(rmcilroy): Perform check for uninitialized legacy const, const and |
954 // let variables. | 954 // let variables. |
955 break; | 955 break; |
956 } | 956 } |
957 case VariableLocation::LOOKUP: | 957 case VariableLocation::LOOKUP: |
958 UNIMPLEMENTED(); | 958 UNIMPLEMENTED(); |
959 } | 959 } |
960 } | 960 } |
961 | 961 |
962 | 962 |
| 963 void BytecodeGenerator::VisitVariableLoadForAccumulatorValue( |
| 964 Variable* variable, FeedbackVectorSlot slot) { |
| 965 AccumulatorResultScope accumulator_result(this); |
| 966 VisitVariableLoad(variable, slot); |
| 967 } |
| 968 |
| 969 |
| 970 Register BytecodeGenerator::VisitVariableLoadForRegisterValue( |
| 971 Variable* variable, FeedbackVectorSlot slot) { |
| 972 RegisterResultScope register_scope(this); |
| 973 VisitVariableLoad(variable, slot); |
| 974 return register_scope.ResultRegister(); |
| 975 } |
| 976 |
| 977 |
963 void BytecodeGenerator::VisitVariableAssignment(Variable* variable, | 978 void BytecodeGenerator::VisitVariableAssignment(Variable* variable, |
964 FeedbackVectorSlot slot) { | 979 FeedbackVectorSlot slot) { |
965 switch (variable->location()) { | 980 switch (variable->location()) { |
966 case VariableLocation::LOCAL: { | 981 case VariableLocation::LOCAL: { |
967 // TODO(rmcilroy): support const mode initialization. | 982 // TODO(rmcilroy): support const mode initialization. |
968 Register destination(variable->index()); | 983 Register destination(variable->index()); |
969 builder()->StoreAccumulatorInRegister(destination); | 984 builder()->StoreAccumulatorInRegister(destination); |
970 RecordStoreToRegister(destination); | 985 RecordStoreToRegister(destination); |
971 break; | 986 break; |
972 } | 987 } |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 builder()->StoreAccumulatorInRegister(receiver); | 1182 builder()->StoreAccumulatorInRegister(receiver); |
1168 VisitPropertyLoadForAccumulator(receiver, property); | 1183 VisitPropertyLoadForAccumulator(receiver, property); |
1169 builder()->StoreAccumulatorInRegister(callee); | 1184 builder()->StoreAccumulatorInRegister(callee); |
1170 break; | 1185 break; |
1171 } | 1186 } |
1172 case Call::GLOBAL_CALL: { | 1187 case Call::GLOBAL_CALL: { |
1173 // Receiver is undefined for global calls. | 1188 // Receiver is undefined for global calls. |
1174 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); | 1189 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); |
1175 // Load callee as a global variable. | 1190 // Load callee as a global variable. |
1176 VariableProxy* proxy = callee_expr->AsVariableProxy(); | 1191 VariableProxy* proxy = callee_expr->AsVariableProxy(); |
1177 // Result scope for VisitVariableLoad to avoid using our temporaries | 1192 VisitVariableLoadForAccumulatorValue(proxy->var(), |
1178 // and double setting the result in our result_scope() and. | 1193 proxy->VariableFeedbackSlot()); |
1179 AccumulatorResultScope accumulator_execution_result(this); | |
1180 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot()); | |
1181 builder()->StoreAccumulatorInRegister(callee); | 1194 builder()->StoreAccumulatorInRegister(callee); |
1182 break; | 1195 break; |
1183 } | 1196 } |
1184 case Call::OTHER_CALL: { | 1197 case Call::OTHER_CALL: { |
1185 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); | 1198 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); |
1186 VisitForAccumulatorValue(callee_expr); | 1199 VisitForAccumulatorValue(callee_expr); |
1187 builder()->StoreAccumulatorInRegister(callee); | 1200 builder()->StoreAccumulatorInRegister(callee); |
1188 break; | 1201 break; |
1189 } | 1202 } |
1190 case Call::LOOKUP_SLOT_CALL: | 1203 case Call::LOOKUP_SLOT_CALL: |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1288 case Token::Value::BIT_NOT: | 1301 case Token::Value::BIT_NOT: |
1289 case Token::Value::DELETE: | 1302 case Token::Value::DELETE: |
1290 UNIMPLEMENTED(); | 1303 UNIMPLEMENTED(); |
1291 default: | 1304 default: |
1292 UNREACHABLE(); | 1305 UNREACHABLE(); |
1293 } | 1306 } |
1294 } | 1307 } |
1295 | 1308 |
1296 | 1309 |
1297 void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { | 1310 void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { |
1298 UNIMPLEMENTED(); | 1311 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); |
| 1312 |
| 1313 // Left-hand side can only be a property, a global or a variable slot. |
| 1314 Property* property = expr->expression()->AsProperty(); |
| 1315 LhsKind assign_type = Property::GetAssignType(property); |
| 1316 |
| 1317 // TODO(rmcilroy): Set is_postfix to false if visiting for effect. |
| 1318 bool is_postfix = expr->is_postfix(); |
| 1319 |
| 1320 // Evaluate LHS expression and get old value. |
| 1321 Register obj, key, old_value; |
| 1322 size_t name_index = kMaxUInt32; |
| 1323 switch (assign_type) { |
| 1324 case VARIABLE: { |
| 1325 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 1326 VisitVariableLoadForAccumulatorValue(proxy->var(), |
| 1327 proxy->VariableFeedbackSlot()); |
| 1328 break; |
| 1329 } |
| 1330 case NAMED_PROPERTY: { |
| 1331 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
| 1332 obj = VisitForRegisterValue(property->obj()); |
| 1333 name_index = builder()->GetConstantPoolEntry( |
| 1334 property->key()->AsLiteral()->AsPropertyName()); |
| 1335 builder()->LoadNamedProperty(obj, name_index, feedback_index(slot), |
| 1336 language_mode()); |
| 1337 break; |
| 1338 } |
| 1339 case KEYED_PROPERTY: { |
| 1340 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
| 1341 obj = VisitForRegisterValue(property->obj()); |
| 1342 // Use visit for accumulator here since we need the key in the accumulator |
| 1343 // for the LoadKeyedProperty. |
| 1344 key = execution_result()->NewRegister(); |
| 1345 VisitForAccumulatorValue(property->key()); |
| 1346 builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty( |
| 1347 obj, feedback_index(slot), language_mode()); |
| 1348 break; |
| 1349 } |
| 1350 case NAMED_SUPER_PROPERTY: |
| 1351 case KEYED_SUPER_PROPERTY: |
| 1352 UNIMPLEMENTED(); |
| 1353 } |
| 1354 |
| 1355 // Convert old value into a number. |
| 1356 if (!is_strong(language_mode())) { |
| 1357 builder()->CastAccumulatorToNumber(); |
| 1358 } |
| 1359 |
| 1360 // Save result for postfix expressions. |
| 1361 if (is_postfix) { |
| 1362 old_value = execution_result()->NewRegister(); |
| 1363 builder()->StoreAccumulatorInRegister(old_value); |
| 1364 } |
| 1365 |
| 1366 // Perform +1/-1 operation. |
| 1367 builder()->CountOperation(expr->binary_op(), language_mode_strength()); |
| 1368 |
| 1369 // Store the value. |
| 1370 FeedbackVectorSlot feedback_slot = expr->CountSlot(); |
| 1371 switch (assign_type) { |
| 1372 case VARIABLE: { |
| 1373 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
| 1374 VisitVariableAssignment(variable, feedback_slot); |
| 1375 break; |
| 1376 } |
| 1377 case NAMED_PROPERTY: { |
| 1378 builder()->StoreNamedProperty( |
| 1379 obj, name_index, feedback_index(feedback_slot), language_mode()); |
| 1380 break; |
| 1381 } |
| 1382 case KEYED_PROPERTY: { |
| 1383 builder()->StoreKeyedProperty(obj, key, feedback_index(feedback_slot), |
| 1384 language_mode()); |
| 1385 break; |
| 1386 } |
| 1387 case NAMED_SUPER_PROPERTY: |
| 1388 case KEYED_SUPER_PROPERTY: |
| 1389 UNIMPLEMENTED(); |
| 1390 } |
| 1391 |
| 1392 // Restore old value for postfix expressions. |
| 1393 if (is_postfix) { |
| 1394 execution_result()->SetResultInRegister(old_value); |
| 1395 } else { |
| 1396 execution_result()->SetResultInAccumulator(); |
| 1397 } |
1299 } | 1398 } |
1300 | 1399 |
1301 | 1400 |
1302 void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) { | 1401 void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) { |
1303 switch (binop->op()) { | 1402 switch (binop->op()) { |
1304 case Token::COMMA: | 1403 case Token::COMMA: |
1305 VisitCommaExpression(binop); | 1404 VisitCommaExpression(binop); |
1306 break; | 1405 break; |
1307 case Token::OR: | 1406 case Token::OR: |
1308 VisitLogicalOrExpression(binop); | 1407 VisitLogicalOrExpression(binop); |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1616 } | 1715 } |
1617 | 1716 |
1618 | 1717 |
1619 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 1718 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
1620 return info()->feedback_vector()->GetIndex(slot); | 1719 return info()->feedback_vector()->GetIndex(slot); |
1621 } | 1720 } |
1622 | 1721 |
1623 } // namespace interpreter | 1722 } // namespace interpreter |
1624 } // namespace internal | 1723 } // namespace internal |
1625 } // namespace v8 | 1724 } // namespace v8 |
OLD | NEW |