| Index: src/arm/full-codegen-arm.cc
|
| diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
|
| index 660c10fe6269152ae3b82ff81be97eb6d9f44c7c..f307ba0d1c395d4da4ce1e916e168f9e66905ee7 100644
|
| --- a/src/arm/full-codegen-arm.cc
|
| +++ b/src/arm/full-codegen-arm.cc
|
| @@ -1883,22 +1883,8 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
|
|
| Comment cmnt(masm_, "[ Assignment");
|
|
|
| - // Left-hand side can only be a property, a global or a (parameter or local)
|
| - // slot.
|
| - enum LhsKind {
|
| - VARIABLE,
|
| - NAMED_PROPERTY,
|
| - KEYED_PROPERTY,
|
| - NAMED_SUPER_PROPERTY
|
| - };
|
| - LhsKind assign_type = VARIABLE;
|
| Property* property = expr->target()->AsProperty();
|
| - if (property != NULL) {
|
| - assign_type = (property->key()->IsPropertyName())
|
| - ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY
|
| - : NAMED_PROPERTY)
|
| - : KEYED_PROPERTY;
|
| - }
|
| + LhsKind assign_type = GetAssignType(property);
|
|
|
| // Evaluate LHS expression.
|
| switch (assign_type) {
|
| @@ -1925,6 +1911,21 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
| __ Push(result_register());
|
| }
|
| break;
|
| + case KEYED_SUPER_PROPERTY:
|
| + VisitForStackValue(property->obj()->AsSuperReference()->this_var());
|
| + EmitLoadHomeObject(property->obj()->AsSuperReference());
|
| + __ Push(result_register());
|
| + VisitForAccumulatorValue(property->key());
|
| + __ Push(result_register());
|
| + if (expr->is_compound()) {
|
| + const Register scratch = r1;
|
| + __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
|
| + __ Push(scratch);
|
| + __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
|
| + __ Push(scratch);
|
| + __ Push(result_register());
|
| + }
|
| + break;
|
| case KEYED_PROPERTY:
|
| if (expr->is_compound()) {
|
| VisitForStackValue(property->obj());
|
| @@ -1956,6 +1957,10 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
| EmitNamedSuperPropertyLoad(property);
|
| PrepareForBailoutForId(property->LoadId(), TOS_REG);
|
| break;
|
| + case KEYED_SUPER_PROPERTY:
|
| + EmitKeyedSuperPropertyLoad(property);
|
| + PrepareForBailoutForId(property->LoadId(), TOS_REG);
|
| + break;
|
| case KEYED_PROPERTY:
|
| EmitKeyedPropertyLoad(property);
|
| PrepareForBailoutForId(property->LoadId(), TOS_REG);
|
| @@ -2006,6 +2011,10 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
| EmitNamedSuperPropertyStore(property);
|
| context()->Plug(r0);
|
| break;
|
| + case KEYED_SUPER_PROPERTY:
|
| + EmitKeyedSuperPropertyStore(property);
|
| + context()->Plug(r0);
|
| + break;
|
| case KEYED_PROPERTY:
|
| EmitKeyedPropertyAssignment(expr);
|
| break;
|
| @@ -2651,14 +2660,27 @@ void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
|
| Literal* key = prop->key()->AsLiteral();
|
| DCHECK(key != NULL);
|
|
|
| - __ Push(r0);
|
| __ Push(key->value());
|
| + __ Push(r0);
|
| __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
|
| : Runtime::kStoreToSuper_Sloppy),
|
| 4);
|
| }
|
|
|
|
|
| +void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
|
| + // Assignment to named property of super.
|
| + // r0 : value
|
| + // stack : receiver ('this'), home_object, key
|
| + DCHECK(prop != NULL);
|
| +
|
| + __ Push(r0);
|
| + __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict
|
| + : Runtime::kStoreKeyedToSuper_Sloppy),
|
| + 4);
|
| +}
|
| +
|
| +
|
| void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
|
| // Assignment to a property, using a keyed store IC.
|
|
|
| @@ -4430,24 +4452,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
| Comment cmnt(masm_, "[ CountOperation");
|
| SetSourcePosition(expr->position());
|
|
|
| - // Expression can only be a property, a global or a (parameter or local)
|
| - // slot.
|
| - enum LhsKind {
|
| - VARIABLE,
|
| - NAMED_PROPERTY,
|
| - KEYED_PROPERTY,
|
| - NAMED_SUPER_PROPERTY
|
| - };
|
| - LhsKind assign_type = VARIABLE;
|
| Property* prop = expr->expression()->AsProperty();
|
| - // In case of a property we use the uninitialized expression context
|
| - // of the key to detect a named property.
|
| - if (prop != NULL) {
|
| - assign_type =
|
| - (prop->key()->IsPropertyName())
|
| - ? (prop->IsSuperAccess() ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
|
| - : KEYED_PROPERTY;
|
| - }
|
| + LhsKind assign_type = GetAssignType(prop);
|
|
|
| // Evaluate expression and get value.
|
| if (assign_type == VARIABLE) {
|
| @@ -4460,27 +4466,55 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
| __ mov(ip, Operand(Smi::FromInt(0)));
|
| __ push(ip);
|
| }
|
| - if (assign_type == NAMED_PROPERTY) {
|
| - // Put the object both on the stack and in the register.
|
| - VisitForStackValue(prop->obj());
|
| - __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
|
| - EmitNamedPropertyLoad(prop);
|
| - } else if (assign_type == NAMED_SUPER_PROPERTY) {
|
| - VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
| - EmitLoadHomeObject(prop->obj()->AsSuperReference());
|
| - __ Push(result_register());
|
| - const Register scratch = r1;
|
| - __ ldr(scratch, MemOperand(sp, kPointerSize));
|
| - __ Push(scratch);
|
| - __ Push(result_register());
|
| - EmitNamedSuperPropertyLoad(prop);
|
| - } else {
|
| - VisitForStackValue(prop->obj());
|
| - VisitForStackValue(prop->key());
|
| - __ ldr(LoadDescriptor::ReceiverRegister(),
|
| - MemOperand(sp, 1 * kPointerSize));
|
| - __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
|
| - EmitKeyedPropertyLoad(prop);
|
| + switch (assign_type) {
|
| + case NAMED_PROPERTY: {
|
| + // Put the object both on the stack and in the register.
|
| + VisitForStackValue(prop->obj());
|
| + __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
|
| + EmitNamedPropertyLoad(prop);
|
| + break;
|
| + }
|
| +
|
| + case NAMED_SUPER_PROPERTY: {
|
| + VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
| + EmitLoadHomeObject(prop->obj()->AsSuperReference());
|
| + __ Push(result_register());
|
| + const Register scratch = r1;
|
| + __ ldr(scratch, MemOperand(sp, kPointerSize));
|
| + __ Push(scratch);
|
| + __ Push(result_register());
|
| + EmitNamedSuperPropertyLoad(prop);
|
| + break;
|
| + }
|
| +
|
| + case KEYED_SUPER_PROPERTY: {
|
| + VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
| + EmitLoadHomeObject(prop->obj()->AsSuperReference());
|
| + __ Push(result_register());
|
| + VisitForAccumulatorValue(prop->key());
|
| + __ Push(result_register());
|
| + const Register scratch = r1;
|
| + __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
|
| + __ Push(scratch);
|
| + __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
|
| + __ Push(scratch);
|
| + __ Push(result_register());
|
| + EmitKeyedSuperPropertyLoad(prop);
|
| + break;
|
| + }
|
| +
|
| + case KEYED_PROPERTY: {
|
| + VisitForStackValue(prop->obj());
|
| + VisitForStackValue(prop->key());
|
| + __ ldr(LoadDescriptor::ReceiverRegister(),
|
| + MemOperand(sp, 1 * kPointerSize));
|
| + __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
|
| + EmitKeyedPropertyLoad(prop);
|
| + break;
|
| + }
|
| +
|
| + case VARIABLE:
|
| + UNREACHABLE();
|
| }
|
| }
|
|
|
| @@ -4520,6 +4554,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
| case KEYED_PROPERTY:
|
| __ str(r0, MemOperand(sp, 2 * kPointerSize));
|
| break;
|
| + case KEYED_SUPER_PROPERTY:
|
| + __ str(r0, MemOperand(sp, 3 * kPointerSize));
|
| + break;
|
| }
|
| }
|
| }
|
| @@ -4553,6 +4590,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
| case KEYED_PROPERTY:
|
| __ str(r0, MemOperand(sp, 2 * kPointerSize));
|
| break;
|
| + case KEYED_SUPER_PROPERTY:
|
| + __ str(r0, MemOperand(sp, 3 * kPointerSize));
|
| + break;
|
| }
|
| }
|
| }
|
| @@ -4619,6 +4659,17 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
| }
|
| break;
|
| }
|
| + case KEYED_SUPER_PROPERTY: {
|
| + EmitKeyedSuperPropertyStore(prop);
|
| + if (expr->is_postfix()) {
|
| + if (!context()->IsEffect()) {
|
| + context()->PlugTOS();
|
| + }
|
| + } else {
|
| + context()->Plug(r0);
|
| + }
|
| + break;
|
| + }
|
| case KEYED_PROPERTY: {
|
| __ Pop(StoreDescriptor::ReceiverRegister(),
|
| StoreDescriptor::NameRegister());
|
|
|