LibreOffice Module bridges (master)  1
gcc3_linux_x86-64/cpp2uno.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 
21 #include <stdio.h>
22 #include <stdlib.h>
23 
24 #include <rtl/alloc.h>
25 #include <sal/log.hxx>
26 
27 #include <com/sun/star/uno/genfunc.hxx>
28 #include <com/sun/star/uno/RuntimeException.hpp>
29 #include <config_options.h>
30 #include <uno/data.h>
31 #include <typelib/typedescription.hxx>
32 
33 #include <bridge.hxx>
34 #include <cppinterfaceproxy.hxx>
35 #include <types.hxx>
36 #include <vtablefactory.hxx>
37 
38 #include "abi.hxx"
39 #include "call.hxx"
40 #include "rtti.hxx"
41 #include "share.hxx"
42 
43 using namespace ::com::sun::star::uno;
44 
45 // Perform the UNO call
46 //
47 // We must convert the parameters stored in gpreg, fpreg and ovrflw to UNO
48 // arguments and call pThis->getUnoI()->pDispatcher.
49 //
50 // gpreg: [ret *], this, [gpr params]
51 // fpreg: [fpr params]
52 // ovrflw: [gpr or fpr params (properly aligned)]
53 //
54 // [ret *] is present when we are returning a structure bigger than 16 bytes
55 // Simple types are returned in rax, rdx (int), or xmm0, xmm1 (fp).
56 // Similarly structures <= 16 bytes are in rax, rdx, xmm0, xmm1 as necessary.
57 //
58 // The return value is the same as for cpp_vtable_call.
59 static int cpp2uno_call(
61  const typelib_TypeDescription * pMemberTypeDescr,
62  typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
63  sal_Int32 nParams, typelib_MethodParameter * pParams,
64  void ** gpreg, void ** fpreg, void ** ovrflw,
65  sal_uInt64 * pRegisterReturn /* space for register return */ )
66 {
67  unsigned int nr_gpr = 0; //number of gpr registers used
68  unsigned int nr_fpr = 0; //number of fpr registers used
69 
70  // return
71  typelib_TypeDescription * pReturnTypeDescr = nullptr;
72  if (pReturnTypeRef)
73  TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
74  x86_64::ReturnKind returnKind
75  = (pReturnTypeRef == nullptr || pReturnTypeRef->eTypeClass == typelib_TypeClass_VOID)
77 
78  void * pUnoReturn = nullptr;
79  void * pCppReturn = nullptr; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
80 
81  if ( pReturnTypeDescr )
82  {
83  if ( returnKind == x86_64::ReturnKind::Memory )
84  {
85  pCppReturn = *gpreg++;
86  nr_gpr++;
87 
88  pUnoReturn = ( bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
89  ? alloca( pReturnTypeDescr->nSize )
90  : pCppReturn ); // direct way
91  }
92  else
93  pUnoReturn = pRegisterReturn; // direct way for simple types
94  }
95 
96  // pop this
97  gpreg++;
98  nr_gpr++;
99 
100  // stack space
101  // parameters
102  void ** pUnoArgs = static_cast<void **>(alloca( 4 * sizeof(void *) * nParams ));
103  void ** pCppArgs = pUnoArgs + nParams;
104  // indices of values this have to be converted (interface conversion cpp<=>uno)
105  sal_Int32 * pTempIndices = reinterpret_cast<sal_Int32 *>(pUnoArgs + (2 * nParams));
106  // type descriptions for reconversions
107  typelib_TypeDescription ** ppTempParamTypeDescr = reinterpret_cast<typelib_TypeDescription **>(pUnoArgs + (3 * nParams));
108 
109  sal_Int32 nTempIndices = 0;
110 
111  for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
112  {
113  const typelib_MethodParameter & rParam = pParams[nPos];
114 
115  if ( !rParam.bOut && bridges::cpp_uno::shared::isSimpleType( rParam.pTypeRef ) ) // value
116  {
117  int nUsedGPR = 0;
118  int nUsedSSE = 0;
119  bool bFitsRegisters = x86_64::examine_argument( rParam.pTypeRef, nUsedGPR, nUsedSSE );
120 
121  // Simple types must fit exactly one register on x86_64
122  assert( bFitsRegisters && ( ( nUsedSSE == 1 && nUsedGPR == 0 ) || ( nUsedSSE == 0 && nUsedGPR == 1 ) ) ); (void)bFitsRegisters;
123 
124  if ( nUsedSSE == 1 )
125  {
126  if ( nr_fpr < x86_64::MAX_SSE_REGS )
127  {
128  pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
129  nr_fpr++;
130  }
131  else
132  pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
133  }
134  else if ( nUsedGPR == 1 )
135  {
136  if ( nr_gpr < x86_64::MAX_GPR_REGS )
137  {
138  pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
139  nr_gpr++;
140  }
141  else
142  pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
143  }
144  }
145  else // ref
146  {
147  typelib_TypeDescription * pParamTypeDescr = nullptr;
148  TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
149 
150  void *pCppStack;
151  if ( nr_gpr < x86_64::MAX_GPR_REGS )
152  {
153  pCppArgs[nPos] = pCppStack = *gpreg++;
154  nr_gpr++;
155  }
156  else
157  pCppArgs[nPos] = pCppStack = *ovrflw++;
158 
159  if (! rParam.bIn) // is pure out
160  {
161  // uno out is unconstructed mem!
162  pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
163  pTempIndices[nTempIndices] = nPos;
164  // will be released at reconversion
165  ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
166  }
167  else if ( bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ) ) // is in/inout
168  {
169  pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
170  uno_copyAndConvertData( pUnoArgs[nPos],
171  pCppStack, pParamTypeDescr,
172  pThis->getBridge()->getCpp2Uno() );
173  pTempIndices[nTempIndices] = nPos; // has to be reconverted
174  // will be released at reconversion
175  ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
176  }
177  else // direct way
178  {
179  pUnoArgs[nPos] = pCppStack;
180  // no longer needed
181  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
182  }
183  }
184  }
185 
186  // ExceptionHolder
187  uno_Any aUnoExc; // Any will be constructed by callee
188  uno_Any * pUnoExc = &aUnoExc;
189 
190  // invoke uno dispatch call
191  (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
192 
193  // in case an exception occurred...
194  if ( pUnoExc )
195  {
196  // destruct temporary in/inout params
197  for ( ; nTempIndices--; )
198  {
199  sal_Int32 nIndex = pTempIndices[nTempIndices];
200 
201  if (pParams[nIndex].bIn) // is in/inout => was constructed
202  uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], nullptr );
203  TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
204  }
205  if (pReturnTypeDescr)
206  TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
207 
208  CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
209  // is here for dummy
210  return 0;
211  }
212  else // else no exception occurred...
213  {
214  // temporary params
215  for ( ; nTempIndices--; )
216  {
217  sal_Int32 nIndex = pTempIndices[nTempIndices];
218  typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
219 
220  if ( pParams[nIndex].bOut ) // inout/out
221  {
222  // convert and assign
223  uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
224  uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
225  pThis->getBridge()->getUno2Cpp() );
226  }
227  // destroy temp uno param
228  uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, nullptr );
229 
230  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
231  }
232  // return
233  if ( pCppReturn ) // has complex return
234  {
235  if ( pUnoReturn != pCppReturn ) // needs reconversion
236  {
237  uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
238  pThis->getBridge()->getUno2Cpp() );
239  // destroy temp uno return
240  uno_destructData( pUnoReturn, pReturnTypeDescr, nullptr );
241  }
242  // complex return ptr is set to return reg
243  *reinterpret_cast<void **>(pRegisterReturn) = pCppReturn;
244  }
245  if ( pReturnTypeDescr )
246  {
247  TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
248  }
249  switch (returnKind) {
251  return 0;
253  return 1;
254  default:
255  return -1;
256  }
257  }
258 }
259 
260 // Returns -1 for the general case where potential return values from privateSnippetExecutor can be
261 // copied from pRegisterReturn to both %rax and %rdx (in that order) and to %xmm0 and %xmm1 (in that
262 // order)---each specific return type will only require a subset of that copy operations, but the
263 // other copies to those non--callee-saved registers will be redundant and harmless. Returns 0 for
264 // the special case where return values from privateSnippetExecutor must be copied from
265 // pRegisterReturn to %xmm0 and %rax (in that order). Returns 1 for the special case where return
266 // privateSnippetExecutor must be copied from pRegisterReturn to %rax and %xmm0 (in that order).
268  sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
269  void ** gpreg, void ** fpreg, void ** ovrflw,
270  sal_uInt64 * pRegisterReturn /* space for register return */ )
271 {
272  // gpreg: [ret *], this, [other gpr params]
273  // fpreg: [fpr params]
274  // ovrflw: [gpr or fpr params (properly aligned)]
275  void * pThis;
276  if ( nFunctionIndex & 0x80000000 )
277  {
278  nFunctionIndex &= 0x7fffffff;
279  pThis = gpreg[1];
280  }
281  else
282  {
283  pThis = gpreg[0];
284  }
285  pThis = static_cast<char *>( pThis ) - nVtableOffset;
286 
289 
290  typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
291 
292  if ( nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex )
293  {
294  SAL_WARN(
295  "bridges",
296  "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
297  << " vtable index " << nFunctionIndex << "/"
298  << pTypeDescr->nMapFunctionIndexToMemberIndex);
299  throw RuntimeException(
300  ("illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
301  + " vtable index " + OUString::number(nFunctionIndex) + "/"
302  + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
303  reinterpret_cast<XInterface *>( pCppI ) );
304  }
305 
306  // determine called method
307  sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
308  assert(nMemberPos < pTypeDescr->nAllMembers);
309 
310  TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
311 
312  int eRet;
313  switch ( aMemberDescr.get()->eTypeClass )
314  {
315  case typelib_TypeClass_INTERFACE_ATTRIBUTE:
316  {
317  typelib_TypeDescriptionReference *pAttrTypeRef =
318  reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( aMemberDescr.get() )->pAttributeTypeRef;
319 
320  if ( pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex )
321  {
322  // is GET method
323  eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
324  0, nullptr, // no params
325  gpreg, fpreg, ovrflw, pRegisterReturn );
326  }
327  else
328  {
329  // is SET method
330  typelib_MethodParameter aParam;
331  aParam.pTypeRef = pAttrTypeRef;
332  aParam.bIn = true;
333  aParam.bOut = false;
334 
335  eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
336  nullptr, // indicates void return
337  1, &aParam,
338  gpreg, fpreg, ovrflw, pRegisterReturn );
339  }
340  break;
341  }
342  case typelib_TypeClass_INTERFACE_METHOD:
343  {
344  // is METHOD
345  switch ( nFunctionIndex )
346  {
347  case 1: // acquire()
348  pCppI->acquireProxy(); // non virtual call!
349  eRet = 0;
350  break;
351  case 2: // release()
352  pCppI->releaseProxy(); // non virtual call!
353  eRet = 0;
354  break;
355  case 0: // queryInterface() opt
356  {
357  typelib_TypeDescription * pTD = nullptr;
358  TYPELIB_DANGER_GET( &pTD, static_cast<Type *>( gpreg[2] )->getTypeLibType() );
359  if ( pTD )
360  {
361  XInterface * pInterface = nullptr;
362  (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
363  ( pCppI->getBridge()->getCppEnv(),
364  reinterpret_cast<void **>(&pInterface),
365  pCppI->getOid().pData,
366  reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
367 
368  if ( pInterface )
369  {
370  ::uno_any_construct( static_cast<uno_Any *>( gpreg[0] ),
371  &pInterface, pTD, cpp_acquire );
372 
373  pInterface->release();
374  TYPELIB_DANGER_RELEASE( pTD );
375 
376  reinterpret_cast<void **>( pRegisterReturn )[0] = gpreg[0];
377  eRet = 0;
378  break;
379  }
380  TYPELIB_DANGER_RELEASE( pTD );
381  }
382  [[fallthrough]]; // else perform queryInterface()
383  }
384  default:
385  {
386  typelib_InterfaceMethodTypeDescription *pMethodTD =
387  reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( aMemberDescr.get() );
388 
389  eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
390  pMethodTD->pReturnTypeRef,
391  pMethodTD->nParams,
392  pMethodTD->pParams,
393  gpreg, fpreg, ovrflw, pRegisterReturn );
394  }
395  }
396  break;
397  }
398  default:
399  {
400  throw RuntimeException("no member description found!",
401  reinterpret_cast<XInterface *>( pCppI ) );
402  }
403  }
404 
405  return eRet;
406 }
407 
408 const int codeSnippetSize = 24;
409 
410 // Generate a trampoline that redirects method calls to
411 // privateSnippetExecutor().
412 //
413 // privateSnippetExecutor() saves all the registers that are used for
414 // parameter passing on x86_64, and calls the cpp_vtable_call().
415 // When it returns, privateSnippetExecutor() sets the return value.
416 //
417 // Note: The code snippet we build here must not create a stack frame,
418 // otherwise the UNO exceptions stop working thanks to non-existing
419 // unwinding info.
420 static unsigned char * codeSnippet( unsigned char * code,
421  sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
422  bool bHasHiddenParam )
423 {
424  sal_uInt64 nOffsetAndIndex = ( static_cast<sal_uInt64>(nVtableOffset) << 32 ) | static_cast<sal_uInt64>(nFunctionIndex);
425 
426  if ( bHasHiddenParam )
427  nOffsetAndIndex |= 0x80000000;
428 
429  // movq $<nOffsetAndIndex>, %r10
430  *reinterpret_cast<sal_uInt16 *>( code ) = 0xba49;
431  *reinterpret_cast<sal_uInt16 *>( code + 2 ) = nOffsetAndIndex & 0xFFFF;
432  *reinterpret_cast<sal_uInt32 *>( code + 4 ) = nOffsetAndIndex >> 16;
433  *reinterpret_cast<sal_uInt16 *>( code + 8 ) = nOffsetAndIndex >> 48;
434 
435  // movq $<address of the privateSnippetExecutor>, %r11
436  *reinterpret_cast<sal_uInt16 *>( code + 10 ) = 0xbb49;
437  *reinterpret_cast<sal_uInt32 *>( code + 12 )
438  = reinterpret_cast<sal_uInt64>(privateSnippetExecutor);
439  *reinterpret_cast<sal_uInt32 *>( code + 16 )
440  = reinterpret_cast<sal_uInt64>(privateSnippetExecutor) >> 32;
441 
442  // jmpq *%r11
443  *reinterpret_cast<sal_uInt32 *>( code + 20 ) = 0x00e3ff49;
444 
445 #if OSL_DEBUG_LEVEL > 1
446  fprintf(stderr,
447  "==> codeSnippet, functionIndex=%d%s, vtableOffset=%d\n",
448  nFunctionIndex, (bHasHiddenParam ? "|0x80000000":""), nVtableOffset);
449 #endif
450 
451  return code + codeSnippetSize;
452 }
453 
455 
458 {
459  return static_cast< Slot * >(block) + 2;
460 }
461 
463  sal_Int32 slotCount)
464 {
465  return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
466 }
467 
470  void * block, sal_Int32 slotCount, sal_Int32 vtableNumber,
471  typelib_InterfaceTypeDescription * type)
472 {
473  Slot * slots = mapBlockToVtable(block);
474  slots[-2].fn = reinterpret_cast<void *>(-(vtableNumber * sizeof (void *)));
475 #if ENABLE_RUNTIME_OPTIMIZATIONS
476  slots[-1].fn = nullptr;
477  (void)type;
478 #else
479  slots[-1].fn = x86_64::getRtti(type->aBase);
480 #endif
481  return slots + slotCount;
482 }
483 
484 
486  Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
487  typelib_InterfaceTypeDescription const * type, sal_Int32 nFunctionOffset,
488  sal_Int32 functionCount, sal_Int32 nVtableOffset )
489 {
490  (*slots) -= functionCount;
491  Slot * s = *slots;
492  for ( sal_Int32 nPos = 0; nPos < type->nMembers; ++nPos )
493  {
494  typelib_TypeDescription * pTD = nullptr;
495 
496  TYPELIB_DANGER_GET( &pTD, type->ppMembers[ nPos ] );
497  assert(pTD);
498 
499  if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE )
500  {
501  typelib_InterfaceAttributeTypeDescription *pAttrTD =
502  reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
503 
504  // get method
505  (s++)->fn = code + writetoexecdiff;
506  code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
507  x86_64::return_in_hidden_param( pAttrTD->pAttributeTypeRef ) );
508 
509  if ( ! pAttrTD->bReadOnly )
510  {
511  // set method
512  (s++)->fn = code + writetoexecdiff;
513  code = codeSnippet( code, nFunctionOffset++, nVtableOffset, false );
514  }
515  }
516  else if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_METHOD )
517  {
518  typelib_InterfaceMethodTypeDescription *pMethodTD =
519  reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD );
520 
521  (s++)->fn = code + writetoexecdiff;
522  code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
523  x86_64::return_in_hidden_param( pMethodTD->pReturnTypeRef ) );
524  }
525  else
526  assert(false);
527 
528  TYPELIB_DANGER_RELEASE( pTD );
529  }
530  return code;
531 }
532 
534  SAL_UNUSED_PARAMETER unsigned char const *,
535  SAL_UNUSED_PARAMETER unsigned char const * )
536 {}
537 
538 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const sal_uInt32 MAX_GPR_REGS
void(* privateSnippetExecutor)()
sal_Int32 nIndex
std::type_info * getRtti(typelib_TypeDescription const &type)
Definition: rtti.cxx:269
void SAL_CALL uno_destructData(void *pValue, typelib_TypeDescription *pTypeDescr, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
bool isSimpleType(typelib_TypeClass typeClass)
Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT, UNSIGNED SHORT...
Definition: types.cxx:28
static std::size_t getBlockSize(sal_Int32 slotCount)
Calculate the size of a raw vtable block.
const int codeSnippetSize
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
static Slot * initializeBlock(void *block, sal_Int32 slotCount, sal_Int32 vtableNumber, typelib_InterfaceTypeDescription *type)
Initialize a raw vtable block.
ReturnKind getReturnKind(typelib_TypeDescriptionReference *type) noexcept
static Slot * mapBlockToVtable(void *block)
Given a pointer to a block, turn it into a vtable pointer.
struct _uno_Any uno_Any
Definition: msvc/except.hxx:31
uno_Mapping * getUno2Cpp()
Definition: bridge.hxx:73
uno_ExtEnvironment * getCppEnv()
Definition: bridge.hxx:69
static unsigned char * addLocalFunctions(Slot **slots, unsigned char *code, sal_PtrDiff writetoexecdiff, typelib_InterfaceTypeDescription const *type, sal_Int32 functionOffset, sal_Int32 functionCount, sal_Int32 vtableOffset)
Fill the vtable slots corresponding to all local (i.e., not inherited) functions of a given interface...
typelib_InterfaceTypeDescription * getTypeDescr()
A cpp proxy wrapping a uno interface.
void SAL_CALL uno_copyAndConvertData(void *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_Mapping *mapping) SAL_THROW_EXTERN_C()
struct _typelib_TypeDescription typelib_TypeDescription
Definition: msvc/except.hxx:52
uno_Mapping * getCpp2Uno()
Definition: bridge.hxx:72
bool examine_argument(typelib_TypeDescriptionReference *pTypeRef, int &nUsedGPR, int &nUsedSSE) noexcept
const sal_uInt32 MAX_SSE_REGS
void raiseException(uno_Any *pUnoExc, uno_Mapping *pUno2Cpp)
static int cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy *pThis, const typelib_TypeDescription *pMemberTypeDescr, typelib_TypeDescriptionReference *pReturnTypeRef, sal_Int32 nParams, typelib_MethodParameter *pParams, void **gpreg, void **fpreg, void **ovrflw, sal_uInt64 *pRegisterReturn)
static unsigned char * codeSnippet(unsigned char *code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, bool bHasHiddenParam)
static void flushCode(unsigned char const *begin, unsigned char const *end)
Flush all the generated code snippets of a vtable, on platforms that require it.
#define SAL_WARN(area, stream)
static CppInterfaceProxy * castInterfaceToProxy(void *pInterface)
int cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void **gpreg, void **fpreg, void **ovrflw, sal_uInt64 *pRegisterReturn)
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef) noexcept
Does function that returns this type use a hidden parameter, or registers?
sal_uInt16 nPos
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo