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()); |