merge the formfield patch from ooo-build
[ooovba.git] / bridges / source / cpp_uno / cc50_solaris_intel / except.cxx
blob1e2f8c1a321b9f5c1f755ecfbbea92698e614b08
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: except.cxx,v $
10 * $Revision: 1.18 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_bridges.hxx"
34 #include <cstddef>
35 #include <dlfcn.h>
36 #include <new.h>
37 #include <typeinfo>
38 #include <list>
39 #include <map>
40 #include <rtl/alloc.h>
41 #include <osl/diagnose.h>
43 #include <rtl/strbuf.hxx>
44 #include <typelib/typedescription.hxx>
45 #include <com/sun/star/uno/Any.hxx>
47 #include "bridges/cpp_uno/shared/arraypointer.hxx"
49 #include "cc50_solaris_intel.hxx"
51 #include <hash.cxx>
53 // need a += operator for OString and sal_Char
54 namespace rtl
56 inline OString& operator+=( OString& rString, sal_Char cAdd )
58 sal_Char add[2];
59 add[0] = cAdd;
60 add[1] = 0;
61 return rString += add;
65 using namespace std;
66 using namespace osl;
67 using namespace rtl;
68 using namespace com::sun::star::uno;
70 namespace CPPU_CURRENT_NAMESPACE
73 static OString toUNOname( const OString & rRTTIname )
75 OString aRet;
77 const sal_Char* pRTTI = rRTTIname.getStr();
78 const sal_Char* pOrg = pRTTI;
79 const sal_Char* pLast = pRTTI;
81 while( 1 )
83 if( *pRTTI == ':' || ! *pRTTI )
85 if( aRet.getLength() )
86 aRet += ".";
87 aRet += rRTTIname.copy( pLast - pOrg, pRTTI - pLast );
88 while( *pRTTI == ':' )
89 pRTTI++;
90 pLast = pRTTI;
91 if( ! *pRTTI )
92 break;
94 else
95 pRTTI++;
98 return aRet;
100 //==================================================================================================
101 static OString toRTTIname( const OString & rUNOname )
103 OStringBuffer aRet( rUNOname.getLength()*2 );
105 sal_Int32 nIndex = 0;
108 if( nIndex > 0 )
109 aRet.append( "::" );
110 aRet.append( rUNOname.getToken( 0, '.', nIndex ) );
111 } while( nIndex != -1 );
113 return aRet.makeStringAndClear();
115 //==================================================================================================
117 static OString toRTTImangledname( const OString & rRTTIname )
119 if( ! rRTTIname.getLength() )
120 return OString();
122 OStringBuffer aRet( rRTTIname.getLength()*2 );
124 aRet.append( "__1n" );
125 sal_Int32 nIndex = 0;
128 OString aToken( rRTTIname.getToken( 0, ':', nIndex ) );
129 int nBytes = aToken.getLength();
130 if( nBytes )
132 if( nBytes > 25 )
134 aRet.append( (sal_Char)( nBytes/26 + 'a' ) );
135 aRet.append( (sal_Char)( nBytes%26 + 'A' ) );
137 else
138 aRet.append( (sal_Char)( nBytes + 'A' ) );
139 for (sal_Int32 i = 0; i < aToken.getLength(); ++i) {
140 char c = aToken[i];
141 if (c == 'Q') {
142 aRet.append("QdD");
143 } else {
144 aRet.append(c);
148 } while( nIndex != -1 );
150 aRet.append( '_' );
152 return aRet.makeStringAndClear();
155 //##################################################################################################
156 //#### RTTI simulation #############################################################################
157 //##################################################################################################
159 class RTTIHolder
161 std::map< OString, void* > aAllRTTI;
162 public:
163 ~RTTIHolder();
165 void* getRTTI( const OString& rTypename );
166 void* getRTTI_UnoName( const OString& rUnoTypename )
167 { return getRTTI( toRTTIname( rUnoTypename ) ); }
169 void* insertRTTI( const OString& rTypename );
170 void* insertRTTI_UnoName( const OString& rTypename )
171 { return insertRTTI( toRTTIname( rTypename ) ); }
172 void* generateRTTI( typelib_CompoundTypeDescription* pCompTypeDescr );
175 RTTIHolder::~RTTIHolder()
177 for ( std::map< OString, void* >::const_iterator iPos( aAllRTTI.begin() );
178 iPos != aAllRTTI.end(); ++iPos )
180 delete[] static_cast< char * >(iPos->second);
184 #if OSL_DEBUG_LEVEL > 1
185 #include <stdio.h>
186 #endif
188 void* RTTIHolder::getRTTI( const OString& rTypename )
190 std::map< OString, void* >::iterator element;
192 element = aAllRTTI.find( rTypename );
193 if( element != aAllRTTI.end() )
194 return (*element).second;
196 // create rtti structure
197 element = aAllRTTI.find( rTypename );
198 if( element != aAllRTTI.end() )
199 return (*element).second;
201 return NULL;
204 static long nMagicId = 1;
206 void* RTTIHolder::insertRTTI( const OString& rTypename )
208 OString aMangledName( toRTTImangledname( rTypename ) );
209 NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
212 // rSuperTypename MUST exist !!!
213 std::size_t const RTTI_SIZE = 19; // 14???
214 void** pRTTI = reinterpret_cast< void ** >(
215 new char[RTTI_SIZE * sizeof (void *) + strlen(rTypename.getStr()) + 1]);
216 pRTTI[ 0 ] = reinterpret_cast< void * >(RTTI_SIZE * sizeof (void *));
217 pRTTI[ 1 ] = NULL;
218 pRTTI[ 2 ] = (void*)(7*sizeof(void*));
219 pRTTI[ 3 ] = (void*)aHash.getHash()[0];
220 pRTTI[ 4 ] = (void*)aHash.getHash()[1];
221 pRTTI[ 5 ] = (void*)aHash.getHash()[2];
222 pRTTI[ 6 ] = (void*)aHash.getHash()[3];
223 pRTTI[ 7 ] = NULL;
224 pRTTI[ 8 ] = NULL;
226 pRTTI[ 9 ] = pRTTI[ 3 ];
227 pRTTI[ 10 ] = pRTTI[ 4 ];
228 pRTTI[ 11 ] = pRTTI[ 5 ];
229 pRTTI[ 12 ] = pRTTI[ 6 ];
230 pRTTI[ 13 ] = (void*)0x80000000;
231 strcpy(reinterpret_cast< char * >(pRTTI + RTTI_SIZE), rTypename.getStr());
233 aAllRTTI[ rTypename ] = (void*)pRTTI;
234 #if OSL_DEBUG_LEVEL > 1
235 fprintf( stderr,
236 "generating base RTTI for type %s:\n"
237 " mangled: %s\n"
238 " hash: %.8x %.8x %.8x %.8x\n",
239 rTypename.getStr(),
240 aMangledName.getStr(),
241 pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ]
243 #endif
244 return pRTTI;
247 void* RTTIHolder::generateRTTI( typelib_CompoundTypeDescription * pCompTypeDescr )
249 OString aUNOCompTypeName( OUStringToOString( pCompTypeDescr->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US ) );
250 OString aRTTICompTypeName( toRTTIname( aUNOCompTypeName ) );
252 void* pHaveRTTI = getRTTI( aRTTICompTypeName );
253 if( pHaveRTTI )
254 return pHaveRTTI;
256 if( ! pCompTypeDescr->pBaseTypeDescription )
257 // this is a base type
258 return insertRTTI( aRTTICompTypeName );
260 // get base class RTTI
261 void* pSuperRTTI = generateRTTI( pCompTypeDescr->pBaseTypeDescription );
262 OSL_ENSURE( pSuperRTTI, "could not generate RTTI for supertype !" );
264 // find out the size to allocate for RTTI
265 void** pInherit = (void**)((sal_uInt32)pSuperRTTI + ((sal_uInt32*)pSuperRTTI)[2] + 8);
266 int nInherit;
267 for( nInherit = 1; pInherit[ nInherit*5-1 ] != (void*)0x80000000; nInherit++ )
270 OString aMangledName( toRTTImangledname( aRTTICompTypeName ) );
271 NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
273 std::size_t const rttiSize = 14 + nInherit * 5;
274 void** pRTTI = reinterpret_cast< void ** >(
275 new char[
276 rttiSize * sizeof (void *)
277 + strlen(aRTTICompTypeName.getStr()) + 1]);
278 pRTTI[ 0 ] = reinterpret_cast< void * >(rttiSize * sizeof (void *));
279 pRTTI[ 1 ] = NULL;
280 pRTTI[ 2 ] = (void*)(7*sizeof(void*));
281 pRTTI[ 3 ] = (void*)aHash.getHash()[0];
282 pRTTI[ 4 ] = (void*)aHash.getHash()[1];
283 pRTTI[ 5 ] = (void*)aHash.getHash()[2];
284 pRTTI[ 6 ] = (void*)aHash.getHash()[3];
285 pRTTI[ 7 ] = NULL;
286 pRTTI[ 8 ] = NULL;
288 memcpy( pRTTI+9, pInherit, 4*nInherit*5 );
289 pRTTI[ 8 +nInherit*5 ] = NULL;
290 pRTTI[ 9 +nInherit*5 ] = pRTTI[ 3 ];
291 pRTTI[ 10+nInherit*5 ] = pRTTI[ 4 ];
292 pRTTI[ 11+nInherit*5 ] = pRTTI[ 5 ];
293 pRTTI[ 12+nInherit*5 ] = pRTTI[ 6 ];
294 pRTTI[ 13+nInherit*5 ] = (void*)0x80000000;
295 strcpy(
296 reinterpret_cast< char * >(pRTTI + rttiSize),
297 aRTTICompTypeName.getStr());
299 aAllRTTI[ aRTTICompTypeName ] = (void*)pRTTI;
301 #if OSL_DEBUG_LEVEL > 1
302 fprintf( stderr,
303 "generating struct RTTI for type %s:\n"
304 " mangled: %s\n"
305 " hash: %.8x %.8x %.8X %.8x\n",
306 aRTTICompTypeName.getStr(),
307 aMangledName.getStr(),
308 pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ]
310 #endif
312 return pRTTI;
315 //__________________________________________________________________________________________________
317 static void deleteException(
318 void* pExc, unsigned char* thunk, typelib_TypeDescription* pType )
320 uno_destructData(
321 pExc, pType, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
322 typelib_typedescription_release( pType );
323 delete[] thunk;
326 //__________________________________________________________________________________________________
328 //##################################################################################################
329 //#### exported ####################################################################################
330 //##################################################################################################
332 void cc50_solaris_intel_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
334 #if OSL_DEBUG_LEVEL > 1
335 OString cstr(
336 OUStringToOString(
337 *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
338 RTL_TEXTENCODING_ASCII_US ) );
339 fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
340 #endif
341 bridges::cpp_uno::shared::ArrayPointer< unsigned char > thunkPtr(
342 new unsigned char[24]);
343 typelib_TypeDescription * pTypeDescr = 0;
344 // will be released by deleteException
345 typelib_typedescriptionreference_getDescription( &pTypeDescr, pUnoExc->pType );
347 void* pRTTI;
349 static ::osl::Mutex aMutex;
350 ::osl::Guard< ::osl::Mutex > guard( aMutex );
352 static RTTIHolder * s_pRTTI = 0;
353 if (! s_pRTTI)
355 #ifdef LEAK_STATIC_DATA
356 s_pRTTI = new RTTIHolder();
357 #else
358 static RTTIHolder s_aRTTI;
359 s_pRTTI = &s_aRTTI;
360 #endif
363 pRTTI = s_pRTTI->generateRTTI( (typelib_CompoundTypeDescription *)pTypeDescr );
366 // a must be
367 OSL_ENSURE( sizeof(sal_Int32) == sizeof(void *), "### pointer size differs from sal_Int32!" );
369 void * pCppExc = __Crun::ex_alloc( pTypeDescr->nSize );
370 uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
372 // destruct uno exception
373 uno_any_destruct( pUnoExc, 0 );
375 unsigned char * thunk = thunkPtr.release();
376 // movl %esp, %ecx:
377 thunk[0] = 0x8B;
378 thunk[1] = 0xCC;
379 // pushl pTypeDescr:
380 thunk[2] = 0x68;
381 *reinterpret_cast< void ** >(thunk + 3) = pTypeDescr;
382 // pushl thunk:
383 thunk[7] = 0x68;
384 *reinterpret_cast< void ** >(thunk + 8) = thunk;
385 // pushl 4(%ecx):
386 thunk[12] = 0xFF;
387 thunk[13] = 0x71;
388 thunk[14] = 0x04;
389 // call deleteException:
390 thunk[15] = 0xE8;
391 #pragma disable_warn
392 void * d = reinterpret_cast< void * >(deleteException);
393 #pragma enable_warn
394 *reinterpret_cast< std::ptrdiff_t * >(thunk + 16) =
395 static_cast< unsigned char * >(d) - (thunk + 20);
396 // addl $12, %esp:
397 thunk[20] = 0x83;
398 thunk[21] = 0xC4;
399 thunk[22] = 0x0C;
400 // ret:
401 thunk[23] = 0xC3;
403 #pragma disable_warn
404 void (* f)(void *) = reinterpret_cast< void (*)(void *) >(thunk);
405 #pragma enable_warn
406 __Crun::ex_throw(pCppExc, (const __Crun::static_type_info*)pRTTI, f);
409 void cc50_solaris_intel_fillUnoException(
410 void* pCppExc,
411 const char* pInfo,
412 uno_Any* pUnoExc,
413 uno_Mapping * pCpp2Uno )
415 OSL_ASSERT( pInfo != 0 );
416 OString uno_name( toUNOname( pInfo ) );
417 OUString aName( OStringToOUString(
418 uno_name, RTL_TEXTENCODING_ASCII_US ) );
419 typelib_TypeDescription * pExcTypeDescr = 0;
420 typelib_typedescription_getByName( &pExcTypeDescr, aName.pData );
422 if (pExcTypeDescr == 0) // the thing that should not be
424 RuntimeException aRE(
425 OUString( RTL_CONSTASCII_USTRINGPARAM(
426 "exception type not found: ") ) + aName,
427 Reference< XInterface >() );
428 Type const & rType = ::getCppuType( &aRE );
429 uno_type_any_constructAndConvert(
430 pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
431 #if OSL_DEBUG_LEVEL > 0
432 OString cstr( OUStringToOString(
433 aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
434 OSL_ENSURE( 0, cstr.getStr() );
435 #endif
436 return;
439 #if OSL_DEBUG_LEVEL > 1
440 fprintf( stderr, "> c++ exception occured: %s\n",
441 ::rtl::OUStringToOString(
442 pExcTypeDescr->pTypeName,
443 RTL_TEXTENCODING_ASCII_US ).getStr() );
444 #endif
445 // construct uno exception any
446 uno_any_constructAndConvert(
447 pUnoExc, pCppExc, pExcTypeDescr, pCpp2Uno );
448 typelib_typedescription_release( pExcTypeDescr );