michael@0: ; This Source Code Form is subject to the terms of the Mozilla Public michael@0: ; License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: ; file, You can obtain one at http://mozilla.org/MPL/2.0/. michael@0: michael@0: extrn invoke_copy_to_stack:PROC michael@0: michael@0: michael@0: .CODE michael@0: michael@0: ; michael@0: ;XPTC__InvokebyIndex(nsISupports* that, uint32_t methodIndex, michael@0: ; uint32_t paramCount, nsXPTCVariant* params) michael@0: ; michael@0: michael@0: XPTC__InvokebyIndex PROC FRAME michael@0: michael@0: ; store register parameters michael@0: michael@0: mov qword ptr [rsp+32], r9 ; params michael@0: mov dword ptr [rsp+24], r8d ; paramCount michael@0: mov dword ptr [rsp+16], edx ; methodIndex michael@0: mov qword ptr [rsp+8], rcx ; that michael@0: michael@0: push rbp michael@0: .PUSHREG rbp michael@0: mov rbp, rsp ; store current RSP to RBP michael@0: .SETFRAME rbp, 0 michael@0: .ENDPROLOG michael@0: michael@0: sub rsp, 32 michael@0: michael@0: ; maybe we don't have any parameters to copy michael@0: michael@0: test r8d, r8d michael@0: jz noparams michael@0: michael@0: ; michael@0: ; Build stack for stdcall michael@0: ; michael@0: michael@0: ; 1st parameter is space for parameters michael@0: michael@0: mov eax, r8d michael@0: or eax, 1 michael@0: shl rax, 3 ; *= 8 michael@0: sub rsp, rax michael@0: mov rcx, rsp michael@0: michael@0: ; 2nd parameter is parameter count michael@0: michael@0: mov edx, r8d michael@0: michael@0: ; 3rd parameter is params michael@0: michael@0: mov r8, r9 michael@0: michael@0: sub rsp, 40 michael@0: call invoke_copy_to_stack ; rcx = d michael@0: ; edx = paramCount michael@0: ; r8 = s michael@0: add rsp, 32 michael@0: michael@0: ; Current stack is the following. michael@0: ; michael@0: ; 0h: [space (for this)] michael@0: ; 8h: [1st parameter] michael@0: ; 10h: [2nd parameter] michael@0: ; 18h: [3rd parameter] michael@0: ; 20h: [4th parameter] michael@0: ; ... michael@0: ; michael@0: ; On Win64 ABI, the first 4 parameters are passed using registers, michael@0: ; and others are on stack. michael@0: michael@0: ; 1st, 2nd and 3rd arguments are passed via registers michael@0: michael@0: mov rdx, qword ptr [rsp+8] ; 1st parameter michael@0: movsd xmm1, qword ptr [rsp+8] ; for double michael@0: michael@0: mov r8, qword ptr [rsp+16] ; 2nd parameter michael@0: movsd xmm2, qword ptr [rsp+16] ; for double michael@0: michael@0: mov r9, qword ptr [rsp+24] ; 3rd parameter michael@0: movsd xmm3, qword ptr [rsp+24] ; for double michael@0: michael@0: ; rcx register is this michael@0: michael@0: mov rcx, qword ptr [rbp+8+8] ; that michael@0: michael@0: noparams: michael@0: michael@0: ; calculate call address michael@0: michael@0: mov r11, qword ptr [rcx] michael@0: mov eax, dword ptr [rbp+16+8] ; methodIndex michael@0: michael@0: call qword ptr [r11+rax*8] ; stdcall, i.e. callee cleans up stack. michael@0: michael@0: mov rsp, rbp michael@0: pop rbp michael@0: michael@0: ret michael@0: michael@0: XPTC__InvokebyIndex ENDP michael@0: michael@0: michael@0: END