LibreOffice Module bridges (master) 1
gcc3_aix_powerpc/except.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21#include <stdio.h>
22#include <dlfcn.h>
23#include <cxxabi.h>
24
25#include <rtl/strbuf.hxx>
26#include <rtl/ustrbuf.hxx>
27#include <osl/mutex.hxx>
28
29#include <com/sun/star/uno/genfunc.hxx>
30#include <typelib/typedescription.hxx>
31#include <uno/any2.h>
32#include <unordered_map>
33#include "share.hxx"
34#include <string.h>
35
36
37using namespace ::std;
38using namespace ::osl;
39using namespace ::com::sun::star::uno;
40using namespace ::__cxxabiv1;
41
42
44{
45
46void dummy_can_throw_anything( char const * )
47{
48}
49
50
51static OUString toUNOname( char const * p )
52{
53#ifdef DEBUG
54 char const * start = p;
55#endif
56
57 // example: N3com3sun4star4lang24IllegalArgumentExceptionE
58
59 OUStringBuffer buf( 64 );
60 assert( 'N' == *p );
61 ++p; // skip N
62
63 while ('E' != *p)
64 {
65 // read chars count
66 long n = (*p++ - '0');
67 while ('0' <= *p && '9' >= *p)
68 {
69 n *= 10;
70 n += (*p++ - '0');
71 }
72 buf.appendAscii( p, n );
73 p += n;
74 if ('E' != *p)
75 buf.append( '.' );
76 }
77
78#ifdef DEBUG
79 OUString ret( buf.makeStringAndClear() );
80 OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
81 fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
82 return ret;
83#else
84 return buf.makeStringAndClear();
85#endif
86}
87
88
89class RTTI
90{
91 typedef std::unordered_map< OUString, type_info * > t_rtti_map;
92
93 Mutex m_mutex;
96
97 void * m_hApp;
98
99public:
100 RTTI();
101 ~RTTI();
102
103 type_info * getRTTI( typelib_CompoundTypeDescription * );
104};
105
107 : m_hApp( dlopen( 0, RTLD_LAZY ) )
108{
109}
110
112{
113 dlclose( m_hApp );
114}
115
116
117type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr )
118{
119 type_info * rtti;
120
121 OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
122
123 MutexGuard guard( m_mutex );
124 t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
125 if (iFind == m_rttis.end())
126 {
127 // RTTI symbol
128 OStringBuffer buf( 64 );
129 buf.append( "_ZTIN" );
130 sal_Int32 index = 0;
131 do
132 {
133 OUString token( unoName.getToken( 0, '.', index ) );
134 buf.append( token.getLength() );
135 OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
136 buf.append( c_token );
137 }
138 while (index >= 0);
139 buf.append( 'E' );
140
141 OString symName( buf.makeStringAndClear() );
142 rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
143
144 if (rtti)
145 {
146 pair< t_rtti_map::iterator, bool > insertion(
147 m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
148 assert(insertion.second);
149 }
150 else
151 {
152 // try to lookup the symbol in the generated rtti map
153 t_rtti_map::const_iterator iiFind( m_generatedRttis.find( unoName ) );
154 if (iiFind == m_generatedRttis.end())
155 {
156 // we must generate it !
157 // symbol and rtti-name is nearly identical,
158 // the symbol is prefixed with _ZTI
159 char const * rttiName = symName.getStr() +4;
160#ifdef DEBUG
161 fprintf( stderr,"generated rtti for %s\n", rttiName );
162#endif
163 if (pTypeDescr->pBaseTypeDescription)
164 {
165 // ensure availability of base
166 type_info * base_rtti = getRTTI(
167 (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
168 rtti = new __si_class_type_info(
169 strdup( rttiName ), (__class_type_info *)base_rtti );
170 }
171 else
172 {
173 // this class has no base class
174 rtti = new __class_type_info( strdup( rttiName ) );
175 }
176
177 pair< t_rtti_map::iterator, bool > insertion(
178 m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
179 assert(insertion.second);
180 }
181 else // taking already generated rtti
182 {
183 rtti = iiFind->second;
184 }
185 }
186 }
187 else
188 {
189 rtti = iFind->second;
190 }
191 return rtti;
192}
193
194
195static void deleteException( void * pExc )
196{
197 __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
198 typelib_TypeDescription * pTD = 0;
199 OUString unoName( toUNOname( header->exceptionType->name() ) );
200 ::typelib_typedescription_getByName( &pTD, unoName.pData );
201 assert(pTD && "### unknown exception type! leaving out destruction => leaking!!!");
202 if (pTD)
203 {
204 ::uno_destructData( pExc, pTD, cpp_release );
205 ::typelib_typedescription_release( pTD );
206 }
207}
208
209
210void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
211{
212 void * pCppExc;
213 type_info * rtti;
214
215 {
216 // construct cpp exception object
217 typelib_TypeDescription * pTypeDescr = 0;
218 TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
219 if (! pTypeDescr)
220 terminate();
221
222 pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
223 ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
224
225 // destruct uno exception
226 ::uno_any_destruct( pUnoExc, 0 );
227 // avoiding locked counts
228 static RTTI rtti_data;
229 rtti = (type_info*)rtti_data.getRTTI((typelib_CompoundTypeDescription*)pTypeDescr);
230 TYPELIB_DANGER_RELEASE( pTypeDescr );
231 if (! rtti)
232 terminate();
233 }
234
235 __cxa_throw( pCppExc, rtti, deleteException );
236}
237
238
239void fillUnoException(uno_Any * pExc, uno_Mapping * pCpp2Uno)
240{
242 if (! header)
243 terminate();
244
245 std::type_info *exceptionType = __cxa_current_exception_type();
246
247 typelib_TypeDescription * pExcTypeDescr = 0;
248 OUString unoName( toUNOname( exceptionType->name() ) );
249 ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
250 if (! pExcTypeDescr)
251 terminate();
252
253 // construct uno exception any
254 ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
255 ::typelib_typedescription_release( pExcTypeDescr );
256}
257
258}
259
260/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr sal_Int8 header[]
type_info * getRTTI(typelib_CompoundTypeDescription *)
std::unordered_map< OUString, type_info * > t_rtti_map
void * m_hApp
void * p
sal_Int64 n
struct _uno_Mapping uno_Mapping
Definition: msvc/except.hxx:32
struct _typelib_TypeDescription typelib_TypeDescription
Definition: msvc/except.hxx:52
struct _uno_Any uno_Any
Definition: msvc/except.hxx:31
static void deleteException(void *pExc)
__cxa_eh_globals * __cxa_get_globals()
void __cxa_throw(void *thrown_exception, std::type_info *tinfo, void(*dest)(void *)) __attribute__((noreturn))
void dummy_can_throw_anything(char const *)
void fillUnoException(uno_Any *pExc, uno_Mapping *pCpp2Uno)
void * __cxa_allocate_exception(std::size_t thrown_size)
std::type_info * __cxa_current_exception_type()
static OUString toUNOname(char const *p)
void raiseException(uno_Any *pUnoExc, uno_Mapping *pUno2Cpp)
index
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)