| Index: src/mips64/full-codegen-mips64.cc
|
| diff --git a/src/mips64/full-codegen-mips64.cc b/src/mips64/full-codegen-mips64.cc
|
| index 5c26f163911cc726c8bb074a609f7d4e7a127174..1d4e63e8d5932314ef557ed79c7bfc08abfdf269 100644
|
| --- a/src/mips64/full-codegen-mips64.cc
|
| +++ b/src/mips64/full-codegen-mips64.cc
|
| @@ -1871,13 +1871,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.
|
| @@ -1894,6 +1900,16 @@ 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 = a1;
|
| + __ ld(scratch, MemOperand(sp, kPointerSize));
|
| + __ Push(scratch, result_register());
|
| + }
|
| + break;
|
| case KEYED_PROPERTY:
|
| // We need the key and receiver on both the stack and in v0 and a1.
|
| if (expr->is_compound()) {
|
| @@ -1922,6 +1938,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);
|
| @@ -1968,6 +1988,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;
|
| @@ -2310,15 +2333,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(v0);
|
| - VisitForStackValue(super_ref->this_var());
|
| __ Push(key->value());
|
| __ CallRuntime(Runtime::kLoadFromSuper, 3);
|
| }
|
| @@ -2593,6 +2613,24 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
|
| }
|
|
|
|
|
| +void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) {
|
| + // Assignment to named property of super.
|
| + // v0 : value
|
| + // stack : receiver ('this'), home_object
|
| + Property* prop = expr->target()->AsProperty();
|
| + DCHECK(prop != NULL);
|
| + Literal* key = prop->key()->AsLiteral();
|
| + DCHECK(key != NULL);
|
| +
|
| + __ Push(v0);
|
| + __ Push(key->value());
|
| + __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
|
| + : Runtime::kStoreToSuper_Sloppy),
|
| + 4);
|
| + context()->Plug(v0);
|
| +}
|
| +
|
| +
|
| void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
|
| // Assignment to a property, using a keyed store IC.
|
|
|
| @@ -2625,6 +2663,9 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
|
| __ Move(LoadDescriptor::ReceiverRegister(), v0);
|
| EmitNamedPropertyLoad(expr);
|
| } else {
|
| + VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
|
| + EmitLoadHomeObject(expr->obj()->AsSuperReference());
|
| + __ Push(result_register());
|
| EmitNamedSuperPropertyLoad(expr);
|
| }
|
| PrepareForBailoutForId(expr->LoadId(), TOS_REG);
|
| @@ -2693,18 +2734,16 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
|
| const Register scratch = a1;
|
| SuperReference* super_ref = prop->obj()->AsSuperReference();
|
| EmitLoadHomeObject(super_ref);
|
| - __ Push(v0);
|
| + __ mov(scratch, v0);
|
| VisitForAccumulatorValue(super_ref->this_var());
|
| - __ Push(v0);
|
| - __ ld(scratch, MemOperand(sp, kPointerSize));
|
| - __ Push(scratch, v0);
|
| + __ Push(scratch, v0, v0, 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);
|
|
|
| @@ -4351,6 +4390,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.
|
|
|