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 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 // Nothing to do to evaluate variable assignment LHS. | 1030 // Nothing to do to evaluate variable assignment LHS. |
1031 break; | 1031 break; |
1032 case NAMED_PROPERTY: { | 1032 case NAMED_PROPERTY: { |
1033 object = VisitForRegisterValue(property->obj()); | 1033 object = VisitForRegisterValue(property->obj()); |
1034 name_index = builder()->GetConstantPoolEntry( | 1034 name_index = builder()->GetConstantPoolEntry( |
1035 property->key()->AsLiteral()->AsPropertyName()); | 1035 property->key()->AsLiteral()->AsPropertyName()); |
1036 break; | 1036 break; |
1037 } | 1037 } |
1038 case KEYED_PROPERTY: { | 1038 case KEYED_PROPERTY: { |
1039 object = VisitForRegisterValue(property->obj()); | 1039 object = VisitForRegisterValue(property->obj()); |
1040 key = VisitForRegisterValue(property->key()); | 1040 if (expr->is_compound()) { |
| 1041 // Use VisitForAccumulator and store to register so that the key is |
| 1042 // still in the accumulator for loading the old value below. |
| 1043 key = execution_result()->NewRegister(); |
| 1044 VisitForAccumulatorValue(property->key()); |
| 1045 builder()->StoreAccumulatorInRegister(key); |
| 1046 } else { |
| 1047 key = VisitForRegisterValue(property->key()); |
| 1048 } |
1041 break; | 1049 break; |
1042 } | 1050 } |
1043 case NAMED_SUPER_PROPERTY: | 1051 case NAMED_SUPER_PROPERTY: |
1044 case KEYED_SUPER_PROPERTY: | 1052 case KEYED_SUPER_PROPERTY: |
1045 UNIMPLEMENTED(); | 1053 UNIMPLEMENTED(); |
1046 } | 1054 } |
1047 | 1055 |
1048 // Evaluate the value and potentially handle compound assignments by loading | 1056 // Evaluate the value and potentially handle compound assignments by loading |
1049 // the left-hand side value and performing a binary operation. | 1057 // the left-hand side value and performing a binary operation. |
1050 if (expr->is_compound()) { | 1058 if (expr->is_compound()) { |
1051 UNIMPLEMENTED(); | 1059 Register old_value; |
| 1060 switch (assign_type) { |
| 1061 case VARIABLE: { |
| 1062 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| 1063 old_value = VisitVariableLoadForRegisterValue( |
| 1064 proxy->var(), proxy->VariableFeedbackSlot()); |
| 1065 break; |
| 1066 } |
| 1067 case NAMED_PROPERTY: { |
| 1068 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
| 1069 old_value = execution_result()->NewRegister(); |
| 1070 builder() |
| 1071 ->LoadNamedProperty(object, name_index, feedback_index(slot), |
| 1072 language_mode()) |
| 1073 .StoreAccumulatorInRegister(old_value); |
| 1074 break; |
| 1075 } |
| 1076 case KEYED_PROPERTY: { |
| 1077 // Key is already in accumulator at this point due to evaluating the |
| 1078 // LHS above. |
| 1079 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
| 1080 old_value = execution_result()->NewRegister(); |
| 1081 builder() |
| 1082 ->LoadKeyedProperty(object, feedback_index(slot), language_mode()) |
| 1083 .StoreAccumulatorInRegister(old_value); |
| 1084 break; |
| 1085 } |
| 1086 case NAMED_SUPER_PROPERTY: |
| 1087 case KEYED_SUPER_PROPERTY: |
| 1088 UNIMPLEMENTED(); |
| 1089 break; |
| 1090 } |
| 1091 VisitForAccumulatorValue(expr->value()); |
| 1092 builder()->BinaryOperation(expr->binary_op(), old_value, |
| 1093 language_mode_strength()); |
1052 } else { | 1094 } else { |
1053 VisitForAccumulatorValue(expr->value()); | 1095 VisitForAccumulatorValue(expr->value()); |
1054 } | 1096 } |
1055 | 1097 |
1056 // Store the value. | 1098 // Store the value. |
1057 FeedbackVectorSlot slot = expr->AssignmentSlot(); | 1099 FeedbackVectorSlot slot = expr->AssignmentSlot(); |
1058 switch (assign_type) { | 1100 switch (assign_type) { |
1059 case VARIABLE: { | 1101 case VARIABLE: { |
1060 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. | 1102 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. |
1061 // Is the value in the accumulator safe? Yes, but scary. | 1103 // Is the value in the accumulator safe? Yes, but scary. |
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1715 } | 1757 } |
1716 | 1758 |
1717 | 1759 |
1718 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 1760 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
1719 return info()->feedback_vector()->GetIndex(slot); | 1761 return info()->feedback_vector()->GetIndex(slot); |
1720 } | 1762 } |
1721 | 1763 |
1722 } // namespace interpreter | 1764 } // namespace interpreter |
1723 } // namespace internal | 1765 } // namespace internal |
1724 } // namespace v8 | 1766 } // namespace v8 |
OLD | NEW |