| Index: src/ia32/full-codegen-ia32.cc
|
| diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
|
| index 6ee5d959af0004110f80e64d5fa78d82ef14cc62..4b603ddabc20ab10de126c4f04bbfcac3943e086 100644
|
| --- a/src/ia32/full-codegen-ia32.cc
|
| +++ b/src/ia32/full-codegen-ia32.cc
|
| @@ -2956,8 +2956,7 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) {
|
| - DCHECK(super_ref != NULL);
|
| +void FullCodeGenerator::EmitLoadSuperConstructor() {
|
| __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
|
| __ CallRuntime(Runtime::kGetPrototype, 1);
|
| }
|
| @@ -3075,7 +3074,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
| EmitSuperConstructorCall(expr);
|
| } else {
|
| SuperReference* super_ref = callee->AsSuperReference();
|
| - EmitLoadSuperConstructor(super_ref);
|
| + EmitLoadSuperConstructor();
|
| __ push(result_register());
|
| VisitForStackValue(super_ref->this_var());
|
| EmitCall(expr, CallICState::METHOD);
|
| @@ -3148,7 +3147,7 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
| __ push(eax);
|
|
|
| SuperReference* super_ref = expr->expression()->AsSuperReference();
|
| - EmitLoadSuperConstructor(super_ref);
|
| + EmitLoadSuperConstructor();
|
| __ push(result_register());
|
|
|
| Variable* this_var = super_ref->this_var()->var();
|
| @@ -4071,6 +4070,55 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
|
| }
|
|
|
|
|
| +void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
|
| + Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
|
| + GetVar(eax, new_target_var);
|
| + __ push(eax);
|
| +
|
| + EmitLoadSuperConstructor();
|
| + __ push(result_register());
|
| +
|
| + // Check if the calling frame is an arguments adaptor frame.
|
| + Label adaptor_frame, args_set_up, runtime;
|
| + __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
|
| + __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
|
| + __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
|
| + __ j(equal, &adaptor_frame);
|
| + // default constructor has no arguments, so no adaptor frame means no args.
|
| + __ mov(eax, Immediate(0));
|
| + __ jmp(&args_set_up);
|
| +
|
| + // Copy arguments from adaptor frame.
|
| + {
|
| + __ bind(&adaptor_frame);
|
| + __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
| + __ SmiUntag(ecx);
|
| +
|
| + // Subtract 1 from arguments count, for new.target.
|
| + __ sub(ecx, Immediate(1));
|
| + __ mov(eax, ecx);
|
| + __ lea(edx, Operand(edx, ecx, times_pointer_size,
|
| + StandardFrameConstants::kCallerSPOffset));
|
| + Label loop;
|
| + __ bind(&loop);
|
| + __ push(Operand(edx, -1 * kPointerSize));
|
| + __ sub(edx, Immediate(kPointerSize));
|
| + __ dec(ecx);
|
| + __ j(not_zero, &loop);
|
| + }
|
| +
|
| + __ bind(&args_set_up);
|
| + __ mov(edi, Operand(esp, eax, times_pointer_size, 0));
|
| +
|
| + CallConstructStub stub(isolate(), SUPER_CONSTRUCTOR_CALL);
|
| + __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
|
| +
|
| + __ Drop(1);
|
| +
|
| + context()->Plug(eax);
|
| +}
|
| +
|
| +
|
| void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
|
| // Load the arguments on the stack and call the stub.
|
| RegExpConstructResultStub stub(isolate());
|
|
|