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

leginee pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/openoffice.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 079530e0cc Win64 bridge backport (#492)
079530e0cc is described below

commit 079530e0cc63d88d2438d6ca375766814976df0e
Author: Peter <[email protected]>
AuthorDate: Sat Aug 1 10:24:35 2026 +0000

    Win64 bridge backport (#492)
    
    * bridges/msvc_win64: pass simple argument values, not the temp's address
    
    uno2cpp.cxx converts each simple by-value argument into an 8-byte alloca
    temp and stores the pointer in pCppArgs[nPos]:
    
        uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), ... );
    
    Copying the value into the outgoing slot therefore has to dereference that
    pointer.  The marshalling switch used &pCppArgs[nPos] instead, which reads
    the pCppArgs array slot itself, i.e. the temp's address -- so every HYPER,
    LONG, ENUM, SHORT, CHAR, BOOLEAN, BYTE, FLOAT and DOUBLE parameter reached
    the callee as a stack address (or its low 16/32 bits) rather than a value.
    
    The same expression is correct in the complex/ref branch, where the pointer
    IS the argument; written there as (sal_uInt64)pCppArgs[nPos] to make the
    difference between the two branches obvious.
    
    This only affects calls that cross between the uno and cpp environments, so
    a pure-C++ session never trips it; it surfaces via pyuno and the invocation
    adapters.
    
    Co-Authored-By: Claude Opus 5 <[email protected]>
    
    * bridges/msvc_win64: return queryInterface's Any in the hidden return 
buffer
    
    The Win64 call stack is "ret addr, this, [ret *], params", so a method with
    a hidden return pointer finds it at pCallStack[2] -- cpp2uno_call() reads
    pCppReturn from [2], and the queryInterface shortcut in cpp_mediate() reads
    its Type argument from [3] accordingly.
    
    That shortcut nevertheless built the returned Any at pCallStack[1] and
    returned [1] in the register slot.  [1] is `this`, so it constructed a
    24-byte Any over the proxy object and never wrote the caller's own return
    buffer.  The caller then read and destructed an uninitialised Any, faulting
    in uno_any_destruct() on a stale stack value used as a
    typelib_TypeDescription*.
    
    The x86 bridge has always used pCallStack[2] here; the Win64 port carried
    over the x86 index, where the layout puts the hidden pointer before `this`.
    
    Reproducer: any queryInterface on a raw uno_Interface proxy -- e.g. pyuno's
    Adapter::getOutIndexes() inspecting an InvocationAdapterFactory adapter,
    which crashed on every use of the Python macro organiser.
    
    Co-Authored-By: Claude Opus 5 <[email protected]>
    
    * pre-commit: fix whitespace in the msvc_win64 bridge sources
    
    The x64 bridge backport in ebdb555ed2 brought these files over from
    origin/windows-amd64, a branch predating the tree-wide whitespace
    cleanups in #383 and #462, so it silently reintroduced trailing
    whitespace in the license headers of call.asm, cpp2uno.cxx and
    except.cxx plus a stray blank line at the end of except.cxx.
    
    Since the pre-commit workflow runs with --all-files, this fails the
    check on every pull request against trunk, not just ones touching
    these files.
    
    Co-Authored-By: Claude Opus 5 <[email protected]>
    
    ---------
    
    Co-authored-by: Claude Opus 5 <[email protected]>
---
 .../bridges/source/cpp_uno/msvc_win64_x86-64/call.asm | 10 +++++-----
 .../source/cpp_uno/msvc_win64_x86-64/cpp2uno.cxx      | 19 ++++++++++++-------
 .../source/cpp_uno/msvc_win64_x86-64/except.cxx       | 19 +++++++++----------
 .../source/cpp_uno/msvc_win64_x86-64/uno2cpp.cxx      | 18 ++++++++++++------
 4 files changed, 38 insertions(+), 28 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 402d7e2319..ebee156e3a 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
@@ -6,16 +6,16 @@
 ; to you under the Apache License, Version 2.0 (the
 ; "License"); you may not use this file except in compliance
 ; with the License.  You may obtain a copy of the License at
-; 
+;
 ;   http://www.apache.org/licenses/LICENSE-2.0
-; 
+;
 ; Unless required by applicable law or agreed to in writing,
 ; software distributed under the License is distributed on an
 ; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 ; KIND, either express or implied.  See the License for the
 ; specific language governing permissions and limitations
 ; under the License.
