1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: except.cxx,v $
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"
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"
54 // need a += operator for OString and sal_Char
57 inline OString
& operator+=( OString
& rString
, sal_Char cAdd
)
62 return rString
+= add
;
69 using namespace com::sun::star::uno
;
71 namespace CPPU_CURRENT_NAMESPACE
74 //==================================================================================================
75 static OString
toUNOname( const OString
& rRTTIname
)
79 const sal_Char
* pRTTI
= rRTTIname
.getStr();
80 const sal_Char
* pOrg
= pRTTI
;
81 const sal_Char
* pLast
= pRTTI
;
85 if( *pRTTI
== ':' || ! *pRTTI
)
87 if( aRet
.getLength() )
89 aRet
+= rRTTIname
.copy( pLast
- pOrg
, pRTTI
- pLast
);
90 while( *pRTTI
== ':' )
102 //==================================================================================================
103 static OString
toRTTIname( const OString
& rUNOname
)
105 OStringBuffer
aRet( rUNOname
.getLength()*2 );
107 sal_Int32 nIndex
= 0;
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() )
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();
136 aRet
.append( (sal_Char
)( nBytes
/26 + 'a' ) );
137 aRet
.append( (sal_Char
)( nBytes
%26 + 'A' ) );
140 aRet
.append( (sal_Char
)( nBytes
+ 'A' ) );
141 for (sal_Int32 i
= 0; i
< aToken
.getLength(); ++i
) {
150 } while( nIndex
!= -1 );
154 return aRet
.makeStringAndClear();
158 //##################################################################################################
159 //#### RTTI simulation #############################################################################
160 //##################################################################################################
164 std::map
< OString
, void* > aAllRTTI
;
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
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
;
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 *));
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];
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
235 "generating base RTTI for type %s:\n"
237 " hash: %.8x %.8x %.8x %.8x\n",
239 aMangledName
.getStr(),
240 pRTTI
[ 3 ], pRTTI
[ 4 ], pRTTI
[ 5 ], pRTTI
[ 6 ]
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
);
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);
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 ** >(
277 rttiSize
* sizeof (void *)
278 + strlen(aRTTICompTypeName
.getStr()) + 1]);
279 pRTTI
[ 0 ] = reinterpret_cast< void * >(rttiSize
* sizeof (void *));
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];
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;
297 reinterpret_cast< char * >(pRTTI
+ rttiSize
),
298 aRTTICompTypeName
.getStr());
300 aAllRTTI
[ aRTTICompTypeName
] = (void*)pRTTI
;
302 #if OSL_DEBUG_LEVEL > 1
304 "generating struct RTTI for type %s:\n"
306 " hash: %.8x %.8x %.8X %.8x\n",
307 aRTTICompTypeName
.getStr(),
308 aMangledName
.getStr(),
309 pRTTI
[ 3 ], pRTTI
[ 4 ], pRTTI
[ 5 ], pRTTI
[ 6 ]
316 //--------------------------------------------------------------------------------------------------
318 static void deleteException(
319 void* pExc
, unsigned int* thunk
, typelib_TypeDescription
* pType
)
322 pExc
, pType
, reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
323 typelib_typedescription_release( pType
);
327 //__________________________________________________________________________________________________
329 //##################################################################################################
330 //#### exported ####################################################################################
331 //##################################################################################################
333 void cc50_solaris_sparc_raiseException( uno_Any
* pUnoExc
, uno_Mapping
* pUno2Cpp
)
335 #if OSL_DEBUG_LEVEL > 1
338 *reinterpret_cast< OUString
const * >( &pUnoExc
->pType
->pTypeName
),
339 RTL_TEXTENCODING_ASCII_US
) );
340 fprintf( stderr
, "> uno exception occured: %s\n", cstr
.getStr() );
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
);
351 static ::osl::Mutex aMutex
;
352 ::osl::Guard
< ::osl::Mutex
> guard( aMutex
);
354 static RTTIHolder
* s_pRTTI
= 0;
357 #ifdef LEAK_STATIC_DATA
358 s_pRTTI
= new RTTIHolder();
360 static RTTIHolder s_aRTTI
;
365 pRTTI
= s_pRTTI
->generateRTTI( (typelib_CompoundTypeDescription
*)pTypeDescr
);
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);
397 void (* f
)(void *) = reinterpret_cast< void (*)(void *) >(thunk
);
399 __Crun::ex_throw(pCppExc
, (const __Crun::static_type_info
*)pRTTI
, f
);
402 void cc50_solaris_sparc_fillUnoException(
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() );
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() );
438 // construct uno exception any
439 uno_any_constructAndConvert(
440 pUnoExc
, pCppExc
, pExcTypeDescr
, pCpp2Uno
);
441 typelib_typedescription_release( pExcTypeDescr
);