1*61dff127SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*61dff127SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*61dff127SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*61dff127SAndrew Rist * distributed with this work for additional information 6*61dff127SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*61dff127SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*61dff127SAndrew Rist * "License"); you may not use this file except in compliance 9*61dff127SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*61dff127SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*61dff127SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*61dff127SAndrew Rist * software distributed under the License is distributed on an 15*61dff127SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*61dff127SAndrew Rist * KIND, either express or implied. See the License for the 17*61dff127SAndrew Rist * specific language governing permissions and limitations 18*61dff127SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*61dff127SAndrew Rist *************************************************************/ 21*61dff127SAndrew Rist 22*61dff127SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_bridges.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <com/sun/star/uno/genfunc.hxx> 28cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp" 29cdf0e10cSrcweir #include <uno/data.h> 30cdf0e10cSrcweir #include <sal/alloca.h> 31cdf0e10cSrcweir 32cdf0e10cSrcweir #include "bridges/cpp_uno/shared/bridge.hxx" 33cdf0e10cSrcweir #include "bridges/cpp_uno/shared/types.hxx" 34cdf0e10cSrcweir #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx" 35cdf0e10cSrcweir #include "bridges/cpp_uno/shared/vtables.hxx" 36cdf0e10cSrcweir 37cdf0e10cSrcweir #include "share.hxx" 38cdf0e10cSrcweir #include "smallstruct.hxx" 39cdf0e10cSrcweir 40cdf0e10cSrcweir using namespace ::rtl; 41cdf0e10cSrcweir using namespace ::com::sun::star::uno; 42cdf0e10cSrcweir 43cdf0e10cSrcweir namespace 44cdf0e10cSrcweir { 45cdf0e10cSrcweir 46cdf0e10cSrcweir //================================================================================================== 47cdf0e10cSrcweir // The call instruction within the asm section of callVirtualMethod may throw 48cdf0e10cSrcweir // exceptions. So that the compiler handles this correctly, it is important 49cdf0e10cSrcweir // that (a) callVirtualMethod might call dummy_can_throw_anything (although this 50cdf0e10cSrcweir // never happens at runtime), which in turn can throw exceptions, and (b) 51cdf0e10cSrcweir // callVirtualMethod is not inlined at its call site (so that any exceptions are 52cdf0e10cSrcweir // caught which are thrown from the instruction calling callVirtualMethod): 53cdf0e10cSrcweir void callVirtualMethod( 54cdf0e10cSrcweir void * pAdjustedThisPtr, 55cdf0e10cSrcweir sal_Int32 nVtableIndex, 56cdf0e10cSrcweir void * pRegisterReturn, 57cdf0e10cSrcweir typelib_TypeDescription const * returnType, 58cdf0e10cSrcweir sal_Int32 * pStackLongs, 59cdf0e10cSrcweir sal_Int32 nStackLongs ) __attribute__((noinline)); 60cdf0e10cSrcweir 61cdf0e10cSrcweir void callVirtualMethod( 62cdf0e10cSrcweir void * pAdjustedThisPtr, 63cdf0e10cSrcweir sal_Int32 nVtableIndex, 64cdf0e10cSrcweir void * pRegisterReturn, 65cdf0e10cSrcweir typelib_TypeDescription const * returnType, 66cdf0e10cSrcweir sal_Int32 * pStackLongs, 67cdf0e10cSrcweir sal_Int32 nStackLongs ) 68cdf0e10cSrcweir { 69cdf0e10cSrcweir // parameter list is mixed list of * and values 70cdf0e10cSrcweir // reference parameters are pointers 71cdf0e10cSrcweir 72cdf0e10cSrcweir OSL_ENSURE( pStackLongs && pAdjustedThisPtr, "### null ptr!" ); 73cdf0e10cSrcweir OSL_ENSURE( (sizeof(void *) == 4) && (sizeof(sal_Int32) == 4), "### unexpected size of int!" ); 74cdf0e10cSrcweir OSL_ENSURE( nStackLongs && pStackLongs, "### no stack in callVirtualMethod !" ); 75cdf0e10cSrcweir 76cdf0e10cSrcweir // never called 77cdf0e10cSrcweir if (! pAdjustedThisPtr) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something 78cdf0e10cSrcweir 79cdf0e10cSrcweir volatile long edx = 0, eax = 0; // for register returns 80cdf0e10cSrcweir void * stackptr; 81cdf0e10cSrcweir asm volatile ( 82cdf0e10cSrcweir "mov %%esp, %6\n\t" 83cdf0e10cSrcweir // copy values 84cdf0e10cSrcweir "mov %0, %%eax\n\t" 85cdf0e10cSrcweir "mov %%eax, %%edx\n\t" 86cdf0e10cSrcweir "dec %%edx\n\t" 87cdf0e10cSrcweir "shl $2, %%edx\n\t" 88cdf0e10cSrcweir "add %1, %%edx\n" 89cdf0e10cSrcweir "Lcopy:\n\t" 90cdf0e10cSrcweir "pushl 0(%%edx)\n\t" 91cdf0e10cSrcweir "sub $4, %%edx\n\t" 92cdf0e10cSrcweir "dec %%eax\n\t" 93cdf0e10cSrcweir "jne Lcopy\n\t" 94cdf0e10cSrcweir // do the actual call 95cdf0e10cSrcweir "mov %2, %%edx\n\t" 96cdf0e10cSrcweir "mov 0(%%edx), %%edx\n\t" 97cdf0e10cSrcweir "mov %3, %%eax\n\t" 98cdf0e10cSrcweir "shl $2, %%eax\n\t" 99cdf0e10cSrcweir "add %%eax, %%edx\n\t" 100cdf0e10cSrcweir "mov 0(%%edx), %%edx\n\t" 101cdf0e10cSrcweir "call *%%edx\n\t" 102cdf0e10cSrcweir // save return registers 103cdf0e10cSrcweir "mov %%eax, %4\n\t" 104cdf0e10cSrcweir "mov %%edx, %5\n\t" 105cdf0e10cSrcweir // cleanup stack 106cdf0e10cSrcweir "mov %6, %%esp\n\t" 107cdf0e10cSrcweir : 108cdf0e10cSrcweir : "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr), 109cdf0e10cSrcweir "m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr) 110cdf0e10cSrcweir : "eax", "edx" ); 111cdf0e10cSrcweir switch( returnType->eTypeClass ) 112cdf0e10cSrcweir { 113cdf0e10cSrcweir case typelib_TypeClass_VOID: 114cdf0e10cSrcweir break; 115cdf0e10cSrcweir case typelib_TypeClass_HYPER: 116cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_HYPER: 117cdf0e10cSrcweir ((long*)pRegisterReturn)[1] = edx; 118cdf0e10cSrcweir case typelib_TypeClass_LONG: 119cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_LONG: 120cdf0e10cSrcweir case typelib_TypeClass_CHAR: 121cdf0e10cSrcweir case typelib_TypeClass_ENUM: 122cdf0e10cSrcweir ((long*)pRegisterReturn)[0] = eax; 123cdf0e10cSrcweir break; 124cdf0e10cSrcweir case typelib_TypeClass_SHORT: 125cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_SHORT: 126cdf0e10cSrcweir *(unsigned short*)pRegisterReturn = eax; 127cdf0e10cSrcweir break; 128cdf0e10cSrcweir case typelib_TypeClass_BOOLEAN: 129cdf0e10cSrcweir case typelib_TypeClass_BYTE: 130cdf0e10cSrcweir *(unsigned char*)pRegisterReturn = eax; 131cdf0e10cSrcweir break; 132cdf0e10cSrcweir case typelib_TypeClass_FLOAT: 133cdf0e10cSrcweir asm ( "fstps %0" : : "m"(*(char *)pRegisterReturn) ); 134cdf0e10cSrcweir break; 135cdf0e10cSrcweir case typelib_TypeClass_DOUBLE: 136cdf0e10cSrcweir asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) ); 137cdf0e10cSrcweir break; 138cdf0e10cSrcweir case typelib_TypeClass_STRUCT: 139cdf0e10cSrcweir if (bridges::cpp_uno::shared::isSmallStruct(returnType)) { 140cdf0e10cSrcweir if (returnType->nSize <= 1) { 141cdf0e10cSrcweir *(unsigned char*)pRegisterReturn = eax; 142cdf0e10cSrcweir } 143cdf0e10cSrcweir else if (returnType->nSize <= 2) { 144cdf0e10cSrcweir *(unsigned short*)pRegisterReturn = eax; 145cdf0e10cSrcweir } 146cdf0e10cSrcweir else if (returnType->nSize <= 8) { 147cdf0e10cSrcweir ((long*)pRegisterReturn)[0] = eax; 148cdf0e10cSrcweir if (returnType->nSize > 4) { 149cdf0e10cSrcweir ((long*)pRegisterReturn)[1] = edx; 150cdf0e10cSrcweir } 151cdf0e10cSrcweir } 152cdf0e10cSrcweir } 153cdf0e10cSrcweir break; 154cdf0e10cSrcweir default: 155cdf0e10cSrcweir break; 156cdf0e10cSrcweir } 157cdf0e10cSrcweir } 158cdf0e10cSrcweir 159cdf0e10cSrcweir //================================================================================================== 160cdf0e10cSrcweir static void cpp_call( 161cdf0e10cSrcweir bridges::cpp_uno::shared::UnoInterfaceProxy * pThis, 162cdf0e10cSrcweir bridges::cpp_uno::shared::VtableSlot aVtableSlot, 163cdf0e10cSrcweir typelib_TypeDescriptionReference * pReturnTypeRef, 164cdf0e10cSrcweir sal_Int32 nParams, typelib_MethodParameter * pParams, 165cdf0e10cSrcweir void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc ) 166cdf0e10cSrcweir { 167cdf0e10cSrcweir // max space for: [complex ret ptr], values|ptr ... 168cdf0e10cSrcweir char * pCppStack = 169cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 170cdf0e10cSrcweir (char *)malloc( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) ); 171cdf0e10cSrcweir #else 172cdf0e10cSrcweir (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) ); 173cdf0e10cSrcweir #endif 174cdf0e10cSrcweir char * pCppStackStart = pCppStack; 175cdf0e10cSrcweir 176cdf0e10cSrcweir // return 177cdf0e10cSrcweir typelib_TypeDescription * pReturnTypeDescr = 0; 178cdf0e10cSrcweir TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); 179cdf0e10cSrcweir OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" ); 180cdf0e10cSrcweir 181cdf0e10cSrcweir void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion 182cdf0e10cSrcweir 183cdf0e10cSrcweir if (pReturnTypeDescr) 184cdf0e10cSrcweir { 185cdf0e10cSrcweir if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr )) 186cdf0e10cSrcweir { 187cdf0e10cSrcweir pCppReturn = pUnoReturn; // direct way for simple types 188cdf0e10cSrcweir } 189cdf0e10cSrcweir else 190cdf0e10cSrcweir { 191cdf0e10cSrcweir // complex return via ptr 192cdf0e10cSrcweir pCppReturn 193cdf0e10cSrcweir = (bridges::cpp_uno::shared::relatesToInterfaceType( 194cdf0e10cSrcweir pReturnTypeDescr ) 195cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 196cdf0e10cSrcweir ? malloc( pReturnTypeDescr->nSize ) 197cdf0e10cSrcweir #else 198cdf0e10cSrcweir ? alloca( pReturnTypeDescr->nSize ) 199cdf0e10cSrcweir #endif 200cdf0e10cSrcweir : pUnoReturn); // direct way 201cdf0e10cSrcweir if (!bridges::cpp_uno::shared::isSmallStruct(pReturnTypeDescr)) { 202cdf0e10cSrcweir *(void **)pCppStack = pCppReturn; 203cdf0e10cSrcweir pCppStack += sizeof(void *); 204cdf0e10cSrcweir } 205cdf0e10cSrcweir } 206cdf0e10cSrcweir } 207cdf0e10cSrcweir // push this 208cdf0e10cSrcweir void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI()) 209cdf0e10cSrcweir + aVtableSlot.offset; 210cdf0e10cSrcweir *(void**)pCppStack = pAdjustedThisPtr; 211cdf0e10cSrcweir pCppStack += sizeof( void* ); 212cdf0e10cSrcweir 213cdf0e10cSrcweir // stack space 214cdf0e10cSrcweir OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" ); 215cdf0e10cSrcweir // args 216cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 217cdf0e10cSrcweir void ** pCppArgs = (void **)malloc( 3 * sizeof(void *) * nParams ); 218cdf0e10cSrcweir #else 219cdf0e10cSrcweir void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams ); 220cdf0e10cSrcweir #endif 221cdf0e10cSrcweir // indizes of values this have to be converted (interface conversion cpp<=>uno) 222cdf0e10cSrcweir sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams); 223cdf0e10cSrcweir // type descriptions for reconversions 224cdf0e10cSrcweir typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams)); 225cdf0e10cSrcweir 226cdf0e10cSrcweir sal_Int32 nTempIndizes = 0; 227cdf0e10cSrcweir 228cdf0e10cSrcweir for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) 229cdf0e10cSrcweir { 230cdf0e10cSrcweir const typelib_MethodParameter & rParam = pParams[nPos]; 231cdf0e10cSrcweir typelib_TypeDescription * pParamTypeDescr = 0; 232cdf0e10cSrcweir TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); 233cdf0e10cSrcweir 234cdf0e10cSrcweir if (!rParam.bOut 235cdf0e10cSrcweir && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) 236cdf0e10cSrcweir { 237cdf0e10cSrcweir uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr, 238cdf0e10cSrcweir pThis->getBridge()->getUno2Cpp() ); 239cdf0e10cSrcweir 240cdf0e10cSrcweir switch (pParamTypeDescr->eTypeClass) 241cdf0e10cSrcweir { 242cdf0e10cSrcweir case typelib_TypeClass_HYPER: 243cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_HYPER: 244cdf0e10cSrcweir case typelib_TypeClass_DOUBLE: 245cdf0e10cSrcweir pCppStack += sizeof(sal_Int32); // extra long 246cdf0e10cSrcweir break; 247cdf0e10cSrcweir default: 248cdf0e10cSrcweir break; 249cdf0e10cSrcweir } 250cdf0e10cSrcweir // no longer needed 251cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 252cdf0e10cSrcweir } 253cdf0e10cSrcweir else // ptr to complex value | ref 254cdf0e10cSrcweir { 255cdf0e10cSrcweir if (! rParam.bIn) // is pure out 256cdf0e10cSrcweir { 257cdf0e10cSrcweir // cpp out is constructed mem, uno out is not! 258cdf0e10cSrcweir uno_constructData( 259cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 260cdf0e10cSrcweir *(void **)pCppStack = pCppArgs[nPos] = malloc( pParamTypeDescr->nSize ), 261cdf0e10cSrcweir #else 262cdf0e10cSrcweir *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ), 263cdf0e10cSrcweir #endif 264cdf0e10cSrcweir pParamTypeDescr ); 265cdf0e10cSrcweir pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call 266cdf0e10cSrcweir // will be released at reconversion 267cdf0e10cSrcweir ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 268cdf0e10cSrcweir } 269cdf0e10cSrcweir // is in/inout 270cdf0e10cSrcweir else if (bridges::cpp_uno::shared::relatesToInterfaceType( 271cdf0e10cSrcweir pParamTypeDescr )) 272cdf0e10cSrcweir { 273cdf0e10cSrcweir uno_copyAndConvertData( 274cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 275cdf0e10cSrcweir *(void **)pCppStack = pCppArgs[nPos] = malloc( pParamTypeDescr->nSize ), 276cdf0e10cSrcweir #else 277cdf0e10cSrcweir *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ), 278cdf0e10cSrcweir #endif 279cdf0e10cSrcweir pUnoArgs[nPos], pParamTypeDescr, 280cdf0e10cSrcweir pThis->getBridge()->getUno2Cpp() ); 281cdf0e10cSrcweir 282cdf0e10cSrcweir pTempIndizes[nTempIndizes] = nPos; // has to be reconverted 283cdf0e10cSrcweir // will be released at reconversion 284cdf0e10cSrcweir ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 285cdf0e10cSrcweir } 286cdf0e10cSrcweir else // direct way 287cdf0e10cSrcweir { 288cdf0e10cSrcweir *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos]; 289cdf0e10cSrcweir // no longer needed 290cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 291cdf0e10cSrcweir } 292cdf0e10cSrcweir } 293cdf0e10cSrcweir pCppStack += sizeof(sal_Int32); // standard parameter length 294cdf0e10cSrcweir } 295cdf0e10cSrcweir 296cdf0e10cSrcweir try 297cdf0e10cSrcweir { 298cdf0e10cSrcweir OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" ); 299cdf0e10cSrcweir callVirtualMethod( 300cdf0e10cSrcweir pAdjustedThisPtr, aVtableSlot.index, 301cdf0e10cSrcweir pCppReturn, pReturnTypeDescr, 302cdf0e10cSrcweir (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) ); 303cdf0e10cSrcweir // NO exception occured... 304cdf0e10cSrcweir *ppUnoExc = 0; 305cdf0e10cSrcweir 306cdf0e10cSrcweir // reconvert temporary params 307cdf0e10cSrcweir for ( ; nTempIndizes--; ) 308cdf0e10cSrcweir { 309cdf0e10cSrcweir sal_Int32 nIndex = pTempIndizes[nTempIndizes]; 310cdf0e10cSrcweir typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes]; 311cdf0e10cSrcweir 312cdf0e10cSrcweir if (pParams[nIndex].bIn) 313cdf0e10cSrcweir { 314cdf0e10cSrcweir if (pParams[nIndex].bOut) // inout 315cdf0e10cSrcweir { 316cdf0e10cSrcweir uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value 317cdf0e10cSrcweir uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr, 318cdf0e10cSrcweir pThis->getBridge()->getCpp2Uno() ); 319cdf0e10cSrcweir } 320cdf0e10cSrcweir } 321cdf0e10cSrcweir else // pure out 322cdf0e10cSrcweir { 323cdf0e10cSrcweir uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr, 324cdf0e10cSrcweir pThis->getBridge()->getCpp2Uno() ); 325cdf0e10cSrcweir } 326cdf0e10cSrcweir // destroy temp cpp param => cpp: every param was constructed 327cdf0e10cSrcweir uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); 328cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 329cdf0e10cSrcweir free( pCppArgs[nIndex] ); 330cdf0e10cSrcweir #endif 331cdf0e10cSrcweir 332cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 333cdf0e10cSrcweir } 334cdf0e10cSrcweir // return value 335cdf0e10cSrcweir if (pCppReturn && pUnoReturn != pCppReturn) 336cdf0e10cSrcweir { 337cdf0e10cSrcweir uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr, 338cdf0e10cSrcweir pThis->getBridge()->getCpp2Uno() ); 339cdf0e10cSrcweir uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release ); 340cdf0e10cSrcweir } 341cdf0e10cSrcweir } 342cdf0e10cSrcweir catch (...) 343cdf0e10cSrcweir { 344cdf0e10cSrcweir // fill uno exception 345cdf0e10cSrcweir fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() ); 346cdf0e10cSrcweir 347cdf0e10cSrcweir // temporary params 348cdf0e10cSrcweir for ( ; nTempIndizes--; ) 349cdf0e10cSrcweir { 350cdf0e10cSrcweir sal_Int32 nIndex = pTempIndizes[nTempIndizes]; 351cdf0e10cSrcweir // destroy temp cpp param => cpp: every param was constructed 352cdf0e10cSrcweir uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release ); 353cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] ); 354cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 355cdf0e10cSrcweir free( pCppArgs[nIndex] ); 356cdf0e10cSrcweir #endif 357cdf0e10cSrcweir } 358cdf0e10cSrcweir // return type 359cdf0e10cSrcweir if (pReturnTypeDescr) 360cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); 361cdf0e10cSrcweir } 362cdf0e10cSrcweir if (pCppReturn && pUnoReturn != pCppReturn) 363cdf0e10cSrcweir { 364cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 365cdf0e10cSrcweir free( pCppReturn ); 366cdf0e10cSrcweir #endif 367cdf0e10cSrcweir } 368cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 369cdf0e10cSrcweir free( pCppStackStart ); 370cdf0e10cSrcweir #endif 371cdf0e10cSrcweir } 372cdf0e10cSrcweir 373cdf0e10cSrcweir } 374cdf0e10cSrcweir 375cdf0e10cSrcweir namespace bridges { namespace cpp_uno { namespace shared { 376cdf0e10cSrcweir 377cdf0e10cSrcweir void unoInterfaceProxyDispatch( 378cdf0e10cSrcweir uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr, 379cdf0e10cSrcweir void * pReturn, void * pArgs[], uno_Any ** ppException ) 380cdf0e10cSrcweir { 381cdf0e10cSrcweir // is my surrogate 382cdf0e10cSrcweir bridges::cpp_uno::shared::UnoInterfaceProxy * pThis 383cdf0e10cSrcweir = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI); 384cdf0e10cSrcweir 385cdf0e10cSrcweir switch (pMemberDescr->eTypeClass) 386cdf0e10cSrcweir { 387cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_ATTRIBUTE: 388cdf0e10cSrcweir { 389cdf0e10cSrcweir VtableSlot aVtableSlot( 390cdf0e10cSrcweir getVtableSlot( 391cdf0e10cSrcweir reinterpret_cast< 392cdf0e10cSrcweir typelib_InterfaceAttributeTypeDescription const * >( 393cdf0e10cSrcweir pMemberDescr))); 394cdf0e10cSrcweir if (pReturn) 395cdf0e10cSrcweir { 396cdf0e10cSrcweir // dependent dispatch 397cdf0e10cSrcweir cpp_call( 398cdf0e10cSrcweir pThis, aVtableSlot, 399cdf0e10cSrcweir ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef, 400cdf0e10cSrcweir 0, 0, // no params 401cdf0e10cSrcweir pReturn, pArgs, ppException ); 402cdf0e10cSrcweir } 403cdf0e10cSrcweir else 404cdf0e10cSrcweir { 405cdf0e10cSrcweir // is SET 406cdf0e10cSrcweir typelib_MethodParameter aParam; 407cdf0e10cSrcweir aParam.pTypeRef = 408cdf0e10cSrcweir ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef; 409cdf0e10cSrcweir aParam.bIn = sal_True; 410cdf0e10cSrcweir aParam.bOut = sal_False; 411cdf0e10cSrcweir 412cdf0e10cSrcweir typelib_TypeDescriptionReference * pReturnTypeRef = 0; 413cdf0e10cSrcweir OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") ); 414cdf0e10cSrcweir typelib_typedescriptionreference_new( 415cdf0e10cSrcweir &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData ); 416cdf0e10cSrcweir 417cdf0e10cSrcweir // dependent dispatch 418cdf0e10cSrcweir aVtableSlot.index += 1; // get, then set method 419cdf0e10cSrcweir cpp_call( 420cdf0e10cSrcweir pThis, aVtableSlot, 421cdf0e10cSrcweir pReturnTypeRef, 422cdf0e10cSrcweir 1, &aParam, 423cdf0e10cSrcweir pReturn, pArgs, ppException ); 424cdf0e10cSrcweir 425cdf0e10cSrcweir typelib_typedescriptionreference_release( pReturnTypeRef ); 426cdf0e10cSrcweir } 427cdf0e10cSrcweir 428cdf0e10cSrcweir break; 429cdf0e10cSrcweir } 430cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_METHOD: 431cdf0e10cSrcweir { 432cdf0e10cSrcweir VtableSlot aVtableSlot( 433cdf0e10cSrcweir getVtableSlot( 434cdf0e10cSrcweir reinterpret_cast< 435cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription const * >( 436cdf0e10cSrcweir pMemberDescr))); 437cdf0e10cSrcweir switch (aVtableSlot.index) 438cdf0e10cSrcweir { 439cdf0e10cSrcweir // standard calls 440cdf0e10cSrcweir case 1: // acquire uno interface 441cdf0e10cSrcweir (*pUnoI->acquire)( pUnoI ); 442cdf0e10cSrcweir *ppException = 0; 443cdf0e10cSrcweir break; 444cdf0e10cSrcweir case 2: // release uno interface 445cdf0e10cSrcweir (*pUnoI->release)( pUnoI ); 446cdf0e10cSrcweir *ppException = 0; 447cdf0e10cSrcweir break; 448cdf0e10cSrcweir case 0: // queryInterface() opt 449cdf0e10cSrcweir { 450cdf0e10cSrcweir typelib_TypeDescription * pTD = 0; 451cdf0e10cSrcweir TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() ); 452cdf0e10cSrcweir if (pTD) 453cdf0e10cSrcweir { 454cdf0e10cSrcweir uno_Interface * pInterface = 0; 455cdf0e10cSrcweir (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)( 456cdf0e10cSrcweir pThis->pBridge->getUnoEnv(), 457cdf0e10cSrcweir (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD ); 458cdf0e10cSrcweir 459cdf0e10cSrcweir if (pInterface) 460cdf0e10cSrcweir { 461cdf0e10cSrcweir ::uno_any_construct( 462cdf0e10cSrcweir reinterpret_cast< uno_Any * >( pReturn ), 463cdf0e10cSrcweir &pInterface, pTD, 0 ); 464cdf0e10cSrcweir (*pInterface->release)( pInterface ); 465cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pTD ); 466cdf0e10cSrcweir *ppException = 0; 467cdf0e10cSrcweir break; 468cdf0e10cSrcweir } 469cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pTD ); 470cdf0e10cSrcweir } 471cdf0e10cSrcweir } // else perform queryInterface() 472cdf0e10cSrcweir default: 473cdf0e10cSrcweir // dependent dispatch 474cdf0e10cSrcweir cpp_call( 475cdf0e10cSrcweir pThis, aVtableSlot, 476cdf0e10cSrcweir ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef, 477cdf0e10cSrcweir ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams, 478cdf0e10cSrcweir ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams, 479cdf0e10cSrcweir pReturn, pArgs, ppException ); 480cdf0e10cSrcweir } 481cdf0e10cSrcweir break; 482cdf0e10cSrcweir } 483cdf0e10cSrcweir default: 484cdf0e10cSrcweir { 485cdf0e10cSrcweir ::com::sun::star::uno::RuntimeException aExc( 486cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ), 487cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() ); 488cdf0e10cSrcweir 489cdf0e10cSrcweir Type const & rExcType = ::getCppuType( &aExc ); 490cdf0e10cSrcweir // binary identical null reference 491cdf0e10cSrcweir ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 ); 492cdf0e10cSrcweir } 493cdf0e10cSrcweir } 494cdf0e10cSrcweir } 495cdf0e10cSrcweir 496cdf0e10cSrcweir } } } 497