| Index: src/x64/full-codegen-x64.cc
|
| diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
|
| index 2ad757f843c5e47feb0583f7d3e8ef95ff7247de..052bcd8ba11865bc3949418831b4800300069cc7 100644
|
| --- a/src/x64/full-codegen-x64.cc
|
| +++ b/src/x64/full-codegen-x64.cc
|
| @@ -232,10 +232,15 @@ void FullCodeGenerator::Generate() {
|
| }
|
| }
|
|
|
| + Variable* new_target_var = scope()->new_target_var();
|
| + if (new_target_var != nullptr) {
|
| + EmitAssignNewTarget(new_target_var);
|
| + new_target_var->set_initializer_position(scope()->start_position());
|
| + }
|
| +
|
| + // TODO(arv): Remove ArgumentsAccessStub::HasNewTarget
|
| ArgumentsAccessStub::HasNewTarget has_new_target =
|
| - IsSubclassConstructor(info->function()->kind())
|
| - ? ArgumentsAccessStub::HAS_NEW_TARGET
|
| - : ArgumentsAccessStub::NO_NEW_TARGET;
|
| + ArgumentsAccessStub::NO_NEW_TARGET;
|
|
|
| // Possibly allocate RestParameters
|
| int rest_index;
|
| @@ -447,12 +452,11 @@ void FullCodeGenerator::EmitReturnSequence() {
|
| __ popq(rbp);
|
| int no_frame_start = masm_->pc_offset();
|
|
|
| - int arg_count = info_->scope()->num_parameters() + 1;
|
| - if (IsSubclassConstructor(info_->function()->kind())) {
|
| - arg_count++;
|
| + int offset = info_->scope()->num_parameters() + 1;
|
| + if (scope()->uses_new_target()) {
|
| + offset++;
|
| }
|
| - int arguments_bytes = arg_count * kPointerSize;
|
| - __ Ret(arguments_bytes, rcx);
|
| + __ Ret(offset * kPointerSize, rcx);
|
|
|
| // Add padding that will be overwritten by a debugger breakpoint. We
|
| // have just generated at least 7 bytes: "movp rsp, rbp; pop rbp; ret k"
|
| @@ -3023,6 +3027,68 @@ void FullCodeGenerator::EmitInitializeThisAfterSuper(
|
| }
|
|
|
|
|
| +void FullCodeGenerator::EmitAssignNewTarget(Variable* new_target_var) {
|
| + __ CallRuntime(Runtime::kGetNewTarget, 0);
|
| +
|
| + // Register fp = rax;
|
| + // // Register count = rbx;
|
| + // // Register scratch = rcx;
|
| +
|
| + // // Get the frame pointer for the calling frame.
|
| + // __ movp(fp, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
| +
|
| + // // Skip the arguments adaptor frame if it exists.
|
| + // Label check_frame_marker, construct_frame, assign;
|
| +
|
| + // __ Cmp(Operand(fp, StandardFrameConstants::kContextOffset),
|
| + // Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
| + // __ j(not_equal, &check_frame_marker, Label::kNear);
|
| + // __ movp(fp, Operand(fp, StandardFrameConstants::kCallerFPOffset));
|
| +
|
| + // // Check the marker in the calling frame.
|
| + // __ bind(&check_frame_marker);
|
| + // __ Cmp(Operand(fp, StandardFrameConstants::kMarkerOffset),
|
| + // Smi::FromInt(StackFrame::CONSTRUCT));
|
| + // __ j(equal, &construct_frame, Label::kNear);
|
| +
|
| + // // [[Call]] always return undefined
|
| + // __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
|
| + // __ jmp(&assign, Label::kNear);
|
| +
|
| + // // [[Construct]] get new.target from stack.
|
| + // __ bind(&construct_frame);
|
| +
|
| + // // Get the number of formal parameters.
|
| + // // __ Move(count, Smi::FromInt(info_->scope()->num_parameters()));
|
| +
|
| + // // Label length_done;
|
| + // // // TODO(arv): Don't check this again...
|
| + // // // Check if the calling frame is an arguments adaptor frame.
|
| + // // __ movp(scratch, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
| + // // __ Cmp(Operand(scratch, StandardFrameConstants::kContextOffset),
|
| + // // Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
| + // // __ j(not_equal, &length_done, Label::kNear);
|
| +
|
| + // // // Arguments adaptor case: Read the arguments length from the
|
| + // // // adaptor frame.
|
| + // // __ movp(count, Operand(rbx,
|
| + // ArgumentsAdaptorFrameConstants::kLengthOffset));
|
| +
|
| + // // __ bind(&length_done);
|
| +
|
| + // // // static const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
|
| + // // static const int kNewTargetOffset = 3 * kPointerSize;
|
| +
|
| + // // __ leap(rax, Operand(fp, count, times_pointer_size, kNewTargetOffset));
|
| +
|
| + // __ movp(rax, Operand(fp, (3 + info_->scope()->num_parameters()) *
|
| + // kPointerSize));
|
| +
|
| + // __ bind(&assign);
|
| + EmitVariableAssignment(new_target_var, Token::INIT_CONST);
|
| +}
|
| +
|
| +
|
| void FullCodeGenerator::VisitCall(Call* expr) {
|
| #ifdef DEBUG
|
| // We want to verify that RecordJSReturnSite gets called on all paths
|
| @@ -4128,7 +4194,8 @@ void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
|
| __ SmiToInteger64(rcx, rcx);
|
|
|
| // Subtract 1 from arguments count, for new.target.
|
| - __ subp(rcx, Immediate(1));
|
| + // TODO(arv): FIXME!
|
| + // __ subp(rcx, Immediate(1));
|
| __ movp(rax, rcx);
|
| __ leap(rdx, Operand(rdx, rcx, times_pointer_size,
|
| StandardFrameConstants::kCallerSPOffset));
|
|
|