File: | bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx |
Location: | line 151, column 17 |
Description: | Access to field 'eTypeClass' results in a dereference of a null pointer (loaded from variable 'pParamTypeDescr') |
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: */ |