Commit 8be79b00 authored by chunyang.dai's avatar chunyang.dai Committed by Commit bot

X87: new classes: implement new.target passing to superclass constructor

port bf49be39 (r26572)

original commit message:

   new classes: implement new.target passing to superclass constructor

BUG=

Review URL: https://codereview.chromium.org/912233003

Cr-Commit-Position: refs/heads/master@{#26596}
parent 464f76b7
...@@ -519,6 +519,9 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { ...@@ -519,6 +519,9 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
__ push(eax); __ push(eax);
__ SmiUntag(eax); __ SmiUntag(eax);
// Push new.target.
__ push(edx);
// receiver is the hole. // receiver is the hole.
__ push(Immediate(masm->isolate()->factory()->the_hole_value())); __ push(Immediate(masm->isolate()->factory()->the_hole_value()));
...@@ -535,6 +538,7 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { ...@@ -535,6 +538,7 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
__ dec(ecx); __ dec(ecx);
__ j(greater_equal, &loop); __ j(greater_equal, &loop);
__ inc(eax); // Pushed new.target.
ParameterCount actual(eax); ParameterCount actual(eax);
__ InvokeFunction(edi, actual, CALL_FUNCTION, NullCallWrapper()); __ InvokeFunction(edi, actual, CALL_FUNCTION, NullCallWrapper());
......
...@@ -419,6 +419,7 @@ void LoadIndexedStringStub::Generate(MacroAssembler* masm) { ...@@ -419,6 +419,7 @@ void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
CHECK(!has_new_target());
// The key is in edx and the parameter count is in eax. // The key is in edx and the parameter count is in eax.
DCHECK(edx.is(ArgumentsAccessReadDescriptor::index())); DCHECK(edx.is(ArgumentsAccessReadDescriptor::index()));
DCHECK(eax.is(ArgumentsAccessReadDescriptor::parameter_count())); DCHECK(eax.is(ArgumentsAccessReadDescriptor::parameter_count()));
...@@ -485,6 +486,8 @@ void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { ...@@ -485,6 +486,8 @@ void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
// esp[8] : receiver displacement // esp[8] : receiver displacement
// esp[12] : function // esp[12] : function
CHECK(!has_new_target());
// Check if the calling frame is an arguments adaptor frame. // Check if the calling frame is an arguments adaptor frame.
Label runtime; Label runtime;
__ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
...@@ -513,6 +516,8 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { ...@@ -513,6 +516,8 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
// ebx = parameter count (tagged) // ebx = parameter count (tagged)
__ mov(ebx, Operand(esp, 1 * kPointerSize)); __ mov(ebx, Operand(esp, 1 * kPointerSize));
CHECK(!has_new_target());
// Check if the calling frame is an arguments adaptor frame. // Check if the calling frame is an arguments adaptor frame.
// TODO(rossberg): Factor out some of the bits that are shared with the other // TODO(rossberg): Factor out some of the bits that are shared with the other
// Generate* functions. // Generate* functions.
...@@ -752,9 +757,15 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { ...@@ -752,9 +757,15 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
// Patch the arguments.length and the parameters pointer. // Patch the arguments.length and the parameters pointer.
__ bind(&adaptor_frame); __ bind(&adaptor_frame);
__ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
__ mov(Operand(esp, 1 * kPointerSize), ecx);
if (has_new_target()) {
// Subtract 1 from smi-tagged arguments count.
__ sub(ecx, Immediate(2));
}
__ lea(edx, Operand(edx, ecx, times_2, __ lea(edx, Operand(edx, ecx, times_2,
StandardFrameConstants::kCallerSPOffset)); StandardFrameConstants::kCallerSPOffset));
__ mov(Operand(esp, 1 * kPointerSize), ecx);
__ mov(Operand(esp, 2 * kPointerSize), edx); __ mov(Operand(esp, 2 * kPointerSize), edx);
// Try the new space allocation. Start out with computing the size of // Try the new space allocation. Start out with computing the size of
...@@ -1836,8 +1847,12 @@ void CallConstructStub::Generate(MacroAssembler* masm) { ...@@ -1836,8 +1847,12 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
__ AssertUndefinedOrAllocationSite(ebx); __ AssertUndefinedOrAllocationSite(ebx);
} }
if (IsSuperConstructorCall()) {
__ mov(edx, Operand(esp, eax, times_pointer_size, 2 * kPointerSize));
} else {
// Pass original constructor to construct stub. // Pass original constructor to construct stub.
__ mov(edx, edi); __ mov(edx, edi);
}
// Jump to the function-specific construct stub. // Jump to the function-specific construct stub.
Register jmp_reg = ecx; Register jmp_reg = ecx;
......
...@@ -212,7 +212,8 @@ void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) { ...@@ -212,7 +212,8 @@ void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) {
bool Deoptimizer::HasAlignmentPadding(JSFunction* function) { bool Deoptimizer::HasAlignmentPadding(JSFunction* function) {
int parameter_count = function->shared()->formal_parameter_count() + 1; int parameter_count =
function->shared()->internal_formal_parameter_count() + 1;
unsigned input_frame_size = input_->GetFrameSize(); unsigned input_frame_size = input_->GetFrameSize();
unsigned alignment_state_offset = unsigned alignment_state_offset =
input_frame_size - parameter_count * kPointerSize - input_frame_size - parameter_count * kPointerSize -
......
...@@ -261,7 +261,11 @@ void FullCodeGenerator::Generate() { ...@@ -261,7 +261,11 @@ void FullCodeGenerator::Generate() {
} else { } else {
type = ArgumentsAccessStub::NEW_SLOPPY_FAST; type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
} }
ArgumentsAccessStub stub(isolate(), type); ArgumentsAccessStub::HasNewTarget has_new_target =
IsSubclassConstructor(info->function()->kind())
? ArgumentsAccessStub::HAS_NEW_TARGET
: ArgumentsAccessStub::NO_NEW_TARGET;
ArgumentsAccessStub stub(isolate(), type, has_new_target);
__ CallStub(&stub); __ CallStub(&stub);
SetVar(arguments, eax, ebx, edx); SetVar(arguments, eax, ebx, edx);
...@@ -410,7 +414,12 @@ void FullCodeGenerator::EmitReturnSequence() { ...@@ -410,7 +414,12 @@ void FullCodeGenerator::EmitReturnSequence() {
int no_frame_start = masm_->pc_offset(); int no_frame_start = masm_->pc_offset();
__ pop(ebp); __ pop(ebp);
int arguments_bytes = (info_->scope()->num_parameters() + 1) * kPointerSize; int arg_count = info_->scope()->num_parameters() + 1;
if (FLAG_experimental_classes &&
IsSubclassConstructor(info_->function()->kind())) {
arg_count++;
}
int arguments_bytes = arg_count * kPointerSize;
__ Ret(arguments_bytes, ecx); __ Ret(arguments_bytes, ecx);
// Check that the size of the code used for returning is large enough // Check that the size of the code used for returning is large enough
// for the debugger's requirements. // for the debugger's requirements.
...@@ -3121,6 +3130,10 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) { ...@@ -3121,6 +3130,10 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
GetVar(eax, new_target_var);
__ push(eax);
SuperReference* super_ref = expr->expression()->AsSuperReference(); SuperReference* super_ref = expr->expression()->AsSuperReference();
EmitLoadSuperConstructor(super_ref); EmitLoadSuperConstructor(super_ref);
__ push(result_register()); __ push(result_register());
...@@ -3162,10 +3175,11 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { ...@@ -3162,10 +3175,11 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
__ LoadHeapObject(ebx, FeedbackVector()); __ LoadHeapObject(ebx, FeedbackVector());
__ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot()))); __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot())));
// TODO(dslomov): use a different stub and propagate new.target. CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET);
CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
__ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
__ Drop(1);
RecordJSReturnSite(expr); RecordJSReturnSite(expr);
EmitVariableAssignment(this_var, Token::INIT_CONST); EmitVariableAssignment(this_var, Token::INIT_CONST);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment