diff options
author | Caolán McNamara <caolanm@redhat.com> | 2010-12-09 12:00:50 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2010-12-09 12:00:50 +0000 |
commit | 3358b4f31190b02a350da6a56e54d8e3fb306b9e (patch) | |
tree | 76c8bd8490cf7392f5670adbaefa7b3ebc38200b | |
parent | 10031bb5bd81412c96fb1af979ae1eb7aa3caacd (diff) |
fix bsd bridges
-rw-r--r-- | bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx | 55 | ||||
-rw-r--r-- | bridges/source/cpp_uno/gcc3_linux_intel/share.hxx | 6 | ||||
-rw-r--r-- | bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx | 59 |
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 | ||
360 | int const codeSnippetSize = 16; | 360 | int const codeSnippetSize = 16; |
361 | 361 | ||
362 | #if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX) | ||
363 | namespace | ||
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 | |||
362 | unsigned char * codeSnippet( | 387 | unsigned 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 | //================================================================================================== |
89 | void fillUnoException( | 89 | void fillUnoException( |
90 | __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno ); | 90 | __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno ); |
91 | |||
92 | } | ||
93 | |||
94 | namespace 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 | ||
348 | namespace 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 | |||
331 | namespace bridges { namespace cpp_uno { namespace shared { | 380 | namespace bridges { namespace cpp_uno { namespace shared { |
332 | 381 | ||
333 | void unoInterfaceProxyDispatch( | 382 | void unoInterfaceProxyDispatch( |