LibreOffice Module bridges (master)  1
gcc3_linux_ia64/uno2cpp.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <exception>
23 #include <malloc.h>
24 #include <typeinfo>
25 
26 #include <com/sun/star/uno/Exception.hpp>
27 #include <com/sun/star/uno/RuntimeException.hpp>
28 #include <com/sun/star/uno/genfunc.hxx>
30 #include <uno/data.h>
31 
32 #include "bridge.hxx"
33 #include "types.hxx"
34 #include "unointerfaceproxy.hxx"
35 #include "vtables.hxx"
36 
37 #include "share.hxx"
38 
39 #include <stdio.h>
40 #include <string.h>
41 
42 
43 using namespace ::com::sun::star::uno;
44 
45 void MapReturn(const ia64::RegReturn &rRet, double dret, typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn, sal_uInt64 *pRegisterReturn)
46 {
47  switch (pReturnTypeDescr->eTypeClass)
48  {
49  case typelib_TypeClass_HYPER:
50  case typelib_TypeClass_UNSIGNED_HYPER:
51  case typelib_TypeClass_LONG:
52  case typelib_TypeClass_UNSIGNED_LONG:
53  case typelib_TypeClass_ENUM:
54  *pRegisterReturn = rRet.r8;
55  break;
56  case typelib_TypeClass_CHAR:
57  case typelib_TypeClass_SHORT:
58  case typelib_TypeClass_UNSIGNED_SHORT:
59  *pRegisterReturn = (unsigned short)rRet.r8;
60  break;
61  case typelib_TypeClass_BOOLEAN:
62  case typelib_TypeClass_BYTE:
63  *pRegisterReturn = (unsigned char)rRet.r8;
64  break;
65  case typelib_TypeClass_FLOAT:
66  *reinterpret_cast<float *>( pRegisterReturn ) = dret;
67  break;
68  case typelib_TypeClass_DOUBLE:
69  *reinterpret_cast<double *>( pRegisterReturn ) = dret;
70  break;
71  case typelib_TypeClass_STRUCT:
72  case typelib_TypeClass_EXCEPTION:
73  {
74  sal_uInt32 nRetSize = pReturnTypeDescr->nSize;
75  if (bSimpleReturn && nRetSize <= 32 && nRetSize > 0)
76  memcpy(pRegisterReturn, (void*)&rRet, nRetSize);
77  break;
78  }
79  default:
80  break;
81  }
82 }
83 
84 namespace ia64
85 {
87  {
88  const typelib_CompoundTypeDescription * p
89  = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
90  for (sal_Int32 i = 0; i < p->nMembers; ++i)
91  {
92  if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
93  p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
94  {
96  TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
97  bool b = is_complex_struct(t);
98  TYPELIB_DANGER_RELEASE(t);
99  if (b) {
100  return true;
101  }
102  }
103  else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
104  return true;
105  }
106  if (p->pBaseTypeDescription != 0)
107  return is_complex_struct(&p->pBaseTypeDescription->aBase);
108  return false;
109  }
110 
111  bool is_complex_struct( typelib_TypeDescriptionReference *pTypeRef )
112  {
113  if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
114  {
115  typelib_TypeDescription * pTypeDescr = 0;
116  TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
117 
118  bool bRet = is_complex_struct( pTypeDescr );
119  TYPELIB_DANGER_RELEASE( pTypeDescr );
120 
121  return bRet;
122  }
123  return false;
124  }
125 
126  bool return_via_r8_buffer( typelib_TypeDescriptionReference *pTypeRef )
127  {
128  if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
129  {
130  if (is_complex_struct( pTypeRef )) return false;
131 
132  typelib_TypeDescription * pTypeDescr = 0;
133  TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
134 
135  /* If the struct is larger than 32 bytes, then there is a buffer at r8 to stick the return value into */
136  bool bRet = pTypeDescr->nSize > 32;
137  TYPELIB_DANGER_RELEASE( pTypeDescr );
138  return bRet;
139  }
140  return false;
141  }
142 
143  bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
144  {
146  return false;
147  else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
148  return is_complex_struct( pTypeRef );
149  return true;
150  }
151 
152 
153 }
154 
155 namespace
156 {
157 
158 static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
159  void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
160  sal_uInt64 *pStack, sal_uInt32 nStack,
161  sal_uInt64 *pGPR, sal_uInt32 nGPR,
162  double *pFPR, sal_uInt32 nFPR)
163 {
164  // Stack, if used, must be 16-bytes aligned
165  if ( nStack )
166  nStack = ( nStack + 1 ) & ~1;
167 
168  // Should not happen, but...
169  if ( nFPR > ia64::MAX_SSE_REGS )
170  nFPR = ia64::MAX_SSE_REGS;
171  if ( nGPR > ia64::MAX_GPR_REGS )
172  nGPR = ia64::MAX_GPR_REGS;
173 
174 #if OSL_DEBUG_LEVEL > 2
175  // Let's figure out what is really going on here
176  {
177  fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
178  for ( unsigned int i = 0; i < nGPR; ++i )
179  fprintf( stderr, "0x%lx, ", pGPR[i] );
180  fprintf( stderr, "\nFPR's (%d): ", nFPR );
181  for ( unsigned int i = 0; i < nFPR; ++i )
182  fprintf( stderr, "0x%lx (%f), ", pFPR[i], pFPR[i] );
183  fprintf( stderr, "\nStack (%d): ", nStack );
184  for ( unsigned int i = 0; i < nStack; ++i )
185  fprintf( stderr, "0x%lx, ", pStack[i] );
186  fprintf( stderr, "\n" );
187  fprintf( stderr, "pRegisterReturn is %p\n", pRegisterReturn);
188  }
189 #endif
190 
191  // Load parameters to stack, if necessary
192  sal_uInt64 *stack = (sal_uInt64 *) __builtin_alloca( nStack * 8 );
193  memcpy( stack, pStack, nStack * 8 );
194 
195  // To get pointer to method
196  // a) get the address of the vtable
197  sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
198  // b) get the address from the vtable entry at offset, each entry is 16bytes,
199  // 8 for function pointer, and 8 for global pointer
200  pMethod += 16 * nVtableIndex;
201 
202  typedef void (* FunctionCall )( sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64 );
203  FunctionCall pFunc = (FunctionCall)pMethod;
204 
205  switch (nFPR) //deliberate fall through
206  {
207  case 8:
208  asm volatile("ldfd f15=%0" : : "m"(pFPR[7]) : "f15");
209  case 7:
210  asm volatile("ldfd f14=%0" : : "m"(pFPR[6]) : "f14");
211  case 6:
212  asm volatile("ldfd f13=%0" : : "m"(pFPR[5]) : "f13");
213  case 5:
214  asm volatile("ldfd f12=%0" : : "m"(pFPR[4]) : "f12");
215  case 4:
216  asm volatile("ldfd f11=%0" : : "m"(pFPR[3]) : "f11");
217  case 3:
218  asm volatile("ldfd f10=%0" : : "m"(pFPR[2]) : "f10");
219  case 2:
220  asm volatile("ldfd f9=%0" : : "m"(pFPR[1]) : "f9");
221  case 1:
222  asm volatile("ldfd f8=%0" : : "m"(pFPR[0]) : "f8");
223  default:
224  break;
225  }
226 
227  //stick the return area into r8 for big struct returning
228  asm volatile("ld8 r8=%0" : : "m"(pRegisterReturn) : "r8");
229 
230  (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3], pGPR[4], pGPR[5], pGPR[6], pGPR[7]);
231 
232  register double f8 asm("f8");
233  ia64::RegReturn ret;
234  {
235  register long r8 asm("r8"); ret.r8 = r8;
236  register long r9 asm("r9"); ret.r9 = r9;
237  register long r10 asm("r10"); ret.r10 = r10;
238  register long r11 asm("r11"); ret.r11 = r11;
239  }
240 
241  MapReturn(ret, f8, pReturnTypeDescr, bSimpleReturn, (sal_uInt64*)pRegisterReturn);
242 }
243 
244 // Macros for easier insertion of values to registers or stack
245 // pSV - pointer to the source
246 // nr - order of the value [will be increased if stored to register]
247 // pFPR, pGPR - pointer to the registers
248 // pDS - pointer to the stack [will be increased if stored here]
249 
250 // The value in %xmm register is already prepared to be retrieved as a float,
251 // thus we treat float and double the same
252 #define INSERT_FLOAT( pSV, nfr, pFPR, ngr, pGPR, pDS, bOverflow ) \
253  if ( nfr < ia64::MAX_SSE_REGS && ngr < ia64::MAX_GPR_REGS ) \
254  pFPR[nfr++] = *reinterpret_cast<float *>( pSV ); \
255  if ( ngr < ia64::MAX_GPR_REGS ) \
256  pGPR[ngr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
257  else \
258  bOverflow = true; \
259  if (bOverflow) \
260  *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
261 
262 #define INSERT_DOUBLE( pSV, nfr, pFPR, ngr, pGPR, pDS, bOverflow ) \
263  if ( nfr < ia64::MAX_SSE_REGS && ngr < ia64::MAX_GPR_REGS ) \
264  pFPR[nfr++] = *reinterpret_cast<double *>( pSV ); \
265  if ( ngr < ia64::MAX_GPR_REGS ) \
266  pGPR[ngr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
267  else \
268  bOverflow = true; \
269  if (bOverflow) \
270  *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
271 
272 #define INSERT_INT64( pSV, nr, pGPR, pDS, bOverflow ) \
273  if ( nr < ia64::MAX_GPR_REGS ) \
274  pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
275  else \
276  bOverflow = true; \
277  if (bOverflow) \
278  *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
279 
280 #define INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow ) \
281  if ( nr < ia64::MAX_GPR_REGS ) \
282  pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
283  else \
284  bOverflow = true; \
285  if (bOverflow) \
286  *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
287 
288 #define INSERT_INT16( pSV, nr, pGPR, pDS, bOverflow ) \
289  if ( nr < ia64::MAX_GPR_REGS ) \
290  pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
291  else \
292  bOverflow = true; \
293  if (bOverflow) \
294  *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
295 
296 #define INSERT_INT8( pSV, nr, pGPR, pDS, bOverflow ) \
297  if ( nr < ia64::MAX_GPR_REGS ) \
298  pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
299  else \
300  bOverflow = true; \
301  if (bOverflow) \
302  *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
303 
304 static void cpp_call(
307  typelib_TypeDescriptionReference * pReturnTypeRef,
308  sal_Int32 nParams, typelib_MethodParameter * pParams,
309  void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
310 {
311  // max space for: [complex ret ptr], values|ptr ...
312  sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+3) * sizeof(sal_Int64) );
313  sal_uInt64 * pStackStart = pStack;
314 
315  sal_uInt64 pGPR[ia64::MAX_GPR_REGS];
316  sal_uInt32 nGPR = 0;
317 
318  double pFPR[ia64::MAX_SSE_REGS];
319  sal_uInt32 nFPR = 0;
320 
321  // return
322  typelib_TypeDescription * pReturnTypeDescr = 0;
323  TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
324  assert(pReturnTypeDescr);
325 
326  void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
327 
328  bool bOverflow = false;
329 
330  bool bSimpleReturn = true;
331  if (pReturnTypeDescr)
332  {
333 #if OSL_DEBUG_LEVEL > 2
334  fprintf(stderr, "return type is %d\n", pReturnTypeDescr->eTypeClass);
335 #endif
336  if ( ia64::return_in_hidden_param(pReturnTypeRef) || ia64::return_via_r8_buffer(pReturnTypeRef) )
337  bSimpleReturn = false;
338 
339  if ( bSimpleReturn )
340  {
341  pCppReturn = pUnoReturn; // direct way for simple types
342 #if OSL_DEBUG_LEVEL > 2
343  fprintf(stderr, "simple return\n");
344 #endif
345  }
346  else
347  {
348  // complex return via ptr
349  pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
350  ? alloca( pReturnTypeDescr->nSize ) : pUnoReturn);
351 #if OSL_DEBUG_LEVEL > 2
352  fprintf(stderr, "pCppReturn/pUnoReturn is %lx/%lx", pCppReturn, pUnoReturn);
353 #endif
354  if (!ia64::return_via_r8_buffer(pReturnTypeRef))
355  INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack, bOverflow );
356  }
357  }
358  // push "this" pointer
359  void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
360 
361 #if OSL_DEBUG_LEVEL > 2
362  fprintf(stderr, "this pointer is %p\n", pAdjustedThisPtr);
363 #endif
364  INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverflow );
365 
366  // Args
367  void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
368  // indices of values this have to be converted (interface conversion cpp<=>uno)
369  sal_Int32 * pTempIndices = (sal_Int32 *)(pCppArgs + nParams);
370  // type descriptions for reconversions
371  typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
372 
373  sal_Int32 nTempIndices = 0;
374 
375 #if OSL_DEBUG_LEVEL > 2
376  fprintf(stderr, "n params is %d\n", nParams);
377 #endif
378 
379  for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
380  {
381  const typelib_MethodParameter & rParam = pParams[nPos];
382  typelib_TypeDescription * pParamTypeDescr = 0;
383  TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
384 
385 #if OSL_DEBUG_LEVEL > 2
386  fprintf(stderr, "param %d is %d %d %d\n", nPos, rParam.bOut, bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ),
387  pParamTypeDescr->eTypeClass);
388 #endif
389 
390  if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
391  {
392 // uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
393  uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos], pParamTypeDescr,
394  pThis->getBridge()->getUno2Cpp() );
395  switch (pParamTypeDescr->eTypeClass)
396  {
397  case typelib_TypeClass_HYPER:
398  case typelib_TypeClass_UNSIGNED_HYPER:
399 #if OSL_DEBUG_LEVEL > 2
400  fprintf(stderr, "hyper is %lx\n", *(unsigned long*)(pCppArgs[nPos]));
401 #endif
402  INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
403  break;
404  case typelib_TypeClass_LONG:
405  case typelib_TypeClass_UNSIGNED_LONG:
406  case typelib_TypeClass_ENUM:
407 #if OSL_DEBUG_LEVEL > 2
408  fprintf(stderr, "long is %lx\n", *(unsigned int*)(pCppArgs[nPos]));
409 #endif
410  INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
411  break;
412  case typelib_TypeClass_SHORT:
413  case typelib_TypeClass_CHAR:
414  case typelib_TypeClass_UNSIGNED_SHORT:
415 #if OSL_DEBUG_LEVEL > 2
416  fprintf(stderr, "short is %x\n", *(unsigned short*)(pCppArgs[nPos]));
417 #endif
418  INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
419  break;
420  case typelib_TypeClass_BOOLEAN:
421  case typelib_TypeClass_BYTE:
422 #if OSL_DEBUG_LEVEL > 2
423  fprintf(stderr, "byte is %x\n", *(unsigned char*)(pCppArgs[nPos]));
424 #endif
425  INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
426  break;
427  case typelib_TypeClass_FLOAT:
428 #if OSL_DEBUG_LEVEL > 2
429  fprintf(stderr, "a float is %f\n", *(float*)(pCppArgs[nPos]));
430  fprintf(stderr, "b float is %f\n", *(double*)(pCppArgs[nPos]));
431 #endif
432  INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR, nGPR, pGPR, pStack, bOverflow );
433  break;
434  case typelib_TypeClass_DOUBLE:
435 #if OSL_DEBUG_LEVEL > 2
436  fprintf(stderr, "double is %f\n", *(double*)(pCppArgs[nPos]));
437 #endif
438  INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, nGPR, pGPR, pStack, bOverflow );
439  break;
440  default:
441  break;
442  }
443 
444  // no longer needed
445  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
446 
447  }
448  else // ptr to complex value | ref
449  {
450 #if OSL_DEBUG_LEVEL > 2
451  fprintf(stderr, "complex type again %d\n", rParam.bIn);
452 #endif
453  if (! rParam.bIn) // is pure out
454  {
455 #if OSL_DEBUG_LEVEL > 2
456  fprintf(stderr, "complex size is %d\n", pParamTypeDescr->nSize );
457 #endif
458  // cpp out is constructed mem, uno out is not!
460  pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
461  pParamTypeDescr );
462  pTempIndices[nTempIndices] = nPos; // default constructed for cpp call
463  // will be released at reconversion
464  ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
465  }
466  // is in/inout
467  else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
468  {
469 #if OSL_DEBUG_LEVEL > 2
470  fprintf(stderr, "this one\n");
471 #endif
473  pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
474  pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
475 
476  pTempIndices[nTempIndices] = nPos; // has to be reconverted
477  // will be released at reconversion
478  ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
479  }
480  else // direct way
481  {
482 #if OSL_DEBUG_LEVEL > 2
483  fprintf(stderr, "that one, passing %lx through\n", pUnoArgs[nPos]);
484 #endif
485  pCppArgs[nPos] = pUnoArgs[nPos];
486  // no longer needed
487  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
488  }
489  INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverflow );
490  }
491  }
492 
493  try
494  {
495  try {
497  pAdjustedThisPtr, aVtableSlot.index,
498  pCppReturn, pReturnTypeDescr, bSimpleReturn,
499  pStackStart, ( pStack - pStackStart ),
500  pGPR, nGPR,
501  pFPR, nFPR );
502  } catch (css::uno::Exception &) {
503  throw;
504  } catch (std::exception & e) {
505  throw css::uno::RuntimeException(
506  "C++ code threw " + o3tl::runtimeToOUString(typeid(e).name()) + ": "
507  + o3tl::runtimeToOUString(e.what()));
508  } catch (...) {
509  throw css::uno::RuntimeException("C++ code threw unknown exception");
510  }
511  // NO exception occurred...
512  *ppUnoExc = 0;
513 
514  // reconvert temporary params
515  for ( ; nTempIndices--; )
516  {
517  sal_Int32 nIndex = pTempIndices[nTempIndices];
518  typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
519 
520  if (pParams[nIndex].bIn)
521  {
522  if (pParams[nIndex].bOut) // inout
523  {
524  uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
525  uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
526  pThis->getBridge()->getCpp2Uno() );
527  }
528  }
529  else // pure out
530  {
531  uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
532  pThis->getBridge()->getCpp2Uno() );
533  }
534  // destroy temp cpp param => cpp: every param was constructed
535  uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
536 
537  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
538  }
539  // return value
540  if (pCppReturn && pUnoReturn != pCppReturn)
541  {
542  uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
543  pThis->getBridge()->getCpp2Uno() );
544  uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
545  }
546  }
547  catch (...)
548  {
549  // fill uno exception
551 
552  // temporary params
553  for ( ; nTempIndices--; )
554  {
555  sal_Int32 nIndex = pTempIndices[nTempIndices];
556  // destroy temp cpp param => cpp: every param was constructed
557  uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndices], cpp_release );
558  TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
559  }
560  // return type
561  if (pReturnTypeDescr)
562  TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
563  }
564 }
565 
566 }
567 
568 namespace bridges::cpp_uno::shared {
569 
571  uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
572  void * pReturn, void * pArgs[], uno_Any ** ppException )
573 {
574  // is my surrogate
576  = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy *> (pUnoI);
577 
578  switch (pMemberDescr->eTypeClass)
579  {
580  case typelib_TypeClass_INTERFACE_ATTRIBUTE:
581  {
582 
583  VtableSlot aVtableSlot(
585  reinterpret_cast<
586  typelib_InterfaceAttributeTypeDescription const * >(
587  pMemberDescr)));
588 
589  if (pReturn)
590  {
591  // dependent dispatch
592  cpp_call(
593  pThis, aVtableSlot,
594  ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
595  0, 0, // no params
596  pReturn, pArgs, ppException );
597  }
598  else
599  {
600  // is SET
601  typelib_MethodParameter aParam;
602  aParam.pTypeRef =
603  ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
604  aParam.bIn = sal_True;
605  aParam.bOut = sal_False;
606 
607  typelib_TypeDescriptionReference * pReturnTypeRef = 0;
608  OUString aVoidName("void");
610  &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
611 
612  // dependent dispatch
613  aVtableSlot.index += 1; //get then set method
614  cpp_call(
615  pThis, aVtableSlot,
616  pReturnTypeRef,
617  1, &aParam,
618  pReturn, pArgs, ppException );
619 
621  }
622 
623  break;
624  }
625  case typelib_TypeClass_INTERFACE_METHOD:
626  {
627 
628  VtableSlot aVtableSlot(
630  reinterpret_cast<
631  typelib_InterfaceMethodTypeDescription const * >(
632  pMemberDescr)));
633  switch (aVtableSlot.index)
634  {
635  // standard calls
636  case 1: // acquire uno interface
637  (*pUnoI->acquire)( pUnoI );
638  *ppException = 0;
639  break;
640  case 2: // release uno interface
641  (*pUnoI->release)( pUnoI );
642  *ppException = 0;
643  break;
644  case 0: // queryInterface() opt
645  {
646  typelib_TypeDescription * pTD = 0;
647  TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
648  if (pTD)
649  {
650  uno_Interface * pInterface = 0;
651  (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
652  pThis->pBridge->getUnoEnv(),
653  (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
654 
655  if (pInterface)
656  {
657  ::uno_any_construct(
658  reinterpret_cast< uno_Any * >( pReturn ),
659  &pInterface, pTD, 0 );
660  (*pInterface->release)( pInterface );
661  TYPELIB_DANGER_RELEASE( pTD );
662  *ppException = 0;
663  break;
664  }
665  TYPELIB_DANGER_RELEASE( pTD );
666  }
667  } // else perform queryInterface()
668  default:
669  // dependent dispatch
670  cpp_call(
671  pThis, aVtableSlot,
672  ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
673  ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
674  ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
675  pReturn, pArgs, ppException );
676  }
677  break;
678  }
679  default:
680  {
681  ::com::sun::star::uno::RuntimeException aExc(
682  "illegal member type description!",
684 
685  Type const & rExcType = cppu::UnoType<decltype(aExc)>::get();
686  // binary identical null reference
687  ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
688  }
689  }
690 }
691 
692 }
693 
694 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Type
sal_Int32 nIndex
void SAL_CALL uno_destructData(void *pValue, typelib_TypeDescription *pTypeDescr, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
#define INSERT_FLOAT(pSV, nfr, pFPR, ngr, pGPR, pDS, bOverflow)
Represents a vtable slot of a C++ class.
Definition: vtables.hxx:59
void fillUnoException(uno_Any *pExc, uno_Mapping *pCpp2Uno)
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef)
Does function that returns this type use a hidden parameter, or registers?
bool isSimpleType(typelib_TypeClass typeClass)
Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT, UNSIGNED SHORT...
Definition: types.cxx:28
#define INSERT_INT64(pSV, nr, pGPR, pDS, bOverflow)
sal_Int32 index
The index within the vtable.
Definition: vtables.hxx:76
A uno proxy wrapping a cpp interface.
void callVirtualMethod(void *pThis, sal_uInt32 nVtableIndex, void *pRegisterReturn, typelib_TypeDescription *pReturnTypeDescr, bool bRegisterReturn, sal_uInt32 *pStack, sal_uInt32 nStack, sal_uInt32 *pGPR, double *pFPR) __attribute__((noinline))
bool relatesToInterfaceType(typelib_TypeDescription const *type)
Determines whether a type relates to an interface type (is itself an interface type, or might contain entities of interface type).
Definition: types.cxx:41
bool return_via_r8_buffer(typelib_TypeDescriptionReference *pTypeRef)
void unoInterfaceProxyDispatch(uno_Interface *pUnoI, const typelib_TypeDescription *pMemberDescr, void *pReturn, void *pArgs[], uno_Any **ppException)
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
uno_ExtEnvironment * getUnoEnv()
Definition: bridge.hxx:70
bool is_complex_struct(const typelib_TypeDescription *type)
struct _uno_Any uno_Any
Definition: msvc/except.hxx:31
uno_Mapping * getUno2Cpp()
Definition: bridge.hxx:73
static void cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy *pThis, bridges::cpp_uno::shared::VtableSlot aVtableSlot, typelib_TypeDescriptionReference *pReturnTypeRef, sal_Int32 nParams, typelib_MethodParameter *pParams, void *pUnoReturn, void *pUnoArgs[], uno_Any **ppUnoExc)
sal_Int32 offset
The offset of the vtable.
Definition: vtables.hxx:68
int i
void SAL_CALL uno_constructData(void *pMem, typelib_TypeDescription *pTypeDescr) SAL_THROW_EXTERN_C()
#define sal_True
void SAL_CALL uno_copyAndConvertData(void *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_Mapping *mapping) SAL_THROW_EXTERN_C()
#define INSERT_INT32(pSV, nr, pGPR, pDS, bOverflow)
void SAL_CALL typelib_typedescriptionreference_release(typelib_TypeDescriptionReference *pRef) SAL_THROW_EXTERN_C()
#define INSERT_INT8(pSV, nr, pGPR, pDS, bOverflow)
#define INSERT_INT16(pSV, nr, pGPR, pDS, bOverflow)
struct _typelib_TypeDescription typelib_TypeDescription
Definition: msvc/except.hxx:52
uno_Mapping * getCpp2Uno()
Definition: bridge.hxx:72
VtableSlot getVtableSlot(typelib_InterfaceAttributeTypeDescription const *ifcMember)
Calculates the vtable slot associated with an interface attribute member.
Definition: vtables.cxx:132
XPropertyListType t
void SAL_CALL typelib_typedescriptionreference_new(typelib_TypeDescriptionReference **ppTDR, typelib_TypeClass eTypeClass, rtl_uString *pTypeName) SAL_THROW_EXTERN_C()
#define INSERT_DOUBLE(pSV, nfr, pFPR, ngr, pGPR, pDS, bOverflow)
OUString runtimeToOUString(char const *runtimeString)
#define sal_False
void * p
void MapReturn(const ia64::RegReturn &rRet, double dret, typelib_TypeDescription *pReturnTypeDescr, bool bSimpleReturn, sal_uInt64 *pRegisterReturn)
com::sun::star::uno::XInterface * getCppI()
sal_uInt16 nPos
char const * name
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo