+// static
+void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- rax : the number of arguments (not including the receiver)
+ // -- rdx : the original constructor (checked to be a JSFunction)
+ // -- rdi : the constructor to call (checked to be a JSFunction)
+ // -----------------------------------
+ __ AssertFunction(rdx);
+ __ AssertFunction(rdi);
+
+ // Calling convention for function specific ConstructStubs require
+ // rbx to contain either an AllocationSite or undefined.
+ __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
+
+ // Tail call to the function-specific construct stub (still in the caller
+ // context at this point).
+ __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
+ __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset));
+ __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
+ __ jmp(rcx);
+}
+
+
+// static
+void Builtins::Generate_Construct(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- rax : the number of arguments (not including the receiver)
+ // -- rdx : the original constructor (either the same as the constructor or
+ // the JSFunction on which new was invoked initially)
+ // -- rdi : the constructor to call (can be any Object)
+ // -----------------------------------
+
+ Label slow;
+ __ JumpIfSmi(rdi, &slow, Label::kNear);
+ __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
+ __ j(equal, masm->isolate()->builtins()->ConstructFunction(),
+ RelocInfo::CODE_TARGET);
+ __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE);
+ __ j(not_equal, &slow, Label::kNear);
+
+ // TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies.
+ __ movp(rdi, FieldOperand(rdi, JSFunctionProxy::kConstructTrapOffset));
+ __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
+
+ __ bind(&slow);
+ {
+ // Determine the delegate for the target (if any).
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Integer32ToSmi(rax, rax);
+ __ Push(rax);
+ __ Push(rdi);
+ __ CallRuntime(Runtime::kGetConstructorDelegate, 1);
+ __ movp(rdi, rax);
+ __ Pop(rax);
+ __ SmiToInteger32(rax, rax);
+ }
+ // The delegate is always a regular function.
+ __ AssertFunction(rdi);
+ __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET);
+}
+
+