Index: src/arm/full-codegen-arm.cc |
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc |
index 6108c0b92c9e2641e2b61e11cbdd94168127e3f9..42a605c7e9c350b57feb4555507d7cd65e105666 100644 |
--- a/src/arm/full-codegen-arm.cc |
+++ b/src/arm/full-codegen-arm.cc |
@@ -1885,13 +1885,19 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
// Left-hand side can only be a property, a global or a (parameter or local) |
// slot. |
- enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; |
+ 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()) |
- ? NAMED_PROPERTY |
- : KEYED_PROPERTY; |
+ ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY |
+ : NAMED_PROPERTY) |
+ : KEYED_PROPERTY; |
} |
// Evaluate LHS expression. |
@@ -1908,6 +1914,17 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
VisitForStackValue(property->obj()); |
} |
break; |
+ case NAMED_SUPER_PROPERTY: |
+ VisitForStackValue(property->obj()->AsSuperReference()->this_var()); |
+ EmitLoadHomeObject(property->obj()->AsSuperReference()); |
+ __ Push(result_register()); |
+ if (expr->is_compound()) { |
+ const Register scratch = r1; |
+ __ ldr(scratch, MemOperand(sp, kPointerSize)); |
+ __ Push(scratch); |
+ __ Push(result_register()); |
+ } |
+ break; |
case KEYED_PROPERTY: |
if (expr->is_compound()) { |
VisitForStackValue(property->obj()); |
@@ -1935,6 +1952,10 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
EmitNamedPropertyLoad(property); |
PrepareForBailoutForId(property->LoadId(), TOS_REG); |
break; |
+ case NAMED_SUPER_PROPERTY: |
+ EmitNamedSuperPropertyLoad(property); |
+ PrepareForBailoutForId(property->LoadId(), TOS_REG); |
+ break; |
case KEYED_PROPERTY: |
EmitKeyedPropertyLoad(property); |
PrepareForBailoutForId(property->LoadId(), TOS_REG); |
@@ -1981,6 +2002,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
case NAMED_PROPERTY: |
EmitNamedPropertyAssignment(expr); |
break; |
+ case NAMED_SUPER_PROPERTY: |
+ EmitNamedSuperPropertyAssignment(expr); |
+ break; |
case KEYED_PROPERTY: |
EmitKeyedPropertyAssignment(expr); |
break; |
@@ -2319,6 +2343,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) { |
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
SetSourcePosition(prop->position()); |
Literal* key = prop->key()->AsLiteral(); |
+ DCHECK(!prop->IsSuperAccess()); |
__ mov(LoadDescriptor::NameRegister(), Operand(key->value())); |
if (FLAG_vector_ics) { |
@@ -2332,15 +2357,12 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { |
+ // Stack: receiver, home_object. |
SetSourcePosition(prop->position()); |
Literal* key = prop->key()->AsLiteral(); |
DCHECK(!key->value()->IsSmi()); |
DCHECK(prop->IsSuperAccess()); |
- SuperReference* super_ref = prop->obj()->AsSuperReference(); |
- EmitLoadHomeObject(super_ref); |
- __ Push(r0); |
- VisitForStackValue(super_ref->this_var()); |
__ Push(key->value()); |
__ CallRuntime(Runtime::kLoadFromSuper, 3); |
} |
@@ -2612,6 +2634,24 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
} |
+void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) { |
+ // Assignment to named property of super. |
+ // r0 : value |
+ // stack : receiver ('this'), home_object |
+ Property* prop = expr->target()->AsProperty(); |
+ DCHECK(prop != NULL); |
+ Literal* key = prop->key()->AsLiteral(); |
+ DCHECK(key != NULL); |
+ |
+ __ Push(r0); |
+ __ Push(key->value()); |
+ __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict |
+ : Runtime::kStoreToSuper_Sloppy), |
+ 4); |
+ context()->Plug(r0); |
+} |
+ |
+ |
void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
// Assignment to a property, using a keyed store IC. |
@@ -2638,6 +2678,9 @@ void FullCodeGenerator::VisitProperty(Property* expr) { |
__ Move(LoadDescriptor::ReceiverRegister(), r0); |
EmitNamedPropertyLoad(expr); |
} else { |
+ VisitForStackValue(expr->obj()->AsSuperReference()->this_var()); |
+ EmitLoadHomeObject(expr->obj()->AsSuperReference()); |
+ __ Push(result_register()); |
EmitNamedSuperPropertyLoad(expr); |
} |
PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
@@ -2712,16 +2755,16 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
__ Push(r0); |
VisitForAccumulatorValue(super_ref->this_var()); |
__ Push(r0); |
- __ ldr(scratch, MemOperand(sp, kPointerSize)); |
- __ Push(scratch); |
__ Push(r0); |
+ __ ldr(scratch, MemOperand(sp, kPointerSize * 2)); |
+ __ Push(scratch); |
__ Push(key->value()); |
// Stack here: |
// - home_object |
// - this (receiver) |
- // - home_object <-- LoadFromSuper will pop here and below. |
- // - this (receiver) |
+ // - this (receiver) <-- LoadFromSuper will pop here and below. |
+ // - home_object |
// - key |
__ CallRuntime(Runtime::kLoadFromSuper, 3); |
@@ -4339,6 +4382,11 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
if (prop != NULL) { |
assign_type = |
(prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; |
+ if (prop->IsSuperAccess()) { |
+ // throw exception. |
+ VisitSuperReference(prop->obj()->AsSuperReference()); |
+ return; |
+ } |
} |
// Evaluate expression and get value. |