-; 
+;
 
 
 typelib_TypeClass_VOID equ 0
@@ -79,7 +79,7 @@ privateSnippetExecutor PROC FRAME
        sub     rsp, 48
        .ENDPROLOG
 
-       ; 4th param: sal_uInt64 *pRegisterReturn 
+       ; 4th param: sal_uInt64 *pRegisterReturn
        lea r9, -8[rbp]
 
        ; 3rd param: sal_Int32 nVtableOffset
@@ -183,7 +183,7 @@ populateArgumentRegisters:
 
        .ENDPROLOG
 
-       
+
 callMethod:
        ; Find the method pointer
        mov rax, 16[rbp]
diff --git a/main/bridges/source/cpp_uno/msvc_win64_x86-64/cpp2uno.cxx 
b/main/bridges/source/cpp_uno/msvc_win64_x86-64/cpp2uno.cxx
index 59f250784c..aa3c1a7086 100644
--- a/main/bridges/source/cpp_uno/msvc_win64_x86-64/cpp2uno.cxx
+++ b/main/bridges/source/cpp_uno/msvc_win64_x86-64/cpp2uno.cxx
@@ -1,5 +1,5 @@
 /**************************************************************
- * 
+ *
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -7,16 +7,16 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  *   http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- * 
+ *
  *************************************************************/
 
 
