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 static typelib_TypeClass cpp2uno_call(
59  const typelib_TypeDescription * pMemberTypeDescr,
60  typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
61  sal_Int32 nParams, typelib_MethodParameter * pParams,
62  void ** gpreg, void ** fpreg, void ** ovrflw,
63  sal_uInt64 * pRegisterReturn /* space for register return */ )
64 {
65  unsigned int nr_gpr = 0; //number of gpr registers used
66  unsigned int nr_fpr = 0; //number of fpr registers used
67 
68  // return
69  typelib_TypeDescription * pReturnTypeDescr = nullptr;
70  if (pReturnTypeRef)
71  TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
72 
73  void * pUnoReturn = nullptr;
74  void * pCppReturn = nullptr; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
75 
76  if ( pReturnTypeDescr )
77  {
78  if ( x86_64::return_in_hidden_param( pReturnTypeRef ) )
79  {
80  pCppReturn = *gpreg++;
81  nr_gpr++;
82 
83  pUnoReturn = ( bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
84  ? alloca( pReturnTypeDescr->nSize )
85  : pCppReturn ); // direct way
86  }
87  else
88  pUnoReturn = pRegisterReturn; // direct way for simple types
89  }
90 
91  // pop this
92  gpreg++;
93  nr_gpr++;
94 
95  // stack space
96  // parameters
97  void ** pUnoArgs = static_cast<void **>(alloca( 4 * sizeof(void *) * nParams ));
98  void ** pCppArgs = pUnoArgs + nParams;
99  // indices of values this have to be converted (interface conversion cpp<=>uno)
100  sal_Int32 * pTempIndices = reinterpret_cast<sal_Int32 *>(pUnoArgs + (2 * nParams));
101  // type descriptions for reconversions
102  typelib_TypeDescription ** ppTempParamTypeDescr = reinterpret_cast<typelib_TypeDescription **>(pUnoArgs + (3 * nParams));
103 
104  sal_Int32 nTempIndices = 0;
105 
106  for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
107  {
108  const typelib_MethodParameter & rParam = pParams[nPos];
109 
110  int nUsedGPR = 0;
111  int nUsedSSE = 0;
112  bool bFitsRegisters = x86_64::examine_argument( rParam.pTypeRef, false, nUsedGPR, nUsedSSE );
113  if ( !rParam.bOut && bridges::cpp_uno::shared::isSimpleType( rParam.pTypeRef ) ) // value
114  {
115  // Simple types must fit exactly one register on x86_64
116  assert( bFitsRegisters && ( ( nUsedSSE == 1 && nUsedGPR == 0 ) || ( nUsedSSE == 0 && nUsedGPR == 1 ) ) ); (void)bFitsRegisters;
117 
118  if ( nUsedSSE == 1 )
119  {
120  if ( nr_fpr < x86_64::MAX_SSE_REGS )
121  {
122  pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
123  nr_fpr++;
124  }
125  else
126  pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
127  }
128  else if ( nUsedGPR == 1 )
129  {
130  if ( nr_gpr < x86_64::MAX_GPR_REGS )
131  {
132  pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
133  nr_gpr++;
134  }
135  else
136  pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
137  }
138  }
139  else // struct <= 16 bytes || ptr to complex value || ref
140  {
141  typelib_TypeDescription * pParamTypeDescr = nullptr;
142  TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
143 
144  void *pCppStack;
145  if ( nr_gpr < x86_64::MAX_GPR_REGS )
146  {
147  pCppArgs[nPos] = pCppStack = *gpreg++;
148  nr_gpr++;
149  }
150  else
151  pCppArgs[nPos] = pCppStack = *ovrflw++;
152 
153  if (! rParam.bIn) // is pure out
154  {
155  // uno out is unconstructed mem!
156  pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
157  pTempIndices[nTempIndices] = nPos;
158  // will be released at reconversion
159  ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
160  }
161  else if ( bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ) ) // is in/inout
162  {
163  pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
164  uno_copyAndConvertData( pUnoArgs[nPos],
165  pCppStack, pParamTypeDescr,
166  pThis->getBridge()->getCpp2Uno() );
167  pTempIndices[nTempIndices] = nPos; // has to be reconverted
168  // will be released at reconversion
169  ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
170  }
171  else // direct way
172  {
173  pUnoArgs[nPos] = pCppStack;
174  // no longer needed
175  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
176  }
177  }
178  }
179 
180  // ExceptionHolder
181  uno_Any aUnoExc; // Any will be constructed by callee
182  uno_Any * pUnoExc = &aUnoExc;
183 
184  // invoke uno dispatch call
185  (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
186 
187  // in case an exception occurred...
188  if ( pUnoExc )
189  {
190  // destruct temporary in/inout params
191  for ( ; nTempIndices--; )
192  {
193  sal_Int32 nIndex = pTempIndices[nTempIndices];
194 
195  if (pParams[nIndex].bIn) // is in/inout => was constructed
196  uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], nullptr );
197  TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
198  }
199  if (pReturnTypeDescr)
200  TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
201 
202  CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
203  // is here for dummy
204  return typelib_TypeClass_VOID;
205  }
206  else // else no exception occurred...
207  {
208  // temporary params
209  for ( ; nTempIndices--; )
210  {
211  sal_Int32 nIndex = pTempIndices[nTempIndices];
212  typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
213 
214  if ( pParams[nIndex].bOut ) // inout/out
215  {
216  // convert and assign
217  uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
218  uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
219  pThis->getBridge()->getUno2Cpp() );
220  }
221  // destroy temp uno param
222  uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, nullptr );
223 
224  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
225  }
226  // return
227  if ( pCppReturn ) // has complex return
228  {
229  if ( pUnoReturn != pCppReturn ) // needs reconversion
230  {
231  uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
232  pThis->getBridge()->getUno2Cpp() );
233  // destroy temp uno return
234  uno_destructData( pUnoReturn, pReturnTypeDescr, nullptr );
235  }
236  // complex return ptr is set to return reg
237  *reinterpret_cast<void **>(pRegisterReturn) = pCppReturn;
238  }
239  if ( pReturnTypeDescr )
240  {
241  typelib_TypeClass eRet = pReturnTypeDescr->eTypeClass;
242  TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
243  return eRet;
244  }
245  else
246  return typelib_TypeClass_VOID;
247  }
248 }
249 
250 
251 typelib_TypeClass cpp_vtable_call(
252  sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
253  void ** gpreg, void ** fpreg, void ** ovrflw,
254  sal_uInt64 * pRegisterReturn /* space for register return */ )
255 {
256  // gpreg: [ret *], this, [other gpr params]
257  // fpreg: [fpr params]
258  // ovrflw: [gpr or fpr params (properly aligned)]
259  void * pThis;
260  if ( nFunctionIndex & 0x80000000 )
261  {
262  nFunctionIndex &= 0x7fffffff;
263  pThis = gpreg[1];
264  }
265  else
266  {
267  pThis = gpreg[0];
268  }
269  pThis = static_cast<char *>( pThis ) - nVtableOffset;
270 
273 
274  typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
275 
276  if ( nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex )
277  {
278  SAL_WARN(
279  "bridges",
280  "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
281  << " vtable index " << nFunctionIndex << "/"
282  << pTypeDescr->nMapFunctionIndexToMemberIndex);
283  throw RuntimeException(
284  ("illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
285  + " vtable index " + OUString::number(nFunctionIndex) + "/"
286  + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
287  reinterpret_cast<XInterface *>( pCppI ) );
288  }
289 
290  // determine called method
291  sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
292  assert(nMemberPos < pTypeDescr->nAllMembers);
293 
294  TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
295 
296  typelib_TypeClass eRet;
297  switch ( aMemberDescr.get()->eTypeClass )
298  {
299  case typelib_TypeClass_INTERFACE_ATTRIBUTE:
300  {
301  typelib_TypeDescriptionReference *pAttrTypeRef =
302  reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( aMemberDescr.get() )->pAttributeTypeRef;
303 
304  if ( pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex )
305  {
306  // is GET method
307  eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
308  0, nullptr, // no params
309  gpreg, fpreg, ovrflw, pRegisterReturn );
310  }
311  else
312  {
313  // is SET method
314  typelib_MethodParameter aParam;
315  aParam.pTypeRef = pAttrTypeRef;
316  aParam.bIn = true;
317  aParam.bOut = false;
318 
319  eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
320  nullptr, // indicates void return
321  1, &aParam,
322  gpreg, fpreg, ovrflw, pRegisterReturn );
323  }
324  break;
325  }
326  case typelib_TypeClass_INTERFACE_METHOD:
327  {
328  // is METHOD
329  switch ( nFunctionIndex )
330  {
331  case 1: // acquire()
332  pCppI->acquireProxy(); // non virtual call!
333  eRet = typelib_TypeClass_VOID;
334  break;
335  case 2: // release()
336  pCppI->releaseProxy(); // non virtual call!
337  eRet = typelib_TypeClass_VOID;
338  break;
339  case 0: // queryInterface() opt
340  {
341  typelib_TypeDescription * pTD = nullptr;
342  TYPELIB_DANGER_GET( &pTD, static_cast<Type *>( gpreg[2] )->getTypeLibType() );
343  if ( pTD )
344  {
345  XInterface * pInterface = nullptr;
346  (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
347  ( pCppI->getBridge()->getCppEnv(),
348  reinterpret_cast<void **>(&pInterface),
349  pCppI->getOid().pData,
350  reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
351 
352  if ( pInterface )
353  {
354  ::uno_any_construct( static_cast<uno_Any *>( gpreg[0] ),
355  &pInterface, pTD, cpp_acquire );
356 
357  pInterface->release();
358  TYPELIB_DANGER_RELEASE( pTD );
359 
360  reinterpret_cast<void **>( pRegisterReturn )[0] = gpreg[0];
361  eRet = typelib_TypeClass_ANY;
362  break;
363  }
364  TYPELIB_DANGER_RELEASE( pTD );
365  }
366  [[fallthrough]]; // else perform queryInterface()
367  }
368  default:
369  {
370  typelib_InterfaceMethodTypeDescription *pMethodTD =
371  reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( aMemberDescr.get() );
372 
373  eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
374  pMethodTD->pReturnTypeRef,
375  pMethodTD->nParams,
376  pMethodTD->pParams,
377  gpreg, fpreg, ovrflw, pRegisterReturn );
378  }
379  }
380  break;
381  }
382  default:
383  {
384  throw RuntimeException("no member description found!",
385  reinterpret_cast<XInterface *>( pCppI ) );
386  }
387  }
388 
389  return eRet;
390 }
391 
392 const int codeSnippetSize = 24;
393 
394 // Generate a trampoline that redirects method calls to
395 // privateSnippetExecutor().
396 //
397 // privateSnippetExecutor() saves all the registers that are used for
398 // parameter passing on x86_64, and calls the cpp_vtable_call().
399 // When it returns, privateSnippetExecutor() sets the return value.
400 //
401 // Note: The code snippet we build here must not create a stack frame,
402 // otherwise the UNO exceptions stop working thanks to non-existing
403 // unwinding info.
404 static unsigned char * codeSnippet( unsigned char * code,
405  sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
406  bool bHasHiddenParam )
407 {
408  sal_uInt64 nOffsetAndIndex = ( static_cast<sal_uInt64>(nVtableOffset) << 32 ) | static_cast<sal_uInt64>(nFunctionIndex);
409 
410  if ( bHasHiddenParam )
411  nOffsetAndIndex |= 0x80000000;
412 
413  // movq $<nOffsetAndIndex>, %r10
414  *reinterpret_cast<sal_uInt16 *>( code ) = 0xba49;
415  *reinterpret_cast<sal_uInt16 *>( code + 2 ) = nOffsetAndIndex & 0xFFFF;
416  *reinterpret_cast<sal_uInt32 *>( code + 4 ) = nOffsetAndIndex >> 16;
417  *reinterpret_cast<sal_uInt16 *>( code + 8 ) = nOffsetAndIndex >> 48;
418 
419  // movq $<address of the privateSnippetExecutor>, %r11
420  *reinterpret_cast<sal_uInt16 *>( code + 10 ) = 0xbb49;
421  *reinterpret_cast<sal_uInt32 *>( code + 12 )
422  = reinterpret_cast<sal_uInt64>(privateSnippetExecutor);
423  *reinterpret_cast<sal_uInt32 *>( code + 16 )
424  = reinterpret_cast<sal_uInt64>(privateSnippetExecutor) >> 32;
425 
426  // jmpq *%r11
427  *reinterpret_cast<sal_uInt32 *>( code + 20 ) = 0x00e3ff49;
428 
429 #if OSL_DEBUG_LEVEL > 1
430  fprintf(stderr,
431  "==> codeSnippet, functionIndex=%d%s, vtableOffset=%d\n",
432  nFunctionIndex, (bHasHiddenParam ? "|0x80000000":""), nVtableOffset);
433 #endif
434 
435  return code + codeSnippetSize;
436 }
437 
439 
442 {
443  return static_cast< Slot * >(block) + 2;
444 }
445 
447  sal_Int32 slotCount)
448 {
449  return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
450 }
451 
454  void * block, sal_Int32 slotCount, sal_Int32 vtableNumber,
455  typelib_InterfaceTypeDescription * type)
456 {
457  Slot * slots = mapBlockToVtable(block);
458  slots[-2].fn = reinterpret_cast<void *>(-(vtableNumber * sizeof (void *)));
459 #if ENABLE_RUNTIME_OPTIMIZATIONS
460  slots[-1].fn = nullptr;
461  (void)type;
462 #else
463  slots[-1].fn = x86_64::getRtti(type->aBase);
464 #endif
465  return slots + slotCount;
466 }
467 
468 
470  Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
471  typelib_InterfaceTypeDescription const * type, sal_Int32 nFunctionOffset,
472  sal_Int32 functionCount, sal_Int32 nVtableOffset )
473 {
474  (*slots) -= functionCount;
475  Slot * s = *slots;
476  for ( sal_Int32 nPos = 0; nPos < type->nMembers; ++nPos )
477  {
478  typelib_TypeDescription * pTD = nullptr;
479 
480  TYPELIB_DANGER_GET( &pTD, type->ppMembers[ nPos ] );
481  assert(pTD);
482 
483  if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE )
484  {
485  typelib_InterfaceAttributeTypeDescription *pAttrTD =
486  reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
487 
488  // get method
489  (s++)->fn = code + writetoexecdiff;
490  code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
491  x86_64::return_in_hidden_param( pAttrTD->pAttributeTypeRef ) );
492 
493  if ( ! pAttrTD->bReadOnly )
494  {
495  // set method
496  (s++)->fn = code + writetoexecdiff;
497  code = codeSnippet( code, nFunctionOffset++, nVtableOffset, false );
498  }
499  }
500  else if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_METHOD )
501  {
502  typelib_InterfaceMethodTypeDescription *pMethodTD =
503  reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD );
504 
505  (s++)->fn = code + writetoexecdiff;
506  code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
507  x86_64::return_in_hidden_param( pMethodTD->pReturnTypeRef ) );
508  }
509  else
510  assert(false);
511 
512  TYPELIB_DANGER_RELEASE( pTD );
513  }
514  return code;
515 }
516 
518  SAL_UNUSED_PARAMETER unsigned char const *,
519  SAL_UNUSED_PARAMETER unsigned char const * )
520 {}
521 
522 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static typelib_TypeClass 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)
const sal_uInt32 MAX_GPR_REGS
void(* privateSnippetExecutor)()
sal_Int32 nIndex
bool examine_argument(typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedSSE)
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef)
Does function that returns this type use a hidden parameter, or registers?
std::type_info * getRtti(typelib_TypeDescription const &type)
Definition: rtti.cxx:277
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
typelib_TypeClass cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void **gpreg, void **fpreg, void **ovrflw, sal_uInt64 *pRegisterReturn)
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
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
static Slot * initializeBlock(void *block, sal_Int32 slotCount, sal_Int32 vtableNumber, typelib_InterfaceTypeDescription *type)
Initialize a raw vtable block.
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
const sal_uInt32 MAX_SSE_REGS
void raiseException(uno_Any *pUnoExc, uno_Mapping *pUno2Cpp)
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)
sal_uInt16 nPos
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo