| 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: */ |