LibreOffice Module bridges (master)  1
gcc3_linux_sparc64/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 #define SET_FP(n, p) \
40  __asm__( "ldx %0, %%l0\n\t" \
41  "ldd [%%l0], %%f" #n "\n" \
42  : : "m"(p) );
43 
44 using namespace com::sun::star::uno;
45 
46 namespace
47 {
48  void fillReturn(const typelib_TypeDescription * pTypeDescr,
49  long long * oret, float * fret, double * dret, void * pRegisterReturn)
50  {
51  for (const typelib_CompoundTypeDescription *p =
52  reinterpret_cast<const typelib_CompoundTypeDescription*>( pTypeDescr );
53  p != NULL; p = p->pBaseTypeDescription)
54  {
55 
56  for (sal_Int32 i = 0; i < p->nMembers; ++i)
57  {
58  typelib_TypeDescriptionReference *pTypeInStruct = p->ppTypeRefs[ i ];
59 
60  sal_Int32 nOff = p->pMemberOffsets[ i ];
61 
62  switch (pTypeInStruct->eTypeClass)
63  {
64  case typelib_TypeClass_HYPER:
65  case typelib_TypeClass_UNSIGNED_HYPER:
66  *(long*)((char *)pRegisterReturn + nOff) = *(long*)((char *)oret + nOff);
67  break;
68  case typelib_TypeClass_LONG:
69  case typelib_TypeClass_UNSIGNED_LONG:
70  case typelib_TypeClass_ENUM:
71  *(int*)((char *)pRegisterReturn + nOff) = *(int*)((char *)oret + nOff);
72  break;
73  case typelib_TypeClass_CHAR:
74  case typelib_TypeClass_SHORT:
75  case typelib_TypeClass_UNSIGNED_SHORT:
76  *(unsigned short*)((char *)pRegisterReturn + nOff) = *(unsigned short*)((char *)oret + nOff);
77  break;
78  case typelib_TypeClass_BOOLEAN:
79  case typelib_TypeClass_BYTE:
80  *(unsigned char*)((char *)pRegisterReturn + nOff) = *(unsigned char*)((char *)oret + nOff);
81  break;
82  case typelib_TypeClass_FLOAT:
83  *(float*)((char *)pRegisterReturn + nOff) = *(float*)((char *)fret + nOff);
84  break;
85  case typelib_TypeClass_DOUBLE:
86  *(double*)((char *)pRegisterReturn + nOff) = *(double*)((char *)dret + nOff);
87  break;
88  case typelib_TypeClass_STRUCT:
89  case typelib_TypeClass_EXCEPTION:
90  {
92  TYPELIB_DANGER_GET(&td, pTypeInStruct);
93  fillReturn(td,
94  (long long *)((char *)oret + nOff),
95  (float *)((char *)fret + nOff),
96  (double *)((char *)dret + nOff),
97  (char *)pRegisterReturn + nOff);
98  TYPELIB_DANGER_RELEASE(td);
99  }
100  default:
101  break;
102  }
103  }
104  }
105  }
106 
107 // The call instruction within the asm section of callVirtualMethod may throw
108 // exceptions. So that the compiler handles this correctly, it is important
109 // that (a) callVirtualMethod might call dummy_can_throw_anything (although this
110 // never happens at runtime), which in turn can throw exceptions, and (b)
111 // callVirtualMethod is not inlined at its call site (so that any exceptions are
112 // caught which are thrown from the instruction calling callVirtualMethod):
113 
114 void callVirtualMethod( void * pAdjustedThisPtr,
115  sal_Int32 nVtableIndex,
116  void * pRegisterReturn,
117  typelib_TypeDescriptionReference * pReturnTypeRef,
118  sal_Int64 * pStackHypers,
119  sal_Int32 nStackHypers,
120  typelib_MethodParameter * pParams, sal_Int32 nParams) __attribute__((noinline));
121 
122 void callVirtualMethod( void * pAdjustedThisPtr,
123  sal_Int32 /* nVtableIndex */,
124  void * pRegisterReturn,
125  typelib_TypeDescriptionReference * pReturnTypeRef,
126  sal_Int64 * pStackHypers,
127 #if OSL_DEBUG_LEVEL > 0
128  sal_Int32 nStackHypers,
129 #else
130 // sal_Int64 * /*pStackHypers*/,
131  sal_Int32 /*nStackHypers*/,
132 #endif
133  typelib_MethodParameter * pParams, sal_Int32 nParams)
134 {
135  // parameter list is mixed list of * and values
136  // reference parameters are pointers
137 
138  assert(pStackHypers && pAdjustedThisPtr);
139  static_assert( (sizeof(void *) == 8) &&
140  (sizeof(sal_Int64) == 8), "### unexpected size of int!" );
141  assert(nStackHypers && pStackHypers && "### no stack in callVirtualMethod !");
142 
143  // never called
144  if (! pAdjustedThisPtr) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
145 
146  long bSimpleReturn = !CPPU_CURRENT_NAMESPACE::return_in_hidden_param( pReturnTypeRef );
147 
148  int paramsOffset = bSimpleReturn ? 1 : 2;
149  for (sal_Int32 i = 0; i < nParams; ++i)
150  {
151  if (!pParams[i].bOut)
152  {
153  switch (pParams[i].pTypeRef->eTypeClass) {
154  case typelib_TypeClass_FLOAT:
155  case typelib_TypeClass_DOUBLE:
156  {
157  int paramArrayIdx = i + paramsOffset;
158  assert(paramArrayIdx < nStackHypers);
159  void *p = &pStackHypers[paramArrayIdx];
160  switch (paramArrayIdx) {
161  // Cannot be 0 - paramsOffset >= 1
162  case 1:
163  SET_FP(2, p);
164  break;
165  case 2:
166  SET_FP(4, p);
167  break;
168  case 3:
169  SET_FP(6, p);
170  break;
171  case 4:
172  SET_FP(8, p);
173  break;
174  case 5:
175  SET_FP(10, p);
176  break;
177  case 6:
178  SET_FP(12, p);
179  break;
180  case 7:
181  SET_FP(14, p);
182  break;
183  case 8:
184  SET_FP(16, p);
185  break;
186  case 9:
187  SET_FP(18, p);
188  break;
189  case 10:
190  SET_FP(20, p);
191  break;
192  case 11:
193  SET_FP(22, p);
194  break;
195  case 12:
196  SET_FP(24, p);
197  break;
198  case 13:
199  SET_FP(26, p);
200  break;
201  case 14:
202  SET_FP(28, p);
203  break;
204  case 15:
205  SET_FP(30, p);
206  break;
207  // Anything larger is passed on the stack
208  }
209  break;
210  }
211  default:
212  break;
213  }
214  }
215  }
216 
217  //long o0;
218  //double f0d;
219  //float f0f;
220  volatile long long saveReg[14];
221 
222  long long oret[4];
223  union {
224  float f[8];
225  double d[4];
226  } fdret;
227 
228  __asm__ (
229  // save registers
230  "stx %%l0, [%[saveReg]]\n\t"
231  "stx %%l1, [%[saveReg]+8]\n\t"
232  "mov %[saveReg], %%l1\n\t"
233  "add %%l1, 16, %%l0\n\t"
234  "stx %%l2, [%%l0]\n\t"
235  "add %%l0, 8, %%l0\n\t"
236  "stx %%l3, [%%l0]\n\t"
237  "add %%l0, 8, %%l0\n\t"
238  "stx %%l4, [%%l0]\n\t"
239  "add %%l0, 8, %%l0\n\t"
240  "stx %%l5, [%%l0]\n\t"
241  "add %%l0, 8, %%l0\n\t"
242  "stx %%o0, [%%l0]\n\t"
243  "add %%l0, 8, %%l0\n\t"
244  "stx %%o1, [%%l0]\n\t"
245  "add %%l0, 8, %%l0\n\t"
246  "stx %%o2, [%%l0]\n\t"
247  "add %%l0, 8, %%l0\n\t"
248  "stx %%o3, [%%l0]\n\t"
249  "add %%l0, 8, %%l0\n\t"
250  "stx %%o4, [%%l0]\n\t"
251  "add %%l0, 8, %%l0\n\t"
252  "stx %%o5, [%%l0]\n\t"
253  "add %%l0, 8, %%l0\n\t"
254  "stx %%l6, [%%l0]\n\t"
255  "add %%l0, 8, %%l0\n\t"
256  "stx %%l7, [%%l0]\n\t"
257  "mov %%l1, %%l7\n\t"
258 
259  // increase our own stackframe if necessary
260  "mov %%sp, %%l3\n\t" // save stack ptr for readjustment
261 
262  "subcc %%i5, 6, %%l0\n\t"
263  "ble .LmoveOn\n\t"
264  "nop\n\t"
265 
266  "sllx %%l0, 3, %%l0\n\t"
267  "add %%l0, 192, %%l0\n\t"
268  "add %%sp, 2047, %%l1\n\t" // old stack ptr
269  "sub %%l1, %%l0, %%l0\n\t" // future stack ptr
270  "andcc %%l0, 15, %%g0\n\t" // align stack to 16
271  "be .LisAligned\n\t"
272  "nop\n\t"
273  "sub %%l0, 8, %%l0\n"
274  ".LisAligned:\n\t"
275  "mov %%l0, %%o5\n\t" // save newly computed stack ptr
276  "add %%g0, 16, %%o4\n"
277 
278  // now copy hypers down to save register window
279  // and local variables
280  ".LcopyDown:\n\t"
281  "ldx [%%l1], %%l2\n\t"
282  "stx %%l2,[%%l0]\n\t"
283  "add %%l0, 8, %%l0\n\t"
284  "add %%l1, 8, %%l1\n\t"
285  "subcc %%o4, 1, %%o4\n\t"
286  "bne .LcopyDown\n\t"
287  "nop\n\t"
288 
289  "sub %%o5, 2047, %%sp\n\t" // move new stack ptr (hopefully) atomically - with bias
290  // while register window is valid in both spaces
291  // (scheduling might hit in copyDown loop)
292 
293  "sub %%i5, 6, %%l0\n\t" // copy parameters past the sixth to stack
294  "add %%i4, 48, %%l1\n\t"
295  "add %%sp, 2223, %%l2\n" // 2047+176
296  ".LcopyLong:\n\t"
297  "ldx [%%l1], %%o0\n\t"
298  "stx %%o0, [%%l2]\n\t"
299  "add %%l1, 8, %%l1\n\t"
300  "add %%l2, 8, %%l2\n\t"
301  "subcc %%l0, 1, %%l0\n\t"
302  "bne .LcopyLong\n\t"
303  "nop\n"
304 
305  ".LmoveOn:\n\t"
306  "mov %%i5, %%l0\n\t" // prepare out registers
307  "mov %%i4, %%l1\n\t"
308 
309  "ldx [%%l1], %%o0\n\t"// // prepare complex return ptr
310  //"ldd [%%l1], %%f0\n\t"
311  //"stx %%o0, [%%sp+2047+128]\n\t"
312  "sub %%l0, 1, %%l0\n\t"
313  "add %%l1, 8, %%l1\n\t"
314  //"subxcc %%o0, %%g0, %%o0\n\t"
315  //"bne .LhadComplexReturn\n\t"
316  //"nop\n\t"
317 
318  // No complex return ptr - this (next on stack) goes in %o0
319 
320  //"ldx [%%l1], %%o0\n\t"
321  //"subcc %%l0, 1, %%l0\n\t"
322  //"be .LdoCall\n\t"
323  //"nop\n\t"
324  //"add %%l1, 8, %%l1\n\t"
325 
326  //".LhadComplexReturn:\n\t"
327  "ldx [%%l1], %%o1\n\t"
328  //"ldd [%%l1], %%f2\n\t"
329  "subcc %%l0, 1, %%l0\n\t"
330  "be .LdoCall\n\t"
331  "nop\n\t"
332 
333  "add %%l1, 8, %%l1\n\t"
334  "ldx [%%l1], %%o2\n\t"
335  //"ldd [%%l1], %%f4\n\t"
336  "subcc %%l0, 1, %%l0\n\t"
337  "be .LdoCall\n\t"
338  "nop\n\t"
339 
340  "add %%l1, 8, %%l1\n\t"
341  "ldx [%%l1], %%o3\n\t"
342  //"ldd [%%l1], %%f6\n\t"
343  "subcc %%l0, 1, %%l0\n\t"
344  "be .LdoCall\n\t"
345  "nop\n\t"
346 
347  "add %%l1, 8, %%l1\n\t"
348  "ldx [%%l1], %%o4\n\t"
349  //"ldd [%%l1], %%f8\n\t"
350  "subcc %%l0, 1, %%l0\n\t"
351  "be .LdoCall\n\t"
352  "nop\n\t"
353 
354  "add %%l1, 8, %%l1\n\t"
355  "ldx [%%l1], %%o5\n"
356  //"ldd [%%l1], %%f10\n\t"
357 
358  ".LdoCall:\n\t"
359  "ldx [%%i0], %%l0\n\t" // get vtable ptr
360 
361 "sllx %%i1, 3, %%l6\n\t"
362 // "add %%l6, 8, %%l6\n\t"
363  "add %%l6, %%l0, %%l0\n\t"
364 // // vtable has 8byte wide entries,
365 // // upper half contains 2 half words, of which the first
366 // // is the this ptr patch !
367 // // first entry is (or __tf)
368 
369 // "ldsh [%%l0], %%l6\n\t" // load this ptr patch
370 // "add %%l6, %%o0, %%o0\n\t" // patch this ptr
371 
372 // "add %%l0, 4, %%l0\n\t" // get virtual function ptr
373  "ldx [%%l0], %%l0\n\t"
374 
375 // "ldx %0, %%l2\n\t"
376 // "subcc %%l2, %%g0, %%l2\n\t"
377 // "be .LcomplexCall\n\t"
378 // "nop\n\t"
379  "call %%l0\n\t"
380  "nop\n\t"
381 // "ba .LcallReturned\n\t"
382 // "nop\n"
383 // ".LcomplexCall:\n\t"
384 // "call %%l0\n\t"
385 // "nop\n\t"
386 // "unimp\n"
387 
388 // ".LcallReturned:\n\t"
389  "subcc %%l3, %%sp, %%g0\n\t"
390  "be .LcopiedUp\n\t"
391  "nop\n\t"
392  // Copy register save area back up
393  // Note: copy in reverse order (top down) in case areas overlap
394  "add %%sp, 2167, %%l0\n\t" // 2047+120
395  "add %%l3, 2167, %%l1\n\t"
396  "add %%g0, 16, %%o4\n\t"
397  ".LcopyUp:\n\t"
398  "ldx [%%l0], %%l2\n\t"
399  "stx %%l2, [%%l1]\n\t"
400  "sub %%l0, 8, %%l0\n\t"
401  "sub %%l1, 8, %%l1\n\t"
402  "subcc %%o4, 1, %%o4\n\t"
403  "bne .LcopyUp\n\t"
404  "nop\n\t"
405 
406  ".LcopiedUp:\n\t"
407  "mov %%l3, %%sp\n\t" // readjust stack so that our locals are where they belong
408 
409  // save possible return registers into our locals
410  "stx %%o0, %[oret0]\n\t"
411  "stx %%o1, %[oret1]\n\t"
412  "stx %%o2, %[oret2]\n\t"
413  "stx %%o3, %[oret3]\n\t"
414  "std %%f0, %[dret0]\n\t"
415  "std %%f2, %[dret1]\n\t"
416  "std %%f4, %[dret2]\n\t"
417  "std %%f6, %[dret3]\n\t"
418  //"st %%f0, %3\n\t"
419 
420  // restore registers
421  "ldx [%%l7], %%l0\n\t"
422  "add %%l7, 8, %%l7\n\t"
423  "ldx [%%l7], %%l1\n\t"
424  "add %%l7, 8, %%l7\n\t"
425  "ldx [%%l7], %%l2\n\t"
426  "add %%l7, 8, %%l7\n\t"
427  "ldx [%%l7], %%l3\n\t"
428  "add %%l7, 8, %%l7\n\t"
429  "ldx [%%l7], %%l4\n\t"
430  "add %%l7, 8, %%l7\n\t"
431  "ldx [%%l7], %%l5\n\t"
432  "add %%l7, 8, %%l7\n\t"
433  "ldx [%%l7], %%o0\n\t"
434  "add %%l7, 8, %%l7\n\t"
435  "ldx [%%l7], %%o1\n\t"
436  "add %%l7, 8, %%l7\n\t"
437  "ldx [%%l7], %%o2\n\t"
438  "add %%l7, 8, %%l7\n\t"
439  "ldx [%%l7], %%o3\n\t"
440  "add %%l7, 8, %%l7\n\t"
441  "ldx [%%l7], %%o4\n\t"
442  "add %%l7, 8, %%l7\n\t"
443  "ldx [%%l7], %%o5\n\t"
444  "add %%l7, 8, %%l7\n\t"
445  "ldx [%%l7], %%l6\n\t"
446  "add %%l7, 8, %%l7\n\t"
447  "ldx [%%l7], %%l7\n\t"
448  :
449  //"=m"(bSimpleReturn),
450  [oret0]"=m"(oret[0]), [oret1]"=m"(oret[1]), [oret2]"=m"(oret[2]), [oret3]"=m"(oret[3]),
451  [dret0]"=m"(fdret.d[0]), [dret1]"=m"(fdret.d[1]), [dret2]"=m"(fdret.d[2]), [dret3]"=m"(fdret.d[3])
452  //"=m"(f0f)
453  :
454  [saveReg]"r"(&saveReg[0])
455  :
456  "memory"
457  );
458  switch(pReturnTypeRef->eTypeClass)
459  {
460  case typelib_TypeClass_HYPER:
461  case typelib_TypeClass_UNSIGNED_HYPER:
462  *(long*)pRegisterReturn = oret[0];
463  break;
464  case typelib_TypeClass_LONG:
465  case typelib_TypeClass_UNSIGNED_LONG:
466  case typelib_TypeClass_ENUM:
467  *(int*)pRegisterReturn = (int)oret[0];
468  break;
469  case typelib_TypeClass_CHAR:
470  case typelib_TypeClass_SHORT:
471  case typelib_TypeClass_UNSIGNED_SHORT:
472  *(unsigned short*)pRegisterReturn = (unsigned short)oret[0];
473  break;
474  case typelib_TypeClass_BOOLEAN:
475  case typelib_TypeClass_BYTE:
476  *(unsigned char*)pRegisterReturn = (unsigned char)oret[0];
477  break;
478  case typelib_TypeClass_FLOAT:
479  *(float*)pRegisterReturn = fdret.f[0];
480  break;
481  case typelib_TypeClass_DOUBLE:
482  *(double*)pRegisterReturn = fdret.d[0];
483  break;
484  case typelib_TypeClass_STRUCT:
485  case typelib_TypeClass_EXCEPTION:
486  {
487  sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize;
488  if (bSimpleReturn && nRetSize <= 32 && nRetSize > 0)
489  {
490  typelib_TypeDescription * pTypeDescr = 0;
491  TYPELIB_DANGER_GET( &pTypeDescr, pReturnTypeRef );
492  fillReturn(pTypeDescr, oret, fdret.f, fdret.d, pRegisterReturn);
493  TYPELIB_DANGER_RELEASE( pTypeDescr );
494  }
495  break;
496  }
497  default:
498  break;
499  }
500 }
501 
502 static void cpp_call(
505  typelib_TypeDescriptionReference * pReturnTypeRef,
506  sal_Int32 nParams, typelib_MethodParameter * pParams,
507  void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
508 {
509  // max space for: complex ret ptr, this, values|ptr ...
510  char * pCppStack =
511  (char *)alloca( (nParams+2) * sizeof(sal_Int64) );
512  char * pCppStackStart = pCppStack;
513 
514  //fprintf(stderr, "pCppStack: %p, pCppStackStart: %p\n", pCppStack, pCppStackStart);
515 
516  // return
517  typelib_TypeDescription * pReturnTypeDescr = 0;
518  TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
519  assert(pReturnTypeDescr);
520 
521  void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
522 
523  if (pReturnTypeDescr)
524  {
525  if ( CPPU_CURRENT_NAMESPACE::return_in_hidden_param( pReturnTypeRef ) )
526  {
527  // complex return via ptr
528  pCppReturn = *(void **)pCppStack = (bridges::cpp_uno::shared::relatesToInterfaceType(pReturnTypeDescr )
529  ? alloca( pReturnTypeDescr->nSize )
530  : pUnoReturn); // direct way
531  pCppStack += sizeof(void*);
532  }
533  else
534  {
535  pCppReturn = pUnoReturn; // direct way for simple types
536  }
537  }
538  // push this
539  void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
540  + aVtableSlot.offset;
541  *(void**)pCppStack = pAdjustedThisPtr;
542  pCppStack += sizeof( void* );
543 
544  // stack space
545  static_assert(sizeof(void *) == sizeof(sal_Int64), "### unexpected size!");
546  // args
547  void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
548  // indices of values this have to be converted (interface conversion cpp<=>uno)
549  sal_Int32 * pTempIndices = (sal_Int32 *)(pCppArgs + nParams);
550  // type descriptions for reconversions
551  typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
552 
553  sal_Int32 nTempIndices = 0;
554 
555  for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
556  {
557  const typelib_MethodParameter & rParam = pParams[nPos];
558  typelib_TypeDescription * pParamTypeDescr = 0;
559  TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
560  if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
561  {
562  uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
563  pThis->getBridge()->getUno2Cpp() );
564 
565  switch (pParamTypeDescr->eTypeClass)
566  {
567  case typelib_TypeClass_LONG:
568  *(sal_Int64 *)pCppStack = *(sal_Int32 *)pCppArgs[nPos];
569  break;
570  case typelib_TypeClass_UNSIGNED_LONG:
571  case typelib_TypeClass_ENUM:
572  *(sal_Int64 *)pCppStack = *(sal_uInt32 *)pCppArgs[nPos];
573  break;
574  case typelib_TypeClass_CHAR:
575  case typelib_TypeClass_SHORT:
576  *(sal_Int64 *)pCppStack = *(sal_Int16 *)pCppArgs[nPos];
577  break;
578  case typelib_TypeClass_UNSIGNED_SHORT:
579  *(sal_Int64 *)pCppStack = *(sal_uInt16 *)pCppArgs[nPos];
580  break;
581  case typelib_TypeClass_BOOLEAN:
582  case typelib_TypeClass_BYTE:
583  *(sal_Int64 *)pCppStack = *(sal_Int8 *)pCppArgs[nPos];
584  break;
585  case typelib_TypeClass_FLOAT:
586  *(float *)(pCppStack+4) = *(float *)pCppArgs[nPos];
587  break;
588  case typelib_TypeClass_DOUBLE:
589  *(double *)pCppStack = *(double *)pCppArgs[nPos];
590  break;
591  case typelib_TypeClass_HYPER:
592  case typelib_TypeClass_UNSIGNED_HYPER:
593  *(sal_Int64 *)pCppStack = *(sal_Int64 *)pCppArgs[nPos];
594  break;
595  default:
596  break;
597  }
598  // no longer needed
599  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
600  }
601  else // ptr to complex value | ref
602  {
603  if (! rParam.bIn) // is pure out
604  {
605  // cpp out is constructed mem, uno out is not!
607  *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
608  pParamTypeDescr );
609  pTempIndices[nTempIndices] = nPos; // default constructed for cpp call
610  // will be released at reconversion
611  ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
612  }
613  // is in/inout
615  pParamTypeDescr ))
616  {
618  *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
619  pUnoArgs[nPos], pParamTypeDescr,
620  pThis->getBridge()->getUno2Cpp() );
621 
622  pTempIndices[nTempIndices] = nPos; // has to be reconverted
623  // will be released at reconversion
624  ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
625  }
626  else // direct way
627  {
628  *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
629  // no longer needed
630  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
631  }
632  }
633  pCppStack += sizeof(sal_Int64); // standard parameter length
634  }
635 
636  try
637  {
638  int nStackHypers = (pCppStack - pCppStackStart)/sizeof(sal_Int64);
639  assert( !( (pCppStack - pCppStackStart ) & 7) && "UNALIGNED STACK !!! (Please DO panic" );
640 
641  //fprintf( stderr, "callVirtualMethod: %p, %lld, %p, %p, %p, %lld\n",
642  // pAdjustedThisPtr,
643  // (long long)aVtableSlot.index,
644  // pCppReturn,
645  // pReturnTypeRef,
646  // pCppStackStart,
647  // (long long)nStackHypers);
648  try {
650  pAdjustedThisPtr,
651  aVtableSlot.index,
652  pCppReturn,
653  pReturnTypeRef,
654  (sal_Int64 *)pCppStackStart,
655  nStackHypers,
656  pParams,
657  nParams);
658  } catch (css::uno::Exception &) {
659  throw;
660  } catch (std::exception & e) {
661  throw css::uno::RuntimeException(
662  "C++ code threw " + o3tl::runtimeToOUString(typeid(e).name()) + ": "
663  + o3tl::runtimeToOUString(e.what()));
664  } catch (...) {
665  throw css::uno::RuntimeException("C++ code threw unknown exception");
666  }
667  // NO exception occurred...
668  *ppUnoExc = 0;
669 
670  // reconvert temporary params
671  for ( ; nTempIndices--; )
672  {
673  sal_Int32 nIndex = pTempIndices[nTempIndices];
674  typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
675 
676  if (pParams[nIndex].bIn)
677  {
678  if (pParams[nIndex].bOut) // inout
679  {
680  uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
681  uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
682  pThis->getBridge()->getCpp2Uno() );
683  }
684  }
685  else // pure out
686  {
687  uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
688  pThis->getBridge()->getCpp2Uno() );
689  }
690  // destroy temp cpp param => cpp: every param was constructed
691  uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
692 
693  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
694  }
695  // return value
696  if (pCppReturn && pUnoReturn != pCppReturn)
697  {
698  uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
699  pThis->getBridge()->getCpp2Uno() );
700  uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
701  }
702  }
703  catch( ... )
704  {
705  // get exception
707 
708  // temporary params
709  for ( ; nTempIndices--; )
710  {
711  sal_Int32 nIndex = pTempIndices[nTempIndices];
712  // destroy temp cpp param => cpp: every param was constructed
713  uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndices], cpp_release );
714  TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
715  }
716  // return type
717  if (pReturnTypeDescr)
718  TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
719  }
720 }
721 
722 }
723 
724 namespace bridges::cpp_uno::shared {
725 
727  uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
728  void * pReturn, void * pArgs[], uno_Any ** ppException )
729 {
730 #if defined BRIDGES_DEBUG
731  OString cstr( OUStringToOString( pMemberDescr->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
732  fprintf( stderr, "received dispatch( %s )\n", cstr.getStr() );
733 #endif
734 
735  // is my surrogate
737  = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
738 // typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
739 
740  switch (pMemberDescr->eTypeClass)
741  {
742  case typelib_TypeClass_INTERFACE_ATTRIBUTE:
743  {
744  VtableSlot aVtableSlot(
746  reinterpret_cast<
747  typelib_InterfaceAttributeTypeDescription const * >(
748  pMemberDescr)));
749  if (pReturn)
750  {
751  // dependent dispatch
752  cpp_call(
753  pThis, aVtableSlot,
754  ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
755  0, 0, // no params
756  pReturn, pArgs, ppException );
757  }
758  else
759  {
760  // is SET
761  typelib_MethodParameter aParam;
762  aParam.pTypeRef =
763  ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
764  aParam.bIn = sal_True;
765  aParam.bOut = sal_False;
766 
767  typelib_TypeDescriptionReference * pReturnTypeRef = 0;
768  OUString aVoidName("void");
770  &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
771 
772  // dependent dispatch
773  aVtableSlot.index += 1; // get, then set method
774  cpp_call(
775  pThis, aVtableSlot,
776  pReturnTypeRef,
777  1, &aParam,
778  pReturn, pArgs, ppException );
779 
781  }
782 
783  break;
784  }
785  case typelib_TypeClass_INTERFACE_METHOD:
786  {
787  VtableSlot aVtableSlot(
789  reinterpret_cast<
790  typelib_InterfaceMethodTypeDescription const * >(
791  pMemberDescr)));
792  switch (aVtableSlot.index)
793  {
794  // standard calls
795  case 1: // acquire uno interface
796  (*pUnoI->acquire)( pUnoI );
797  *ppException = 0;
798  break;
799  case 2: // release uno interface
800  (*pUnoI->release)( pUnoI );
801  *ppException = 0;
802  break;
803  case 0: // queryInterface() opt
804  {
805  typelib_TypeDescription * pTD = 0;
806  TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
807  if (pTD)
808  {
809  uno_Interface * pInterface = 0;
810  (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
811  pThis->pBridge->getUnoEnv(),
812  (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
813 
814  if (pInterface)
815  {
816  ::uno_any_construct(
817  reinterpret_cast< uno_Any * >( pReturn ),
818  &pInterface, pTD, 0 );
819  (*pInterface->release)( pInterface );
820  TYPELIB_DANGER_RELEASE( pTD );
821  *ppException = 0;
822  break;
823  }
824  TYPELIB_DANGER_RELEASE( pTD );
825  }
826  } // else perform queryInterface()
827  default:
828  // dependent dispatch
829  cpp_call(
830  pThis, aVtableSlot,
831  ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
832  ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
833  ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
834  pReturn, pArgs, ppException );
835  }
836  break;
837  }
838  default:
839  {
840  ::com::sun::star::uno::RuntimeException aExc(
841  "illegal member type description!",
843 
844  Type const & rExcType = cppu::UnoType<decltype(aExc)>::get();
845  // binary identical null reference
846  ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
847  }
848  }
849 }
850 
851 }
852 
853 /* 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()
signed char sal_Int8
Represents a vtable slot of a C++ class.
Definition: vtables.hxx:59
void fillUnoException(uno_Any *pExc, uno_Mapping *pCpp2Uno)
bool isSimpleType(typelib_TypeClass typeClass)
Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT, UNSIGNED SHORT...
Definition: types.cxx:28
#define SET_FP(n, p)
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
return NULL
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef)
Does function that returns this type use a hidden parameter, or registers?
void unoInterfaceProxyDispatch(uno_Interface *pUnoI, const typelib_TypeDescription *pMemberDescr, void *pReturn, void *pArgs[], uno_Any **ppException)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
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)
unsigned _Unwind_Word __attribute__((__mode__(__word__)))
Definition: unwind-cxx.h:45
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()
void SAL_CALL typelib_typedescriptionreference_release(typelib_TypeDescriptionReference *pRef) SAL_THROW_EXTERN_C()
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
void SAL_CALL typelib_typedescriptionreference_new(typelib_TypeDescriptionReference **ppTDR, typelib_TypeClass eTypeClass, rtl_uString *pTypeName) SAL_THROW_EXTERN_C()
register sal_uInt32 r28 __asm__("%r28")
double d
OUString runtimeToOUString(char const *runtimeString)
#define sal_False
void * p
void(* f)(TrueTypeTable *)
void dummy_can_throw_anything(char const *)
com::sun::star::uno::XInterface * getCppI()
sal_uInt16 nPos
char const * name