summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2010-12-09 12:00:50 +0000
committerCaolán McNamara <caolanm@redhat.com>2010-12-09 12:00:50 +0000
commit3358b4f31190b02a350da6a56e54d8e3fb306b9e (patch)
tree76c8bd8490cf7392f5670adbaefa7b3ebc38200b
parent10031bb5bd81412c96fb1af979ae1eb7aa3caacd (diff)
fix bsd bridges
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx55
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/share.hxx6
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx59
3 files changed, 105 insertions, 15 deletions
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx
index ac9ac4233f23..84c05578bf5b 100644
--- a/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx
@@ -68,7 +68,7 @@ void cpp2uno_call(
68 68
69 if (pReturnTypeDescr) 69 if (pReturnTypeDescr)
70 { 70 {
71 if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr )) 71 if (x86::isSimpleReturnType( pReturnTypeDescr ))
72 { 72 {
73 pUnoReturn = pReturnValue; // direct way for simple types 73 pUnoReturn = pReturnValue; // direct way for simple types
74 } 74 }
@@ -359,15 +359,39 @@ extern "C" typedef void (*PrivateSnippetExecutor)();
359 359
360int const codeSnippetSize = 16; 360int const codeSnippetSize = 16;
361 361
362#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX)
363namespace
364{
365 PrivateSnippetExecutor returnsInRegister(typelib_TypeDescriptionReference * pReturnTypeRef)
366 {
367 //These archs apparently are returning small structs in registers, while Linux
368 //doesn't
369 PrivateSnippetExecutor exec=NULL;
370
371 typelib_TypeDescription * pReturnTypeDescr = 0;
372 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
373 const bool bSimpleReturnStruct = x86::isSimpleReturnType(pReturnTypeDescr);
374 const sal_Int32 nRetSize = pReturnTypeDescr->nSize;
375 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
376 if (bSimpleReturnStruct)
377 {
378 exec = privateSnippetExecutorGeneral; // fills eax
379 if (nRetSize > 4)
380 exec = privateSnippetExecutorHyper; // fills eax/edx
381 }
382 return exec;
383 }
384}
385#endif
386
362unsigned char * codeSnippet( 387unsigned char * codeSnippet(
363 unsigned char * code, sal_PtrDiff writetoexecdiff, sal_Int32 functionIndex, sal_Int32 vtableOffset, 388 unsigned char * code, sal_PtrDiff writetoexecdiff, sal_Int32 functionIndex, sal_Int32 vtableOffset,
364 typelib_TypeClass returnTypeClass) 389 typelib_TypeDescriptionReference * pReturnTypeRef)
365{ 390{
366 if (!bridges::cpp_uno::shared::isSimpleType(returnTypeClass)) {
367 functionIndex |= 0x80000000;
368 }
369 PrivateSnippetExecutor exec; 391 PrivateSnippetExecutor exec;
370 switch (returnTypeClass) { 392 typelib_TypeClass eReturnClass = pReturnTypeRef ? pReturnTypeRef->eTypeClass : typelib_TypeClass_VOID;
393 switch (eReturnClass)
394 {
371 case typelib_TypeClass_VOID: 395 case typelib_TypeClass_VOID:
372 exec = privateSnippetExecutorVoid; 396 exec = privateSnippetExecutorVoid;
373 break; 397 break;
@@ -381,13 +405,24 @@ unsigned char * codeSnippet(
381 case typelib_TypeClass_DOUBLE: 405 case typelib_TypeClass_DOUBLE:
382 exec = privateSnippetExecutorDouble; 406 exec = privateSnippetExecutorDouble;
383 break; 407 break;
408 case typelib_TypeClass_STRUCT:
409 case typelib_TypeClass_EXCEPTION:
410#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX)
411 exec = returnsInRegister(pReturnTypeRef);
412 if (!exec)
413 {
414 exec = privateSnippetExecutorClass;
415 functionIndex |= 0x80000000;
416 }
417 break;
418#endif
384 case typelib_TypeClass_STRING: 419 case typelib_TypeClass_STRING:
385 case typelib_TypeClass_TYPE: 420 case typelib_TypeClass_TYPE:
386 case typelib_TypeClass_ANY: 421 case typelib_TypeClass_ANY:
387 case typelib_TypeClass_SEQUENCE: 422 case typelib_TypeClass_SEQUENCE:
388 case typelib_TypeClass_STRUCT:
389 case typelib_TypeClass_INTERFACE: 423 case typelib_TypeClass_INTERFACE:
390 exec = privateSnippetExecutorClass; 424 exec = privateSnippetExecutorClass;
425 functionIndex |= 0x80000000;
391 break; 426 break;
392 default: 427 default:
393 exec = privateSnippetExecutorGeneral; 428 exec = privateSnippetExecutorGeneral;
@@ -455,7 +490,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
455 code = codeSnippet( 490 code = codeSnippet(
456 code, writetoexecdiff, functionOffset++, vtableOffset, 491 code, writetoexecdiff, functionOffset++, vtableOffset,
457 reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >( 492 reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
458 member)->pAttributeTypeRef->eTypeClass); 493 member)->pAttributeTypeRef);
459 // Setter: 494 // Setter:
460 if (!reinterpret_cast< 495 if (!reinterpret_cast<
461 typelib_InterfaceAttributeTypeDescription * >( 496 typelib_InterfaceAttributeTypeDescription * >(
@@ -464,7 +499,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
464 (s++)->fn = code + writetoexecdiff; 499 (s++)->fn = code + writetoexecdiff;
465 code = codeSnippet( 500 code = codeSnippet(
466 code, writetoexecdiff, functionOffset++, vtableOffset, 501 code, writetoexecdiff, functionOffset++, vtableOffset,
467 typelib_TypeClass_VOID); 502 NULL);
468 } 503 }
469 break; 504 break;
470 505
@@ -473,7 +508,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
473 code = codeSnippet( 508 code = codeSnippet(
474 code, writetoexecdiff, functionOffset++, vtableOffset, 509 code, writetoexecdiff, functionOffset++, vtableOffset,
475 reinterpret_cast< typelib_InterfaceMethodTypeDescription * >( 510 reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
476 member)->pReturnTypeRef->eTypeClass); 511 member)->pReturnTypeRef);
477 break; 512 break;
478 513
479 default: 514 default:
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx b/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx
index da2367ad172b..8a3e136bfb7b 100644
--- a/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx
@@ -88,6 +88,12 @@ void raiseException(
88//================================================================================================== 88//==================================================================================================
89void fillUnoException( 89void fillUnoException(
90 __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno ); 90 __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
91
92}
93
94namespace x86
95{
96 bool isSimpleReturnType(typelib_TypeDescription * pTD, bool recursive = false);
91} 97}
92 98
93/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 99/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx
index 035dab08d848..6af5b4aa7274 100644
--- a/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx
@@ -59,7 +59,7 @@ void callVirtualMethod(
59 void * pAdjustedThisPtr, 59 void * pAdjustedThisPtr,
60 sal_Int32 nVtableIndex, 60 sal_Int32 nVtableIndex,
61 void * pRegisterReturn, 61 void * pRegisterReturn,
62 typelib_TypeClass eReturnType, 62 typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
63 sal_Int32 * pStackLongs, 63 sal_Int32 * pStackLongs,
64 sal_Int32 nStackLongs ) __attribute__((noinline)); 64 sal_Int32 nStackLongs ) __attribute__((noinline));
65 65
@@ -67,7 +67,7 @@ void callVirtualMethod(
67 void * pAdjustedThisPtr, 67 void * pAdjustedThisPtr,
68 sal_Int32 nVtableIndex, 68 sal_Int32 nVtableIndex,
69 void * pRegisterReturn, 69 void * pRegisterReturn,
70 typelib_TypeClass eReturnType, 70 typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
71 sal_Int32 * pStackLongs, 71 sal_Int32 * pStackLongs,
72 sal_Int32 nStackLongs ) 72 sal_Int32 nStackLongs )
73{ 73{
@@ -120,8 +120,10 @@ void callVirtualMethod(
120 : "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr), 120 : "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr),
121 "m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr) 121 "m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr)
122 : "eax", "edx" ); 122 : "eax", "edx" );
123 switch( eReturnType ) 123 switch( pReturnTypeDescr->eTypeClass )
124 { 124 {
125 case typelib_TypeClass_VOID:
126 break;
125 case typelib_TypeClass_HYPER: 127 case typelib_TypeClass_HYPER:
126 case typelib_TypeClass_UNSIGNED_HYPER: 128 case typelib_TypeClass_UNSIGNED_HYPER:
127 ((long*)pRegisterReturn)[1] = edx; 129 ((long*)pRegisterReturn)[1] = edx;
@@ -146,7 +148,20 @@ void callVirtualMethod(
146 asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) ); 148 asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) );
147 break; 149 break;
148 default: 150 default:
151 {
152#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX)
153 sal_Int32 const nRetSize = pReturnTypeDescr->nSize;
154 if (bSimpleReturn && nRetSize <= 8 && nRetSize > 0)
155 {
156 if (nRetSize > 4)
157 static_cast<long *>(pRegisterReturn)[1] = edx;
158 static_cast<long *>(pRegisterReturn)[0] = eax;
159 }
160#else
161 (void)bSimpleReturn;
162#endif
149 break; 163 break;
164 }
150 } 165 }
151} 166}
152 167
@@ -169,10 +184,12 @@ static void cpp_call(
169 OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" ); 184 OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
170 185
171 void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion 186 void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
187 bool bSimpleReturn = true;
172 188
173 if (pReturnTypeDescr) 189 if (pReturnTypeDescr)
174 { 190 {
175 if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr )) 191 bSimpleReturn = x86::isSimpleReturnType(pReturnTypeDescr);
192 if (bSimpleReturn)
176 { 193 {
177 pCppReturn = pUnoReturn; // direct way for simple types 194 pCppReturn = pUnoReturn; // direct way for simple types
178 } 195 }
@@ -269,7 +286,7 @@ static void cpp_call(
269 OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" ); 286 OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
270 callVirtualMethod( 287 callVirtualMethod(
271 pAdjustedThisPtr, aVtableSlot.index, 288 pAdjustedThisPtr, aVtableSlot.index,
272 pCppReturn, pReturnTypeDescr->eTypeClass, 289 pCppReturn, pReturnTypeDescr, bSimpleReturn,
273 (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) ); 290 (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
274 // NO exception occurred... 291 // NO exception occurred...
275 *ppUnoExc = 0; 292 *ppUnoExc = 0;
@@ -328,6 +345,38 @@ static void cpp_call(
328 345
329} 346}
330 347
348namespace x86
349{
350 bool isSimpleReturnType(typelib_TypeDescription * pTD, bool recursive)
351 {
352 if (bridges::cpp_uno::shared::isSimpleType( pTD ))
353 return true;
354#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX)
355 // Only structs of exactly 1, 2, 4, or 8 bytes are returned through
356 // registers, see <http://developer.apple.com/documentation/DeveloperTools/
357 // Conceptual/LowLevelABI/Articles/IA32.html>:
358 if (pTD->eTypeClass == typelib_TypeClass_STRUCT &&
359 (recursive || pTD->nSize <= 2 || pTD->nSize == 4 || pTD->nSize == 8))
360 {
361 typelib_CompoundTypeDescription *const pCompTD =
362 (typelib_CompoundTypeDescription *) pTD;
363 for ( sal_Int32 pos = pCompTD->nMembers; pos--; ) {
364 typelib_TypeDescription * pMemberTD = 0;
365 TYPELIB_DANGER_GET( &pMemberTD, pCompTD->ppTypeRefs[pos] );
366 bool const b = isSimpleReturnType(pMemberTD, true);
367 TYPELIB_DANGER_RELEASE( pMemberTD );
368 if (! b)
369 return false;
370 }
371 return true;
372 }
373#else
374 (void)recursive;
375#endif
376 return false;
377 }
378}
379
331namespace bridges { namespace cpp_uno { namespace shared { 380namespace bridges { namespace cpp_uno { namespace shared {
332 381
333void unoInterfaceProxyDispatch( 382void unoInterfaceProxyDispatch(