LibreOffice Module bridges (master)  1
gcc3_linux_mips64/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 #include <com/sun/star/uno/genfunc.hxx>
20 #include <sal/log.hxx>
21 #include <typelib/typedescription.hxx>
22 #include <uno/data.h>
23 #include <osl/endian.h>
24 #include "bridge.hxx"
25 #include "cppinterfaceproxy.hxx"
26 #include "types.hxx"
27 #include "vtablefactory.hxx"
28 #include "call.hxx"
29 #include "share.hxx"
30 
31 #include <stdio.h>
32 #include <string.h>
33 
34 using namespace com::sun::star::uno;
35 
36 //#define BRDEBUG
37 
38 #ifdef BRDEBUG
39 #include <rtl/strbuf.hxx>
40 #include <rtl/ustrbuf.hxx>
41 using namespace ::std;
42 using namespace ::osl;
43 using namespace ::rtl;
44 #endif
45 
46 #ifndef ANDROID
47 #include <sys/sysmips.h>
48 #endif
49 
50 #ifdef ANDROID
51 #include <unistd.h>
52 #endif
53 
54 namespace CPPU_CURRENT_NAMESPACE
55 {
57  {
58  const typelib_CompoundTypeDescription * p
59  = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
60  for (sal_Int32 i = 0; i < p->nMembers; ++i)
61  {
62  if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
63  p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
64  {
66  TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
67  bool b = is_complex_struct(t);
68  TYPELIB_DANGER_RELEASE(t);
69  if (b) {
70  return true;
71  }
72  }
73  else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
74  return true;
75  }
76  if (p->pBaseTypeDescription != 0)
77  return is_complex_struct(&p->pBaseTypeDescription->aBase);
78  return false;
79  }
80 
81  bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
82  {
84  return false;
85  else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT ||
86  pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
87  {
88  typelib_TypeDescription * pTypeDescr = 0;
89  TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
90 
91  //A Composite Type not larger than 16 bytes is returned in up to two GPRs
92  bool bRet = pTypeDescr->nSize > 16 || is_complex_struct(pTypeDescr);
93 
94  TYPELIB_DANGER_RELEASE( pTypeDescr );
95  return bRet;
96  }
97  return true;
98  }
99 }
100 
101 namespace
102 {
103 
104  static typelib_TypeClass cpp2uno_call(
106  const typelib_TypeDescription * pMemberTypeDescr,
107  typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
108  sal_Int32 nParams, typelib_MethodParameter * pParams,
109  void ** gpreg, void ** fpreg, void ** ovrflw,
110  sal_uInt64 * pRegisterReturn /* space for register return */ )
111  {
112  /* Most MIPS ABIs view the arguments as a struct, of which the
113  first N words go in registers and the rest go on the stack. If I < N, the
114  With word might go in With integer argument register or the With
115  floating-point one. For these ABIs, we only need to remember the number
116  of words passed so far. We are interested only in n64 ABI,so it is the
117  case.
118  */
119  unsigned int nREG = 0;
120 
121 #ifdef BRDEBUG
122  fprintf(stderr, "cpp2uno_call:begin\n");
123 #endif
124 
125  // return
126  typelib_TypeDescription * pReturnTypeDescr = 0;
127  if (pReturnTypeRef)
128  TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
129 
130  void * pUnoReturn = 0;
131  void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
132 
133  if (pReturnTypeDescr)
134  {
135  if (CPPU_CURRENT_NAMESPACE::return_in_hidden_param( pReturnTypeRef ) )
136  {
137  pCppReturn = gpreg[nREG]; // complex return via ptr (pCppReturn)
138  nREG++;
139 
140  pUnoReturn = ( bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
141  ? alloca( pReturnTypeDescr->nSize )
142  : pCppReturn); // direct way
143 #ifdef BRDEBUG
144  fprintf(stderr, "cpp2uno_call:complexreturn\n");
145 #endif
146  }
147  else
148  {
149  pUnoReturn = pRegisterReturn; // direct way for simple types
150 #ifdef BRDEBUG
151  fprintf(stderr, "cpp2uno_call:simplereturn\n");
152 #endif
153  }
154  }
155 
156  // pop this
157  nREG++;
158 
159  // stack space
160  static_assert(sizeof(void *) == sizeof(sal_Int64), "### unexpected size!");
161  // parameters
162  void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
163  void ** pCppArgs = pUnoArgs + nParams;
164  // indices of values this have to be converted (interface conversion cpp<=>uno)
165  sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
166  // type descriptions for reconversions
167  typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
168 
169  sal_Int32 nTempIndices = 0;
170 
171 #ifdef BRDEBUG
172  fprintf(stderr, "cpp2uno_call:nParams=%d\n", nParams);
173 #endif
174  for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
175  {
176  const typelib_MethodParameter & rParam = pParams[nPos];
177 
178  typelib_TypeDescription * pParamTypeDescr = 0;
179  TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
180 
181  if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value
182  {
183 #ifdef BRDEBUG
184  fprintf(stderr, "cpp2uno_call:Param %u, type %u\n", nPos, pParamTypeDescr->eTypeClass);
185 #endif
186  switch (pParamTypeDescr->eTypeClass)
187  {
188  case typelib_TypeClass_FLOAT:
189  case typelib_TypeClass_DOUBLE:
190  if (nREG < MAX_FP_REGS) {
191 #ifdef BRDEBUG
192  fprintf(stderr, "cpp2uno_call:fpr=%p\n", fpreg[nREG]);
193 #endif
194  pCppArgs[nPos] = &(fpreg[nREG]);
195  pUnoArgs[nPos] = &(fpreg[nREG]);
196  } else {
197 #ifdef BRDEBUG
198  fprintf(stderr, "cpp2uno_call:fpr=%p\n", ovrflw[nREG - MAX_FP_REGS]);
199 #endif
200  pCppArgs[nPos] = &(ovrflw[nREG - MAX_FP_REGS]);
201  pUnoArgs[nPos] = &(ovrflw[nREG - MAX_FP_REGS]);
202  }
203  nREG++;
204  break;
205 
206 
207  default:
208  if (nREG < MAX_GP_REGS) {
209 #ifdef BRDEBUG
210  fprintf(stderr, "cpp2uno_call:gpr=%p\n", gpreg[nREG]);
211 #endif
212  pCppArgs[nPos] = &(gpreg[nREG]);
213  pUnoArgs[nPos] = &(gpreg[nREG]);
214  } else {
215 #ifdef BRDEBUG
216  fprintf(stderr, "cpp2uno_call:gpr=%p\n", ovrflw[nREG - MAX_GP_REGS]);
217 #endif
218  pCppArgs[nPos] = &(ovrflw[nREG - MAX_GP_REGS]);
219  pUnoArgs[nPos] = &(ovrflw[nREG - MAX_GP_REGS]);
220  }
221  nREG++;
222  break;
223 
224  }
225  // no longer needed
226  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
227  }
228  else // ptr to complex value | ref
229  {
230 #ifdef BRDEBUG
231  fprintf(stderr,"cpp2uno_call:ptr|ref\n");
232 #endif
233  void *pCppStack;
234  if (nREG < MAX_GP_REGS) {
235  pCppArgs[nPos] = pCppStack = gpreg[nREG];
236  } else {
237  pCppArgs[nPos] = pCppStack = ovrflw[nREG - MAX_GP_REGS];
238  }
239  nREG++;
240 #ifdef BRDEBUG
241  fprintf(stderr, "cpp2uno_call:pCppStack=%p\n", pCppStack);
242 #endif
243 
244  if (! rParam.bIn) // is pure out
245  {
246  // uno out is unconstructed mem!
247  pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
248  pTempIndices[nTempIndices] = nPos;
249  // will be released at reconversion
250  ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
251  }
252  // is in/inout
253  else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
254  {
255  uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
256  pCppStack, pParamTypeDescr,
257  pThis->getBridge()->getCpp2Uno() );
258  pTempIndices[nTempIndices] = nPos; // has to be reconverted
259  // will be released at reconversion
260  ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
261 #ifdef BRDEBUG
262  fprintf(stderr, "cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",
263  pCppStack, pParamTypeDescr->nSize, nPos, pUnoArgs[nPos]);
264 #endif
265  }
266  else // direct way
267  {
268  pUnoArgs[nPos] = pCppStack;
269 #ifdef BRDEBUG
270  fprintf(stderr, "cpp2uno_call:direct,pUnoArgs[%d]=%p\n", nPos, pUnoArgs[nPos]);
271 #endif
272  // no longer needed
273  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
274  }
275  }
276  }
277 #ifdef BRDEBUG
278  fprintf(stderr, "cpp2uno_call2,%p,unoargs=%p\n", pThis->getUnoI()->pDispatcher, pUnoArgs);
279 #endif
280 
281  // ExceptionHolder
282  uno_Any aUnoExc; // Any will be constructed by callee
283  uno_Any * pUnoExc = &aUnoExc;
284 
285  // invoke uno dispatch call
286  (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
287 #ifdef BRDEBUG
288  fprintf(stderr, "cpp2uno_call2,after dispatch\n");
289 #endif
290 
291  // in case an exception occurred...
292  if (pUnoExc)
293  {
294  // destruct temporary in/inout params
295  for ( ; nTempIndices--; )
296  {
297  sal_Int32 nIndex = pTempIndices[nTempIndices];
298 
299  if (pParams[nIndex].bIn) // is in/inout => was constructed
300  uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
301  TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
302  }
303  if (pReturnTypeDescr)
304  TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
305 
307  // has to destruct the any
308  // is here for dummy
309  return typelib_TypeClass_VOID;
310  }
311  else // else no exception occurred...
312  {
313  // temporary params
314  for ( ; nTempIndices--; )
315  {
316  sal_Int32 nIndex = pTempIndices[nTempIndices];
317  typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
318 
319  if (pParams[nIndex].bOut) // inout/out
320  {
321  // convert and assign
322  uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
323  uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
324  pThis->getBridge()->getUno2Cpp() );
325  }
326  // destroy temp uno param
327  uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
328 
329  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
330  }
331  // return
332  if (pCppReturn) // has complex return
333  {
334  if (pUnoReturn != pCppReturn) // needs reconversion
335  {
336  uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
337  pThis->getBridge()->getUno2Cpp() );
338  // destroy temp uno return
339  uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
340  }
341  // complex return ptr is set to return reg
342  *(void **)pRegisterReturn = pCppReturn;
343  }
344  if (pReturnTypeDescr)
345  {
346  typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
347  TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
348  return eRet;
349  }
350  else
351  return typelib_TypeClass_VOID;
352  }
353  }
354 
355 
360  typelib_TypeClass cpp_vtable_call(
361  sal_Int32 nFunctionIndex,
362  sal_Int32 nVtableOffset,
363  void ** gpreg, void ** fpreg, void ** ovrflw,
364  sal_uInt64 * pRegisterReturn /* space for register return */ )
365  {
366  static_assert( sizeof(sal_Int64)==sizeof(void *), "### unexpected!" );
367 
368 #ifdef BRDEBUG
369  fprintf(stderr, "in cpp_vtable_call nFunctionIndex is %d\n", nFunctionIndex);
370  fprintf(stderr, "in cpp_vtable_call nVtableOffset is %d\n", nVtableOffset);
371  fprintf(stderr, "in cpp_vtable_call gp=%p, fp=%p, ov=%p\n", gpreg, fpreg, ovrflw);
372 #endif
373 
374  // gpreg: [ret *], this, [other gpr params]
375  // fpreg: [fpr params]
376  // ovrflw: [gpr or fpr params (properly aligned)]
377  void * pThis;
378  if (nFunctionIndex & 0x80000000 )
379  {
380  nFunctionIndex &= 0x7fffffff;
381  pThis = gpreg[1];
382  }
383  else
384  {
385  pThis = gpreg[0];
386  }
387 #ifdef BRDEBUG
388  fprintf(stderr, "cpp_vtable_call, pThis=%p, nFunctionIndex=%d, nVtableOffset=%d\n",
389  pThis, nFunctionIndex, nVtableOffset);
390 #endif
391 
392  pThis = static_cast< char * >(pThis) - nVtableOffset;
395 #ifdef BRDEBUG
396  fprintf(stderr, "cpp_vtable_call, pCppI=%p\n", pCppI);
397 #endif
398 
399  typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
400 
401  if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
402  {
403  SAL_WARN(
404  "bridges",
405  "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
406  << " vtable index " << nFunctionIndex << "/"
407  << pTypeDescr->nMapFunctionIndexToMemberIndex);
408  throw RuntimeException(
409  ("illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
410  + " vtable index " + OUString::number(nFunctionIndex) + "/"
411  + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
412  (XInterface *)pThis);
413  }
414 
415  // determine called method
416  sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
417  assert(nMemberPos < pTypeDescr->nAllMembers);
418 
419  TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
420 
421 #ifdef BRDEBUG
422  OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
423  fprintf(stderr, "calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
424 #endif
425  typelib_TypeClass eRet;
426  switch (aMemberDescr.get()->eTypeClass)
427  {
428  case typelib_TypeClass_INTERFACE_ATTRIBUTE:
429  {
430 #ifdef BRDEBUG
431  fprintf(stderr, "cpp_vtable_call interface attribute\n");
432 #endif
433  typelib_TypeDescriptionReference *pAttrTypeRef =
434  reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( aMemberDescr.get() )->pAttributeTypeRef;
435 
436  if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
437  {
438  // is GET method
439  eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
440  0, 0, // no params
441  gpreg, fpreg, ovrflw, pRegisterReturn );
442  }
443  else
444  {
445  // is SET method
446  typelib_MethodParameter aParam;
447  aParam.pTypeRef = pAttrTypeRef;
448  aParam.bIn = sal_True;
449  aParam.bOut = sal_False;
450 
451  eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
452  0, // indicates void return
453  1, &aParam,
454  gpreg, fpreg, ovrflw, pRegisterReturn );
455  }
456  break;
457  }
458  case typelib_TypeClass_INTERFACE_METHOD:
459  {
460 #ifdef BRDEBUG
461  fprintf(stderr, "cpp_vtable_call interface method\n");
462 #endif
463  // is METHOD
464  switch (nFunctionIndex)
465  {
466  case 1: // acquire()
467 #ifdef BRDEBUG
468  fprintf(stderr, "cpp_vtable_call method acquire\n");
469 #endif
470  pCppI->acquireProxy(); // non virtual call!
471  eRet = typelib_TypeClass_VOID;
472  break;
473  case 2: // release()
474 #ifdef BRDEBUG
475  fprintf(stderr, "cpp_vtable_call method release\n");
476 #endif
477  pCppI->releaseProxy(); // non virtual call!
478  eRet = typelib_TypeClass_VOID;
479  break;
480  case 0: // queryInterface() opt
481  {
482 #ifdef BRDEBUG
483  fprintf(stderr, "cpp_vtable_call method query interface opt\n");
484 #endif
485  typelib_TypeDescription * pTD = 0;
486  TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
487  if (pTD)
488  {
489  XInterface * pInterface = 0;
490  (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
491  ( pCppI->getBridge()->getCppEnv(),
492  (void **)&pInterface,
493  pCppI->getOid().pData,
494  reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
495 
496  if (pInterface)
497  {
498  ::uno_any_construct( reinterpret_cast< uno_Any * >( gpreg[0] ),
499  &pInterface, pTD, cpp_acquire );
500 
501  pInterface->release();
502  TYPELIB_DANGER_RELEASE( pTD );
503 
504  reinterpret_cast<void **>( pRegisterReturn )[0] = gpreg[0];
505  eRet = typelib_TypeClass_ANY;
506  break;
507  }
508  TYPELIB_DANGER_RELEASE( pTD );
509  }
510  } // else perform queryInterface()
511  default:
512 #ifdef BRDEBUG
513  fprintf(stderr, "cpp_vtable_call method query interface\n");
514 #endif
515  typelib_InterfaceMethodTypeDescription *pMethodTD =
516  reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( aMemberDescr.get() );
517 
518  eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
519  pMethodTD->pReturnTypeRef,
520  pMethodTD->nParams,
521  pMethodTD->pParams,
522  gpreg, fpreg, ovrflw, pRegisterReturn );
523  }
524  break;
525  }
526  default:
527  {
528 #ifdef BRDEBUG
529  fprintf(stderr, "cpp_vtable_call no member\n");
530 #endif
531  throw RuntimeException( "no member description found!", (XInterface *)pThis );
532  }
533  }
534 
535  return eRet;
536  }
537 
538  extern "C" void privateSnippetExecutor( ... );
539 
540  int const codeSnippetSize = 0x44;
541 
542  unsigned char * codeSnippet( unsigned char * code,
543  sal_Int32 functionIndex, sal_Int32 vtableOffset,
544  bool bHasHiddenParam )
545  {
546 #ifdef BRDEBUG
547  fprintf(stderr,"in codeSnippet functionIndex is %d\n", functionIndex);
548  fprintf(stderr,"in codeSnippet vtableOffset is %d\n", vtableOffset);
549  fflush(stderr);
550 #endif
551 
552  if ( bHasHiddenParam )
553  functionIndex |= 0x80000000;
554 
555  unsigned int * p = (unsigned int *) code;
556 
557  assert((((unsigned long)code) & 0x3) == 0 ); //aligned to 4 otherwise a mistake
558 
559  /* generate this code */
560  /*
561  # index
562  0: 3c020000 lui v0,0x0
563  4: 34420000 ori v0,v0,0x0
564  # privateSnippetExecutor
565  8: 3c0c0000 lui t0,0x0
566  c: 358c0000 ori t0,t0,0x0
567  10: 000c6438 dsll t0,t0,0x10
568  14: 358c0000 ori t0,t0,0x0
569  18: 000c6438 dsll t0,t0,0x10
570  1c: 358c0000 ori t0,t0,0x0
571  # cpp_vtable_call
572  20: 3c190000 lui t9,0x0
573  24: 37390000 ori t9,t9,0x0
574  28: 0019cc38 dsll t9,t9,0x10
575  2c: 37390000 ori t9,t9,0x0
576  30: 0019cc38 dsll t9,t9,0x10
577  34: 37390000 ori t9,t9,0x0
578  # offset
579  38: 3c030000 lui v1,0x0
580  3c: 01800008 jr t0
581  40: 34630000 ori v1,v1,0x0
582  */
583 
584  * p++ = 0x3c020000 | ((functionIndex>>16) & 0x0000ffff);
585  * p++ = 0x34420000 | (functionIndex & 0x0000ffff);
586  * p++ = 0x3c0c0000 | ((((unsigned long)privateSnippetExecutor) >> 48) & 0x0000ffff);
587  * p++ = 0x358c0000 | ((((unsigned long)privateSnippetExecutor) >> 32) & 0x0000ffff);
588  * p++ = 0x000c6438;
589  * p++ = 0x358c0000 | ((((unsigned long)privateSnippetExecutor) >> 16) & 0x0000ffff);
590  * p++ = 0x000c6438;
591  * p++ = 0x358c0000 | (((unsigned long)privateSnippetExecutor) & 0x0000ffff);
592  * p++ = 0x3c190000 | ((((unsigned long)cpp_vtable_call) >> 48) & 0x0000ffff);
593  * p++ = 0x37390000 | ((((unsigned long)cpp_vtable_call) >> 32) & 0x0000ffff);
594  * p++ = 0x0019cc38;
595  * p++ = 0x37390000 | ((((unsigned long)cpp_vtable_call) >> 16) & 0x0000ffff);
596  * p++ = 0x0019cc38;
597  * p++ = 0x37390000 | (((unsigned long)cpp_vtable_call) & 0x0000ffff);
598  * p++ = 0x3c030000 | ((vtableOffset>>16) & 0x0000ffff);
599  * p++ = 0x01800008;
600  * p++ = 0x34630000 | (vtableOffset & 0x0000ffff);
601  return (code + codeSnippetSize);
602 
603  }
604 
605 }
606 
607 
608 void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *bptr, unsigned char const *eptr)
609 {
610 #ifndef ANDROID
611  (void) bptr;
612  (void) eptr;
613  sysmips(FLUSH_CACHE, 0, 0, 0);
614 #else
615  cacheflush((long) bptr, (long) eptr, 0);
616 #endif
617 }
618 
620 
623 {
624  return static_cast< Slot * >(block) + 2;
625 }
626 
627 
629  sal_Int32 slotCount)
630 {
631  return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
632 }
633 
636  void * block, sal_Int32 slotCount, sal_Int32,
637  typelib_InterfaceTypeDescription *)
638 {
639  Slot * slots = mapBlockToVtable(block);
640  slots[-2].fn = 0; //null
641  slots[-1].fn = 0; //destructor
642  return slots + slotCount;
643 }
644 
646  Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
647  typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
648  sal_Int32 functionCount, sal_Int32 vtableOffset)
649 {
650  (*slots) -= functionCount;
651  Slot * s = *slots;
652 
653 #ifdef BRDEBUG
654  fprintf(stderr, "in addLocalFunctions functionOffset is %d\n", functionOffset);
655  fprintf(stderr, "in addLocalFunctions vtableOffset is %d\n", vtableOffset);
656  fprintf(stderr, "nMembers=%d\n", type->nMembers);
657  fflush(stderr);
658 #endif
659 
660  for (sal_Int32 i = 0; i < type->nMembers; ++i) {
661  typelib_TypeDescription * member = 0;
662  TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
663  assert(member != 0);
664  switch (member->eTypeClass) {
665  case typelib_TypeClass_INTERFACE_ATTRIBUTE:
666  // Getter:
667  (s++)->fn = code + writetoexecdiff;
668  code = codeSnippet(
669  code, functionOffset++, vtableOffset,
671  reinterpret_cast<
672  typelib_InterfaceAttributeTypeDescription * >(
673  member)->pAttributeTypeRef));
674 
675  // Setter:
676  if (!reinterpret_cast<
677  typelib_InterfaceAttributeTypeDescription * >(
678  member)->bReadOnly)
679  {
680  (s++)->fn = code + writetoexecdiff;
681  code = codeSnippet(code, functionOffset++, vtableOffset, false);
682  }
683  break;
684 
685  case typelib_TypeClass_INTERFACE_METHOD:
686  (s++)->fn = code + writetoexecdiff;
687  code = codeSnippet(
688  code, functionOffset++, vtableOffset,
690  reinterpret_cast<
691  typelib_InterfaceMethodTypeDescription * >(
692  member)->pReturnTypeRef));
693  break;
694 
695  default:
696  assert(false);
697  break;
698  }
699  TYPELIB_DANGER_RELEASE(member);
700  }
701  return code;
702 }
703 
704 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void(* privateSnippetExecutor)()
sal_Int32 nIndex
void SAL_CALL uno_destructData(void *pValue, typelib_TypeDescription *pTypeDescr, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
#define MAX_FP_REGS
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
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef)
Does function that returns this type use a hidden parameter, or registers?
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.
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
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.
int i
#define sal_True
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
XPropertyListType t
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)
bool is_complex_struct(const typelib_TypeDescription *type)
static unsigned char * codeSnippet(unsigned char *code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, bool bHasHiddenParam)
void cpp_vtable_call(sal_Int32 func, sal_Int32 offset, void **pStack)
is called on incoming vtable calls (called by asm snippets)
#define sal_False
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.
void * p
#define SAL_WARN(area, stream)
static CppInterfaceProxy * castInterfaceToProxy(void *pInterface)
#define MAX_GP_REGS
sal_uInt16 nPos
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo