| Index: src/mips/full-codegen-mips.cc
|
| diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
|
| index f99085adfea614bc21039ccfa15c6fd44c7dc7e3..7b493283c27e54c306506b33acb33fb0ab1bb7a2 100644
|
| --- a/src/mips/full-codegen-mips.cc
|
| +++ b/src/mips/full-codegen-mips.cc
|
| @@ -3041,8 +3041,7 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) {
|
| - DCHECK(super_ref != NULL);
|
| +void FullCodeGenerator::EmitLoadSuperConstructor() {
|
| __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
| __ Push(a0);
|
| __ CallRuntime(Runtime::kGetPrototype, 1);
|
| @@ -3166,9 +3165,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
| if (FLAG_experimental_classes) {
|
| EmitSuperConstructorCall(expr);
|
| } else {
|
| - SuperReference* super_ref = callee->AsSuperReference();
|
| - EmitLoadSuperConstructor(super_ref);
|
| + EmitLoadSuperConstructor();
|
| __ Push(result_register());
|
| + SuperReference* super_ref = callee->AsSuperReference();
|
| VisitForStackValue(super_ref->this_var());
|
| EmitCall(expr, CallICState::METHOD);
|
| }
|
| @@ -3241,10 +3240,10 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
| GetVar(result_register(), new_target_var);
|
| __ Push(result_register());
|
|
|
| - SuperReference* super_ref = expr->expression()->AsSuperReference();
|
| - EmitLoadSuperConstructor(super_ref);
|
| + EmitLoadSuperConstructor();
|
| __ push(result_register());
|
|
|
| + SuperReference* super_ref = expr->expression()->AsSuperReference();
|
| Variable* this_var = super_ref->this_var()->var();
|
|
|
| GetVar(a0, this_var);
|
| @@ -4175,6 +4174,63 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
|
| }
|
|
|
|
|
| +void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
|
| + Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
|
| + GetVar(result_register(), new_target_var);
|
| + __ Push(result_register());
|
| +
|
| + EmitLoadSuperConstructor();
|
| + __ Push(result_register());
|
| +
|
| + // Check if the calling frame is an arguments adaptor frame.
|
| + Label adaptor_frame, args_set_up, runtime;
|
| + __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
| + __ lw(a3, MemOperand(a2, StandardFrameConstants::kContextOffset));
|
| + __ Branch(&adaptor_frame, eq, a3,
|
| + Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
|
| + // default constructor has no arguments, so no adaptor frame means no args.
|
| + __ mov(a0, zero_reg);
|
| + __ Branch(&args_set_up);
|
| +
|
| + // Copy arguments from adaptor frame.
|
| + {
|
| + __ bind(&adaptor_frame);
|
| + __ lw(a1, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
| + __ SmiUntag(a1, a1);
|
| +
|
| + // Subtract 1 from arguments count, for new.target.
|
| + __ Addu(a1, a1, Operand(-1));
|
| + __ mov(a0, a1);
|
| +
|
| + // Get arguments pointer in a2.
|
| + __ sll(at, a1, kPointerSizeLog2);
|
| + __ addu(a2, a2, at);
|
| + __ Addu(a2, a2, Operand(StandardFrameConstants::kCallerSPOffset));
|
| + Label loop;
|
| + __ bind(&loop);
|
| + // Pre-decrement a2 with kPointerSize on each iteration.
|
| + // Pre-decrement in order to skip receiver.
|
| + __ Addu(a2, a2, Operand(-kPointerSize));
|
| + __ lw(a3, MemOperand(a2));
|
| + __ Push(a3);
|
| + __ Addu(a1, a1, Operand(-1));
|
| + __ Branch(&loop, ne, a1, Operand(zero_reg));
|
| + }
|
| +
|
| + __ bind(&args_set_up);
|
| + __ sll(at, a0, kPointerSizeLog2);
|
| + __ Addu(at, at, Operand(sp));
|
| + __ lw(a1, MemOperand(at, 0));
|
| +
|
| + CallConstructStub stub(isolate(), SUPER_CONSTRUCTOR_CALL);
|
| + __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
|
| +
|
| + __ Drop(1);
|
| +
|
| + context()->Plug(result_register());
|
| +}
|
| +
|
| +
|
| void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
|
| RegExpConstructResultStub stub(isolate());
|
| ZoneList<Expression*>* args = expr->arguments();
|
|
|