[Libreoffice-commits] core.git: bridges/source

Caolán McNamara caolanm at redhat.com
Fri Aug 22 05:35:17 PDT 2014


 bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx |   15 ++--
 bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx   |    1 
 bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx |   50 ++++++++++++++++
 3 files changed, 58 insertions(+), 8 deletions(-)

New commits:
commit 970ad502e3ea2cc992c6cc1c7583231aec5bf5da
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Aug 22 13:31:03 2014 +0100

    Related: rhbz#1125588 ppc64le has new struct passing rules
    
    http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01145.html
    http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01147.html
    
    now we just fail instead of crash
    
    Change-Id: I329c676337885bcf4fdfdcdb5912d75424862126

diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
index c0ca97f..dbdef1b 100644
--- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
@@ -72,7 +72,7 @@ static typelib_TypeClass cpp2uno_call(
 
     if (pReturnTypeDescr)
     {
-        if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+        if (!ppc64::return_in_hidden_param(pReturnTypeRef))
         {
             pUnoReturn = pRegisterReturn; // direct way for simple types
         }
@@ -599,7 +599,7 @@ const int codeSnippetSize = 24;
 #endif
 
 unsigned char *  codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
-                              bool simpleRetType)
+                              bool bHasHiddenParam)
 {
 #if OSL_DEBUG_LEVEL > 2
     fprintf(stderr,"in codeSnippet functionIndex is %x\n", nFunctionIndex);
@@ -608,9 +608,8 @@ unsigned char *  codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sa
 
     sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
 
-    if ( !simpleRetType )
+    if ( bHasHiddenParam )
         nOffsetAndIndex |= 0x80000000;
-
 #if _CALL_ELF == 2
     unsigned int *raw = (unsigned int *)&code[0];
 
@@ -629,7 +628,7 @@ unsigned char *  codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sa
 #endif
 #if OSL_DEBUG_LEVEL > 2
     fprintf(stderr, "in: offset/index is %x %x %d, %lx\n",
-    nFunctionIndex, nVtableOffset, !simpleRetType, raw[2]);
+    nFunctionIndex, nVtableOffset, bHasHiddenParam, raw[2]);
 #endif
     return (code + codeSnippetSize);
 }
@@ -696,7 +695,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
             (s++)->fn = code + writetoexecdiff;
             code = codeSnippet(
                 code, functionOffset++, vtableOffset,
-                bridges::cpp_uno::shared::isSimpleType(
+                ppc64::return_in_hidden_param(
                     reinterpret_cast<
                     typelib_InterfaceAttributeTypeDescription * >(
                         member)->pAttributeTypeRef));
@@ -707,7 +706,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
                     member)->bReadOnly)
             {
                 (s++)->fn = code + writetoexecdiff;
-                code = codeSnippet(code, functionOffset++, vtableOffset, true);
+                code = codeSnippet(code, functionOffset++, vtableOffset, false);
             }
             break;
 
@@ -715,7 +714,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
             (s++)->fn = code + writetoexecdiff;
             code = codeSnippet(
                 code, functionOffset++, vtableOffset,
-                bridges::cpp_uno::shared::isSimpleType(
+                ppc64::return_in_hidden_param(
                     reinterpret_cast<
                     typelib_InterfaceMethodTypeDescription * >(
                         member)->pReturnTypeRef));
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
index 87303b6..b5f609a 100644
--- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
@@ -85,6 +85,7 @@ void fillUnoException(
 namespace ppc64
 {
     enum ppclimits { MAX_GPR_REGS = 8, MAX_SSE_REGS = 13 };
+    bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
 }
 
 #endif
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
index 33131ea..55a5308 100644
--- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
@@ -37,6 +37,56 @@
 using namespace ::rtl;
 using namespace ::com::sun::star::uno;
 
+namespace ppc64
+{
+#if _CALL_ELF == 2
+    bool is_complex_struct(const typelib_TypeDescription * type)
+    {
+        const typelib_CompoundTypeDescription * p
+            = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
+        for (sal_Int32 i = 0; i < p->nMembers; ++i)
+        {
+            if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
+                p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
+            {
+                typelib_TypeDescription * t = 0;
+                TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
+                bool b = is_complex_struct(t);
+                TYPELIB_DANGER_RELEASE(t);
+                if (b) {
+                    return true;
+                }
+            }
+            else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
+                return true;
+        }
+        if (p->pBaseTypeDescription != 0)
+            return is_complex_struct(&p->pBaseTypeDescription->aBase);
+        return false;
+    }
+#endif
+
+    bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
+    {
+        if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
+            return false;
+#if _CALL_ELF == 2
+        else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
+        {
+            typelib_TypeDescription * pTypeDescr = 0;
+            TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+            //A Composite Type not larger than 16 bytes is returned in up to two GPRs
+            bool bRet = pTypeDescr->nSize > 16 || is_complex_struct(pTypeDescr);
+
+            TYPELIB_DANGER_RELEASE( pTypeDescr );
+            return bRet;
+        }
+#endif
+        return true;
+    }
+}
+
 void MapReturn(long r3, double dret, typelib_TypeClass eTypeClass, void *pRegisterReturn)
 {
     switch (eTypeClass)


More information about the Libreoffice-commits mailing list