@@ -301,13 +301,18 @@ extern "C" typelib_TypeClass cpp_vtable_call(
 
                                if ( pInterface )
                                {
-                                   ::uno_any_construct( 
reinterpret_cast<uno_Any *>( pCallStack[1] ),
+                                   // pCallStack is "ret addr, this, [ret *], 
params", so the
+                                   // hidden return buffer is [2]; [1] is 
`this`.  Writing the
+                                   // Any to [1] overwrote the proxy object 
and left the
+                                   // caller's return buffer untouched, so the 
caller then
+                                   // destructed an uninitialised Any.
+                                   ::uno_any_construct( 
reinterpret_cast<uno_Any *>( pCallStack[2] ),
                                                                                
                 &pInterface, pTD, cpp_acquire );
 
                                    pInterface->release();
                                    TYPELIB_DANGER_RELEASE( pTD );
 
-                                   reinterpret_cast<void **>( pRegisterReturn 
)[0] = pCallStack[1];
+                                   reinterpret_cast<void **>( pRegisterReturn 
)[0] = pCallStack[2];
                                    eRet = typelib_TypeClass_ANY;
                                    break;
                                }
@@ -366,7 +371,7 @@ unsigned char * codeSnippet(
     //  rsp+08 +----------------------------+ -------
     //         | return address             |
     //  rsp--> +----------------------------+
-    // 
+    //
     //
 
     // When it doubt about correctness,
diff --git a/main/bridges/source/cpp_uno/msvc_win64_x86-64/except.cxx 
b/main/bridges/source/cpp_uno/msvc_win64_x86-64/except.cxx
index 98218480ab..d689dccd6e 100644
--- a/main/bridges/source/cpp_uno/msvc_win64_x86-64/except.cxx
+++ b/main/bridges/source/cpp_uno/msvc_win64_x86-64/except.cxx
@@ -1,5 +1,5 @@
 /**************************************************************
- * 
+ *
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -7,16 +7,16 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  *   http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- * 
+ *
  *************************************************************/
 
 
@@ -486,7 +486,7 @@ ExceptionInfos::~ExceptionInfos() throw ()
 #if OSL_DEBUG_LEVEL > 1
        OSL_TRACE( "> freeing exception infos... <\n" );
 #endif
-    
+
        MutexGuard aGuard( _aMutex );
        for ( t_string2PtrMap::const_iterator iPos( _allRaiseInfos.begin() );
           iPos != _allRaiseInfos.end(); ++iPos )
@@ -608,7 +608,7 @@ int mscx_filterCppException(
     // handle only C++ exceptions:
        if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
         return EXCEPTION_CONTINUE_SEARCH;
-    
+
 #if _MSC_VER < 1300 // MSVC -6
     bool rethrow = (pRecord->NumberParameters < 4 ||
                     pRecord->ExceptionInformation[ 2 ] == 0);
@@ -633,7 +633,7 @@ int mscx_filterCppException(
     // rethrow: handle only C++ exceptions:
        if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
         return EXCEPTION_CONTINUE_SEARCH;
-    
+
     if (pRecord->NumberParameters == 4 &&
 //             pRecord->ExceptionInformation[ 0 ] == MSVC_magic_number &&
                pRecord->ExceptionInformation[ 1 ] != 0 &&
@@ -655,7 +655,7 @@ int mscx_filterCppException(
                             baseAddress + pType->_pTypeInfo )->_m_d_name,
                         RTL_TEXTENCODING_ASCII_US ) );
                                OUString aUNOname( toUNOname( aRTTIname ) );
-                
+
                                typelib_TypeDescription * pExcTypeDescr = 0;
                                typelib_typedescription_getByName(
                     &pExcTypeDescr, aUNOname.pData );
@@ -699,7 +699,7 @@ int mscx_filterCppException(
 #endif
                                        typelib_typedescription_release( 
pExcTypeDescr );
                                }
-                
+
                                return EXCEPTION_EXECUTE_HANDLER;
                        }
                }
@@ -719,4 +719,3 @@ int mscx_filterCppException(
 }
 
 #pragma pack(pop)
-
diff --git a/main/bridges/source/cpp_uno/msvc_win64_x86-64/uno2cpp.cxx 
b/main/bridges/source/cpp_uno/msvc_win64_x86-64/uno2cpp.cxx
index 2f8e80ca4d..b9e43adb45 100644
--- a/main/bridges/source/cpp_uno/msvc_win64_x86-64/uno2cpp.cxx
+++ b/main/bridges/source/cpp_uno/msvc_win64_x86-64/uno2cpp.cxx
@@ -105,29 +105,34 @@ static void cpp_call(
                        uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), 
pUnoArgs[nPos], pParamTypeDescr,
                                                                        
pThis->getBridge()->getUno2Cpp() );
 
+                       // pCppArgs[nPos] is the alloca(8) temp above, i.e. a 
POINTER to the
+                       // converted value -- the value is *pCppArgs[nPos].  
Using
+                       // &pCppArgs[nPos] would read the array slot instead, 
passing the
+                       // temp's address as the argument.  (That form is 
correct only in the
+                       // complex/ref branch below, where the pointer IS the 
argument.)
                        switch (pParamTypeDescr->eTypeClass)
                        {
                        case typelib_TypeClass_HYPER:
                        case typelib_TypeClass_UNSIGNED_HYPER:
-                               *pStack++ = *(sal_uInt64*)&pCppArgs[nPos];
+                               *pStack++ = *(sal_uInt64*)pCppArgs[nPos];
                                break;
                        case typelib_TypeClass_LONG:
                        case typelib_TypeClass_UNSIGNED_LONG:
                        case typelib_TypeClass_ENUM:
-                               *pStack++ = *(sal_uInt32*)&pCppArgs[nPos];
+                               *pStack++ = *(sal_uInt32*)pCppArgs[nPos];
                                break;
                        case typelib_TypeClass_SHORT:
                        case typelib_TypeClass_UNSIGNED_SHORT:
                        case typelib_TypeClass_CHAR:
-                               *pStack++ = *(sal_uInt16*)&pCppArgs[nPos];
+                               *pStack++ = *(sal_uInt16*)pCppArgs[nPos];
                                break;
                        case typelib_TypeClass_BOOLEAN:
                        case typelib_TypeClass_BYTE:
-                               *pStack++ = *(sal_uInt8*)&pCppArgs[nPos];
+                               *pStack++ = *(sal_uInt8*)pCppArgs[nPos];
                                break;
                        case typelib_TypeClass_FLOAT:
                        case typelib_TypeClass_DOUBLE:
-                               *pStack++ = *(sal_uInt64*)&pCppArgs[nPos]; // 
verbatim!
+                               *pStack++ = *(sal_uInt64*)pCppArgs[nPos]; // 
verbatim!
                 break;
             default:
                 break;
@@ -164,7 +169,8 @@ static void cpp_call(
                                // no longer needed
                                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
                        }
-                       *pStack++ = *(sal_uInt64*)&pCppArgs[nPos];
+                       // here the POINTER is the argument (complex value 
passed by ref)
+                       *pStack++ = (sal_uInt64)pCppArgs[nPos];
                }
        }
 

Reply via email to