Bump for 3.6-28
[LibreOffice.git] / bridges / source / cpp_uno / cc50_solaris_sparc / except.cxx
blob75b23c61073d687086f339a786da2eadec948baa
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <cstddef>
31 #include <dlfcn.h>
32 #include <new.h>
33 #include <typeinfo>
34 #include <list>
35 #include <map>
36 #include <rtl/alloc.h>
37 #include <rtl/instance.hxx>
38 #include <osl/diagnose.h>
39 #include <typelib/typedescription.hxx>
40 #include <com/sun/star/uno/Any.hxx>
41 #include "com/sun/star/uno/RuntimeException.hpp"
43 #include "cc50_solaris_sparc.hxx"
44 #include "flushcode.hxx"
45 #include <rtl/strbuf.hxx>
47 #include "bridges/cpp_uno/shared/arraypointer.hxx"
49 #include <hash.cxx>
51 // need a += operator for OString and sal_Char
52 using ::rtl::OUString;
53 using ::rtl::OString;
54 using ::rtl::OStringBuffer;
55 using ::rtl::OUStringToOString;
56 using ::rtl::OStringToOUString;
59 inline OString& operator+=( OString& rString, sal_Char cAdd )
61 sal_Char add[2];
62 add[0] = cAdd;
63 add[1] = 0;
64 return rString += add;
68 using namespace std;
69 using namespace osl;
70 using namespace com::sun::star::uno;
72 namespace CPPU_CURRENT_NAMESPACE
75 //==================================================================================================
76 static OString toUNOname( const OString & rRTTIname )
78 OString aRet;
80 const sal_Char* pRTTI = rRTTIname.getStr();
81 const sal_Char* pOrg = pRTTI;
82 const sal_Char* pLast = pRTTI;
84 while( 1 )
86 if( *pRTTI == ':' || ! *pRTTI )
88 if( aRet.getLength() )
89 aRet += ".";
90 aRet += rRTTIname.copy( pLast - pOrg, pRTTI - pLast );
91 while( *pRTTI == ':' )
92 pRTTI++;
93 pLast = pRTTI;
94 if( ! *pRTTI )
95 break;
97 else
98 pRTTI++;
101 return aRet;
103 //==================================================================================================
104 static OString toRTTIname( const OString & rUNOname )
106 OStringBuffer aRet( rUNOname.getLength()*2 );
108 sal_Int32 nIndex = 0;
111 if( nIndex > 0 )
112 aRet.append( "::" );
113 aRet.append( rUNOname.getToken( 0, '.', nIndex ) );
114 } while( nIndex != -1 );
116 return aRet.makeStringAndClear();
118 //==================================================================================================
120 static OString toRTTImangledname( const OString & rRTTIname )
122 if( ! rRTTIname.getLength() )
123 return OString();
125 OStringBuffer aRet( rRTTIname.getLength()*2 );
127 aRet.append( "__1n" );
128 sal_Int32 nIndex = 0;
131 OString aToken( rRTTIname.getToken( 0, ':', nIndex ) );
132 int nBytes = aToken.getLength();
133 if( nBytes )
135 if( nBytes > 25 )
137 aRet.append( (sal_Char)( nBytes/26 + 'a' ) );
138 aRet.append( (sal_Char)( nBytes%26 + 'A' ) );
140 else
141 aRet.append( (sal_Char)( nBytes + 'A' ) );
142 for (sal_Int32 i = 0; i < aToken.getLength(); ++i) {
143 char c = aToken[i];
144 if (c == 'Q') {
145 aRet.append("QdD");
146 } else {
147 aRet.append(c);
151 } while( nIndex != -1 );
153 aRet.append( '_' );
155 return aRet.makeStringAndClear();
159 //##################################################################################################
160 //#### RTTI simulation #############################################################################
161 //##################################################################################################
163 class RTTIHolder
165 std::map< OString, void* > aAllRTTI;
166 public:
167 ~RTTIHolder();
169 void* getRTTI( const OString& rTypename );
170 void* getRTTI_UnoName( const OString& rUnoTypename )
171 { return getRTTI( toRTTIname( rUnoTypename ) ); }
173 void* insertRTTI( const OString& rTypename );
174 void* insertRTTI_UnoName( const OString& rTypename )
175 { return insertRTTI( toRTTIname( rTypename ) ); }
176 void* generateRTTI( typelib_CompoundTypeDescription* pCompTypeDescr );
179 RTTIHolder::~RTTIHolder()
181 for ( std::map< OString, void* >::const_iterator iPos( aAllRTTI.begin() );
182 iPos != aAllRTTI.end(); ++iPos )
184 delete[] static_cast< char * >(iPos->second);
188 #if OSL_DEBUG_LEVEL > 1
189 #include <stdio.h>
190 #endif
192 void* RTTIHolder::getRTTI( const OString& rTypename )
194 std::map< OString, void* >::iterator element;
196 element = aAllRTTI.find( rTypename );
197 if( element != aAllRTTI.end() )
198 return (*element).second;
200 // create rtti structure
201 element = aAllRTTI.find( rTypename );
202 if( element != aAllRTTI.end() )
203 return (*element).second;
205 return NULL;
208 void* RTTIHolder::insertRTTI( const OString& rTypename )
210 OString aMangledName( toRTTImangledname( rTypename ) );
211 NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
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 //--------------------------------------------------------------------------------------------------
249 void* RTTIHolder::generateRTTI( typelib_CompoundTypeDescription * pCompTypeDescr )
251 OString aUNOCompTypeName( OUStringToOString( pCompTypeDescr->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US ) );
252 OString aRTTICompTypeName( toRTTIname( aUNOCompTypeName ) );
254 void* pHaveRTTI = getRTTI( aRTTICompTypeName );
255 if( pHaveRTTI )
256 return pHaveRTTI;
258 if( ! pCompTypeDescr->pBaseTypeDescription )
259 // this is a base type
260 return insertRTTI( aRTTICompTypeName );
262 // get base class RTTI
263 void* pSuperRTTI = generateRTTI( pCompTypeDescr->pBaseTypeDescription );
264 OSL_ENSURE( pSuperRTTI, "could not generate RTTI for supertype !" );
266 // find out the size to allocate for RTTI
267 void** pInherit = (void**)((sal_uInt32)pSuperRTTI + ((sal_uInt32*)pSuperRTTI)[2] + 8);
268 int nInherit;
269 for( nInherit = 1; pInherit[ nInherit*5-1 ] != (void*)0x80000000; nInherit++ )
272 OString aMangledName( toRTTImangledname( aRTTICompTypeName ) );
273 NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
275 std::size_t const rttiSize = 14 + nInherit * 5;
276 void** pRTTI = reinterpret_cast< void ** >(
277 new char[
278 rttiSize * sizeof (void *)
279 + strlen(aRTTICompTypeName.getStr()) + 1]);
280 pRTTI[ 0 ] = reinterpret_cast< void * >(rttiSize * sizeof (void *));
281 pRTTI[ 1 ] = NULL;
282 pRTTI[ 2 ] = (void*)(7*sizeof(void*));
283 pRTTI[ 3 ] = (void*)aHash.getHash()[0];
284 pRTTI[ 4 ] = (void*)aHash.getHash()[1];
285 pRTTI[ 5 ] = (void*)aHash.getHash()[2];
286 pRTTI[ 6 ] = (void*)aHash.getHash()[3];
287 pRTTI[ 7 ] = NULL;
288 pRTTI[ 8 ] = NULL;
290 memcpy( pRTTI+9, pInherit, 4*nInherit*5 );
291 pRTTI[ 8 +nInherit*5 ] = NULL;
292 pRTTI[ 9 +nInherit*5 ] = pRTTI[ 3 ];
293 pRTTI[ 10+nInherit*5 ] = pRTTI[ 4 ];
294 pRTTI[ 11+nInherit*5 ] = pRTTI[ 5 ];
295 pRTTI[ 12+nInherit*5 ] = pRTTI[ 6 ];
296 pRTTI[ 13+nInherit*5 ] = (void*)0x80000000;
297 strcpy(
298 reinterpret_cast< char * >(pRTTI + rttiSize),
299 aRTTICompTypeName.getStr());
301 aAllRTTI[ aRTTICompTypeName ] = (void*)pRTTI;
303 #if OSL_DEBUG_LEVEL > 1
304 fprintf( stderr,
305 "generating struct RTTI for type %s:\n"
306 " mangled: %s\n"
307 " hash: %.8x %.8x %.8X %.8x\n",
308 aRTTICompTypeName.getStr(),
309 aMangledName.getStr(),
310 pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ]
312 #endif
314 return pRTTI;
317 struct RTTISingleton: public rtl::Static< RTTIHolder, RTTISingleton > {};
319 //--------------------------------------------------------------------------------------------------
321 static void deleteException(
322 void* pExc, unsigned int* thunk, typelib_TypeDescription* pType )
324 uno_destructData(
325 pExc, pType, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
326 typelib_typedescription_release( pType );
327 delete[] thunk;
330 //__________________________________________________________________________________________________
332 //##################################################################################################
333 //#### exported ####################################################################################
334 //##################################################################################################
336 void cc50_solaris_sparc_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
338 #if OSL_DEBUG_LEVEL > 1
339 OString cstr(
340 OUStringToOString(
341 *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
342 RTL_TEXTENCODING_ASCII_US ) );
343 fprintf( stderr, "> uno exception occurred: %s\n", cstr.getStr() );
344 #endif
345 bridges::cpp_uno::shared::ArrayPointer< unsigned int > thunkPtr(
346 new unsigned int[6]);
348 typelib_TypeDescription * pTypeDescr = 0;
349 // will be released by deleteException
350 typelib_typedescriptionreference_getDescription( &pTypeDescr, pUnoExc->pType );
352 void * pRTTI = RTTISingleton::get().generateRTTI( (typelib_CompoundTypeDescription *)pTypeDescr );
354 // a must be
355 OSL_ENSURE( sizeof(sal_Int32) == sizeof(void *), "### pointer size differs from sal_Int32!" );
357 void * pCppExc = __Crun::ex_alloc( pTypeDescr->nSize );
358 uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
360 // destruct uno exception
361 uno_any_destruct( pUnoExc, 0 );
363 unsigned int * thunk = thunkPtr.release();
364 // sethi %hi(thunk), %o1:
365 thunk[0] = 0x13000000 | (reinterpret_cast< unsigned int >(thunk) >> 10);
366 // or %o1, %lo(thunk), %o1:
367 thunk[1] = 0x92126000 | (reinterpret_cast< unsigned int >(thunk) & 0x3FF);
368 // sethi %hi(pTypeDescr), %o2:
369 thunk[2] = 0x15000000
370 | (reinterpret_cast< unsigned int >(pTypeDescr) >> 10);
371 // sethi %hi(deleteException), %o3
372 thunk[3] = 0x17000000
373 | (reinterpret_cast< unsigned int >(deleteException) >> 10);
374 // jmpl %o3, %lo(deleteException), %g0
375 thunk[4] = 0x81C2E000
376 | (reinterpret_cast< unsigned int >(deleteException) & 0x3FF);
377 // or %o2, %lo(pTypeDescr), %o2:
378 thunk[5] = 0x9412A000
379 | (reinterpret_cast< unsigned int >(pTypeDescr) & 0x3FF);
380 bridges::cpp_uno::cc50_solaris_sparc::flushCode(thunk, thunk + 6);
382 #pragma disable_warn
383 void (* f)(void *) = reinterpret_cast< void (*)(void *) >(thunk);
384 #pragma enable_warn
385 __Crun::ex_throw(pCppExc, (const __Crun::static_type_info*)pRTTI, f);
388 void cc50_solaris_sparc_fillUnoException(
389 void* pCppExc,
390 const char* pInfo,
391 uno_Any* pUnoExc,
392 uno_Mapping * pCpp2Uno )
394 OSL_ASSERT( pInfo != 0 );
395 OString uno_name( toUNOname( pInfo ) );
396 OUString aName( OStringToOUString(
397 uno_name, RTL_TEXTENCODING_ASCII_US ) );
398 typelib_TypeDescription * pExcTypeDescr = 0;
399 typelib_typedescription_getByName( &pExcTypeDescr, aName.pData );
401 if (pExcTypeDescr == 0) // the thing that should not be
403 RuntimeException aRE(
404 OUString( RTL_CONSTASCII_USTRINGPARAM(
405 "exception type not found: ") ) + aName,
406 Reference< XInterface >() );
407 Type const & rType = ::getCppuType( &aRE );
408 uno_type_any_constructAndConvert(
409 pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
410 #if OSL_DEBUG_LEVEL > 0
411 OString cstr( OUStringToOString(
412 aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
413 OSL_FAIL( cstr.getStr() );
414 #endif
415 return;
418 #if OSL_DEBUG_LEVEL > 1
419 fprintf( stderr, "> c++ exception occurred: %s\n",
420 ::rtl::OUStringToOString(
421 pExcTypeDescr->pTypeName,
422 RTL_TEXTENCODING_ASCII_US ).getStr() );
423 #endif
424 // construct uno exception any
425 uno_any_constructAndConvert(
426 pUnoExc, pCppExc, pExcTypeDescr, pCpp2Uno );
427 typelib_typedescription_release( pExcTypeDescr );
435 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */