This is an automated email from the ASF dual-hosted git repository.

damjan pushed a commit to branch windows-amd64
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit 607903dd38f9217a1b2aa61f7ce75d257336de99
Author: Damjan Jovanovic <[email protected]>
AuthorDate: Fri Feb 20 04:18:44 2026 +0200

    Many fixes to the privateSnippetExecutor and callVirtualMethod
    assembly language functions on Windows/AMD64:
    - Write return values <= 8 bytes in size to *pRegisterReturn,
      instead of overwriting pRegisterReturn with it.
    - Return values > 8 bytes in size have already been written into
      *pRegisterReturn by the called function, so don't do anything
      else. Previously we were writing pRegisterReturn into
      *pRegisterReturn, corrupting it...
    - Keep the stack aligned to a 16 byte boundary after the prolog.
    - Generate .pdata and .xdata sections in the PE32+ binary
      to allow proper exception unwinding, which is necessary to allow
      both C++ and SEH exceptions to pass through functions. (On Win64,
      the only functions that are allowed to lack this static data
      describing how to unwind them, are leaf functions that don't
      touch the RBP register.)
    - Improve documentation in the comments.
    
    Patch by: me
---
 .../source/cpp_uno/msvc_win64_x86-64/call.asm      | 48 ++++++++++++++--------
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/main/bridges/source/cpp_uno/msvc_win64_x86-64/call.asm 
b/main/bridges/source/cpp_uno/msvc_win64_x86-64/call.asm
index 0b190228d8..402d7e2319 100644
--- a/main/bridges/source/cpp_uno/msvc_win64_x86-64/call.asm
+++ b/main/bridges/source/cpp_uno/msvc_win64_x86-64/call.asm
@@ -51,8 +51,8 @@ EXTERN cpp_vtable_call: PROC
 ; rbp+16 rsp+08 +----------------------------+ -------
 ;               | return address             |
 ; rbp+08 rsp--> +----------------------------+
-;               | old rbp                    |
-; rbp---------> +----------------------------+
+;               | caller's rbp               |
+; rbp---------> +----------------------------+ <------ 16 byte boundary
 ;               | pRegisterReturn memory     |
 ; rbp-08 -----> +----------------------------+
 ;               |                            |
@@ -72,11 +72,11 @@ EXTERN cpp_vtable_call: PROC
 ;
 
 privateSnippetExecutor PROC FRAME
-
        push    rbp
+       .PUSHREG rbp
        mov     rbp, rsp
+       .SETFRAME rbp, 0
        sub     rsp, 48
-       .ALLOCSTACK(48)
        .ENDPROLOG
 
        ; 4th param: sal_uInt64 *pRegisterReturn 
@@ -122,7 +122,7 @@ privateSnippetExecutor ENDP
 ; rbp+16 -----> +---------------------------------------------+ -------
 ;               | return address                              |
 ; rbp+08 -----> +---------------------------------------------+
-;               | old rbp                                     |
+;               | caller's rbp                                |
 ; rbp --------> +---------------------------------------------+ <---- 16 byte 
boundary
 ;               | (possible 16 byte alignment placeholder)    |
 ; rbp-08 -----> +---------------------------------------------+
@@ -134,8 +134,9 @@ privateSnippetExecutor ENDP
 callVirtualMethod PROC FRAME
 
        push rbp
+       .PUSHREG rbp
        mov rbp, rsp
-       .ENDPROLOG
+       .SETFRAME rbp, 0
 
        ; Save our register arguments to the shadow space:
        mov 16[rbp], rcx
@@ -143,22 +144,28 @@ callVirtualMethod PROC FRAME
        mov 32[rbp], r8
        mov 40[rbp], r9
 
-       ; We must maintain the stack aligned to a 16 byte boundary:
+       ; nStack rounded to multiple of 2, so the stack is aligned to a 16 byte 
boundary:
        mov eax, 56[rbp]
-       test eax, eax
-       jz populateArgumentRegisters
        inc eax
        shr eax, 1
        shl eax, 1
 
+       ; if nStack < 4, add (4 - nStack) empty slots to the stack:
+       mov r10d, 4
+       sub r10d, eax
+       js copyStack
+       shl r10, 3
+       sub rsp, r10
+
+copyStack:
        mov r10, rax
        shl rax, 3
        add rax, 48[rbp]
-copyStack:
+copyStackLoop:
        sub rax, 8
        push [rax]
        dec r10
-       jne copyStack
+       jne copyStackLoop
 
 populateArgumentRegisters:
        ; First 4 args are passed in registers. Floating point args needs to be
@@ -173,6 +180,9 @@ populateArgumentRegisters:
        movsd xmm2, qword ptr 16[rsp]
        mov r9, 24[rsp]
        movsd xmm3, qword ptr 24[rsp]
+
+       .ENDPROLOG
+
        
 callMethod:
        ; Find the method pointer
@@ -184,6 +194,7 @@ callMethod:
        call qword ptr [r10]
 
        mov r10d, 40[rbp]
+       mov r11, 32[rbp]
        cmp r10, typelib_TypeClass_VOID
        je cleanup
        cmp r10, typelib_TypeClass_LONG
@@ -213,30 +224,31 @@ callMethod:
 
        ; 
https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2017
        ; "The same pointer must be returned by the callee in RAX."
-       jmp Lint64
+       jmp cleanup
 
 Lint64:
-       mov 32[rbp], rax
+       mov qword ptr [r11], rax
        jmp cleanup
 
 Lint32:
-       mov 32[rbp], eax
+       mov dword ptr [r11], eax
        jmp cleanup
 
 Lint16:
-       mov 32[rbp], ax
+       mov word ptr [r11], ax
        jmp cleanup
 
 Lint8:
-       mov 32[rbp], al
+       mov byte ptr [r11], al
        jmp cleanup
 
 Lfloat:
-       movsd qword ptr 32[rbp], xmm0
+       movsd qword ptr [r11], xmm0
        jmp cleanup
 
 cleanup:
-       leave
+       lea rsp, 0[rbp]
+       pop rbp
        ret
 
 callVirtualMethod ENDP

Reply via email to