File: | bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx |
Location: | line 486, column 17 |
Description: | Access to field 'eTypeClass' results in a dereference of a null pointer (loaded from variable 'member') |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | |||
2 | /************************************************************************* | |||
3 | * | |||
4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
5 | * | |||
6 | * Copyright 2000, 2010 Oracle and/or its affiliates. | |||
7 | * | |||
8 | * OpenOffice.org - a multi-platform office productivity suite | |||
9 | * | |||
10 | * This file is part of OpenOffice.org. | |||
11 | * | |||
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. | |||
15 | * | |||
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). | |||
21 | * | |||
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. | |||
26 | * | |||
27 | ************************************************************************/ | |||
28 | ||||
29 | ||||
30 | #include <com/sun/star/uno/genfunc.hxx> | |||
31 | #include "com/sun/star/uno/RuntimeException.hpp" | |||
32 | #include <uno/data.h> | |||
33 | #include <typelib/typedescription.hxx> | |||
34 | ||||
35 | #include "bridges/cpp_uno/shared/bridge.hxx" | |||
36 | #include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx" | |||
37 | #include "bridges/cpp_uno/shared/types.hxx" | |||
38 | #include "bridges/cpp_uno/shared/vtablefactory.hxx" | |||
39 | ||||
40 | #include "share.hxx" | |||
41 | ||||
42 | using namespace ::com::sun::star::uno; | |||
43 | ||||
44 | namespace | |||
45 | { | |||
46 | ||||
47 | //================================================================================================== | |||
48 | void cpp2uno_call( | |||
49 | bridges::cpp_uno::shared::CppInterfaceProxy * pThis, | |||
50 | const typelib_TypeDescription * pMemberTypeDescr, | |||
51 | typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return | |||
52 | sal_Int32 nParams, typelib_MethodParameter * pParams, | |||
53 | void ** pCallStack, | |||
54 | void * pReturnValue ) | |||
55 | { | |||
56 | // pCallStack: ret, [return ptr], this, params | |||
57 | char * pCppStack = (char *)(pCallStack +1); | |||
58 | ||||
59 | // return | |||
60 | typelib_TypeDescription * pReturnTypeDescr = 0; | |||
61 | if (pReturnTypeRef) | |||
62 | TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ){ typelib_TypeDescriptionReference * pMacroTypeRef = (pReturnTypeRef ); typelib_TypeDescription ** ppMacroTypeDescr = (&pReturnTypeDescr ); if (((pMacroTypeRef->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || (pMacroTypeRef->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) { typelib_typedescriptionreference_getDescription( ppMacroTypeDescr , pMacroTypeRef ); } else if (!pMacroTypeRef->pType || !pMacroTypeRef ->pType->pWeakRef) { typelib_typedescriptionreference_getDescription ( ppMacroTypeDescr, pMacroTypeRef ); if (*ppMacroTypeDescr) typelib_typedescription_release ( *ppMacroTypeDescr ); } else { *ppMacroTypeDescr = pMacroTypeRef ->pType; } }; | |||
63 | ||||
64 | void * pUnoReturn = 0; | |||
65 | void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need | |||
66 | ||||
67 | if (pReturnTypeDescr) | |||
68 | { | |||
69 | if (x86::isSimpleReturnType( pReturnTypeDescr )) | |||
70 | { | |||
71 | pUnoReturn = pReturnValue; // direct way for simple types | |||
72 | } | |||
73 | else // complex return via ptr (pCppReturn) | |||
74 | { | |||
75 | pCppReturn = *(void **)pCppStack; | |||
76 | pCppStack += sizeof(void *); | |||
77 | ||||
78 | pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( | |||
79 | pReturnTypeDescr ) | |||
80 | ? alloca( pReturnTypeDescr->nSize )__builtin_alloca (pReturnTypeDescr->nSize) | |||
81 | : pCppReturn); // direct way | |||
82 | } | |||
83 | } | |||
84 | // pop this | |||
85 | pCppStack += sizeof( void* ); | |||
86 | ||||
87 | // stack space | |||
88 | OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" )do { if (true && (!(sizeof(void *) == sizeof(sal_Int32 )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/usr/local/src/libreoffice/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx" ":" "88" ": "), "%s", "### unexpected size!"); } } while (false ); | |||
89 | // parameters | |||
90 | void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams )__builtin_alloca (4 * sizeof(void *) * nParams); | |||
91 | void ** pCppArgs = pUnoArgs + nParams; | |||
92 | // indizes of values this have to be converted (interface conversion cpp<=>uno) | |||
93 | sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams)); | |||
94 | // type descriptions for reconversions | |||
95 | typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams)); | |||
96 | ||||
97 | sal_Int32 nTempIndizes = 0; | |||
98 | ||||
99 | for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) | |||
100 | { | |||
101 | const typelib_MethodParameter & rParam = pParams[nPos]; | |||
102 | typelib_TypeDescription * pParamTypeDescr = 0; | |||
103 | TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ){ typelib_TypeDescriptionReference * pMacroTypeRef = (rParam. pTypeRef); typelib_TypeDescription ** ppMacroTypeDescr = (& pParamTypeDescr); if (((pMacroTypeRef->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || (pMacroTypeRef->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) { typelib_typedescriptionreference_getDescription( ppMacroTypeDescr , pMacroTypeRef ); } else if (!pMacroTypeRef->pType || !pMacroTypeRef ->pType->pWeakRef) { typelib_typedescriptionreference_getDescription ( ppMacroTypeDescr, pMacroTypeRef ); if (*ppMacroTypeDescr) typelib_typedescription_release ( *ppMacroTypeDescr ); } else { *ppMacroTypeDescr = pMacroTypeRef ->pType; } }; | |||
104 | ||||
105 | if (!rParam.bOut | |||
106 | && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) | |||
107 | // value | |||
108 | { | |||
109 | pCppArgs[nPos] = pCppStack; | |||
110 | pUnoArgs[nPos] = pCppStack; | |||
111 | switch (pParamTypeDescr->eTypeClass) | |||
112 | { | |||
113 | case typelib_TypeClass_HYPER: | |||
114 | case typelib_TypeClass_UNSIGNED_HYPER: | |||
115 | case typelib_TypeClass_DOUBLE: | |||
116 | pCppStack += sizeof(sal_Int32); // extra long | |||
117 | break; | |||
118 | default: | |||
119 | break; | |||
120 | } | |||
121 | // no longer needed | |||
122 | TYPELIB_DANGER_RELEASE( pParamTypeDescr ){ if ((((pParamTypeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || ((pParamTypeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) typelib_typedescription_release( pParamTypeDescr ); }; | |||
123 | } | |||
124 | else // ptr to complex value | ref | |||
125 | { | |||
126 | pCppArgs[nPos] = *(void **)pCppStack; | |||
127 | ||||
128 | if (! rParam.bIn) // is pure out | |||
129 | { | |||
130 | // uno out is unconstructed mem! | |||
131 | pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize )__builtin_alloca (pParamTypeDescr->nSize); | |||
132 | pTempIndizes[nTempIndizes] = nPos; | |||
133 | // will be released at reconversion | |||
134 | ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; | |||
135 | } | |||
136 | // is in/inout | |||
137 | else if (bridges::cpp_uno::shared::relatesToInterfaceType( | |||
138 | pParamTypeDescr )) | |||
139 | { | |||
140 | uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize )__builtin_alloca (pParamTypeDescr->nSize), | |||
141 | *(void **)pCppStack, pParamTypeDescr, | |||
142 | pThis->getBridge()->getCpp2Uno() ); | |||
143 | pTempIndizes[nTempIndizes] = nPos; // has to be reconverted | |||
144 | // will be released at reconversion | |||
145 | ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; | |||
146 | } | |||
147 | else // direct way | |||
148 | { | |||
149 | pUnoArgs[nPos] = *(void **)pCppStack; | |||
150 | // no longer needed | |||
151 | TYPELIB_DANGER_RELEASE( pParamTypeDescr ){ if ((((pParamTypeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || ((pParamTypeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) typelib_typedescription_release( pParamTypeDescr ); }; | |||
152 | } | |||
153 | } | |||
154 | pCppStack += sizeof(sal_Int32); // standard parameter length | |||
155 | } | |||
156 | ||||
157 | // ExceptionHolder | |||
158 | uno_Any aUnoExc; // Any will be constructed by callee | |||
159 | uno_Any * pUnoExc = &aUnoExc; | |||
160 | ||||
161 | // invoke uno dispatch call | |||
162 | (*pThis->getUnoI()->pDispatcher)( | |||
163 | pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); | |||
164 | ||||
165 | // in case an exception occurred... | |||
166 | if (pUnoExc) | |||
167 | { | |||
168 | // destruct temporary in/inout params | |||
169 | for ( ; nTempIndizes--; ) | |||
170 | { | |||
171 | sal_Int32 nIndex = pTempIndizes[nTempIndizes]; | |||
172 | ||||
173 | if (pParams[nIndex].bIn) // is in/inout => was constructed | |||
174 | uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 ); | |||
175 | TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] ){ if ((((ppTempParamTypeDescr[nTempIndizes])->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || ((ppTempParamTypeDescr [nTempIndizes])->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) typelib_typedescription_release( ppTempParamTypeDescr[nTempIndizes ] ); }; | |||
176 | } | |||
177 | if (pReturnTypeDescr) | |||
178 | TYPELIB_DANGER_RELEASE( pReturnTypeDescr ){ if ((((pReturnTypeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || ((pReturnTypeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) typelib_typedescription_release( pReturnTypeDescr ); }; | |||
179 | ||||
180 | CPPU_CURRENT_NAMESPACEgcc3::raiseException( | |||
181 | &aUnoExc, pThis->getBridge()->getUno2Cpp() ); | |||
182 | // has to destruct the any | |||
183 | } | |||
184 | else // else no exception occurred... | |||
185 | { | |||
186 | // temporary params | |||
187 | for ( ; nTempIndizes--; ) | |||
188 | { | |||
189 | sal_Int32 nIndex = pTempIndizes[nTempIndizes]; | |||
190 | typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes]; | |||
191 | ||||
192 | if (pParams[nIndex].bOut) // inout/out | |||
193 | { | |||
194 | // convert and assign | |||
195 | uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); | |||
196 | uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr, | |||
197 | pThis->getBridge()->getUno2Cpp() ); | |||
198 | } | |||
199 | // destroy temp uno param | |||
200 | uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); | |||
201 | ||||
202 | TYPELIB_DANGER_RELEASE( pParamTypeDescr ){ if ((((pParamTypeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || ((pParamTypeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) typelib_typedescription_release( pParamTypeDescr ); }; | |||
203 | } | |||
204 | // return | |||
205 | if (pCppReturn) // has complex return | |||
206 | { | |||
207 | if (pUnoReturn != pCppReturn) // needs reconversion | |||
208 | { | |||
209 | uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr, | |||
210 | pThis->getBridge()->getUno2Cpp() ); | |||
211 | // destroy temp uno return | |||
212 | uno_destructData( pUnoReturn, pReturnTypeDescr, 0 ); | |||
213 | } | |||
214 | // complex return ptr is set to eax | |||
215 | *static_cast< void ** >(pReturnValue) = pCppReturn; | |||
216 | } | |||
217 | if (pReturnTypeDescr) | |||
218 | { | |||
219 | TYPELIB_DANGER_RELEASE( pReturnTypeDescr ){ if ((((pReturnTypeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || ((pReturnTypeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) typelib_typedescription_release( pReturnTypeDescr ); }; | |||
220 | } | |||
221 | } | |||
222 | } | |||
223 | ||||
224 | ||||
225 | //================================================================================================== | |||
226 | extern "C" void cpp_vtable_call( | |||
227 | int nFunctionIndex, int nVtableOffset, void** pCallStack, | |||
228 | void * pReturnValue ) | |||
229 | { | |||
230 | OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" )do { if (true && (!(sizeof(sal_Int32)==sizeof(void *) ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/usr/local/src/libreoffice/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx" ":" "230" ": "), "%s", "### unexpected!"); } } while (false); | |||
231 | ||||
232 | // pCallStack: ret adr, [ret *], this, params | |||
233 | void * pThis; | |||
234 | if( nFunctionIndex & 0x80000000 ) | |||
235 | { | |||
236 | nFunctionIndex &= 0x7fffffff; | |||
237 | pThis = pCallStack[2]; | |||
238 | } | |||
239 | else | |||
240 | { | |||
241 | pThis = pCallStack[1]; | |||
242 | } | |||
243 | pThis = static_cast< char * >(pThis) - nVtableOffset; | |||
244 | bridges::cpp_uno::shared::CppInterfaceProxy * pCppI | |||
245 | = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( | |||
246 | pThis); | |||
247 | ||||
248 | typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr(); | |||
249 | ||||
250 | OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" )do { if (true && (!(nFunctionIndex < pTypeDescr-> nMapFunctionIndexToMemberIndex))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/usr/local/src/libreoffice/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx" ":" "250" ": "), "%s", "### illegal vtable index!"); } } while (false); | |||
251 | if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex) | |||
252 | { | |||
253 | throw RuntimeException( | |||
254 | rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal vtable index!" )(&("illegal vtable index!")[0]), ((sal_Int32)((sizeof ("illegal vtable index!" ) / sizeof (("illegal vtable index!")[0]))-1)), (((rtl_TextEncoding ) 11))), | |||
255 | (XInterface *)pThis ); | |||
256 | } | |||
257 | ||||
258 | // determine called method | |||
259 | sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex]; | |||
260 | OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" )do { if (true && (!(nMemberPos < pTypeDescr->nAllMembers ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/usr/local/src/libreoffice/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx" ":" "260" ": "), "%s", "### illegal member index!"); } } while (false); | |||
261 | ||||
262 | TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); | |||
263 | ||||
264 | switch (aMemberDescr.get()->eTypeClass) | |||
265 | { | |||
266 | case typelib_TypeClass_INTERFACE_ATTRIBUTE: | |||
267 | { | |||
268 | if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex) | |||
269 | { | |||
270 | // is GET method | |||
271 | cpp2uno_call( | |||
272 | pCppI, aMemberDescr.get(), | |||
273 | ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef, | |||
274 | 0, 0, // no params | |||
275 | pCallStack, pReturnValue ); | |||
276 | } | |||
277 | else | |||
278 | { | |||
279 | // is SET method | |||
280 | typelib_MethodParameter aParam; | |||
281 | aParam.pTypeRef = | |||
282 | ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef; | |||
283 | aParam.bIn = sal_True((sal_Bool)1); | |||
284 | aParam.bOut = sal_False((sal_Bool)0); | |||
285 | ||||
286 | cpp2uno_call( | |||
287 | pCppI, aMemberDescr.get(), | |||
288 | 0, // indicates void return | |||
289 | 1, &aParam, | |||
290 | pCallStack, pReturnValue ); | |||
291 | } | |||
292 | break; | |||
293 | } | |||
294 | case typelib_TypeClass_INTERFACE_METHOD: | |||
295 | { | |||
296 | // is METHOD | |||
297 | switch (nFunctionIndex) | |||
298 | { | |||
299 | case 1: // acquire() | |||
300 | pCppI->acquireProxy(); // non virtual call! | |||
301 | break; | |||
302 | case 2: // release() | |||
303 | pCppI->releaseProxy(); // non virtual call! | |||
304 | break; | |||
305 | case 0: // queryInterface() opt | |||
306 | { | |||
307 | typelib_TypeDescription * pTD = 0; | |||
308 | TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->getTypeLibType() ){ typelib_TypeDescriptionReference * pMacroTypeRef = (reinterpret_cast < Type * >( pCallStack[3] )->getTypeLibType()); typelib_TypeDescription ** ppMacroTypeDescr = (&pTD); if (((pMacroTypeRef->eTypeClass ) == typelib_TypeClass_INTERFACE_METHOD || (pMacroTypeRef-> eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE)) { typelib_typedescriptionreference_getDescription ( ppMacroTypeDescr, pMacroTypeRef ); } else if (!pMacroTypeRef ->pType || !pMacroTypeRef->pType->pWeakRef) { typelib_typedescriptionreference_getDescription ( ppMacroTypeDescr, pMacroTypeRef ); if (*ppMacroTypeDescr) typelib_typedescription_release ( *ppMacroTypeDescr ); } else { *ppMacroTypeDescr = pMacroTypeRef ->pType; } }; | |||
309 | if (pTD) | |||
310 | { | |||
311 | XInterface * pInterface = 0; | |||
312 | (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)( | |||
313 | pCppI->getBridge()->getCppEnv(), | |||
314 | (void **)&pInterface, pCppI->getOid().pData, | |||
315 | (typelib_InterfaceTypeDescription *)pTD ); | |||
316 | ||||
317 | if (pInterface) | |||
318 | { | |||
319 | ::uno_any_construct( | |||
320 | reinterpret_cast< uno_Any * >( pCallStack[1] ), | |||
321 | &pInterface, pTD, cpp_acquire ); | |||
322 | pInterface->release(); | |||
323 | TYPELIB_DANGER_RELEASE( pTD ){ if ((((pTD)->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || ((pTD)->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) typelib_typedescription_release( pTD ); }; | |||
324 | *static_cast< void ** >(pReturnValue) = pCallStack[1]; | |||
325 | break; | |||
326 | } | |||
327 | TYPELIB_DANGER_RELEASE( pTD ){ if ((((pTD)->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || ((pTD)->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) typelib_typedescription_release( pTD ); }; | |||
328 | } | |||
329 | } // else perform queryInterface() | |||
330 | default: | |||
331 | cpp2uno_call( | |||
332 | pCppI, aMemberDescr.get(), | |||
333 | ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef, | |||
334 | ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams, | |||
335 | ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams, | |||
336 | pCallStack, pReturnValue ); | |||
337 | } | |||
338 | break; | |||
339 | } | |||
340 | default: | |||
341 | { | |||
342 | throw RuntimeException( | |||
343 | rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "no member description found!" )(&("no member description found!")[0]), ((sal_Int32)((sizeof ("no member description found!") / sizeof (("no member description found!" )[0]))-1)), (((rtl_TextEncoding) 11))), | |||
344 | (XInterface *)pThis ); | |||
345 | } | |||
346 | } | |||
347 | } | |||
348 | ||||
349 | //================================================================================================== | |||
350 | extern "C" void privateSnippetExecutorGeneral(); | |||
351 | extern "C" void privateSnippetExecutorVoid(); | |||
352 | extern "C" void privateSnippetExecutorHyper(); | |||
353 | extern "C" void privateSnippetExecutorFloat(); | |||
354 | extern "C" void privateSnippetExecutorDouble(); | |||
355 | extern "C" void privateSnippetExecutorClass(); | |||
356 | extern "C" typedef void (*PrivateSnippetExecutor)(); | |||
357 | ||||
358 | int const codeSnippetSize = 16; | |||
359 | ||||
360 | #if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX) || \ | |||
361 | defined(DRAGONFLY) | |||
362 | namespace | |||
363 | { | |||
364 | PrivateSnippetExecutor returnsInRegister(typelib_TypeDescriptionReference * pReturnTypeRef) | |||
365 | { | |||
366 | //These archs apparently are returning small structs in registers, while Linux | |||
367 | //doesn't | |||
368 | PrivateSnippetExecutor exec=NULL__null; | |||
369 | ||||
370 | typelib_TypeDescription * pReturnTypeDescr = 0; | |||
371 | TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ){ typelib_TypeDescriptionReference * pMacroTypeRef = (pReturnTypeRef ); typelib_TypeDescription ** ppMacroTypeDescr = (&pReturnTypeDescr ); if (((pMacroTypeRef->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || (pMacroTypeRef->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) { typelib_typedescriptionreference_getDescription( ppMacroTypeDescr , pMacroTypeRef ); } else if (!pMacroTypeRef->pType || !pMacroTypeRef ->pType->pWeakRef) { typelib_typedescriptionreference_getDescription ( ppMacroTypeDescr, pMacroTypeRef ); if (*ppMacroTypeDescr) typelib_typedescription_release ( *ppMacroTypeDescr ); } else { *ppMacroTypeDescr = pMacroTypeRef ->pType; } }; | |||
372 | const bool bSimpleReturnStruct = x86::isSimpleReturnType(pReturnTypeDescr); | |||
373 | const sal_Int32 nRetSize = pReturnTypeDescr->nSize; | |||
374 | TYPELIB_DANGER_RELEASE( pReturnTypeDescr ){ if ((((pReturnTypeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || ((pReturnTypeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) typelib_typedescription_release( pReturnTypeDescr ); }; | |||
375 | if (bSimpleReturnStruct) | |||
376 | { | |||
377 | exec = privateSnippetExecutorGeneral; // fills eax | |||
378 | if (nRetSize > 4) | |||
379 | exec = privateSnippetExecutorHyper; // fills eax/edx | |||
380 | } | |||
381 | return exec; | |||
382 | } | |||
383 | } | |||
384 | #endif | |||
385 | ||||
386 | unsigned char * codeSnippet( | |||
387 | unsigned char * code, sal_PtrDiff writetoexecdiff, sal_Int32 functionIndex, sal_Int32 vtableOffset, | |||
388 | typelib_TypeDescriptionReference * pReturnTypeRef) | |||
389 | { | |||
390 | PrivateSnippetExecutor exec; | |||
391 | typelib_TypeClass eReturnClass = pReturnTypeRef ? pReturnTypeRef->eTypeClass : typelib_TypeClass_VOID; | |||
392 | switch (eReturnClass) | |||
393 | { | |||
394 | case typelib_TypeClass_VOID: | |||
395 | exec = privateSnippetExecutorVoid; | |||
396 | break; | |||
397 | case typelib_TypeClass_HYPER: | |||
398 | case typelib_TypeClass_UNSIGNED_HYPER: | |||
399 | exec = privateSnippetExecutorHyper; | |||
400 | break; | |||
401 | case typelib_TypeClass_FLOAT: | |||
402 | exec = privateSnippetExecutorFloat; | |||
403 | break; | |||
404 | case typelib_TypeClass_DOUBLE: | |||
405 | exec = privateSnippetExecutorDouble; | |||
406 | break; | |||
407 | case typelib_TypeClass_STRUCT: | |||
408 | case typelib_TypeClass_EXCEPTION: | |||
409 | #if defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX) || \ | |||
410 | defined(DRAGONFLY) | |||
411 | exec = returnsInRegister(pReturnTypeRef); | |||
412 | if (!exec) | |||
413 | { | |||
414 | exec = privateSnippetExecutorClass; | |||
415 | functionIndex |= 0x80000000; | |||
416 | } | |||
417 | break; | |||
418 | #endif | |||
419 | case typelib_TypeClass_STRING: | |||
420 | case typelib_TypeClass_TYPE: | |||
421 | case typelib_TypeClass_ANY: | |||
422 | case typelib_TypeClass_SEQUENCE: | |||
423 | case typelib_TypeClass_INTERFACE: | |||
424 | exec = privateSnippetExecutorClass; | |||
425 | functionIndex |= 0x80000000; | |||
426 | break; | |||
427 | default: | |||
428 | exec = privateSnippetExecutorGeneral; | |||
429 | break; | |||
430 | } | |||
431 | unsigned char * p = code; | |||
432 | OSL_ASSERT(sizeof (sal_Int32) == 4)do { if (true && (!(sizeof (sal_Int32) == 4))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx" ":" "432" ": "), "OSL_ASSERT: %s", "sizeof (sal_Int32) == 4" ); } } while (false); | |||
433 | // mov function_index, %eax: | |||
434 | *p++ = 0xB8; | |||
435 | *reinterpret_cast< sal_Int32 * >(p) = functionIndex; | |||
436 | p += sizeof (sal_Int32); | |||
437 | // mov vtable_offset, %edx: | |||
438 | *p++ = 0xBA; | |||
439 | *reinterpret_cast< sal_Int32 * >(p) = vtableOffset; | |||
440 | p += sizeof (sal_Int32); | |||
441 | // jmp privateSnippetExecutor: | |||
442 | *p++ = 0xE9; | |||
443 | *reinterpret_cast< sal_Int32 * >(p) | |||
444 | = ((unsigned char *) exec) - p - sizeof (sal_Int32) - writetoexecdiff; | |||
445 | p += sizeof (sal_Int32); | |||
446 | OSL_ASSERT(p - code <= codeSnippetSize)do { if (true && (!(p - code <= codeSnippetSize))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/usr/local/src/libreoffice/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx" ":" "446" ": "), "OSL_ASSERT: %s", "p - code <= codeSnippetSize" ); } } while (false); | |||
447 | return code + codeSnippetSize; | |||
448 | } | |||
449 | ||||
450 | } | |||
451 | ||||
452 | struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; }; | |||
453 | ||||
454 | bridges::cpp_uno::shared::VtableFactory::Slot * | |||
455 | bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block) { | |||
456 | return static_cast< Slot * >(block) + 2; | |||
457 | } | |||
458 | ||||
459 | sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize( | |||
460 | sal_Int32 slotCount) | |||
461 | { | |||
462 | return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize; | |||
463 | } | |||
464 | ||||
465 | bridges::cpp_uno::shared::VtableFactory::Slot * | |||
466 | bridges::cpp_uno::shared::VtableFactory::initializeBlock( | |||
467 | void * block, sal_Int32 slotCount) | |||
468 | { | |||
469 | Slot * slots = mapBlockToVtable(block); | |||
470 | slots[-2].fn = 0; | |||
471 | slots[-1].fn = 0; | |||
472 | return slots + slotCount; | |||
473 | } | |||
474 | ||||
475 | unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions( | |||
476 | Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff, | |||
477 | typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset, | |||
478 | sal_Int32 functionCount, sal_Int32 vtableOffset) | |||
479 | { | |||
480 | (*slots) -= functionCount; | |||
481 | Slot * s = *slots; | |||
482 | for (sal_Int32 i = 0; i < type->nMembers; ++i) { | |||
| ||||
483 | typelib_TypeDescription * member = 0; | |||
484 | TYPELIB_DANGER_GET(&member, type->ppMembers[i]){ typelib_TypeDescriptionReference * pMacroTypeRef = (type-> ppMembers[i]); typelib_TypeDescription ** ppMacroTypeDescr = ( &member); if (((pMacroTypeRef->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || (pMacroTypeRef->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) { typelib_typedescriptionreference_getDescription( ppMacroTypeDescr , pMacroTypeRef ); } else if (!pMacroTypeRef->pType || !pMacroTypeRef ->pType->pWeakRef) { typelib_typedescriptionreference_getDescription ( ppMacroTypeDescr, pMacroTypeRef ); if (*ppMacroTypeDescr) typelib_typedescription_release ( *ppMacroTypeDescr ); } else { *ppMacroTypeDescr = pMacroTypeRef ->pType; } }; | |||
485 | OSL_ASSERT(member != 0)do { if (true && (!(member != 0))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx" ":" "485" ": "), "OSL_ASSERT: %s", "member != 0"); } } while (false); | |||
486 | switch (member->eTypeClass) { | |||
| ||||
487 | case typelib_TypeClass_INTERFACE_ATTRIBUTE: | |||
488 | // Getter: | |||
489 | (s++)->fn = code + writetoexecdiff; | |||
490 | code = codeSnippet( | |||
491 | code, writetoexecdiff, functionOffset++, vtableOffset, | |||
492 | reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >( | |||
493 | member)->pAttributeTypeRef); | |||
494 | // Setter: | |||
495 | if (!reinterpret_cast< | |||
496 | typelib_InterfaceAttributeTypeDescription * >( | |||
497 | member)->bReadOnly) | |||
498 | { | |||
499 | (s++)->fn = code + writetoexecdiff; | |||
500 | code = codeSnippet( | |||
501 | code, writetoexecdiff, functionOffset++, vtableOffset, | |||
502 | NULL__null); | |||
503 | } | |||
504 | break; | |||
505 | ||||
506 | case typelib_TypeClass_INTERFACE_METHOD: | |||
507 | (s++)->fn = code + writetoexecdiff; | |||
508 | code = codeSnippet( | |||
509 | code, writetoexecdiff, functionOffset++, vtableOffset, | |||
510 | reinterpret_cast< typelib_InterfaceMethodTypeDescription * >( | |||
511 | member)->pReturnTypeRef); | |||
512 | break; | |||
513 | ||||
514 | default: | |||
515 | OSL_ASSERT(false)do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx" ":" "515" ": "), "OSL_ASSERT: %s", "false"); } } while (false ); | |||
516 | break; | |||
517 | } | |||
518 | TYPELIB_DANGER_RELEASE(member){ if ((((member)->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || ((member)->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) typelib_typedescription_release( member ); }; | |||
519 | } | |||
520 | return code; | |||
521 | } | |||
522 | ||||
523 | void bridges::cpp_uno::shared::VtableFactory::flushCode( | |||
524 | unsigned char const *, unsigned char const *) | |||
525 | {} | |||
526 | ||||
527 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |