From b2f5677499c3ea177447c789ce1d9c9f0e6ac5cc Mon Sep 17 00:00:00 2001 From: "weiliang.lin@intel.com" Date: Fri, 19 Sep 2014 13:44:24 +0000 Subject: [PATCH] X87: Implement loads and calls from 'super'. port r24078. orginal commit message: Implement loads and calls from 'super' BUG= R=weiliang.lin@intel.com Review URL: https://codereview.chromium.org/581273007 Patch from Chunyang Dai . git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24089 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/x87/full-codegen-x87.cc | 101 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 10 deletions(-) diff --git a/src/x87/full-codegen-x87.cc b/src/x87/full-codegen-x87.cc index ac55c28..94ccbcf 100644 --- a/src/x87/full-codegen-x87.cc +++ b/src/x87/full-codegen-x87.cc @@ -1275,6 +1275,25 @@ void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { } +void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) { + Comment cnmt(masm_, "[ SuperReference "); + + __ mov(LoadDescriptor::ReceiverRegister(), + Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); + + Handle home_object_symbol(isolate()->heap()->home_object_symbol()); + __ mov(LoadDescriptor::NameRegister(), home_object_symbol); + + CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId()); + + __ cmp(eax, isolate()->factory()->undefined_value()); + Label done; + __ j(not_equal, &done); + __ CallRuntime(Runtime::kThrowNonMethodError, 0); + __ bind(&done); +} + + void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, TypeofState typeof_state, Label* slow) { @@ -2225,6 +2244,21 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { } +void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { + 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(eax); + VisitForStackValue(super_ref->this_var()); + __ push(Immediate(key->value())); + __ CallRuntime(Runtime::kLoadFromSuper, 3); +} + + void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { SetSourcePosition(prop->position()); Handle ic = CodeFactory::KeyedLoadIC(isolate()).code(); @@ -2514,9 +2548,13 @@ void FullCodeGenerator::VisitProperty(Property* expr) { Expression* key = expr->key(); if (key->IsPropertyName()) { - VisitForAccumulatorValue(expr->obj()); - __ Move(LoadDescriptor::ReceiverRegister(), result_register()); - EmitNamedPropertyLoad(expr); + if (!expr->IsSuperAccess()) { + VisitForAccumulatorValue(expr->obj()); + __ Move(LoadDescriptor::ReceiverRegister(), result_register()); + EmitNamedPropertyLoad(expr); + } else { + EmitNamedSuperPropertyLoad(expr); + } PrepareForBailoutForId(expr->LoadId(), TOS_REG); context()->Plug(eax); } else { @@ -2555,6 +2593,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { } else { // Load the function from the receiver. DCHECK(callee->IsProperty()); + DCHECK(!callee->AsProperty()->IsSuperAccess()); __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); EmitNamedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); @@ -2567,6 +2606,42 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { } +void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { + Expression* callee = expr->expression(); + DCHECK(callee->IsProperty()); + Property* prop = callee->AsProperty(); + DCHECK(prop->IsSuperAccess()); + + SetSourcePosition(prop->position()); + Literal* key = prop->key()->AsLiteral(); + DCHECK(!key->value()->IsSmi()); + // Load the function from the receiver. + SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference(); + EmitLoadHomeObject(super_ref); + __ push(eax); + VisitForAccumulatorValue(super_ref->this_var()); + __ push(eax); + __ push(Operand(esp, kPointerSize)); + __ push(eax); + __ push(Immediate(key->value())); + // Stack here: + // - home_object + // - this (receiver) + // - home_object <-- LoadFromSuper will pop here and below. + // - this (receiver) + // - key + __ CallRuntime(Runtime::kLoadFromSuper, 3); + + // Replace home_object with target function. + __ mov(Operand(esp, kPointerSize), eax); + + // Stack here: + // - target function + // - this (receiver) + EmitCall(expr, CallICState::METHOD); +} + + // Code common for calls using the IC. void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) { @@ -2727,15 +2802,21 @@ void FullCodeGenerator::VisitCall(Call* expr) { } else if (call_type == Call::PROPERTY_CALL) { Property* property = callee->AsProperty(); - { PreservePositionScope scope(masm()->positions_recorder()); - VisitForStackValue(property->obj()); - } - if (property->key()->IsPropertyName()) { - EmitCallWithLoadIC(expr); + bool is_named_call = property->key()->IsPropertyName(); + // super.x() is handled in EmitCallWithLoadIC. + if (property->IsSuperAccess() && is_named_call) { + EmitSuperCallWithLoadIC(expr); } else { - EmitKeyedCallWithLoadIC(expr, property->key()); + { + PreservePositionScope scope(masm()->positions_recorder()); + VisitForStackValue(property->obj()); + } + if (is_named_call) { + EmitCallWithLoadIC(expr); + } else { + EmitKeyedCallWithLoadIC(expr, property->key()); + } } - } else { DCHECK(call_type == Call::OTHER_CALL); // Call to an arbitrary expression not handled specially above. -- 2.7.4