From: arv Date: Mon, 1 Jun 2015 16:10:08 +0000 (-0700) Subject: Revert of [es6] Super call in arrows and eval (patchset #5 id:100001 of https://coder... X-Git-Tag: upstream/4.7.83~2305 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=88b1c9170a0293cbcc8bdaf57fbe12744b48d7e8;p=platform%2Fupstream%2Fv8.git 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} --- diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index 17e5e4c6d..7a0d9b658 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -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); - - VariableProxy* new_target_proxy = super_call_ref->new_target_var(); - VisitForStackValue(new_target_proxy); + Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); + GetVar(result_register(), new_target_var); + __ Push(result_register()); - 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* args = expr->arguments(); - DCHECK(args->length() == 2); - - // new.target - VisitForStackValue(args->at(0)); + Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); + GetVar(result_register(), new_target_var); + __ Push(result_register()); - // .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* 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; diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc index d9fe5d306..0e6391f8e 100644 --- a/src/arm64/full-codegen-arm64.cc +++ b/src/arm64/full-codegen-arm64.cc @@ -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); - - VariableProxy* new_target_proxy = super_call_ref->new_target_var(); - VisitForStackValue(new_target_proxy); + Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); + GetVar(result_register(), new_target_var); + __ Push(result_register()); - 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* args = expr->arguments(); - DCHECK(args->length() == 2); - - // new.target - VisitForStackValue(args->at(0)); + Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); + GetVar(result_register(), new_target_var); + __ Push(result_register()); - // .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* 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; diff --git a/src/ast-numbering.cc b/src/ast-numbering.cc index 59b95cbd2..da23aad98 100644 --- a/src/ast-numbering.cc +++ b/src/ast-numbering.cc @@ -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); diff --git a/src/ast-value-factory.h b/src/ast-value-factory.h index d3b4dc5bf..e9830c33f 100644 --- a/src/ast-value-factory.h +++ b/src/ast-value-factory.h @@ -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") \ diff --git a/src/ast.cc b/src/ast.cc index 697d46d59..73cd013a8 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -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; diff --git a/src/ast.h b/src/ast.h index 4ef0282c0..c2a3b0023 100644 --- a/src/ast.h +++ b/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: diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index ac2ba9dc3..b648495fd 100644 --- a/src/compiler/ast-graph-builder.cc +++ b/src/compiler/ast-graph-builder.cc @@ -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()); diff --git a/src/compiler/ast-loop-assignment-analyzer.cc b/src/compiler/ast-loop-assignment-analyzer.cc index 61ed4f27c..a45848a03 100644 --- a/src/compiler/ast-loop-assignment-analyzer.cc +++ b/src/compiler/ast-loop-assignment-analyzer.cc @@ -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) {} // --------------------------------------------------------------------------- diff --git a/src/full-codegen.cc b/src/full-codegen.cc index 759265e5f..95957d614 100644 --- a/src/full-codegen.cc +++ b/src/full-codegen.cc @@ -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); diff --git a/src/full-codegen.h b/src/full-codegen.h index a7a91d0af..e81b44e4a 100644 --- a/src/full-codegen.h +++ b/src/full-codegen.h @@ -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, diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 693d54050..809640fb4 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -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()); diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index cac11a1ea..573ca702d 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -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); - - VariableProxy* new_target_proxy = super_call_ref->new_target_var(); - VisitForStackValue(new_target_proxy); + Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); + GetVar(eax, new_target_var); + __ push(eax); - 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* args = expr->arguments(); - DCHECK(args->length() == 2); - - // new.target - VisitForStackValue(args->at(0)); + Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); + GetVar(eax, new_target_var); + __ push(eax); - // .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* 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)); diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index 56e3a5fc4..c81f346d1 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -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); - - VariableProxy* new_target_proxy = super_call_ref->new_target_var(); - VisitForStackValue(new_target_proxy); + Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); + GetVar(result_register(), new_target_var); + __ Push(result_register()); - 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* args = expr->arguments(); - DCHECK(args->length() == 2); - - // new.target - VisitForStackValue(args->at(0)); + Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); + GetVar(result_register(), new_target_var); + __ Push(result_register()); - // .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* 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()); diff --git a/src/mips64/full-codegen-mips64.cc b/src/mips64/full-codegen-mips64.cc index 6547a493c..29caab4ad 100644 --- a/src/mips64/full-codegen-mips64.cc +++ b/src/mips64/full-codegen-mips64.cc @@ -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); - - VariableProxy* new_target_proxy = super_call_ref->new_target_var(); - VisitForStackValue(new_target_proxy); + Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); + GetVar(result_register(), new_target_var); + __ Push(result_register()); - 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* args = expr->arguments(); - DCHECK(args->length() == 2); - - // new.target - VisitForStackValue(args->at(0)); + Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); + GetVar(result_register(), new_target_var); + __ Push(result_register()); - // .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* 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()); diff --git a/src/parser.cc b/src/parser.cc index 45baddbc8..196853c02 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -359,17 +359,8 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, body = new (zone()) ZoneList(call_super ? 2 : 1, zone()); AddAssertIsConstruct(body, pos); if (call_super) { - // %_DefaultConstructorCallSuper(new.target, .this_function) ZoneList* args = - new (zone()) ZoneList(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(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* Parser::PrepareSpreadArguments( Expression* Parser::SpreadCall(Expression* function, ZoneList* args, int pos) { - if (function->IsSuperCallReference()) { + if (function->IsSuperReference()) { // Super calls - // %_CallSuperWithSpread(%ReflectConstruct(, 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(1, zone()); + args = new (zone()) ZoneList(0, zone()); args->Add(result, zone()); return factory()->NewCallRuntime( ast_value_factory()->empty_string(), diff --git a/src/parser.h b/src/parser.h index 9080160c7..eba677c94 100644 --- a/src/parser.h +++ b/src/parser.h @@ -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, diff --git a/src/pattern-rewriter.cc b/src/pattern-rewriter.cc index 51cf8bfde..e41420518 100644 --- a/src/pattern-rewriter.cc +++ b/src/pattern-rewriter.cc @@ -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) diff --git a/src/preparser.h b/src/preparser.h index 34295c71f..2fe5db1d0 100644 --- a/src/preparser.h +++ b/src/preparser.h @@ -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::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::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::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); } } diff --git a/src/prettyprinter.cc b/src/prettyprinter.cc index 453a43cb2..160bb6f54 100644 --- a/src/prettyprinter.cc +++ b/src/prettyprinter.cc @@ -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* statements) { @@ -838,13 +835,8 @@ void PrettyPrinter::VisitThisFunction(ThisFunction* node) { } -void PrettyPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) { - Print(""); -} - - -void PrettyPrinter::VisitSuperCallReference(SuperCallReference* node) { - Print(""); +void PrettyPrinter::VisitSuperReference(SuperReference* node) { + Print(""); } @@ -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 diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index c62938a53..ea5570ec5 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -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) \ diff --git a/src/scopes.cc b/src/scopes.cc index 2aa3cbde9..21a8805c5 100644 --- a/src/scopes.cc +++ b/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; - } } diff --git a/src/scopes.h b/src/scopes.h index 63cd13d47..d56018532 100644 --- a/src/scopes.h +++ b/src/scopes.h @@ -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* 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_; diff --git a/src/typing.cc b/src/typing.cc index e24298f77..c0d3ddd30 100644 --- a/src/typing.cc +++ b/src/typing.cc @@ -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* decls) { diff --git a/src/variables.h b/src/variables.h index 0cb50c87e..384a88595 100644 --- a/src/variables.h +++ b/src/variables.h @@ -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() { diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index 2aef9d125..947de3207 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -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); - - VariableProxy* new_target_proxy = super_call_ref->new_target_var(); - VisitForStackValue(new_target_proxy); + Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); + GetVar(result_register(), new_target_var); + __ Push(result_register()); - 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* args = expr->arguments(); - DCHECK(args->length() == 2); - - // new.target - VisitForStackValue(args->at(0)); + Variable* new_target_var = scope()->DeclarationScope()->new_target_var(); + GetVar(result_register(), new_target_var); + __ Push(result_register()); - // .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* 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)); diff --git a/test/mjsunit/harmony/super.js b/test/mjsunit/harmony/super.js index 87fceafb2..1af7ab2e2 100644 --- a/test/mjsunit/harmony/super.js +++ b/test/mjsunit/harmony/super.js @@ -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); -})();