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 ************************************************************************/
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"
51 // need a += operator for OString and sal_Char
52 using ::rtl::OUString
;
54 using ::rtl::OStringBuffer
;
55 using ::rtl::OUStringToOString
;
56 using ::rtl::OStringToOUString
;
59 inline OString
& operator+=( OString
& rString
, sal_Char cAdd
)
64 return rString
+= add
;
70 using namespace com::sun::star::uno
;
72 namespace CPPU_CURRENT_NAMESPACE
75 //==================================================================================================
76 static OString
toUNOname( const OString
& rRTTIname
)
80 const sal_Char
* pRTTI
= rRTTIname
.getStr();
81 const sal_Char
* pOrg
= pRTTI
;
82 const sal_Char
* pLast
= pRTTI
;
86 if( *pRTTI
== ':' || ! *pRTTI
)
88 if( aRet
.getLength() )
90 aRet
+= rRTTIname
.copy( pLast
- pOrg
, pRTTI
- pLast
);
91 while( *pRTTI
== ':' )
103 //==================================================================================================
104 static OString
toRTTIname( const OString
& rUNOname
)
106 OStringBuffer
aRet( rUNOname
.getLength()*2 );
108 sal_Int32 nIndex
= 0;
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() )
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();
137 aRet
.append( (sal_Char
)( nBytes
/26 + 'a' ) );
138 aRet
.append( (sal_Char
)( nBytes
%26 + 'A' ) );
141 aRet
.append( (sal_Char
)( nBytes
+ 'A' ) );
142 for (sal_Int32 i
= 0; i
< aToken
.getLength(); ++i
) {
151 } while( nIndex
!= -1 );
155 return aRet
.makeStringAndClear();
159 //##################################################################################################
160 //#### RTTI simulation #############################################################################
161 //##################################################################################################
165 std::map
< OString
, void* > aAllRTTI
;
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
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
;
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 *));
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];
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
236 "generating base RTTI for type %s:\n"
238 " hash: %.8x %.8x %.8x %.8x\n",
240 aMangledName
.getStr(),
241 pRTTI
[ 3 ], pRTTI
[ 4 ], pRTTI
[ 5 ], pRTTI
[ 6 ]
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
);
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);
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 ** >(
278 rttiSize
* sizeof (void *)
279 + strlen(aRTTICompTypeName
.getStr()) + 1]);
280 pRTTI
[ 0 ] = reinterpret_cast< void * >(rttiSize
* sizeof (void *));
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];
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;
298 reinterpret_cast< char * >(pRTTI
+ rttiSize
),
299 aRTTICompTypeName
.getStr());
301 aAllRTTI
[ aRTTICompTypeName
] = (void*)pRTTI
;
303 #if OSL_DEBUG_LEVEL > 1
305 "generating struct RTTI for type %s:\n"
307 " hash: %.8x %.8x %.8X %.8x\n",
308 aRTTICompTypeName
.getStr(),
309 aMangledName
.getStr(),
310 pRTTI
[ 3 ], pRTTI
[ 4 ], pRTTI
[ 5 ], pRTTI
[ 6 ]
317 struct RTTISingleton
: public rtl::Static
< RTTIHolder
, RTTISingleton
> {};
319 //--------------------------------------------------------------------------------------------------
321 static void deleteException(
322 void* pExc
, unsigned int* thunk
, typelib_TypeDescription
* pType
)
325 pExc
, pType
, reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
326 typelib_typedescription_release( pType
);
330 //__________________________________________________________________________________________________
332 //##################################################################################################
333 //#### exported ####################################################################################
334 //##################################################################################################
336 void cc50_solaris_sparc_raiseException( uno_Any
* pUnoExc
, uno_Mapping
* pUno2Cpp
)
338 #if OSL_DEBUG_LEVEL > 1
341 *reinterpret_cast< OUString
const * >( &pUnoExc
->pType
->pTypeName
),
342 RTL_TEXTENCODING_ASCII_US
) );
343 fprintf( stderr
, "> uno exception occurred: %s\n", cstr
.getStr() );
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
);
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);
383 void (* f
)(void *) = reinterpret_cast< void (*)(void *) >(thunk
);
385 __Crun::ex_throw(pCppExc
, (const __Crun::static_type_info
*)pRTTI
, f
);
388 void cc50_solaris_sparc_fillUnoException(
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() );
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() );
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: */