Revert of [es6] Super call in arrows and eval (patchset #5 id:100001 of https://codereview.chromium.org/1146863007/)
Reason for revert: Fails http://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20nosnap%20-%20debug%20-%201/builds/579/steps/Check/logs/super Original issue's description: > [es6] Super call in arrows and eval > > This splits the SuperReference AST node into SuperPropertyReference and > SuperCallReference. The super call reference node consists of three > unresolved vars to this, new.target and this_function. These gets > declared when the right function is entered and if it is in use. The > variables gets assigned in FullCodeGenerator::Generate. > > BUG=v8:3768 > LOG=N > R=wingo@igalia.com, adamk@chromium.org > > Committed: https://crrev.com/673c0516ab96f24343bbb26e0afc2846b5a679df > Cr-Commit-Position: refs/heads/master@{#28731} TBR=wingo@igalia.com,adamk@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=v8:3768 Review URL: https://codereview.chromium.org/1161243005 Cr-Commit-Position: refs/heads/master@{#28735}
This commit is contained in:
parent
710baad489
commit
88b1c9170a
@ -242,24 +242,6 @@ void FullCodeGenerator::Generate() {
|
||||
}
|
||||
}
|
||||
|
||||
// Possibly set up a local binding to the this function which is used in
|
||||
// derived constructors with super calls.
|
||||
Variable* this_function_var = scope()->this_function_var();
|
||||
if (this_function_var != nullptr) {
|
||||
Comment cmnt(masm_, "[ This function");
|
||||
SetVar(this_function_var, r1, r0, r2);
|
||||
}
|
||||
|
||||
Variable* new_target_var = scope()->new_target_var();
|
||||
if (new_target_var != nullptr) {
|
||||
Comment cmnt(masm_, "[ new.target");
|
||||
// new.target is parameter -2.
|
||||
int offset = 2 * kPointerSize +
|
||||
(info_->scope()->num_parameters() + 1) * kPointerSize;
|
||||
__ ldr(r0, MemOperand(fp, offset));
|
||||
SetVar(new_target_var, r0, r2, r3);
|
||||
}
|
||||
|
||||
Variable* home_object_var = scope()->home_object_var();
|
||||
if (home_object_var != nullptr) {
|
||||
__ Push(r1);
|
||||
@ -2020,10 +2002,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
}
|
||||
break;
|
||||
case NAMED_SUPER_PROPERTY:
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(property->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
property->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
property->obj()->AsSuperReference()->home_object_var());
|
||||
__ Push(result_register());
|
||||
if (expr->is_compound()) {
|
||||
const Register scratch = r1;
|
||||
@ -2033,10 +2014,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
}
|
||||
break;
|
||||
case KEYED_SUPER_PROPERTY:
|
||||
VisitForStackValue(property->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
property->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForAccumulatorValue(property->key());
|
||||
__ Push(result_register());
|
||||
if (expr->is_compound()) {
|
||||
@ -2679,9 +2659,9 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
|
||||
}
|
||||
case NAMED_SUPER_PROPERTY: {
|
||||
__ Push(r0);
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
prop->obj()->AsSuperReference()->home_object_var());
|
||||
// stack: value, this; r0: home_object
|
||||
Register scratch = r2;
|
||||
Register scratch2 = r3;
|
||||
@ -2696,9 +2676,8 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
|
||||
}
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
__ Push(r0);
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForAccumulatorValue(prop->key());
|
||||
Register scratch = r2;
|
||||
Register scratch2 = r3;
|
||||
@ -2922,9 +2901,8 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
|
||||
__ Move(LoadDescriptor::ReceiverRegister(), r0);
|
||||
EmitNamedPropertyLoad(expr);
|
||||
} else {
|
||||
VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
expr->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->home_object_var());
|
||||
EmitNamedSuperPropertyLoad(expr);
|
||||
}
|
||||
} else {
|
||||
@ -2935,9 +2913,8 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
|
||||
__ pop(LoadDescriptor::ReceiverRegister());
|
||||
EmitKeyedPropertyLoad(expr);
|
||||
} else {
|
||||
VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
expr->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForStackValue(expr->key());
|
||||
EmitKeyedSuperPropertyLoad(expr);
|
||||
}
|
||||
@ -3002,7 +2979,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
|
||||
DCHECK(!key->value()->IsSmi());
|
||||
// Load the function from the receiver.
|
||||
const Register scratch = r1;
|
||||
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
|
||||
SuperReference* super_ref = prop->obj()->AsSuperReference();
|
||||
VisitForStackValue(super_ref->home_object_var());
|
||||
VisitForAccumulatorValue(super_ref->this_var());
|
||||
__ Push(r0);
|
||||
@ -3062,7 +3039,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
|
||||
SetSourcePosition(prop->position());
|
||||
// Load the function from the receiver.
|
||||
const Register scratch = r1;
|
||||
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
|
||||
SuperReference* super_ref = prop->obj()->AsSuperReference();
|
||||
VisitForStackValue(super_ref->home_object_var());
|
||||
VisitForAccumulatorValue(super_ref->this_var());
|
||||
__ Push(r0);
|
||||
@ -3144,8 +3121,15 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitLoadSuperConstructor() {
|
||||
__ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
__ Push(r0);
|
||||
__ CallRuntime(Runtime::kGetPrototype, 1);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitInitializeThisAfterSuper(
|
||||
SuperCallReference* super_ref, FeedbackVectorICSlot slot) {
|
||||
SuperReference* super_ref, FeedbackVectorICSlot slot) {
|
||||
Variable* this_var = super_ref->this_var()->var();
|
||||
GetVar(r1, this_var);
|
||||
__ CompareRoot(r1, Heap::kTheHoleValueRootIndex);
|
||||
@ -3305,7 +3289,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
// Push constructor on the stack. If it's not a function it's used as
|
||||
// receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
|
||||
// ignored.
|
||||
DCHECK(!expr->expression()->IsSuperPropertyReference());
|
||||
DCHECK(!expr->expression()->IsSuperReference());
|
||||
VisitForStackValue(expr->expression());
|
||||
|
||||
// Push the arguments ("left-to-right") on the stack.
|
||||
@ -3341,14 +3325,11 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
||||
SuperCallReference* super_call_ref =
|
||||
expr->expression()->AsSuperCallReference();
|
||||
DCHECK_NOT_NULL(super_call_ref);
|
||||
Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
|
||||
GetVar(result_register(), new_target_var);
|
||||
__ Push(result_register());
|
||||
|
||||
VariableProxy* new_target_proxy = super_call_ref->new_target_var();
|
||||
VisitForStackValue(new_target_proxy);
|
||||
|
||||
EmitLoadSuperConstructor(super_call_ref);
|
||||
EmitLoadSuperConstructor();
|
||||
__ push(result_register());
|
||||
|
||||
// Push the arguments ("left-to-right") on the stack.
|
||||
@ -3386,7 +3367,8 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
||||
|
||||
RecordJSReturnSite(expr);
|
||||
|
||||
EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot());
|
||||
EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(),
|
||||
expr->CallFeedbackICSlot());
|
||||
context()->Plug(r0);
|
||||
}
|
||||
|
||||
@ -4247,15 +4229,11 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
|
||||
GetVar(result_register(), new_target_var);
|
||||
__ Push(result_register());
|
||||
|
||||
// new.target
|
||||
VisitForStackValue(args->at(0));
|
||||
|
||||
// .this_function
|
||||
VisitForStackValue(args->at(1));
|
||||
__ CallRuntime(Runtime::kGetPrototype, 1);
|
||||
EmitLoadSuperConstructor();
|
||||
__ Push(result_register());
|
||||
|
||||
// Check if the calling frame is an arguments adaptor frame.
|
||||
@ -4648,14 +4626,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
|
||||
|
||||
void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
// Assert: expr === CallRuntime("ReflectConstruct")
|
||||
DCHECK_EQ(1, expr->arguments()->length());
|
||||
CallRuntime* call = expr->arguments()->at(0)->AsCallRuntime();
|
||||
|
||||
ZoneList<Expression*>* args = call->arguments();
|
||||
DCHECK_EQ(3, args->length());
|
||||
|
||||
SuperCallReference* super_call_ref = args->at(0)->AsSuperCallReference();
|
||||
DCHECK_NOT_NULL(super_call_ref);
|
||||
SuperReference* super_reference = args->at(0)->AsSuperReference();
|
||||
|
||||
// Load ReflectConstruct function
|
||||
EmitLoadJSRuntimeFunction(call);
|
||||
@ -4665,8 +4640,8 @@ void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
__ push(ip);
|
||||
__ str(r0, MemOperand(sp, kPointerSize));
|
||||
|
||||
// Push super constructor
|
||||
EmitLoadSuperConstructor(super_call_ref);
|
||||
// Push super
|
||||
EmitLoadSuperConstructor();
|
||||
__ Push(result_register());
|
||||
|
||||
// Push arguments array
|
||||
@ -4683,7 +4658,7 @@ void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
context()->DropAndPlug(1, r0);
|
||||
|
||||
// TODO(mvstanton): with FLAG_vector_stores this needs a slot id.
|
||||
EmitInitializeThisAfterSuper(super_call_ref);
|
||||
EmitInitializeThisAfterSuper(super_reference);
|
||||
}
|
||||
|
||||
|
||||
@ -4908,9 +4883,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
}
|
||||
|
||||
case NAMED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
prop->obj()->AsSuperReference()->home_object_var());
|
||||
__ Push(result_register());
|
||||
const Register scratch = r1;
|
||||
__ ldr(scratch, MemOperand(sp, kPointerSize));
|
||||
@ -4921,9 +4896,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
}
|
||||
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForAccumulatorValue(prop->key());
|
||||
__ Push(result_register());
|
||||
const Register scratch = r1;
|
||||
|
@ -243,24 +243,6 @@ void FullCodeGenerator::Generate() {
|
||||
}
|
||||
}
|
||||
|
||||
// Possibly set up a local binding to the this function which is used in
|
||||
// derived constructors with super calls.
|
||||
Variable* this_function_var = scope()->this_function_var();
|
||||
if (this_function_var != nullptr) {
|
||||
Comment cmnt(masm_, "[ This function");
|
||||
SetVar(this_function_var, x1, x0, x2);
|
||||
}
|
||||
|
||||
Variable* new_target_var = scope()->new_target_var();
|
||||
if (new_target_var != nullptr) {
|
||||
Comment cmnt(masm_, "[ new.target");
|
||||
// new.target is parameter -2.
|
||||
int offset =
|
||||
2 * kXRegSize + (info_->scope()->num_parameters() + 1) * kPointerSize;
|
||||
__ Ldr(x0, MemOperand(fp, offset));
|
||||
SetVar(new_target_var, x0, x2, x3);
|
||||
}
|
||||
|
||||
Variable* home_object_var = scope()->home_object_var();
|
||||
if (home_object_var != nullptr) {
|
||||
__ Push(x1);
|
||||
@ -1988,10 +1970,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
}
|
||||
break;
|
||||
case NAMED_SUPER_PROPERTY:
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(property->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
property->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
property->obj()->AsSuperReference()->home_object_var());
|
||||
__ Push(result_register());
|
||||
if (expr->is_compound()) {
|
||||
const Register scratch = x10;
|
||||
@ -2000,10 +1981,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
}
|
||||
break;
|
||||
case KEYED_SUPER_PROPERTY:
|
||||
VisitForStackValue(property->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
property->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForAccumulatorValue(property->key());
|
||||
__ Push(result_register());
|
||||
if (expr->is_compound()) {
|
||||
@ -2360,9 +2340,9 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
|
||||
}
|
||||
case NAMED_SUPER_PROPERTY: {
|
||||
__ Push(x0);
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
prop->obj()->AsSuperReference()->home_object_var());
|
||||
// stack: value, this; x0: home_object
|
||||
Register scratch = x10;
|
||||
Register scratch2 = x11;
|
||||
@ -2377,9 +2357,8 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
|
||||
}
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
__ Push(x0);
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForAccumulatorValue(prop->key());
|
||||
Register scratch = x10;
|
||||
Register scratch2 = x11;
|
||||
@ -2605,9 +2584,8 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
|
||||
__ Move(LoadDescriptor::ReceiverRegister(), x0);
|
||||
EmitNamedPropertyLoad(expr);
|
||||
} else {
|
||||
VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
expr->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->home_object_var());
|
||||
EmitNamedSuperPropertyLoad(expr);
|
||||
}
|
||||
} else {
|
||||
@ -2618,9 +2596,8 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
|
||||
__ Pop(LoadDescriptor::ReceiverRegister());
|
||||
EmitKeyedPropertyLoad(expr);
|
||||
} else {
|
||||
VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
expr->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForStackValue(expr->key());
|
||||
EmitKeyedSuperPropertyLoad(expr);
|
||||
}
|
||||
@ -2688,8 +2665,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
|
||||
|
||||
// Load the function from the receiver.
|
||||
const Register scratch = x10;
|
||||
SuperPropertyReference* super_ref =
|
||||
callee->AsProperty()->obj()->AsSuperPropertyReference();
|
||||
SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference();
|
||||
VisitForStackValue(super_ref->home_object_var());
|
||||
VisitForAccumulatorValue(super_ref->this_var());
|
||||
__ Push(x0);
|
||||
@ -2748,8 +2724,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
|
||||
|
||||
// Load the function from the receiver.
|
||||
const Register scratch = x10;
|
||||
SuperPropertyReference* super_ref =
|
||||
callee->AsProperty()->obj()->AsSuperPropertyReference();
|
||||
SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference();
|
||||
VisitForStackValue(super_ref->home_object_var());
|
||||
VisitForAccumulatorValue(super_ref->this_var());
|
||||
__ Push(x0);
|
||||
@ -2830,8 +2805,15 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitLoadSuperConstructor() {
|
||||
__ ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
__ Push(x0);
|
||||
__ CallRuntime(Runtime::kGetPrototype, 1);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitInitializeThisAfterSuper(
|
||||
SuperCallReference* super_ref, FeedbackVectorICSlot slot) {
|
||||
SuperReference* super_ref, FeedbackVectorICSlot slot) {
|
||||
Variable* this_var = super_ref->this_var()->var();
|
||||
GetVar(x1, this_var);
|
||||
Label uninitialized_this;
|
||||
@ -2991,7 +2973,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
// Push constructor on the stack. If it's not a function it's used as
|
||||
// receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
|
||||
// ignored.
|
||||
DCHECK(!expr->expression()->IsSuperPropertyReference());
|
||||
DCHECK(!expr->expression()->IsSuperReference());
|
||||
VisitForStackValue(expr->expression());
|
||||
|
||||
// Push the arguments ("left-to-right") on the stack.
|
||||
@ -3027,14 +3009,11 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
||||
SuperCallReference* super_call_ref =
|
||||
expr->expression()->AsSuperCallReference();
|
||||
DCHECK_NOT_NULL(super_call_ref);
|
||||
Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
|
||||
GetVar(result_register(), new_target_var);
|
||||
__ Push(result_register());
|
||||
|
||||
VariableProxy* new_target_proxy = super_call_ref->new_target_var();
|
||||
VisitForStackValue(new_target_proxy);
|
||||
|
||||
EmitLoadSuperConstructor(super_call_ref);
|
||||
EmitLoadSuperConstructor();
|
||||
__ push(result_register());
|
||||
|
||||
// Push the arguments ("left-to-right") on the stack.
|
||||
@ -3072,7 +3051,8 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
||||
|
||||
RecordJSReturnSite(expr);
|
||||
|
||||
EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot());
|
||||
EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(),
|
||||
expr->CallFeedbackICSlot());
|
||||
context()->Plug(x0);
|
||||
}
|
||||
|
||||
@ -3952,15 +3932,11 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
|
||||
GetVar(result_register(), new_target_var);
|
||||
__ Push(result_register());
|
||||
|
||||
// new.target
|
||||
VisitForStackValue(args->at(0));
|
||||
|
||||
// .this_function
|
||||
VisitForStackValue(args->at(1));
|
||||
__ CallRuntime(Runtime::kGetPrototype, 1);
|
||||
EmitLoadSuperConstructor();
|
||||
__ Push(result_register());
|
||||
|
||||
// Check if the calling frame is an arguments adaptor frame.
|
||||
@ -4333,14 +4309,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
|
||||
|
||||
void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
// Assert: expr === CallRuntime("ReflectConstruct")
|
||||
DCHECK_EQ(1, expr->arguments()->length());
|
||||
CallRuntime* call = expr->arguments()->at(0)->AsCallRuntime();
|
||||
|
||||
ZoneList<Expression*>* args = call->arguments();
|
||||
DCHECK_EQ(3, args->length());
|
||||
|
||||
SuperCallReference* super_call_ref = args->at(0)->AsSuperCallReference();
|
||||
DCHECK_NOT_NULL(super_call_ref);
|
||||
SuperReference* super_reference = args->at(0)->AsSuperReference();
|
||||
|
||||
// Load ReflectConstruct function
|
||||
EmitLoadJSRuntimeFunction(call);
|
||||
@ -4349,8 +4322,8 @@ void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
__ Pop(x10);
|
||||
__ Push(x0, x10);
|
||||
|
||||
// Push super constructor
|
||||
EmitLoadSuperConstructor(super_call_ref);
|
||||
// Push super
|
||||
EmitLoadSuperConstructor();
|
||||
__ Push(result_register());
|
||||
|
||||
// Push arguments array
|
||||
@ -4367,7 +4340,7 @@ void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
context()->DropAndPlug(1, x0);
|
||||
|
||||
// TODO(mvstanton): with FLAG_vector_stores this needs a slot id.
|
||||
EmitInitializeThisAfterSuper(super_call_ref);
|
||||
EmitInitializeThisAfterSuper(super_reference);
|
||||
}
|
||||
|
||||
|
||||
@ -4589,9 +4562,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
}
|
||||
|
||||
case NAMED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
prop->obj()->AsSuperReference()->home_object_var());
|
||||
__ Push(result_register());
|
||||
const Register scratch = x10;
|
||||
__ Peek(scratch, kPointerSize);
|
||||
@ -4601,9 +4574,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
}
|
||||
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForAccumulatorValue(prop->key());
|
||||
__ Push(result_register());
|
||||
const Register scratch1 = x10;
|
||||
|
@ -168,26 +168,15 @@ void AstNumberingVisitor::VisitThisFunction(ThisFunction* node) {
|
||||
}
|
||||
|
||||
|
||||
void AstNumberingVisitor::VisitSuperPropertyReference(
|
||||
SuperPropertyReference* node) {
|
||||
void AstNumberingVisitor::VisitSuperReference(SuperReference* node) {
|
||||
IncrementNodeCount();
|
||||
DisableOptimization(kSuperReference);
|
||||
node->set_base_id(ReserveIdRange(SuperPropertyReference::num_ids()));
|
||||
node->set_base_id(ReserveIdRange(SuperReference::num_ids()));
|
||||
Visit(node->this_var());
|
||||
Visit(node->home_object_var());
|
||||
}
|
||||
|
||||
|
||||
void AstNumberingVisitor::VisitSuperCallReference(SuperCallReference* node) {
|
||||
IncrementNodeCount();
|
||||
DisableOptimization(kSuperReference);
|
||||
node->set_base_id(ReserveIdRange(SuperCallReference::num_ids()));
|
||||
Visit(node->this_var());
|
||||
Visit(node->new_target_var());
|
||||
Visit(node->this_function_var());
|
||||
}
|
||||
|
||||
|
||||
void AstNumberingVisitor::VisitImportDeclaration(ImportDeclaration* node) {
|
||||
IncrementNodeCount();
|
||||
DisableOptimization(kImportDeclaration);
|
||||
|
@ -267,7 +267,6 @@ class AstValue : public ZoneObject {
|
||||
F(spread_arguments, "$spreadArguments") \
|
||||
F(spread_iterable, "$spreadIterable") \
|
||||
F(this, "this") \
|
||||
F(this_function, ".this_function") \
|
||||
F(throw_iterator_result_not_an_object, "ThrowIteratorResultNotAnObject") \
|
||||
F(to_string, "$toString") \
|
||||
F(undefined, "undefined") \
|
||||
|
@ -734,7 +734,7 @@ Call::CallType Call::GetCallType(Isolate* isolate) const {
|
||||
}
|
||||
}
|
||||
|
||||
if (expression()->IsSuperCallReference()) return SUPER_CALL;
|
||||
if (expression()->AsSuperReference() != NULL) return SUPER_CALL;
|
||||
|
||||
Property* property = expression()->AsProperty();
|
||||
return property != NULL ? PROPERTY_CALL : OTHER_CALL;
|
||||
|
58
src/ast.h
58
src/ast.h
@ -87,8 +87,7 @@ namespace internal {
|
||||
V(CompareOperation) \
|
||||
V(Spread) \
|
||||
V(ThisFunction) \
|
||||
V(SuperPropertyReference) \
|
||||
V(SuperCallReference) \
|
||||
V(SuperReference) \
|
||||
V(CaseClause)
|
||||
|
||||
#define AST_NODE_LIST(V) \
|
||||
@ -1761,7 +1760,9 @@ class Property final : public Expression {
|
||||
}
|
||||
bool is_for_call() const { return IsForCallField::decode(bit_field_); }
|
||||
|
||||
bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); }
|
||||
bool IsSuperAccess() {
|
||||
return obj()->IsSuperReference();
|
||||
}
|
||||
|
||||
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
|
||||
Isolate* isolate, const ICSlotCache* cache) override {
|
||||
@ -2790,16 +2791,16 @@ class ThisFunction final : public Expression {
|
||||
};
|
||||
|
||||
|
||||
class SuperPropertyReference final : public Expression {
|
||||
class SuperReference final : public Expression {
|
||||
public:
|
||||
DECLARE_NODE_TYPE(SuperPropertyReference)
|
||||
DECLARE_NODE_TYPE(SuperReference)
|
||||
|
||||
VariableProxy* this_var() const { return this_var_; }
|
||||
VariableProxy* home_object_var() const { return home_object_var_; }
|
||||
|
||||
protected:
|
||||
SuperPropertyReference(Zone* zone, VariableProxy* this_var,
|
||||
VariableProxy* home_object_var, int pos)
|
||||
SuperReference(Zone* zone, VariableProxy* this_var,
|
||||
VariableProxy* home_object_var, int pos)
|
||||
: Expression(zone, pos),
|
||||
this_var_(this_var),
|
||||
home_object_var_(home_object_var) {
|
||||
@ -2813,34 +2814,6 @@ class SuperPropertyReference final : public Expression {
|
||||
};
|
||||
|
||||
|
||||
class SuperCallReference final : public Expression {
|
||||
public:
|
||||
DECLARE_NODE_TYPE(SuperCallReference)
|
||||
|
||||
VariableProxy* this_var() const { return this_var_; }
|
||||
VariableProxy* new_target_var() const { return new_target_var_; }
|
||||
VariableProxy* this_function_var() const { return this_function_var_; }
|
||||
|
||||
protected:
|
||||
SuperCallReference(Zone* zone, VariableProxy* this_var,
|
||||
VariableProxy* new_target_var,
|
||||
VariableProxy* this_function_var, int pos)
|
||||
: Expression(zone, pos),
|
||||
this_var_(this_var),
|
||||
new_target_var_(new_target_var),
|
||||
this_function_var_(this_function_var) {
|
||||
DCHECK(this_var->is_this());
|
||||
DCHECK(new_target_var->raw_name()->IsOneByteEqualTo("new.target"));
|
||||
DCHECK(this_function_var->raw_name()->IsOneByteEqualTo(".this_function"));
|
||||
}
|
||||
|
||||
private:
|
||||
VariableProxy* this_var_;
|
||||
VariableProxy* new_target_var_;
|
||||
VariableProxy* this_function_var_;
|
||||
};
|
||||
|
||||
|
||||
#undef DECLARE_NODE_TYPE
|
||||
|
||||
|
||||
@ -3608,18 +3581,9 @@ class AstNodeFactory final BASE_EMBEDDED {
|
||||
return new (zone_) ThisFunction(zone_, pos);
|
||||
}
|
||||
|
||||
SuperPropertyReference* NewSuperPropertyReference(
|
||||
VariableProxy* this_var, VariableProxy* home_object_var, int pos) {
|
||||
return new (zone_)
|
||||
SuperPropertyReference(zone_, this_var, home_object_var, pos);
|
||||
}
|
||||
|
||||
SuperCallReference* NewSuperCallReference(VariableProxy* this_var,
|
||||
VariableProxy* new_target_var,
|
||||
VariableProxy* this_function_var,
|
||||
int pos) {
|
||||
return new (zone_) SuperCallReference(zone_, this_var, new_target_var,
|
||||
this_function_var, pos);
|
||||
SuperReference* NewSuperReference(VariableProxy* this_var,
|
||||
VariableProxy* home_object_var, int pos) {
|
||||
return new (zone_) SuperReference(zone_, this_var, home_object_var, pos);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -2590,15 +2590,7 @@ void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) {
|
||||
}
|
||||
|
||||
|
||||
void AstGraphBuilder::VisitSuperPropertyReference(
|
||||
SuperPropertyReference* expr) {
|
||||
// TODO(turbofan): Implement super here.
|
||||
SetStackOverflow();
|
||||
ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
|
||||
}
|
||||
|
||||
|
||||
void AstGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) {
|
||||
void AstGraphBuilder::VisitSuperReference(SuperReference* expr) {
|
||||
// TODO(turbofan): Implement super here.
|
||||
SetStackOverflow();
|
||||
ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
|
||||
|
@ -67,8 +67,7 @@ void ALAA::VisitVariableProxy(VariableProxy* leaf) {}
|
||||
void ALAA::VisitLiteral(Literal* leaf) {}
|
||||
void ALAA::VisitRegExpLiteral(RegExpLiteral* leaf) {}
|
||||
void ALAA::VisitThisFunction(ThisFunction* leaf) {}
|
||||
void ALAA::VisitSuperPropertyReference(SuperPropertyReference* leaf) {}
|
||||
void ALAA::VisitSuperCallReference(SuperCallReference* leaf) {}
|
||||
void ALAA::VisitSuperReference(SuperReference* leaf) {}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -276,12 +276,7 @@ void BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) {
|
||||
}
|
||||
|
||||
|
||||
void BreakableStatementChecker::VisitSuperPropertyReference(
|
||||
SuperPropertyReference* expr) {}
|
||||
|
||||
|
||||
void BreakableStatementChecker::VisitSuperCallReference(
|
||||
SuperCallReference* expr) {}
|
||||
void BreakableStatementChecker::VisitSuperReference(SuperReference* expr) {}
|
||||
|
||||
|
||||
#define __ ACCESS_MASM(masm())
|
||||
@ -673,13 +668,7 @@ void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitSuperPropertyReference(
|
||||
SuperPropertyReference* super) {
|
||||
__ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitSuperCallReference(SuperCallReference* super) {
|
||||
void FullCodeGenerator::VisitSuperReference(SuperReference* super) {
|
||||
__ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
|
||||
}
|
||||
|
||||
@ -989,12 +978,6 @@ void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property,
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitLoadSuperConstructor(SuperCallReference* ref) {
|
||||
VisitForStackValue(ref->this_function_var());
|
||||
__ CallRuntime(Runtime::kGetPrototype, 1);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
|
||||
Comment cmnt(masm_, "[ ReturnStatement");
|
||||
SetStatementPosition(stmt);
|
||||
|
@ -672,9 +672,9 @@ class FullCodeGenerator: public AstVisitor {
|
||||
Expression* initializer, int offset,
|
||||
FeedbackVectorICSlot slot = FeedbackVectorICSlot::Invalid());
|
||||
|
||||
void EmitLoadSuperConstructor(SuperCallReference* super_call_ref);
|
||||
void EmitLoadSuperConstructor();
|
||||
void EmitInitializeThisAfterSuper(
|
||||
SuperCallReference* super_call_ref,
|
||||
SuperReference* super_ref,
|
||||
FeedbackVectorICSlot slot = FeedbackVectorICSlot::Invalid());
|
||||
|
||||
void CallIC(Handle<Code> code,
|
||||
|
@ -11568,16 +11568,7 @@ void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) {
|
||||
}
|
||||
|
||||
|
||||
void HOptimizedGraphBuilder::VisitSuperPropertyReference(
|
||||
SuperPropertyReference* expr) {
|
||||
DCHECK(!HasStackOverflow());
|
||||
DCHECK(current_block() != NULL);
|
||||
DCHECK(current_block()->HasPredecessor());
|
||||
return Bailout(kSuperReference);
|
||||
}
|
||||
|
||||
|
||||
void HOptimizedGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) {
|
||||
void HOptimizedGraphBuilder::VisitSuperReference(SuperReference* expr) {
|
||||
DCHECK(!HasStackOverflow());
|
||||
DCHECK(current_block() != NULL);
|
||||
DCHECK(current_block()->HasPredecessor());
|
||||
|
@ -238,24 +238,6 @@ void FullCodeGenerator::Generate() {
|
||||
}
|
||||
}
|
||||
|
||||
// Possibly set up a local binding to the this function which is used in
|
||||
// derived constructors with super calls.
|
||||
Variable* this_function_var = scope()->this_function_var();
|
||||
if (this_function_var != nullptr) {
|
||||
Comment cmnt(masm_, "[ This function");
|
||||
SetVar(this_function_var, edi, ebx, edx);
|
||||
}
|
||||
|
||||
Variable* new_target_var = scope()->new_target_var();
|
||||
if (new_target_var != nullptr) {
|
||||
Comment cmnt(masm_, "[ new.target");
|
||||
// new.target is parameter -2.
|
||||
int offset = 2 * kPointerSize + kFPOnStackSize + kPCOnStackSize +
|
||||
(info_->scope()->num_parameters() - 1) * kPointerSize;
|
||||
__ mov(eax, Operand(ebp, offset));
|
||||
SetVar(new_target_var, eax, ebx, edx);
|
||||
}
|
||||
|
||||
Variable* home_object_var = scope()->home_object_var();
|
||||
if (home_object_var != nullptr) {
|
||||
__ push(edi);
|
||||
@ -1938,10 +1920,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
// Nothing to do here.
|
||||
break;
|
||||
case NAMED_SUPER_PROPERTY:
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(property->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
property->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
property->obj()->AsSuperReference()->home_object_var());
|
||||
__ push(result_register());
|
||||
if (expr->is_compound()) {
|
||||
__ push(MemOperand(esp, kPointerSize));
|
||||
@ -1958,10 +1939,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
}
|
||||
break;
|
||||
case KEYED_SUPER_PROPERTY:
|
||||
VisitForStackValue(property->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
property->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForAccumulatorValue(property->key());
|
||||
__ Push(result_register());
|
||||
if (expr->is_compound()) {
|
||||
@ -2585,9 +2565,9 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
|
||||
}
|
||||
case NAMED_SUPER_PROPERTY: {
|
||||
__ push(eax);
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
prop->obj()->AsSuperReference()->home_object_var());
|
||||
// stack: value, this; eax: home_object
|
||||
Register scratch = ecx;
|
||||
Register scratch2 = edx;
|
||||
@ -2602,9 +2582,8 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
|
||||
}
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
__ push(eax);
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForAccumulatorValue(prop->key());
|
||||
Register scratch = ecx;
|
||||
Register scratch2 = edx;
|
||||
@ -2826,9 +2805,8 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
|
||||
__ Move(LoadDescriptor::ReceiverRegister(), result_register());
|
||||
EmitNamedPropertyLoad(expr);
|
||||
} else {
|
||||
VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
expr->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->home_object_var());
|
||||
EmitNamedSuperPropertyLoad(expr);
|
||||
}
|
||||
} else {
|
||||
@ -2839,9 +2817,8 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
|
||||
__ Move(LoadDescriptor::NameRegister(), result_register()); // Key.
|
||||
EmitKeyedPropertyLoad(expr);
|
||||
} else {
|
||||
VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
expr->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForStackValue(expr->key());
|
||||
EmitKeyedSuperPropertyLoad(expr);
|
||||
}
|
||||
@ -2899,7 +2876,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
|
||||
Literal* key = prop->key()->AsLiteral();
|
||||
DCHECK(!key->value()->IsSmi());
|
||||
// Load the function from the receiver.
|
||||
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
|
||||
SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference();
|
||||
VisitForStackValue(super_ref->home_object_var());
|
||||
VisitForAccumulatorValue(super_ref->this_var());
|
||||
__ push(eax);
|
||||
@ -2955,7 +2932,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
|
||||
|
||||
SetSourcePosition(prop->position());
|
||||
// Load the function from the receiver.
|
||||
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
|
||||
SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference();
|
||||
VisitForStackValue(super_ref->home_object_var());
|
||||
VisitForAccumulatorValue(super_ref->this_var());
|
||||
__ push(eax);
|
||||
@ -3033,9 +3010,15 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitLoadSuperConstructor() {
|
||||
__ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
__ CallRuntime(Runtime::kGetPrototype, 1);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitInitializeThisAfterSuper(
|
||||
SuperCallReference* super_call_ref, FeedbackVectorICSlot slot) {
|
||||
Variable* this_var = super_call_ref->this_var()->var();
|
||||
SuperReference* super_ref, FeedbackVectorICSlot slot) {
|
||||
Variable* this_var = super_ref->this_var()->var();
|
||||
GetVar(ecx, this_var);
|
||||
__ cmp(ecx, isolate()->factory()->the_hole_value());
|
||||
Label uninitialized_this;
|
||||
@ -3184,7 +3167,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
// Push constructor on the stack. If it's not a function it's used as
|
||||
// receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
|
||||
// ignored.
|
||||
DCHECK(!expr->expression()->IsSuperPropertyReference());
|
||||
DCHECK(!expr->expression()->IsSuperReference());
|
||||
VisitForStackValue(expr->expression());
|
||||
|
||||
// Push the arguments ("left-to-right") on the stack.
|
||||
@ -3220,14 +3203,11 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
||||
SuperCallReference* super_call_ref =
|
||||
expr->expression()->AsSuperCallReference();
|
||||
DCHECK_NOT_NULL(super_call_ref);
|
||||
Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
|
||||
GetVar(eax, new_target_var);
|
||||
__ push(eax);
|
||||
|
||||
VariableProxy* new_target_proxy = super_call_ref->new_target_var();
|
||||
VisitForStackValue(new_target_proxy);
|
||||
|
||||
EmitLoadSuperConstructor(super_call_ref);
|
||||
EmitLoadSuperConstructor();
|
||||
__ push(result_register());
|
||||
|
||||
// Push the arguments ("left-to-right") on the stack.
|
||||
@ -3265,7 +3245,8 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
||||
|
||||
RecordJSReturnSite(expr);
|
||||
|
||||
EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot());
|
||||
EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(),
|
||||
expr->CallFeedbackICSlot());
|
||||
context()->Plug(eax);
|
||||
}
|
||||
|
||||
@ -4142,15 +4123,11 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
|
||||
GetVar(eax, new_target_var);
|
||||
__ push(eax);
|
||||
|
||||
// new.target
|
||||
VisitForStackValue(args->at(0));
|
||||
|
||||
// .this_function
|
||||
VisitForStackValue(args->at(1));
|
||||
__ CallRuntime(Runtime::kGetPrototype, 1);
|
||||
EmitLoadSuperConstructor();
|
||||
__ push(result_register());
|
||||
|
||||
// Check if the calling frame is an arguments adaptor frame.
|
||||
@ -4573,14 +4550,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
|
||||
|
||||
void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
// Assert: expr == CallRuntime("ReflectConstruct")
|
||||
DCHECK_EQ(1, expr->arguments()->length());
|
||||
CallRuntime* call = expr->arguments()->at(0)->AsCallRuntime();
|
||||
|
||||
ZoneList<Expression*>* args = call->arguments();
|
||||
DCHECK_EQ(3, args->length());
|
||||
|
||||
SuperCallReference* super_call_ref = args->at(0)->AsSuperCallReference();
|
||||
DCHECK_NOT_NULL(super_call_ref);
|
||||
SuperReference* super_reference = args->at(0)->AsSuperReference();
|
||||
|
||||
// Load ReflectConstruct function
|
||||
EmitLoadJSRuntimeFunction(call);
|
||||
@ -4589,8 +4563,8 @@ void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
__ push(Operand(esp, 0));
|
||||
__ mov(Operand(esp, kPointerSize), eax);
|
||||
|
||||
// Push super constructor
|
||||
EmitLoadSuperConstructor(super_call_ref);
|
||||
// Push super
|
||||
EmitLoadSuperConstructor();
|
||||
__ Push(result_register());
|
||||
|
||||
// Push arguments array
|
||||
@ -4607,7 +4581,7 @@ void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
context()->DropAndPlug(1, eax);
|
||||
|
||||
// TODO(mvstanton): with FLAG_vector_stores this needs a slot id.
|
||||
EmitInitializeThisAfterSuper(super_call_ref);
|
||||
EmitInitializeThisAfterSuper(super_reference);
|
||||
}
|
||||
|
||||
|
||||
@ -4832,9 +4806,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
}
|
||||
|
||||
case NAMED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
prop->obj()->AsSuperReference()->home_object_var());
|
||||
__ push(result_register());
|
||||
__ push(MemOperand(esp, kPointerSize));
|
||||
__ push(result_register());
|
||||
@ -4843,9 +4817,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
}
|
||||
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForAccumulatorValue(prop->key());
|
||||
__ push(result_register());
|
||||
__ push(MemOperand(esp, 2 * kPointerSize));
|
||||
|
@ -251,24 +251,6 @@ void FullCodeGenerator::Generate() {
|
||||
}
|
||||
}
|
||||
|
||||
// Possibly set up a local binding to the this function which is used in
|
||||
// derived constructors with super calls.
|
||||
Variable* this_function_var = scope()->this_function_var();
|
||||
if (this_function_var != nullptr) {
|
||||
Comment cmnt(masm_, "[ This function");
|
||||
SetVar(this_function_var, a1, a2, a3);
|
||||
}
|
||||
|
||||
Variable* new_target_var = scope()->new_target_var();
|
||||
if (new_target_var != nullptr) {
|
||||
Comment cmnt(masm_, "[ new.target");
|
||||
// new.target is parameter -2.
|
||||
int offset = 2 * kPointerSize +
|
||||
(info_->scope()->num_parameters() + 1) * kPointerSize;
|
||||
__ lw(v0, MemOperand(fp, offset));
|
||||
SetVar(new_target_var, v0, a2, a3);
|
||||
}
|
||||
|
||||
Variable* home_object_var = scope()->home_object_var();
|
||||
if (home_object_var != nullptr) {
|
||||
__ Push(a1);
|
||||
@ -2006,10 +1988,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
}
|
||||
break;
|
||||
case NAMED_SUPER_PROPERTY:
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(property->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
property->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
property->obj()->AsSuperReference()->home_object_var());
|
||||
__ Push(result_register());
|
||||
if (expr->is_compound()) {
|
||||
const Register scratch = a1;
|
||||
@ -2019,10 +2000,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
break;
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
const Register scratch = a1;
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(property->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
property->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
property->obj()->AsSuperReference()->home_object_var());
|
||||
__ Move(scratch, result_register());
|
||||
VisitForAccumulatorValue(property->key());
|
||||
__ Push(scratch, result_register());
|
||||
@ -2656,9 +2636,9 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
|
||||
}
|
||||
case NAMED_SUPER_PROPERTY: {
|
||||
__ Push(v0);
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
prop->obj()->AsSuperReference()->home_object_var());
|
||||
// stack: value, this; v0: home_object
|
||||
Register scratch = a2;
|
||||
Register scratch2 = a3;
|
||||
@ -2673,9 +2653,8 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
|
||||
}
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
__ Push(v0);
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForAccumulatorValue(prop->key());
|
||||
Register scratch = a2;
|
||||
Register scratch2 = a3;
|
||||
@ -2904,9 +2883,8 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
|
||||
__ Move(LoadDescriptor::ReceiverRegister(), v0);
|
||||
EmitNamedPropertyLoad(expr);
|
||||
} else {
|
||||
VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
expr->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->home_object_var());
|
||||
EmitNamedSuperPropertyLoad(expr);
|
||||
}
|
||||
} else {
|
||||
@ -2917,9 +2895,8 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
|
||||
__ pop(LoadDescriptor::ReceiverRegister());
|
||||
EmitKeyedPropertyLoad(expr);
|
||||
} else {
|
||||
VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
expr->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForStackValue(expr->key());
|
||||
EmitKeyedSuperPropertyLoad(expr);
|
||||
}
|
||||
@ -2981,7 +2958,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
|
||||
DCHECK(!key->value()->IsSmi());
|
||||
// Load the function from the receiver.
|
||||
const Register scratch = a1;
|
||||
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
|
||||
SuperReference* super_ref = prop->obj()->AsSuperReference();
|
||||
VisitForAccumulatorValue(super_ref->home_object_var());
|
||||
__ mov(scratch, v0);
|
||||
VisitForAccumulatorValue(super_ref->this_var());
|
||||
@ -3039,7 +3016,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
|
||||
SetSourcePosition(prop->position());
|
||||
// Load the function from the receiver.
|
||||
const Register scratch = a1;
|
||||
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
|
||||
SuperReference* super_ref = prop->obj()->AsSuperReference();
|
||||
VisitForAccumulatorValue(super_ref->home_object_var());
|
||||
__ Move(scratch, v0);
|
||||
VisitForAccumulatorValue(super_ref->this_var());
|
||||
@ -3119,8 +3096,15 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitLoadSuperConstructor() {
|
||||
__ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
__ Push(a0);
|
||||
__ CallRuntime(Runtime::kGetPrototype, 1);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitInitializeThisAfterSuper(
|
||||
SuperCallReference* super_ref, FeedbackVectorICSlot slot) {
|
||||
SuperReference* super_ref, FeedbackVectorICSlot slot) {
|
||||
Variable* this_var = super_ref->this_var()->var();
|
||||
GetVar(a1, this_var);
|
||||
__ LoadRoot(at, Heap::kTheHoleValueRootIndex);
|
||||
@ -3278,7 +3262,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
// Push constructor on the stack. If it's not a function it's used as
|
||||
// receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
|
||||
// ignored.
|
||||
DCHECK(!expr->expression()->IsSuperPropertyReference());
|
||||
DCHECK(!expr->expression()->IsSuperReference());
|
||||
VisitForStackValue(expr->expression());
|
||||
|
||||
// Push the arguments ("left-to-right") on the stack.
|
||||
@ -3314,14 +3298,11 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
||||
SuperCallReference* super_call_ref =
|
||||
expr->expression()->AsSuperCallReference();
|
||||
DCHECK_NOT_NULL(super_call_ref);
|
||||
Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
|
||||
GetVar(result_register(), new_target_var);
|
||||
__ Push(result_register());
|
||||
|
||||
VariableProxy* new_target_proxy = super_call_ref->new_target_var();
|
||||
VisitForStackValue(new_target_proxy);
|
||||
|
||||
EmitLoadSuperConstructor(super_call_ref);
|
||||
EmitLoadSuperConstructor();
|
||||
__ push(result_register());
|
||||
|
||||
// Push the arguments ("left-to-right") on the stack.
|
||||
@ -3359,7 +3340,8 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
||||
|
||||
RecordJSReturnSite(expr);
|
||||
|
||||
EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot());
|
||||
EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(),
|
||||
expr->CallFeedbackICSlot());
|
||||
context()->Plug(v0);
|
||||
}
|
||||
|
||||
@ -4245,15 +4227,11 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
|
||||
GetVar(result_register(), new_target_var);
|
||||
__ Push(result_register());
|
||||
|
||||
// new.target
|
||||
VisitForStackValue(args->at(0));
|
||||
|
||||
// .this_function
|
||||
VisitForStackValue(args->at(1));
|
||||
__ CallRuntime(Runtime::kGetPrototype, 1);
|
||||
EmitLoadSuperConstructor();
|
||||
__ Push(result_register());
|
||||
|
||||
// Check if the calling frame is an arguments adaptor frame.
|
||||
@ -4655,14 +4633,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
|
||||
|
||||
void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
// Assert: expr == CallRuntime("ReflectConstruct")
|
||||
DCHECK_EQ(1, expr->arguments()->length());
|
||||
CallRuntime* call = expr->arguments()->at(0)->AsCallRuntime();
|
||||
|
||||
ZoneList<Expression*>* args = call->arguments();
|
||||
DCHECK_EQ(3, args->length());
|
||||
|
||||
SuperCallReference* super_call_ref = args->at(0)->AsSuperCallReference();
|
||||
DCHECK_NOT_NULL(super_call_ref);
|
||||
SuperReference* super_reference = args->at(0)->AsSuperReference();
|
||||
|
||||
// Load ReflectConstruct function
|
||||
EmitLoadJSRuntimeFunction(call);
|
||||
@ -4672,8 +4647,8 @@ void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
__ push(at);
|
||||
__ sw(v0, MemOperand(sp, kPointerSize));
|
||||
|
||||
// Push super constructor
|
||||
EmitLoadSuperConstructor(super_call_ref);
|
||||
// Push super
|
||||
EmitLoadSuperConstructor();
|
||||
__ Push(result_register());
|
||||
|
||||
// Push arguments array
|
||||
@ -4690,7 +4665,7 @@ void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
context()->DropAndPlug(1, v0);
|
||||
|
||||
// TODO(mvstanton): with FLAG_vector_stores this needs a slot id.
|
||||
EmitInitializeThisAfterSuper(super_call_ref);
|
||||
EmitInitializeThisAfterSuper(super_reference);
|
||||
}
|
||||
|
||||
|
||||
@ -4915,9 +4890,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
}
|
||||
|
||||
case NAMED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
prop->obj()->AsSuperReference()->home_object_var());
|
||||
__ Push(result_register());
|
||||
const Register scratch = a1;
|
||||
__ lw(scratch, MemOperand(sp, kPointerSize));
|
||||
@ -4927,9 +4902,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
}
|
||||
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
prop->obj()->AsSuperReference()->home_object_var());
|
||||
const Register scratch = a1;
|
||||
const Register scratch1 = t0;
|
||||
__ Move(scratch, result_register());
|
||||
|
@ -248,24 +248,6 @@ void FullCodeGenerator::Generate() {
|
||||
}
|
||||
}
|
||||
|
||||
// Possibly set up a local binding to the this function which is used in
|
||||
// derived constructors with super calls.
|
||||
Variable* this_function_var = scope()->this_function_var();
|
||||
if (this_function_var != nullptr) {
|
||||
Comment cmnt(masm_, "[ This function");
|
||||
SetVar(this_function_var, a1, a2, a3);
|
||||
}
|
||||
|
||||
Variable* new_target_var = scope()->new_target_var();
|
||||
if (new_target_var != nullptr) {
|
||||
Comment cmnt(masm_, "[ new.target");
|
||||
// new.target is parameter -2.
|
||||
int offset = 2 * kPointerSize +
|
||||
(info_->scope()->num_parameters() + 1) * kPointerSize;
|
||||
__ lw(v0, MemOperand(fp, offset));
|
||||
SetVar(new_target_var, v0, a2, a3);
|
||||
}
|
||||
|
||||
Variable* home_object_var = scope()->home_object_var();
|
||||
if (home_object_var != nullptr) {
|
||||
__ Push(a1);
|
||||
@ -2005,10 +1987,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
}
|
||||
break;
|
||||
case NAMED_SUPER_PROPERTY:
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(property->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
property->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
property->obj()->AsSuperReference()->home_object_var());
|
||||
__ Push(result_register());
|
||||
if (expr->is_compound()) {
|
||||
const Register scratch = a1;
|
||||
@ -2018,10 +1999,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
break;
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
const Register scratch = a1;
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(property->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
property->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
property->obj()->AsSuperReference()->home_object_var());
|
||||
__ Move(scratch, result_register());
|
||||
VisitForAccumulatorValue(property->key());
|
||||
__ Push(scratch, result_register());
|
||||
@ -2655,9 +2635,9 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
|
||||
}
|
||||
case NAMED_SUPER_PROPERTY: {
|
||||
__ Push(v0);
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
prop->obj()->AsSuperReference()->home_object_var());
|
||||
// stack: value, this; v0: home_object
|
||||
Register scratch = a2;
|
||||
Register scratch2 = a3;
|
||||
@ -2672,9 +2652,8 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
|
||||
}
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
__ Push(v0);
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForAccumulatorValue(prop->key());
|
||||
Register scratch = a2;
|
||||
Register scratch2 = a3;
|
||||
@ -2907,9 +2886,8 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
|
||||
__ Move(LoadDescriptor::ReceiverRegister(), v0);
|
||||
EmitNamedPropertyLoad(expr);
|
||||
} else {
|
||||
VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
expr->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->home_object_var());
|
||||
EmitNamedSuperPropertyLoad(expr);
|
||||
}
|
||||
} else {
|
||||
@ -2920,9 +2898,8 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
|
||||
__ pop(LoadDescriptor::ReceiverRegister());
|
||||
EmitKeyedPropertyLoad(expr);
|
||||
} else {
|
||||
VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
expr->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForStackValue(expr->key());
|
||||
EmitKeyedSuperPropertyLoad(expr);
|
||||
}
|
||||
@ -2984,7 +2961,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
|
||||
DCHECK(!key->value()->IsSmi());
|
||||
// Load the function from the receiver.
|
||||
const Register scratch = a1;
|
||||
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
|
||||
SuperReference* super_ref = prop->obj()->AsSuperReference();
|
||||
VisitForAccumulatorValue(super_ref->home_object_var());
|
||||
__ mov(scratch, v0);
|
||||
VisitForAccumulatorValue(super_ref->this_var());
|
||||
@ -3042,7 +3019,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
|
||||
SetSourcePosition(prop->position());
|
||||
// Load the function from the receiver.
|
||||
const Register scratch = a1;
|
||||
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
|
||||
SuperReference* super_ref = prop->obj()->AsSuperReference();
|
||||
VisitForAccumulatorValue(super_ref->home_object_var());
|
||||
__ Move(scratch, v0);
|
||||
VisitForAccumulatorValue(super_ref->this_var());
|
||||
@ -3121,8 +3098,15 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitLoadSuperConstructor() {
|
||||
__ ld(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
__ Push(a0);
|
||||
__ CallRuntime(Runtime::kGetPrototype, 1);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitInitializeThisAfterSuper(
|
||||
SuperCallReference* super_ref, FeedbackVectorICSlot slot) {
|
||||
SuperReference* super_ref, FeedbackVectorICSlot slot) {
|
||||
Variable* this_var = super_ref->this_var()->var();
|
||||
GetVar(a1, this_var);
|
||||
__ LoadRoot(at, Heap::kTheHoleValueRootIndex);
|
||||
@ -3280,7 +3264,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
// Push constructor on the stack. If it's not a function it's used as
|
||||
// receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
|
||||
// ignored.
|
||||
DCHECK(!expr->expression()->IsSuperPropertyReference());
|
||||
DCHECK(!expr->expression()->IsSuperReference());
|
||||
VisitForStackValue(expr->expression());
|
||||
|
||||
// Push the arguments ("left-to-right") on the stack.
|
||||
@ -3316,14 +3300,11 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
||||
SuperCallReference* super_call_ref =
|
||||
expr->expression()->AsSuperCallReference();
|
||||
DCHECK_NOT_NULL(super_call_ref);
|
||||
Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
|
||||
GetVar(result_register(), new_target_var);
|
||||
__ Push(result_register());
|
||||
|
||||
VariableProxy* new_target_proxy = super_call_ref->new_target_var();
|
||||
VisitForStackValue(new_target_proxy);
|
||||
|
||||
EmitLoadSuperConstructor(super_call_ref);
|
||||
EmitLoadSuperConstructor();
|
||||
__ push(result_register());
|
||||
|
||||
// Push the arguments ("left-to-right") on the stack.
|
||||
@ -3361,7 +3342,8 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
||||
|
||||
RecordJSReturnSite(expr);
|
||||
|
||||
EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot());
|
||||
EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(),
|
||||
expr->CallFeedbackICSlot());
|
||||
context()->Plug(v0);
|
||||
}
|
||||
|
||||
@ -4249,15 +4231,11 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
|
||||
GetVar(result_register(), new_target_var);
|
||||
__ Push(result_register());
|
||||
|
||||
// new.target
|
||||
VisitForStackValue(args->at(0));
|
||||
|
||||
// .this_function
|
||||
VisitForStackValue(args->at(1));
|
||||
__ CallRuntime(Runtime::kGetPrototype, 1);
|
||||
EmitLoadSuperConstructor();
|
||||
__ Push(result_register());
|
||||
|
||||
// Check if the calling frame is an arguments adaptor frame.
|
||||
@ -4659,14 +4637,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
|
||||
|
||||
void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
// Assert: expr === CallRuntime("ReflectConstruct")
|
||||
DCHECK_EQ(1, expr->arguments()->length());
|
||||
CallRuntime* call = expr->arguments()->at(0)->AsCallRuntime();
|
||||
|
||||
ZoneList<Expression*>* args = call->arguments();
|
||||
DCHECK_EQ(3, args->length());
|
||||
|
||||
SuperCallReference* super_call_ref = args->at(0)->AsSuperCallReference();
|
||||
DCHECK_NOT_NULL(super_call_ref);
|
||||
SuperReference* super_reference = args->at(0)->AsSuperReference();
|
||||
|
||||
// Load ReflectConstruct function
|
||||
EmitLoadJSRuntimeFunction(call);
|
||||
@ -4676,8 +4651,8 @@ void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
__ push(at);
|
||||
__ sd(v0, MemOperand(sp, kPointerSize));
|
||||
|
||||
// Push super constructor
|
||||
EmitLoadSuperConstructor(super_call_ref);
|
||||
// Push super
|
||||
EmitLoadSuperConstructor();
|
||||
__ Push(result_register());
|
||||
|
||||
// Push arguments array
|
||||
@ -4694,7 +4669,7 @@ void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
context()->DropAndPlug(1, v0);
|
||||
|
||||
// TODO(mvstanton): with FLAG_vector_stores this needs a slot id.
|
||||
EmitInitializeThisAfterSuper(super_call_ref);
|
||||
EmitInitializeThisAfterSuper(super_reference);
|
||||
}
|
||||
|
||||
|
||||
@ -4918,9 +4893,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
}
|
||||
|
||||
case NAMED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
prop->obj()->AsSuperReference()->home_object_var());
|
||||
__ Push(result_register());
|
||||
const Register scratch = a1;
|
||||
__ ld(scratch, MemOperand(sp, kPointerSize));
|
||||
@ -4930,9 +4905,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
}
|
||||
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
prop->obj()->AsSuperReference()->home_object_var());
|
||||
const Register scratch = a1;
|
||||
const Register scratch1 = a4;
|
||||
__ Move(scratch, result_register());
|
||||
|
@ -359,17 +359,8 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
|
||||
body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
|
||||
AddAssertIsConstruct(body, pos);
|
||||
if (call_super) {
|
||||
// %_DefaultConstructorCallSuper(new.target, .this_function)
|
||||
ZoneList<Expression*>* args =
|
||||
new (zone()) ZoneList<Expression*>(2, zone());
|
||||
VariableProxy* new_target_proxy = scope_->NewUnresolved(
|
||||
factory(), ast_value_factory()->new_target_string(), Variable::NORMAL,
|
||||
pos);
|
||||
args->Add(new_target_proxy, zone());
|
||||
VariableProxy* this_function_proxy = scope_->NewUnresolved(
|
||||
factory(), ast_value_factory()->this_function_string(),
|
||||
Variable::NORMAL, pos);
|
||||
args->Add(this_function_proxy, zone());
|
||||
new (zone()) ZoneList<Expression*>(0, zone());
|
||||
CallRuntime* call = factory()->NewCallRuntime(
|
||||
ast_value_factory()->empty_string(),
|
||||
Runtime::FunctionForId(Runtime::kInlineDefaultConstructorCallSuper),
|
||||
@ -756,32 +747,19 @@ Expression* ParserTraits::ThisExpression(Scope* scope, AstNodeFactory* factory,
|
||||
Variable::THIS, pos, pos + 4);
|
||||
}
|
||||
|
||||
Expression* ParserTraits::SuperPropertyReference(Scope* scope,
|
||||
AstNodeFactory* factory,
|
||||
int pos) {
|
||||
Expression* ParserTraits::SuperReference(Scope* scope, AstNodeFactory* factory,
|
||||
int pos) {
|
||||
// TODO(arv): Split into SuperProperty and SuperCall?
|
||||
VariableProxy* home_object_proxy = scope->NewUnresolved(
|
||||
factory, parser_->ast_value_factory()->home_object_string(),
|
||||
Variable::NORMAL, pos);
|
||||
return factory->NewSuperPropertyReference(
|
||||
|
||||
return factory->NewSuperReference(
|
||||
ThisExpression(scope, factory, pos)->AsVariableProxy(), home_object_proxy,
|
||||
pos);
|
||||
}
|
||||
|
||||
|
||||
Expression* ParserTraits::SuperCallReference(Scope* scope,
|
||||
AstNodeFactory* factory, int pos) {
|
||||
VariableProxy* new_target_proxy = scope->NewUnresolved(
|
||||
factory, parser_->ast_value_factory()->new_target_string(),
|
||||
Variable::NORMAL, pos);
|
||||
VariableProxy* this_function_proxy = scope->NewUnresolved(
|
||||
factory, parser_->ast_value_factory()->this_function_string(),
|
||||
Variable::NORMAL, pos);
|
||||
return factory->NewSuperCallReference(
|
||||
ThisExpression(scope, factory, pos)->AsVariableProxy(), new_target_proxy,
|
||||
this_function_proxy, pos);
|
||||
}
|
||||
|
||||
|
||||
Expression* ParserTraits::DefaultConstructor(bool call_super, Scope* scope,
|
||||
int pos, int end_pos) {
|
||||
return parser_->DefaultConstructor(call_super, scope, pos, end_pos);
|
||||
@ -5766,14 +5744,13 @@ ZoneList<v8::internal::Expression*>* Parser::PrepareSpreadArguments(
|
||||
Expression* Parser::SpreadCall(Expression* function,
|
||||
ZoneList<v8::internal::Expression*>* args,
|
||||
int pos) {
|
||||
if (function->IsSuperCallReference()) {
|
||||
if (function->IsSuperReference()) {
|
||||
// Super calls
|
||||
// %_CallSuperWithSpread(%ReflectConstruct(<super>, args, new.target))
|
||||
args->InsertAt(0, function, zone());
|
||||
args->Add(function->AsSuperCallReference()->new_target_var(), zone());
|
||||
args->Add(factory()->NewVariableProxy(scope_->new_target_var()), zone());
|
||||
Expression* result = factory()->NewCallRuntime(
|
||||
ast_value_factory()->reflect_construct_string(), NULL, args, pos);
|
||||
args = new (zone()) ZoneList<Expression*>(1, zone());
|
||||
args = new (zone()) ZoneList<Expression*>(0, zone());
|
||||
args->Add(result, zone());
|
||||
return factory()->NewCallRuntime(
|
||||
ast_value_factory()->empty_string(),
|
||||
|
@ -724,10 +724,7 @@ class ParserTraits {
|
||||
|
||||
Expression* ThisExpression(Scope* scope, AstNodeFactory* factory,
|
||||
int pos = RelocInfo::kNoPosition);
|
||||
Expression* SuperPropertyReference(Scope* scope, AstNodeFactory* factory,
|
||||
int pos);
|
||||
Expression* SuperCallReference(Scope* scope, AstNodeFactory* factory,
|
||||
int pos);
|
||||
Expression* SuperReference(Scope* scope, AstNodeFactory* factory, int pos);
|
||||
Expression* DefaultConstructor(bool call_super, Scope* scope, int pos,
|
||||
int end_pos);
|
||||
Literal* ExpressionFromLiteral(Token::Value token, int pos, Scanner* scanner,
|
||||
|
@ -404,8 +404,7 @@ NOT_A_PATTERN(NativeFunctionLiteral)
|
||||
NOT_A_PATTERN(Property)
|
||||
NOT_A_PATTERN(RegExpLiteral)
|
||||
NOT_A_PATTERN(ReturnStatement)
|
||||
NOT_A_PATTERN(SuperPropertyReference)
|
||||
NOT_A_PATTERN(SuperCallReference)
|
||||
NOT_A_PATTERN(SuperReference)
|
||||
NOT_A_PATTERN(SwitchStatement)
|
||||
NOT_A_PATTERN(ThisFunction)
|
||||
NOT_A_PATTERN(Throw)
|
||||
|
@ -1715,15 +1715,9 @@ class PreParserTraits {
|
||||
return PreParserExpression::This();
|
||||
}
|
||||
|
||||
static PreParserExpression SuperPropertyReference(Scope* scope,
|
||||
PreParserFactory* factory,
|
||||
int pos) {
|
||||
return PreParserExpression::Default();
|
||||
}
|
||||
|
||||
static PreParserExpression SuperCallReference(Scope* scope,
|
||||
PreParserFactory* factory,
|
||||
int pos) {
|
||||
static PreParserExpression SuperReference(Scope* scope,
|
||||
PreParserFactory* factory,
|
||||
int pos) {
|
||||
return PreParserExpression::Default();
|
||||
}
|
||||
|
||||
@ -3521,7 +3515,7 @@ ParserBase<Traits>::ParseStrongSuperCallExpression(
|
||||
Consume(Token::SUPER);
|
||||
int pos = position();
|
||||
Scanner::Location super_loc = scanner()->location();
|
||||
ExpressionT expr = this->SuperCallReference(scope_, factory(), pos);
|
||||
ExpressionT expr = this->SuperReference(scope_, factory(), pos);
|
||||
|
||||
if (peek() != Token::LPAREN) {
|
||||
ReportMessage(MessageTemplate::kStrongConstructorSuper);
|
||||
@ -3586,7 +3580,7 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new,
|
||||
i::IsConstructor(kind)) {
|
||||
if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
|
||||
scope->RecordSuperPropertyUsage();
|
||||
return this->SuperPropertyReference(scope_, factory(), pos);
|
||||
return this->SuperReference(scope_, factory(), pos);
|
||||
}
|
||||
// new super() is never allowed.
|
||||
// super() is only allowed in derived constructor
|
||||
@ -3601,7 +3595,7 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new,
|
||||
// TODO(rossberg): This might not be the correct FunctionState for the
|
||||
// method here.
|
||||
function_state_->set_super_location(scanner()->location());
|
||||
return this->SuperCallReference(scope_, factory(), pos);
|
||||
return this->SuperReference(scope_, factory(), pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -364,10 +364,7 @@ void CallPrinter::VisitSpread(Spread* node) {
|
||||
void CallPrinter::VisitThisFunction(ThisFunction* node) {}
|
||||
|
||||
|
||||
void CallPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {}
|
||||
|
||||
|
||||
void CallPrinter::VisitSuperCallReference(SuperCallReference* node) {}
|
||||
void CallPrinter::VisitSuperReference(SuperReference* node) {}
|
||||
|
||||
|
||||
void CallPrinter::FindStatements(ZoneList<Statement*>* statements) {
|
||||
@ -838,13 +835,8 @@ void PrettyPrinter::VisitThisFunction(ThisFunction* node) {
|
||||
}
|
||||
|
||||
|
||||
void PrettyPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {
|
||||
Print("<super-property-reference>");
|
||||
}
|
||||
|
||||
|
||||
void PrettyPrinter::VisitSuperCallReference(SuperCallReference* node) {
|
||||
Print("<super-call-reference>");
|
||||
void PrettyPrinter::VisitSuperReference(SuperReference* node) {
|
||||
Print("<super-reference>");
|
||||
}
|
||||
|
||||
|
||||
@ -1535,16 +1527,10 @@ void AstPrinter::VisitThisFunction(ThisFunction* node) {
|
||||
}
|
||||
|
||||
|
||||
void AstPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {
|
||||
IndentedScope indent(this, "SUPER-PROPERTY-REFERENCE");
|
||||
void AstPrinter::VisitSuperReference(SuperReference* node) {
|
||||
IndentedScope indent(this, "SUPER-REFERENCE");
|
||||
}
|
||||
|
||||
|
||||
void AstPrinter::VisitSuperCallReference(SuperCallReference* node) {
|
||||
IndentedScope indent(this, "SUPER-CALL-REFERENCE");
|
||||
}
|
||||
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
@ -72,8 +72,8 @@ namespace internal {
|
||||
F(StoreKeyedToSuper_Strict, 4, 1) \
|
||||
F(StoreKeyedToSuper_Sloppy, 4, 1) \
|
||||
F(HandleStepInForDerivedConstructors, 1, 1) \
|
||||
F(DefaultConstructorCallSuper, 2, 1) \
|
||||
F(CallSuperWithSpread, 1, 1)
|
||||
F(DefaultConstructorCallSuper, 0, 1) \
|
||||
F(CallSuperWithSpread, 0, 1)
|
||||
|
||||
|
||||
#define FOR_EACH_INTRINSIC_COLLECTIONS(F) \
|
||||
|
102
src/scopes.cc
102
src/scopes.cc
@ -160,7 +160,6 @@ void Scope::SetDefaults(ScopeType scope_type, Scope* outer_scope,
|
||||
function_ = nullptr;
|
||||
arguments_ = nullptr;
|
||||
home_object_ = nullptr;
|
||||
this_function_ = nullptr;
|
||||
illegal_redecl_ = nullptr;
|
||||
scope_inside_with_ = false;
|
||||
scope_contains_with_ = false;
|
||||
@ -309,44 +308,45 @@ void Scope::Initialize() {
|
||||
}
|
||||
|
||||
// Declare convenience variables and the receiver.
|
||||
if (is_declaration_scope() && has_this_declaration()) {
|
||||
Variable* var = variables_.Declare(
|
||||
this, ast_value_factory_->this_string(),
|
||||
subclass_constructor ? CONST : VAR, Variable::THIS,
|
||||
subclass_constructor ? kNeedsInitialization : kCreatedInitialized);
|
||||
receiver_ = var;
|
||||
}
|
||||
|
||||
if (is_function_scope()) {
|
||||
if (!is_arrow_scope()) {
|
||||
// Declare 'arguments' variable which exists in all non arrow functions.
|
||||
// Note that it might never be accessed, in which case it won't be
|
||||
// allocated during variable allocation.
|
||||
variables_.Declare(this, ast_value_factory_->arguments_string(), VAR,
|
||||
Variable::ARGUMENTS, kCreatedInitialized);
|
||||
if (is_declaration_scope()) {
|
||||
DCHECK(!subclass_constructor || is_function_scope());
|
||||
if (has_this_declaration()) {
|
||||
Variable* var = variables_.Declare(
|
||||
this, ast_value_factory_->this_string(),
|
||||
subclass_constructor ? CONST : VAR, Variable::THIS,
|
||||
subclass_constructor ? kNeedsInitialization : kCreatedInitialized);
|
||||
receiver_ = var;
|
||||
}
|
||||
|
||||
if (subclass_constructor) {
|
||||
DCHECK(!is_arrow_scope());
|
||||
variables_.Declare(this, ast_value_factory_->new_target_string(), CONST,
|
||||
Variable::NORMAL, kCreatedInitialized);
|
||||
new_target_ =
|
||||
variables_.Declare(this, ast_value_factory_->new_target_string(),
|
||||
CONST, Variable::NEW_TARGET, kCreatedInitialized);
|
||||
new_target_->AllocateTo(Variable::PARAMETER, -2);
|
||||
new_target_->set_is_used();
|
||||
}
|
||||
}
|
||||
|
||||
if (IsConciseMethod(function_kind_) || IsConstructor(function_kind_) ||
|
||||
IsAccessorFunction(function_kind_)) {
|
||||
DCHECK(!is_arrow_scope());
|
||||
// Declare '.home_object' variable which exists in all methods.
|
||||
// Note that it might never be accessed, in which case it won't be
|
||||
// allocated during variable allocation.
|
||||
variables_.Declare(this, ast_value_factory_->home_object_string(), CONST,
|
||||
Variable::NORMAL, kCreatedInitialized);
|
||||
}
|
||||
if (is_function_scope() && !is_arrow_scope()) {
|
||||
// Declare 'arguments' variable which exists in all non arrow functions.
|
||||
// Note that it might never be accessed, in which case it won't be
|
||||
// allocated during variable allocation.
|
||||
variables_.Declare(this,
|
||||
ast_value_factory_->arguments_string(),
|
||||
VAR,
|
||||
Variable::ARGUMENTS,
|
||||
kCreatedInitialized);
|
||||
}
|
||||
|
||||
if (IsSubclassConstructor(function_kind_)) {
|
||||
DCHECK(!is_arrow_scope());
|
||||
variables_.Declare(this, ast_value_factory_->this_function_string(),
|
||||
CONST, Variable::NORMAL, kCreatedInitialized);
|
||||
}
|
||||
if (is_function_scope() &&
|
||||
(IsConciseMethod(function_kind_) || IsConstructor(function_kind_) ||
|
||||
IsAccessorFunction(function_kind_))) {
|
||||
DCHECK(!is_arrow_scope());
|
||||
// Declare '.home_object' variable which exists in all methods.
|
||||
// Note that it might never be accessed, in which case it won't be
|
||||
// allocated during variable allocation.
|
||||
variables_.Declare(this, ast_value_factory_->home_object_string(), VAR,
|
||||
Variable::NORMAL, kCreatedInitialized);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1311,7 +1311,7 @@ bool Scope::MustAllocate(Variable* var) {
|
||||
// Give var a read/write use if there is a chance it might be accessed
|
||||
// via an eval() call. This is only possible if the variable has a
|
||||
// visible name.
|
||||
if ((var->is_this() || !var->raw_name()->IsEmpty()) &&
|
||||
if ((var->is_this() || var->is_new_target() || !var->raw_name()->IsEmpty()) &&
|
||||
(var->has_forced_context_allocation() || scope_calls_eval_ ||
|
||||
inner_scope_calls_eval_ || scope_contains_with_ || is_catch_scope() ||
|
||||
is_block_scope() || is_module_scope() || is_script_scope())) {
|
||||
@ -1403,6 +1403,18 @@ void Scope::AllocateParameterLocals(Isolate* isolate) {
|
||||
rest_parameter_ = NULL;
|
||||
}
|
||||
|
||||
Variable* home_object_var =
|
||||
LookupLocal(ast_value_factory_->home_object_string());
|
||||
if (home_object_var != nullptr && uses_super_property() &&
|
||||
MustAllocate(home_object_var)) {
|
||||
// TODO(arv): super() uses a SuperReference so it generates a VariableProxy
|
||||
// for the .home_object which makes it look like we need to allocate the
|
||||
// home_object_var.
|
||||
// Consider splitting the AST node into 2 different nodes since the
|
||||
// semantics is just so different.
|
||||
home_object_ = home_object_var;
|
||||
}
|
||||
|
||||
// The same parameter may occur multiple times in the parameters_ list.
|
||||
// If it does, and if it is not copied into the context object, it must
|
||||
// receive the highest parameter index for that parameter; thus iteration
|
||||
@ -1491,31 +1503,13 @@ void Scope::AllocateNonParameterLocals(Isolate* isolate) {
|
||||
// allocated in the context, it must be the last slot in the context,
|
||||
// because of the current ScopeInfo implementation (see
|
||||
// ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
|
||||
if (function_ != nullptr) {
|
||||
if (function_ != NULL) {
|
||||
AllocateNonParameterLocal(isolate, function_->proxy()->var());
|
||||
}
|
||||
|
||||
if (rest_parameter_ != nullptr) {
|
||||
if (rest_parameter_) {
|
||||
AllocateNonParameterLocal(isolate, rest_parameter_);
|
||||
}
|
||||
|
||||
Variable* home_object_var =
|
||||
LookupLocal(ast_value_factory_->home_object_string());
|
||||
if (home_object_var != nullptr && MustAllocate(home_object_var)) {
|
||||
home_object_ = home_object_var;
|
||||
}
|
||||
|
||||
Variable* new_target_var =
|
||||
LookupLocal(ast_value_factory_->new_target_string());
|
||||
if (new_target_var != nullptr && MustAllocate(new_target_var)) {
|
||||
new_target_ = new_target_var;
|
||||
}
|
||||
|
||||
Variable* this_function_var =
|
||||
LookupLocal(ast_value_factory_->this_function_string());
|
||||
if (this_function_var != nullptr && MustAllocate(this_function_var)) {
|
||||
this_function_ = this_function_var;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -419,13 +419,6 @@ class Scope: public ZoneObject {
|
||||
return home_object_;
|
||||
}
|
||||
|
||||
Variable* this_function_var() const {
|
||||
// This is only used in derived constructors atm.
|
||||
DCHECK(this_function_ == nullptr ||
|
||||
(is_function_scope() && IsSubclassConstructor(function_kind())));
|
||||
return this_function_;
|
||||
}
|
||||
|
||||
// Declarations list.
|
||||
ZoneList<Declaration*>* declarations() { return &decls_; }
|
||||
|
||||
@ -586,8 +579,6 @@ class Scope: public ZoneObject {
|
||||
Variable* arguments_;
|
||||
// Convenience variable; method scopes only.
|
||||
Variable* home_object_;
|
||||
// Convenience variable; Subclass constructor only
|
||||
Variable* this_function_;
|
||||
// Module descriptor; module scopes only.
|
||||
ModuleDescriptor* module_descriptor_;
|
||||
|
||||
|
@ -761,10 +761,7 @@ void AstTyper::VisitThisFunction(ThisFunction* expr) {
|
||||
}
|
||||
|
||||
|
||||
void AstTyper::VisitSuperPropertyReference(SuperPropertyReference* expr) {}
|
||||
|
||||
|
||||
void AstTyper::VisitSuperCallReference(SuperCallReference* expr) {}
|
||||
void AstTyper::VisitSuperReference(SuperReference* expr) {}
|
||||
|
||||
|
||||
void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) {
|
||||
|
@ -20,7 +20,7 @@ class ClassVariable;
|
||||
|
||||
class Variable: public ZoneObject {
|
||||
public:
|
||||
enum Kind { NORMAL, FUNCTION, CLASS, THIS, ARGUMENTS };
|
||||
enum Kind { NORMAL, FUNCTION, CLASS, THIS, NEW_TARGET, ARGUMENTS };
|
||||
|
||||
enum Location {
|
||||
// Before and during variable allocation, a variable whose location is
|
||||
@ -103,6 +103,7 @@ class Variable: public ZoneObject {
|
||||
bool is_function() const { return kind_ == FUNCTION; }
|
||||
bool is_class() const { return kind_ == CLASS; }
|
||||
bool is_this() const { return kind_ == THIS; }
|
||||
bool is_new_target() const { return kind_ == NEW_TARGET; }
|
||||
bool is_arguments() const { return kind_ == ARGUMENTS; }
|
||||
|
||||
ClassVariable* AsClassVariable() {
|
||||
|
@ -234,24 +234,6 @@ void FullCodeGenerator::Generate() {
|
||||
}
|
||||
}
|
||||
|
||||
// Possibly set up a local binding to the this function which is used in
|
||||
// derived constructors with super calls.
|
||||
Variable* this_function_var = scope()->this_function_var();
|
||||
if (this_function_var != nullptr) {
|
||||
Comment cmnt(masm_, "[ This function");
|
||||
SetVar(this_function_var, rdi, rbx, rdx);
|
||||
}
|
||||
|
||||
Variable* new_target_var = scope()->new_target_var();
|
||||
if (new_target_var != nullptr) {
|
||||
Comment cmnt(masm_, "[ new.target");
|
||||
// new.target is parameter -2.
|
||||
int offset = 2 * kPointerSize + kFPOnStackSize + kPCOnStackSize +
|
||||
(info_->scope()->num_parameters() - 1) * kPointerSize;
|
||||
__ movp(rax, Operand(rbp, offset));
|
||||
SetVar(new_target_var, rax, rbx, rdx);
|
||||
}
|
||||
|
||||
Variable* home_object_var = scope()->home_object_var();
|
||||
if (home_object_var != nullptr) {
|
||||
__ Push(rdi);
|
||||
@ -1977,10 +1959,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
}
|
||||
break;
|
||||
case NAMED_SUPER_PROPERTY:
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(property->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
property->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
property->obj()->AsSuperReference()->home_object_var());
|
||||
__ Push(result_register());
|
||||
if (expr->is_compound()) {
|
||||
__ Push(MemOperand(rsp, kPointerSize));
|
||||
@ -1988,10 +1969,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
}
|
||||
break;
|
||||
case KEYED_SUPER_PROPERTY:
|
||||
VisitForStackValue(property->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
property->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
property->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForAccumulatorValue(property->key());
|
||||
__ Push(result_register());
|
||||
if (expr->is_compound()) {
|
||||
@ -2583,9 +2563,9 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
|
||||
}
|
||||
case NAMED_SUPER_PROPERTY: {
|
||||
__ Push(rax);
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
prop->obj()->AsSuperReference()->home_object_var());
|
||||
// stack: value, this; rax: home_object
|
||||
Register scratch = rcx;
|
||||
Register scratch2 = rdx;
|
||||
@ -2600,9 +2580,8 @@ void FullCodeGenerator::EmitAssignment(Expression* expr,
|
||||
}
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
__ Push(rax);
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForAccumulatorValue(prop->key());
|
||||
Register scratch = rcx;
|
||||
Register scratch2 = rdx;
|
||||
@ -2821,9 +2800,8 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
|
||||
__ movp(LoadDescriptor::ReceiverRegister(), rax);
|
||||
EmitNamedPropertyLoad(expr);
|
||||
} else {
|
||||
VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
expr->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->home_object_var());
|
||||
EmitNamedSuperPropertyLoad(expr);
|
||||
}
|
||||
} else {
|
||||
@ -2834,9 +2812,8 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
|
||||
__ Pop(LoadDescriptor::ReceiverRegister());
|
||||
EmitKeyedPropertyLoad(expr);
|
||||
} else {
|
||||
VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
expr->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(expr->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForStackValue(expr->key());
|
||||
EmitKeyedSuperPropertyLoad(expr);
|
||||
}
|
||||
@ -2894,7 +2871,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
|
||||
Literal* key = prop->key()->AsLiteral();
|
||||
DCHECK(!key->value()->IsSmi());
|
||||
// Load the function from the receiver.
|
||||
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
|
||||
SuperReference* super_ref = prop->obj()->AsSuperReference();
|
||||
VisitForStackValue(super_ref->home_object_var());
|
||||
VisitForAccumulatorValue(super_ref->this_var());
|
||||
__ Push(rax);
|
||||
@ -2951,7 +2928,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
|
||||
|
||||
SetSourcePosition(prop->position());
|
||||
// Load the function from the receiver.
|
||||
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
|
||||
SuperReference* super_ref = prop->obj()->AsSuperReference();
|
||||
VisitForStackValue(super_ref->home_object_var());
|
||||
VisitForAccumulatorValue(super_ref->this_var());
|
||||
__ Push(rax);
|
||||
@ -3032,8 +3009,14 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitLoadSuperConstructor() {
|
||||
__ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
__ CallRuntime(Runtime::kGetPrototype, 1);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitInitializeThisAfterSuper(
|
||||
SuperCallReference* super_ref, FeedbackVectorICSlot slot) {
|
||||
SuperReference* super_ref, FeedbackVectorICSlot slot) {
|
||||
Variable* this_var = super_ref->this_var()->var();
|
||||
GetVar(rcx, this_var);
|
||||
__ CompareRoot(rcx, Heap::kTheHoleValueRootIndex);
|
||||
@ -3183,7 +3166,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
// Push constructor on the stack. If it's not a function it's used as
|
||||
// receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
|
||||
// ignored.
|
||||
DCHECK(!expr->expression()->IsSuperPropertyReference());
|
||||
DCHECK(!expr->expression()->IsSuperReference());
|
||||
VisitForStackValue(expr->expression());
|
||||
|
||||
// Push the arguments ("left-to-right") on the stack.
|
||||
@ -3219,14 +3202,11 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
||||
SuperCallReference* super_call_ref =
|
||||
expr->expression()->AsSuperCallReference();
|
||||
DCHECK_NOT_NULL(super_call_ref);
|
||||
Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
|
||||
GetVar(result_register(), new_target_var);
|
||||
__ Push(result_register());
|
||||
|
||||
VariableProxy* new_target_proxy = super_call_ref->new_target_var();
|
||||
VisitForStackValue(new_target_proxy);
|
||||
|
||||
EmitLoadSuperConstructor(super_call_ref);
|
||||
EmitLoadSuperConstructor();
|
||||
__ Push(result_register());
|
||||
|
||||
// Push the arguments ("left-to-right") on the stack.
|
||||
@ -3264,7 +3244,8 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
||||
|
||||
RecordJSReturnSite(expr);
|
||||
|
||||
EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot());
|
||||
EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(),
|
||||
expr->CallFeedbackICSlot());
|
||||
context()->Plug(rax);
|
||||
}
|
||||
|
||||
@ -4131,15 +4112,11 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
|
||||
GetVar(result_register(), new_target_var);
|
||||
__ Push(result_register());
|
||||
|
||||
// new.target
|
||||
VisitForStackValue(args->at(0));
|
||||
|
||||
// .this_function
|
||||
VisitForStackValue(args->at(1));
|
||||
__ CallRuntime(Runtime::kGetPrototype, 1);
|
||||
EmitLoadSuperConstructor();
|
||||
__ Push(result_register());
|
||||
|
||||
// Check if the calling frame is an arguments adaptor frame.
|
||||
@ -4591,14 +4568,11 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
|
||||
|
||||
void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
// Assert: expr === CallRuntime("ReflectConstruct")
|
||||
DCHECK_EQ(1, expr->arguments()->length());
|
||||
CallRuntime* call = expr->arguments()->at(0)->AsCallRuntime();
|
||||
|
||||
ZoneList<Expression*>* args = call->arguments();
|
||||
DCHECK_EQ(3, args->length());
|
||||
|
||||
SuperCallReference* super_call_ref = args->at(0)->AsSuperCallReference();
|
||||
DCHECK_NOT_NULL(super_call_ref);
|
||||
SuperReference* super_reference = args->at(0)->AsSuperReference();
|
||||
|
||||
// Load ReflectConstruct function
|
||||
EmitLoadJSRuntimeFunction(call);
|
||||
@ -4607,8 +4581,8 @@ void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
__ Push(Operand(rsp, 0));
|
||||
__ movp(Operand(rsp, kPointerSize), rax);
|
||||
|
||||
// Push super constructor
|
||||
EmitLoadSuperConstructor(super_call_ref);
|
||||
// Push super
|
||||
EmitLoadSuperConstructor();
|
||||
__ Push(result_register());
|
||||
|
||||
// Push arguments array
|
||||
@ -4625,7 +4599,7 @@ void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
|
||||
context()->DropAndPlug(1, rax);
|
||||
|
||||
// TODO(mvstanton): with FLAG_vector_stores this needs a slot id.
|
||||
EmitInitializeThisAfterSuper(super_call_ref);
|
||||
EmitInitializeThisAfterSuper(super_reference);
|
||||
}
|
||||
|
||||
|
||||
@ -4850,9 +4824,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
}
|
||||
|
||||
case NAMED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
prop->obj()->AsSuperReference()->home_object_var());
|
||||
__ Push(result_register());
|
||||
__ Push(MemOperand(rsp, kPointerSize));
|
||||
__ Push(result_register());
|
||||
@ -4861,9 +4835,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
}
|
||||
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForStackValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
|
||||
VisitForStackValue(prop->obj()->AsSuperReference()->home_object_var());
|
||||
VisitForAccumulatorValue(prop->key());
|
||||
__ Push(result_register());
|
||||
__ Push(MemOperand(rsp, 2 * kPointerSize));
|
||||
|
@ -3,7 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony-classes --harmony-arrow-functions --allow-natives-syntax
|
||||
// Flags: --harmony-spreadcalls
|
||||
|
||||
|
||||
(function TestSuperNamedLoads() {
|
||||
function Base() { }
|
||||
@ -2107,99 +2107,3 @@ TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44);
|
||||
let d = new Derived();
|
||||
assertSame(1, d.arrow());
|
||||
})();
|
||||
|
||||
|
||||
(function TestSuperCallInEval() {
|
||||
'use strict';
|
||||
class Base {
|
||||
constructor(x) {
|
||||
this.x = x;
|
||||
}
|
||||
}
|
||||
class Derived extends Base {
|
||||
constructor(x) {
|
||||
eval('super(x)');
|
||||
}
|
||||
}
|
||||
let d = new Derived(42);
|
||||
assertSame(42, d.x);
|
||||
})();
|
||||
|
||||
|
||||
(function TestSuperCallInArrow() {
|
||||
'use strict';
|
||||
class Base {
|
||||
constructor(x) {
|
||||
this.x = x;
|
||||
}
|
||||
}
|
||||
class Derived extends Base {
|
||||
constructor(x) {
|
||||
(() => super(x))();
|
||||
}
|
||||
}
|
||||
let d = new Derived(42);
|
||||
assertSame(42, d.x);
|
||||
})();
|
||||
|
||||
|
||||
(function TestSuperCallEscapes() {
|
||||
'use strict';
|
||||
class Base {
|
||||
constructor(x) {
|
||||
this.x = x;
|
||||
}
|
||||
}
|
||||
|
||||
let f;
|
||||
class Derived extends Base {
|
||||
constructor() {
|
||||
f = () => super(2);
|
||||
}
|
||||
}
|
||||
assertThrows(function() {
|
||||
new Derived();
|
||||
}, ReferenceError);
|
||||
|
||||
let o = f();
|
||||
assertEquals(2, o.x);
|
||||
assertInstanceof(o, Derived);
|
||||
|
||||
assertThrows(function() {
|
||||
f();
|
||||
}, ReferenceError);
|
||||
})();
|
||||
|
||||
|
||||
(function TestSuperCallSpreadInEval() {
|
||||
'use strict';
|
||||
class Base {
|
||||
constructor(x) {
|
||||
this.x = x;
|
||||
}
|
||||
}
|
||||
class Derived extends Base {
|
||||
constructor(x) {
|
||||
eval('super(...[x])');
|
||||
}
|
||||
}
|
||||
let d = new Derived(42);
|
||||
assertSame(42, d.x);
|
||||
})();
|
||||
|
||||
|
||||
(function TestSuperCallSpreadInArrow() {
|
||||
'use strict';
|
||||
class Base {
|
||||
constructor(x) {
|
||||
this.x = x;
|
||||
}
|
||||
}
|
||||
class Derived extends Base {
|
||||
constructor(x) {
|
||||
(() => super(...[x]))();
|
||||
}
|
||||
}
|
||||
let d = new Derived(42);
|
||||
assertSame(42, d.x);
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user