Update ooo320-m1
[ooovba.git] / bridges / source / cpp_uno / cc50_solaris_sparc / except.cxx
blob9ccd13e2a849a3c475b4d23a3019dcad23c6d077
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>
42 #include <typelib/typedescription.hxx>
43 #include <com/sun/star/uno/Any.hxx>
44 #include "com/sun/star/uno/RuntimeException.hpp"
46 #include "cc50_solaris_sparc.hxx"
47 #include "flushcode.hxx"
48 #include <rtl/strbuf.hxx>
50 #include "bridges/cpp_uno/shared/arraypointer.hxx"
52 #include <hash.cxx>
54 // need a += operator for OString and sal_Char
55 namespace rtl
57 inline OString& operator+=( OString& rString, sal_Char cAdd )
59 sal_Char add[2];
60 add[0] = cAdd;
61 add[1] = 0;
62 return rString += add;
66 using namespace std;
67 using namespace osl;
68 using namespace rtl;
69 using namespace com::sun::star::uno;
71 namespace CPPU_CURRENT_NAMESPACE
74 //==================================================================================================
75 static OString toUNOname( const OString & rRTTIname )
77 OString aRet;
79 const sal_Char* pRTTI = rRTTIname.getStr();
80 const sal_Char* pOrg = pRTTI;
81 const sal_Char* pLast = pRTTI;
83 while( 1 )
85 if( *pRTTI == ':' || ! *pRTTI )
87 if( aRet.getLength() )
88 aRet += ".";
89 aRet += rRTTIname.copy( pLast - pOrg, pRTTI - pLast );
90 while( *pRTTI == ':' )
91 pRTTI++;
92 pLast = pRTTI;
93 if( ! *pRTTI )
94 break;
96 else
97 pRTTI++;
100 return aRet;
102 //==================================================================================================
103 static OString toRTTIname( const OString & rUNOname )
105 OStringBuffer aRet( rUNOname.getLength()*2 );
107 sal_Int32 nIndex = 0;
110 if( nIndex > 0 )
111 aRet.append( "::" );
112 aRet.append( rUNOname.getToken( 0, '.', nIndex ) );
113 } while( nIndex != -1 );
115 return aRet.makeStringAndClear();
117 //==================================================================================================
119 static OString toRTTImangledname( const OString & rRTTIname )
121 if( ! rRTTIname.getLength() )
122 return OString();
124 OStringBuffer aRet( rRTTIname.getLength()*2 );
126 aRet.append( "__1n" );
127 sal_Int32 nIndex = 0;
130 OString aToken( rRTTIname.getToken( 0, ':', nIndex ) );
131 int nBytes = aToken.getLength();
132 if( nBytes )
134 if( nBytes > 25 )
136 aRet.append( (sal_Char)( nBytes/26 + 'a' ) );
137 aRet.append( (sal_Char)( nBytes%26 + 'A' ) );
139 else
140 aRet.append( (sal_Char)( nBytes + 'A' ) );
141 for (sal_Int32 i = 0; i < aToken.getLength(); ++i) {
142 char c = aToken[i];
143 if (c == 'Q') {
144 aRet.append("QdD");
145 } else {
146 aRet.append(c);
150 } while( nIndex != -1 );
152 aRet.append( '_' );
154 return aRet.makeStringAndClear();
158 //##################################################################################################
159 //#### RTTI simulation #############################################################################
160 //##################################################################################################
162 class RTTIHolder
164 std::map< OString, void* > aAllRTTI;
165 public:
166 ~RTTIHolder();
168 void* getRTTI( const OString& rTypename );
169 void* getRTTI_UnoName( const OString& rUnoTypename )
170 { return getRTTI( toRTTIname( rUnoTypename ) ); }
172 void* insertRTTI( const OString& rTypename );
173 void* insertRTTI_UnoName( const OString& rTypename )
174 { return insertRTTI( toRTTIname( rTypename ) ); }
175 void* generateRTTI( typelib_CompoundTypeDescription* pCompTypeDescr );
178 RTTIHolder::~RTTIHolder()
180 for ( std::map< OString, void* >::const_iterator iPos( aAllRTTI.begin() );
181 iPos != aAllRTTI.end(); ++iPos )
183 delete[] static_cast< char * >(iPos->second);
187 #if OSL_DEBUG_LEVEL > 1
188 #include <stdio.h>
189 #endif
191 void* RTTIHolder::getRTTI( const OString& rTypename )
193 std::map< OString, void* >::iterator element;
195 element = aAllRTTI.find( rTypename );
196 if( element != aAllRTTI.end() )
197 return (*element).second;
199 // create rtti structure
200 element = aAllRTTI.find( rTypename );
201 if( element != aAllRTTI.end() )
202 return (*element).second;
204 return NULL;
207 void* RTTIHolder::insertRTTI( const OString& rTypename )
209 OString aMangledName( toRTTImangledname( rTypename ) );
210 NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
212 std::size_t const RTTI_SIZE = 19; // 14???
213 void** pRTTI = reinterpret_cast< void ** >(
214 new char[RTTI_SIZE * sizeof (void *) + strlen(rTypename.getStr()) + 1]);
215 pRTTI[ 0 ] = reinterpret_cast< void * >(RTTI_SIZE * sizeof (void *));
216 pRTTI[ 1 ] = NULL;
217 pRTTI[ 2 ] = (void*)(7*sizeof(void*));
218 pRTTI[ 3 ] = (void*)aHash.getHash()[0];
219 pRTTI[ 4 ] = (void*)aHash.getHash()[1];
220 pRTTI[ 5 ] = (void*)aHash.getHash()[2];
221 pRTTI[ 6 ] = (void*)aHash.getHash()[3];
222 pRTTI[ 7 ] = NULL;
223 pRTTI[ 8 ] = NULL;
225 pRTTI[ 9 ] = pRTTI[ 3 ];
226 pRTTI[ 10 ] = pRTTI[ 4 ];
227 pRTTI[ 11 ] = pRTTI[ 5 ];
228 pRTTI[ 12 ] = pRTTI[ 6 ];
229 pRTTI[ 13 ] = (void*)0x80000000;
230 strcpy(reinterpret_cast< char * >(pRTTI + RTTI_SIZE), rTypename.getStr());
232 aAllRTTI[ rTypename ] = (void*)pRTTI;
233 #if OSL_DEBUG_LEVEL > 1
234 fprintf( stderr,
235 "generating base RTTI for type %s:\n"
236 " mangled: %s\n"
237 " hash: %.8x %.8x %.8x %.8x\n",
238 rTypename.getStr(),
239 aMangledName.getStr(),
240 pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ]
242 #endif
243 return pRTTI;
246 //--------------------------------------------------------------------------------------------------
248 void* RTTIHolder::generateRTTI( typelib_CompoundTypeDescription * pCompTypeDescr )
250 OString aUNOCompTypeName( OUStringToOString( pCompTypeDescr->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US ) );
251 OString aRTTICompTypeName( toRTTIname( aUNOCompTypeName ) );
253 void* pHaveRTTI = getRTTI( aRTTICompTypeName );
254 if( pHaveRTTI )
255 return pHaveRTTI;
257 if( ! pCompTypeDescr->pBaseTypeDescription )
258 // this is a base type
259 return insertRTTI( aRTTICompTypeName );
261 // get base class RTTI
262 void* pSuperRTTI = generateRTTI( pCompTypeDescr->pBaseTypeDescription );
263 OSL_ENSURE( pSuperRTTI, "could not generate RTTI for supertype !" );
265 // find out the size to allocate for RTTI
266 void** pInherit = (void**)((sal_uInt32)pSuperRTTI + ((sal_uInt32*)pSuperRTTI)[2] + 8);
267 int nInherit;
268 for( nInherit = 1; pInherit[ nInherit*5-1 ] != (void*)0x80000000; nInherit++ )
271 OString aMangledName( toRTTImangledname( aRTTICompTypeName ) );
272 NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
274 std::size_t const rttiSize = 14 + nInherit * 5;
275 void** pRTTI = reinterpret_cast< void ** >(
276 new char[
277 rttiSize * sizeof (void *)
278 + strlen(aRTTICompTypeName.getStr()) + 1]);
279 pRTTI[ 0 ] = reinterpret_cast< void * >(rttiSize * sizeof (void *));
280 pRTTI[ 1 ] = NULL;
281 pRTTI[ 2 ] = (void*)(7*sizeof(void*));
282 pRTTI[ 3 ] = (void*)aHash.getHash()[0];
283 pRTTI[ 4 ] = (void*)aHash.getHash()[1];
284 pRTTI[ 5 ] = (void*)aHash.getHash()[2];
285 pRTTI[ 6 ] = (void*)aHash.getHash()[3];
286 pRTTI[ 7 ] = NULL;
287 pRTTI[ 8 ] = NULL;
289 memcpy( pRTTI+9, pInherit, 4*nInherit*5 );
290 pRTTI[ 8 +nInherit*5 ] = NULL;
291 pRTTI[ 9 +nInherit*5 ] = pRTTI[ 3 ];
292 pRTTI[ 10+nInherit*5 ] = pRTTI[ 4 ];
293 pRTTI[ 11+nInherit*5 ] = pRTTI[ 5 ];
294 pRTTI[ 12+nInherit*5 ] = pRTTI[ 6 ];
295 pRTTI[ 13+nInherit*5 ] = (void*)0x80000000;
296 strcpy(
297 reinterpret_cast< char * >(pRTTI + rttiSize),
298 aRTTICompTypeName.getStr());
300 aAllRTTI[ aRTTICompTypeName ] = (void*)pRTTI;
302 #if OSL_DEBUG_LEVEL > 1
303 fprintf( stderr,
304 "generating struct RTTI for type %s:\n"
305 " mangled: %s\n"
306 " hash: %.8x %.8x %.8X %.8x\n",
307 aRTTICompTypeName.getStr(),
308 aMangledName.getStr(),
309 pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ]
311 #endif
313 return pRTTI;
316 //--------------------------------------------------------------------------------------------------
318 static void deleteException(
319 void* pExc, unsigned int* thunk, typelib_TypeDescription* pType )
321 uno_destructData(
322 pExc, pType, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
323 typelib_typedescription_release( pType );
324 delete[] thunk;
327 //__________________________________________________________________________________________________
329 //##################################################################################################
330 //#### exported ####################################################################################
331 //##################################################################################################
333 void cc50_solaris_sparc_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
335 #if OSL_DEBUG_LEVEL > 1
336 OString cstr(
337 OUStringToOString(
338 *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
339 RTL_TEXTENCODING_ASCII_US ) );
340 fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
341 #endif
342 bridges::cpp_uno::shared::ArrayPointer< unsigned int > thunkPtr(
343 new unsigned int[6]);
345 typelib_TypeDescription * pTypeDescr = 0;
346 // will be released by deleteException
347 typelib_typedescriptionreference_getDescription( &pTypeDescr, pUnoExc->pType );
349 void* pRTTI;
351 static ::osl::Mutex aMutex;
352 ::osl::Guard< ::osl::Mutex > guard( aMutex );
354 static RTTIHolder * s_pRTTI = 0;
355 if (! s_pRTTI)
357 #ifdef LEAK_STATIC_DATA
358 s_pRTTI = new RTTIHolder();
359 #else
360 static RTTIHolder s_aRTTI;
361 s_pRTTI = &s_aRTTI;
362 #endif
365 pRTTI = s_pRTTI->generateRTTI( (typelib_CompoundTypeDescription *)pTypeDescr );
368 // a must be
369 OSL_ENSURE( sizeof(sal_Int32) == sizeof(void *), "### pointer size differs from sal_Int32!" );
371 void * pCppExc = __Crun::ex_alloc( pTypeDescr->nSize );
372 uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
374 // destruct uno exception
375 uno_any_destruct( pUnoExc, 0 );
377 unsigned int * thunk = thunkPtr.release();
378 // sethi %hi(thunk), %o1:
379 thunk[0] = 0x13000000 | (reinterpret_cast< unsigned int >(thunk) >> 10);
380 // or %o1, %lo(thunk), %o1:
381 thunk[1] = 0x92126000 | (reinterpret_cast< unsigned int >(thunk) & 0x3FF);
382 // sethi %hi(pTypeDescr), %o2:
383 thunk[2] = 0x15000000
384 | (reinterpret_cast< unsigned int >(pTypeDescr) >> 10);
385 // sethi %hi(deleteException), %o3
386 thunk[3] = 0x17000000
387 | (reinterpret_cast< unsigned int >(deleteException) >> 10);
388 // jmpl %o3, %lo(deleteException), %g0
389 thunk[4] = 0x81C2E000
390 | (reinterpret_cast< unsigned int >(deleteException) & 0x3FF);
391 // or %o2, %lo(pTypeDescr), %o2:
392 thunk[5] = 0x9412A000
393 | (reinterpret_cast< unsigned int >(pTypeDescr) & 0x3FF);
394 bridges::cpp_uno::cc50_solaris_sparc::flushCode(thunk, thunk + 6);
396 #pragma disable_warn
397 void (* f)(void *) = reinterpret_cast< void (*)(void *) >(thunk);
398 #pragma enable_warn
399 __Crun::ex_throw(pCppExc, (const __Crun::static_type_info*)pRTTI, f);
402 void cc50_solaris_sparc_fillUnoException(
403 void* pCppExc,
404 const char* pInfo,
405 uno_Any* pUnoExc,
406 uno_Mapping * pCpp2Uno )
408 OSL_ASSERT( pInfo != 0 );
409 OString uno_name( toUNOname( pInfo ) );
410 OUString aName( OStringToOUString(
411 uno_name, RTL_TEXTENCODING_ASCII_US ) );
412 typelib_TypeDescription * pExcTypeDescr = 0;
413 typelib_typedescription_getByName( &pExcTypeDescr, aName.pData );
415 if (pExcTypeDescr == 0) // the thing that should not be
417 RuntimeException aRE(
418 OUString( RTL_CONSTASCII_USTRINGPARAM(
419 "exception type not found: ") ) + aName,
420 Reference< XInterface >() );
421 Type const & rType = ::getCppuType( &aRE );
422 uno_type_any_constructAndConvert(
423 pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
424 #if OSL_DEBUG_LEVEL > 0
425 OString cstr( OUStringToOString(
426 aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
427 OSL_ENSURE( 0, cstr.getStr() );
428 #endif
429 return;
432 #if OSL_DEBUG_LEVEL > 1
433 fprintf( stderr, "> c++ exception occured: %s\n",
434 ::rtl::OUStringToOString(
435 pExcTypeDescr->pTypeName,
436 RTL_TEXTENCODING_ASCII_US ).getStr() );
437 #endif
438 // construct uno exception any
439 uno_any_constructAndConvert(
440 pUnoExc, pCppExc, pExcTypeDescr, pCpp2Uno );
441 typelib_typedescription_release( pExcTypeDescr );