| Index: src/interpreter/bytecode-generator.cc
|
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
|
| index b051bd9bbb173e4070f6932d525e789f8ae96b97..2b80467bf91119a3bdfa83597b8a7c166ba47abc 100644
|
| --- a/src/interpreter/bytecode-generator.cc
|
| +++ b/src/interpreter/bytecode-generator.cc
|
| @@ -1149,7 +1149,91 @@ void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
|
|
|
|
| void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
|
| - UNIMPLEMENTED();
|
| + DCHECK(expr->expression()->IsValidReferenceExpressionOrThis());
|
| +
|
| + // Left-hand side can only be a property, a global or a variable slot.
|
| + Property* property = expr->expression()->AsProperty();
|
| + LhsKind assign_type = Property::GetAssignType(property);
|
| +
|
| + // TODO(rmcilroy): Set is_postfix to false if visiting for effect.
|
| + bool is_postfix = expr->is_postfix();
|
| +
|
| + // Evaluate LHS expression and get old value.
|
| + TemporaryRegisterScope temporary_register_scope(builder());
|
| + Register obj, key, old_value;
|
| + switch (assign_type) {
|
| + case VARIABLE: {
|
| + VariableProxy* proxy = expr->expression()->AsVariableProxy();
|
| + VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot());
|
| + break;
|
| + }
|
| + case NAMED_PROPERTY: {
|
| + obj = temporary_register_scope.NewRegister();
|
| + key = temporary_register_scope.NewRegister();
|
| + FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
|
| + Visit(property->obj());
|
| + builder()
|
| + ->StoreAccumulatorInRegister(obj)
|
| + .LoadLiteral(property->key()->AsLiteral()->AsPropertyName())
|
| + .StoreAccumulatorInRegister(key)
|
| + .LoadNamedProperty(obj, feedback_index(slot), language_mode());
|
| + break;
|
| + }
|
| + case KEYED_PROPERTY: {
|
| + obj = temporary_register_scope.NewRegister();
|
| + key = temporary_register_scope.NewRegister();
|
| + FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
|
| + Visit(property->obj());
|
| + builder()->StoreAccumulatorInRegister(obj);
|
| + Visit(property->key());
|
| + builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty(
|
| + obj, feedback_index(slot), language_mode());
|
| + break;
|
| + }
|
| + case NAMED_SUPER_PROPERTY:
|
| + case KEYED_SUPER_PROPERTY:
|
| + UNIMPLEMENTED();
|
| + }
|
| +
|
| + // Convert old value into a number.
|
| + if (!is_strong(language_mode())) {
|
| + builder()->CastAccumulatorToNumber();
|
| + }
|
| +
|
| + // Save result for postfix expressions.
|
| + if (is_postfix) {
|
| + old_value = temporary_register_scope.NewRegister();
|
| + builder()->StoreAccumulatorInRegister(old_value);
|
| + }
|
| +
|
| + // Perform +1/-1 operation.
|
| + builder()->CountOperation(expr->binary_op(), language_mode_strength());
|
| +
|
| + // Store the value.
|
| + FeedbackVectorSlot feedback_slot = expr->CountSlot();
|
| + switch (assign_type) {
|
| + case VARIABLE: {
|
| + Variable* variable = expr->expression()->AsVariableProxy()->var();
|
| + VisitVariableAssignment(variable, feedback_slot);
|
| + break;
|
| + }
|
| + case NAMED_PROPERTY: {
|
| + builder()->StoreNamedProperty(obj, key, feedback_index(feedback_slot),
|
| + language_mode());
|
| + break;
|
| + }
|
| + case KEYED_PROPERTY: {
|
| + builder()->StoreKeyedProperty(obj, key, feedback_index(feedback_slot),
|
| + language_mode());
|
| + break;
|
| + }
|
| + case NAMED_SUPER_PROPERTY:
|
| + case KEYED_SUPER_PROPERTY:
|
| + UNIMPLEMENTED();
|
| + }
|
| +
|
| + // Restore old value for postfix expressions.
|
| + if (is_postfix) builder()->LoadAccumulatorWithRegister(old_value);
|
| }
|
|
|
|
|
|
|