| File: | bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx |
| Location: | line 111, column 21 |
| 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: */ |