xref: /trunk/main/bridges/source/cpp_uno/gcc3_solaris_sparc/uno2cpp.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_bridges.hxx"
30 #include <malloc.h>
31 #include <com/sun/star/uno/genfunc.hxx>
32 #include <uno/data.h>
33 
34 #include "bridges/cpp_uno/shared/bridge.hxx"
35 #include "bridges/cpp_uno/shared/types.hxx"
36 #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
37 #include "bridges/cpp_uno/shared/vtables.hxx"
38 
39 #include "share.hxx"
40 
41 #include <sal/alloca.h>
42 
43 using namespace rtl;
44 using namespace com::sun::star::uno;
45 
46 namespace
47 {
48 //==================================================================================================
49 // The call instruction within the asm section of callVirtualMethod may throw
50 // exceptions.  So that the compiler handles this correctly, it is important
51 // that (a) callVirtualMethod might call dummy_can_throw_anything (although this
52 // never happens at runtime), which in turn can throw exceptions, and (b)
53 // callVirtualMethod is not inlined at its call site (so that any exceptions are
54 // caught which are thrown from the instruction calling callVirtualMethod):
55 
56 void callVirtualMethod( void * pAdjustedThisPtr,
57                         sal_Int32 nVtableIndex,
58                         void * pRegisterReturn,
59                         typelib_TypeClass eReturnType,
60                         sal_Int32 * pStackLongs,
61                         sal_Int32 nStackLongs ) __attribute__((noinline));
62 
63 void callVirtualMethod( void * pAdjustedThisPtr,
64                         sal_Int32 nVtableIndex,
65                         void * pRegisterReturn,
66                         typelib_TypeClass eReturnType,
67                         sal_Int32 * pStackLongs,
68                         sal_Int32 nStackLongs )
69 {
70     // parameter list is mixed list of * and values
71     // reference parameters are pointers
72 
73     OSL_ENSURE( pStackLongs && pAdjustedThisPtr, "### null ptr!" );
74     OSL_ENSURE( (sizeof(void *) == 4) &&
75                  (sizeof(sal_Int32) == 4), "### unexpected size of int!" );
76     OSL_ENSURE( nStackLongs && pStackLongs, "### no stack in callVirtualMethod !" );
77 
78     // never called
79     if (! pAdjustedThisPtr) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
80 
81     volatile long o0 = 0, o1 = 0; // for register returns
82     volatile double f0d = 0;
83     volatile float f0f = 0;
84     volatile long long saveReg[7];
85 
86     __asm__ (
87         // save registers
88         "std %%l0, [%4]\n\t"
89         "mov %4, %%l0\n\t"
90         "mov %%l0, %%l1\n\t"
91         "add %%l0, 8, %%l0\n\t"
92         "std %%l2, [%%l0]\n\t"
93         "add %%l0, 8, %%l0\n\t"
94         "std %%l4, [%%l0]\n\t"
95         "add %%l0, 8, %%l0\n\t"
96         "std %%o0, [%%l0]\n\t"
97         "add %%l0, 8, %%l0\n\t"
98         "std %%o2, [%%l0]\n\t"
99         "add %%l0, 8, %%l0\n\t"
100         "std %%o4, [%%l0]\n\t"
101         "add %%l0, 8, %%l0\n\t"
102         "std %%l6, [%%l0]\n\t"
103         "mov %%l1, %%l7\n\t"
104 
105         // increase our own stackframe if necessary
106         "mov %%sp, %%l3\n\t"        // save stack ptr for readjustment
107 
108         "subcc %%i5, 7, %%l0\n\t"
109         "ble .LmoveOn\n\t"
110         "nop\n\t"
111 
112         "sll %%l0, 2, %%l0\n\t"
113         "add %%l0, 96, %%l0\n\t"
114         "mov %%sp, %%l1\n\t"        // old stack ptr
115         "sub %%sp, %%l0, %%l0\n\t"  // future stack ptr
116         "andcc %%l0, 7, %%g0\n\t"   // align stack to 8
117         "be .LisAligned\n\t"
118         "nop\n\t"
119         "sub %%l0, 4, %%l0\n"
120     ".LisAligned:\n\t"
121         "mov %%l0, %%o5\n\t"            // save newly computed stack ptr
122         "add %%g0, 16, %%o4\n"
123 
124         // now copy longs down to save register window
125         // and local variables
126     ".LcopyDown:\n\t"
127         "ld [%%l1], %%l2\n\t"
128         "st %%l2,[%%l0]\n\t"
129         "add %%l0, 4, %%l0\n\t"
130         "add %%l1, 4, %%l1\n\t"
131         "subcc %%o4, 1, %%o4\n\t"
132         "bne .LcopyDown\n\t"
133 
134         "mov %%o5, %%sp\n\t"        // move new stack ptr (hopefully) atomically
135         // while register window is valid in both spaces
136         // (scheduling might hit in copyDown loop)
137 
138         "sub %%i5, 7, %%l0\n\t"     // copy parameters past the sixth to stack
139         "add %%i4, 28, %%l1\n\t"
140         "add %%sp, 92, %%l2\n"
141     ".LcopyLong:\n\t"
142         "ld [%%l1], %%o0\n\t"
143         "st %%o0, [%%l2]\n\t"
144         "add %%l1, 4, %%l1\n\t"
145         "add %%l2, 4, %%l2\n\t"
146         "subcc %%l0, 1, %%l0\n\t"
147         "bne .LcopyLong\n\t"
148         "nop\n"
149 
150     ".LmoveOn:\n\t"
151         "mov %%i5, %%l0\n\t"        // prepare out registers
152         "mov %%i4, %%l1\n\t"
153 
154         "ld [%%l1], %%o0\n\t"       // prepare complex return ptr
155         "st %%o0, [%%sp+64]\n\t"
156         "sub %%l0, 1, %%l0\n\t"
157         "add %%l1, 4, %%l1\n\t"
158 
159         "ld [%%l1], %%o0\n\t"
160         "subcc %%l0, 1, %%l0\n\t"
161         "be .LdoCall\n\t"
162         "nop\n\t"
163 
164         "add %%l1, 4, %%l1\n\t"
165         "ld [%%l1], %%o1\n\t"
166         "subcc %%l0, 1, %%l0\n\t"
167         "be .LdoCall\n\t"
168         "nop\n\t"
169 
170         "add %%l1, 4, %%l1\n\t"
171         "ld [%%l1], %%o2\n\t"
172         "subcc %%l0, 1, %%l0\n\t"
173         "be .LdoCall\n\t"
174         "nop\n\t"
175 
176         "add %%l1, 4, %%l1\n\t"
177         "ld [%%l1], %%o3\n\t"
178         "subcc %%l0, 1, %%l0\n\t"
179         "be .LdoCall\n\t"
180         "nop\n\t"
181 
182         "add %%l1, 4, %%l1\n\t"
183         "ld [%%l1], %%o4\n\t"
184         "subcc %%l0, 1, %%l0\n\t"
185         "be .LdoCall\n\t"
186         "nop\n\t"
187 
188         "add %%l1, 4, %%l1\n\t"
189         "ld [%%l1], %%o5\n"
190 
191     ".LdoCall:\n\t"
192         "ld [%%i0], %%l0\n\t"       // get vtable ptr
193 
194 "sll %%i1, 2, %%l6\n\t"
195 //        "add %%l6, 8, %%l6\n\t"
196         "add %%l6, %%l0, %%l0\n\t"
197 //      // vtable has 8byte wide entries,
198 //      // upper half contains 2 half words, of which the first
199 //      // is the this ptr patch !
200 //      // first entry is (or __tf)
201 
202 //      "ldsh [%%l0], %%l6\n\t"     // load this ptr patch
203 //      "add %%l6, %%o0, %%o0\n\t"  // patch this ptr
204 
205 //      "add %%l0, 4, %%l0\n\t"     // get virtual function ptr
206         "ld [%%l0], %%l0\n\t"
207 
208         "ld [%%i4], %%l2\n\t"
209         "subcc %%l2, %%g0, %%l2\n\t"
210         "bne .LcomplexCall\n\t"
211         "nop\n\t"
212         "call %%l0\n\t"
213         "nop\n\t"
214         "ba .LcallReturned\n\t"
215         "nop\n"
216     ".LcomplexCall:\n\t"
217         "call %%l0\n\t"
218         "nop\n\t"
219         "unimp\n"
220 
221     ".LcallReturned:\n\t"
222         "mov %%l3, %%sp\n\t"        // readjust stack so that our locals are where they belong
223         "st %%o0, %0\n\t"           // save possible return registers into our locals
224         "st %%o1, %1\n\t"
225         "std %%f0, %2\n\t"
226         "st %%f0, %3\n\t"
227 
228         // restore registers
229         "ldd [%%l7], %%l0\n\t"
230         "add %%l7, 8, %%l7\n\t"
231         "ldd [%%l7], %%l2\n\t"
232         "add %%l7, 8, %%l7\n\t"
233         "ldd [%%l7], %%l4\n\t"
234         "add %%l7, 8, %%l7\n\t"
235         "ldd [%%l7], %%o0\n\t"
236         "add %%l7, 8, %%l7\n\t"
237         "ldd [%%l7], %%o2\n\t"
238         "add %%l7, 8, %%l7\n\t"
239         "ldd [%%l7], %%o4\n\t"
240         "add %%l7, 8, %%l7\n\t"
241         "ldd [%%l7], %%l6\n\t"
242         : :
243         "m"(o0),
244         "m"(o1),
245         "m"(f0d),
246         "m"(f0f),
247         "r"(&saveReg[0])
248         );
249     switch( eReturnType )
250     {
251         case typelib_TypeClass_HYPER:
252         case typelib_TypeClass_UNSIGNED_HYPER:
253             ((long*)pRegisterReturn)[1] = o1;
254         case typelib_TypeClass_LONG:
255         case typelib_TypeClass_UNSIGNED_LONG:
256         case typelib_TypeClass_ENUM:
257             ((long*)pRegisterReturn)[0] = o0;
258             break;
259         case typelib_TypeClass_CHAR:
260         case typelib_TypeClass_SHORT:
261         case typelib_TypeClass_UNSIGNED_SHORT:
262             *(unsigned short*)pRegisterReturn = (unsigned short)o0;
263             break;
264         case typelib_TypeClass_BOOLEAN:
265         case typelib_TypeClass_BYTE:
266             *(unsigned char*)pRegisterReturn = (unsigned char)o0;
267             break;
268         case typelib_TypeClass_FLOAT:
269             *(float*)pRegisterReturn = f0f;
270             break;
271         case typelib_TypeClass_DOUBLE:
272             *(double*)pRegisterReturn = f0d;
273             break;
274     }
275 }
276 
277 //=================================================================================================
278 static void cpp_call(
279     bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
280     bridges::cpp_uno::shared::VtableSlot aVtableSlot,
281     typelib_TypeDescriptionReference * pReturnTypeRef,
282     sal_Int32 nParams, typelib_MethodParameter * pParams,
283     void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
284 {
285     // max space for: complex ret ptr, this, values|ptr ...
286     char * pCppStack    =
287         (char *)alloca( (nParams+2) * sizeof(sal_Int64) );
288     char * pCppStackStart   = pCppStack;
289 
290     // return
291     typelib_TypeDescription * pReturnTypeDescr = 0;
292     TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
293     OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
294 
295     void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
296 
297     if (pReturnTypeDescr)
298     {
299         if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
300         {
301             pCppReturn = pUnoReturn; // direct way for simple types
302             *(void**)pCppStack = NULL;
303         }
304         else
305         {
306             // complex return via ptr
307             pCppReturn = *(void **)pCppStack = (bridges::cpp_uno::shared::relatesToInterfaceType(pReturnTypeDescr )
308                                                 ? alloca( pReturnTypeDescr->nSize )
309                                                 : pUnoReturn); // direct way
310         }
311         pCppStack += sizeof(void*);
312     }
313     // push this
314     void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
315            + aVtableSlot.offset;
316            *(void**)pCppStack = pAdjustedThisPtr;
317     pCppStack += sizeof( void* );
318 
319     // stack space
320     OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
321     // args
322     void ** pCppArgs  = (void **)alloca( 3 * sizeof(void *) * nParams );
323     // indizes of values this have to be converted (interface conversion cpp<=>uno)
324     sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
325     // type descriptions for reconversions
326     typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
327 
328     sal_Int32 nTempIndizes   = 0;
329 
330     for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
331     {
332         const typelib_MethodParameter & rParam = pParams[nPos];
333         typelib_TypeDescription * pParamTypeDescr = 0;
334         TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
335         if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
336         {
337             pCppArgs[ nPos ] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack, pParamTypeDescr );
338 
339             switch (pParamTypeDescr->eTypeClass)
340             {
341             case typelib_TypeClass_HYPER:
342             case typelib_TypeClass_UNSIGNED_HYPER:
343             case typelib_TypeClass_DOUBLE:
344                         OSL_ASSERT( sizeof (double) == sizeof (sal_Int64) );
345                           *reinterpret_cast< sal_Int32 * >(pCppStack) =
346                           *reinterpret_cast< sal_Int32 const * >(pUnoArgs[ nPos ]);
347                           pCppStack += sizeof (sal_Int32);
348                           *reinterpret_cast< sal_Int32 * >(pCppStack) =
349                           *(reinterpret_cast< sal_Int32 const * >(pUnoArgs[ nPos ] ) + 1);
350                           break;
351                     default:
352                           uno_copyAndConvertData(
353                              pCppArgs[nPos], pUnoArgs[nPos], pParamTypeDescr,
354                             pThis->getBridge()->getUno2Cpp() );
355                           break;
356                         }
357             // no longer needed
358             TYPELIB_DANGER_RELEASE( pParamTypeDescr );
359         }
360         else // ptr to complex value | ref
361         {
362             if (! rParam.bIn) // is pure out
363             {
364                 // cpp out is constructed mem, uno out is not!
365                 uno_constructData(
366                     *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
367                     pParamTypeDescr );
368                 pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
369                 // will be released at reconversion
370                 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
371             }
372             // is in/inout
373             else if (bridges::cpp_uno::shared::relatesToInterfaceType(
374                             pParamTypeDescr ))
375             {
376                 uno_copyAndConvertData(
377                     *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
378                                     pUnoArgs[nPos], pParamTypeDescr,
379                     pThis->getBridge()->getUno2Cpp() );
380 
381                 pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
382                 // will be released at reconversion
383                 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
384             }
385             else // direct way
386             {
387                 *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
388                 // no longer needed
389                 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
390             }
391         }
392         pCppStack += sizeof(sal_Int32); // standard parameter length
393     }
394 
395     try
396     {
397         int nStackLongs = (pCppStack - pCppStackStart)/sizeof(sal_Int32);
398         OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic" );
399 
400         if( nStackLongs & 1 )
401             // stack has to be 8 byte aligned
402             nStackLongs++;
403         callVirtualMethod(
404             pAdjustedThisPtr,
405             aVtableSlot.index,
406             pCppReturn,
407             pReturnTypeDescr->eTypeClass,
408             (sal_Int32 *)pCppStackStart,
409              nStackLongs);
410         // NO exception occured...
411         *ppUnoExc = 0;
412 
413         // reconvert temporary params
414         for ( ; nTempIndizes--; )
415         {
416             sal_Int32 nIndex = pTempIndizes[nTempIndizes];
417             typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
418 
419             if (pParams[nIndex].bIn)
420             {
421                 if (pParams[nIndex].bOut) // inout
422                 {
423                     uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
424                     uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
425                                             pThis->getBridge()->getCpp2Uno() );
426                 }
427             }
428             else // pure out
429             {
430                 uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
431                                         pThis->getBridge()->getCpp2Uno() );
432             }
433             // destroy temp cpp param => cpp: every param was constructed
434             uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
435 
436             TYPELIB_DANGER_RELEASE( pParamTypeDescr );
437         }
438         // return value
439         if (pCppReturn && pUnoReturn != pCppReturn)
440         {
441             uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
442                                     pThis->getBridge()->getCpp2Uno() );
443             uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
444         }
445     }
446     catch( ... )
447     {
448         // get exception
449            fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions,
450                                 *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
451 
452         // temporary params
453         for ( ; nTempIndizes--; )
454         {
455             sal_Int32 nIndex = pTempIndizes[nTempIndizes];
456             // destroy temp cpp param => cpp: every param was constructed
457             uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
458             TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
459         }
460         // return type
461         if (pReturnTypeDescr)
462             TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
463     }
464 }
465 
466 }
467 
468 namespace bridges { namespace cpp_uno { namespace shared {
469 
470 void unoInterfaceProxyDispatch(
471     uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
472     void * pReturn, void * pArgs[], uno_Any ** ppException )
473 {
474 #if defined BRIDGES_DEBUG
475     OString cstr( OUStringToOString( pMemberDescr->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
476     fprintf( stderr, "received dispatch( %s )\n", cstr.getStr() );
477 #endif
478 
479     // is my surrogate
480     bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
481        = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
482     typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
483 
484     switch (pMemberDescr->eTypeClass)
485     {
486     case typelib_TypeClass_INTERFACE_ATTRIBUTE:
487     {
488      VtableSlot aVtableSlot(
489                getVtableSlot(
490                    reinterpret_cast<
491                        typelib_InterfaceAttributeTypeDescription const * >(
492                            pMemberDescr)));
493         if (pReturn)
494         {
495             // dependent dispatch
496             cpp_call(
497                 pThis, aVtableSlot,
498                 ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
499                 0, 0, // no params
500                 pReturn, pArgs, ppException );
501         }
502         else
503         {
504             // is SET
505             typelib_MethodParameter aParam;
506             aParam.pTypeRef =
507                 ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
508             aParam.bIn      = sal_True;
509             aParam.bOut     = sal_False;
510 
511             typelib_TypeDescriptionReference * pReturnTypeRef = 0;
512             OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
513             typelib_typedescriptionreference_new(
514                 &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
515 
516             // dependent dispatch
517             aVtableSlot.index += 1; // get, then set method
518             cpp_call(
519                 pThis, aVtableSlot,
520                 pReturnTypeRef,
521                 1, &aParam,
522                 pReturn, pArgs, ppException );
523 
524             typelib_typedescriptionreference_release( pReturnTypeRef );
525         }
526 
527         break;
528     }
529     case typelib_TypeClass_INTERFACE_METHOD:
530     {
531         VtableSlot aVtableSlot(
532         getVtableSlot(
533          reinterpret_cast<
534           typelib_InterfaceMethodTypeDescription const * >(
535           pMemberDescr)));
536         switch (aVtableSlot.index)
537         {
538             // standard calls
539         case 1: // acquire uno interface
540             (*pUnoI->acquire)( pUnoI );
541             *ppException = 0;
542             break;
543         case 2: // release uno interface
544             (*pUnoI->release)( pUnoI );
545             *ppException = 0;
546             break;
547         case 0: // queryInterface() opt
548         {
549             typelib_TypeDescription * pTD = 0;
550             TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
551             if (pTD)
552             {
553                 uno_Interface * pInterface = 0;
554         (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
555           pThis->pBridge->getUnoEnv(),
556                    (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
557 
558                 if (pInterface)
559                 {
560                     ::uno_any_construct(
561                         reinterpret_cast< uno_Any * >( pReturn ),
562                         &pInterface, pTD, 0 );
563                     (*pInterface->release)( pInterface );
564                     TYPELIB_DANGER_RELEASE( pTD );
565                     *ppException = 0;
566                     break;
567                 }
568                 TYPELIB_DANGER_RELEASE( pTD );
569             }
570         } // else perform queryInterface()
571         default:
572             // dependent dispatch
573             cpp_call(
574                 pThis, aVtableSlot,
575                 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
576                 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
577                 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
578                 pReturn, pArgs, ppException );
579         }
580         break;
581     }
582     default:
583     {
584         ::com::sun::star::uno::RuntimeException aExc(
585             OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
586             ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
587 
588         Type const & rExcType = ::getCppuType( &aExc );
589         // binary identical null reference
590         ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
591     }
592     }
593 }
594 
595 } } }
596