| Index: src/interpreter/bytecode-generator.cc
|
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
|
| index b1cac30d3690aac041209b0d27e18d29c6df4638..ced5210bf6409c9f579a9818f55dcc469ed3a911 100644
|
| --- a/src/interpreter/bytecode-generator.cc
|
| +++ b/src/interpreter/bytecode-generator.cc
|
| @@ -960,6 +960,21 @@ void BytecodeGenerator::VisitVariableLoad(Variable* variable,
|
| }
|
|
|
|
|
| +void BytecodeGenerator::VisitVariableLoadForAccumulatorValue(
|
| + Variable* variable, FeedbackVectorSlot slot) {
|
| + AccumulatorResultScope accumulator_result(this);
|
| + VisitVariableLoad(variable, slot);
|
| +}
|
| +
|
| +
|
| +Register BytecodeGenerator::VisitVariableLoadForRegisterValue(
|
| + Variable* variable, FeedbackVectorSlot slot) {
|
| + RegisterResultScope register_scope(this);
|
| + VisitVariableLoad(variable, slot);
|
| + return register_scope.ResultRegister();
|
| +}
|
| +
|
| +
|
| void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
|
| FeedbackVectorSlot slot) {
|
| switch (variable->location()) {
|
| @@ -1174,10 +1189,8 @@ void BytecodeGenerator::VisitCall(Call* expr) {
|
| builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
|
| // Load callee as a global variable.
|
| VariableProxy* proxy = callee_expr->AsVariableProxy();
|
| - // Result scope for VisitVariableLoad to avoid using our temporaries
|
| - // and double setting the result in our result_scope() and.
|
| - AccumulatorResultScope accumulator_execution_result(this);
|
| - VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot());
|
| + VisitVariableLoadForAccumulatorValue(proxy->var(),
|
| + proxy->VariableFeedbackSlot());
|
| builder()->StoreAccumulatorInRegister(callee);
|
| break;
|
| }
|
| @@ -1295,7 +1308,93 @@ 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.
|
| + Register obj, key, old_value;
|
| + size_t name_index = kMaxUInt32;
|
| + switch (assign_type) {
|
| + case VARIABLE: {
|
| + VariableProxy* proxy = expr->expression()->AsVariableProxy();
|
| + VisitVariableLoadForAccumulatorValue(proxy->var(),
|
| + proxy->VariableFeedbackSlot());
|
| + break;
|
| + }
|
| + case NAMED_PROPERTY: {
|
| + FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
|
| + obj = VisitForRegisterValue(property->obj());
|
| + name_index = builder()->GetConstantPoolEntry(
|
| + property->key()->AsLiteral()->AsPropertyName());
|
| + builder()->LoadNamedProperty(obj, name_index, feedback_index(slot),
|
| + language_mode());
|
| + break;
|
| + }
|
| + case KEYED_PROPERTY: {
|
| + FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
|
| + obj = VisitForRegisterValue(property->obj());
|
| + // Use visit for accumulator here since we need the key in the accumulator
|
| + // for the LoadKeyedProperty.
|
| + key = execution_result()->NewRegister();
|
| + VisitForAccumulatorValue(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 = execution_result()->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, name_index, 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) {
|
| + execution_result()->SetResultInRegister(old_value);
|
| + } else {
|
| + execution_result()->SetResultInAccumulator();
|
| + }
|
| }
|
|
|
|
|
|
|