LibreOffice Module bridges (master)  1
gcc3_linux_sparc64/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 #include <com/sun/star/uno/genfunc.hxx>
21 #include <sal/log.hxx>
22 #include <typelib/typedescription.hxx>
23 #include <uno/data.h>
24 #include "bridge.hxx"
25 #include "cppinterfaceproxy.hxx"
26 #include "types.hxx"
27 #include "vtablefactory.hxx"
28 #include "share.hxx"
29 
30 #define GET_FP(n, p) \
31  __asm__( "ldx %0, %%l0\n\t" \
32  "std %%f" #n ", [%%l0]\n" \
33  : : "m"(p) );
34 
35 using namespace com::sun::star::uno;
36 
37 namespace CPPU_CURRENT_NAMESPACE
38 {
40  {
41  for (const typelib_CompoundTypeDescription * p
42  = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
43  p != NULL; p = p->pBaseTypeDescription)
44  {
45  for (sal_Int32 i = 0; i < p->nMembers; ++i)
46  {
47  if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
48  p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
49  {
51  TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
52  bool b = is_complex_struct(t);
53  TYPELIB_DANGER_RELEASE(t);
54  if (b) {
55  return true;
56  }
57  }
58  else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
59  return true;
60  }
61  }
62  return false;
63  }
64 
65  bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
66  {
68  return false;
69  else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT ||
70  pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
71  {
72  typelib_TypeDescription * pTypeDescr = 0;
73  TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
74 
75  //A Composite Type not larger than 32 bytes is returned in up to two GPRs
76  bool bRet = pTypeDescr->nSize > 32 || is_complex_struct(pTypeDescr);
77 
78  TYPELIB_DANGER_RELEASE( pTypeDescr );
79  return bRet;
80  }
81  return true;
82  }
83 }
84 
85 
86 namespace
87 {
88 
89 static typelib_TypeClass cpp2uno_call(
91  const typelib_TypeDescription * pMemberTypeDescr,
92  typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
93  sal_Int32 nParams, typelib_MethodParameter * pParams,
94  void ** pCallStack,
95  sal_Int64 * pRegisterReturn /* space for register return */ )
96 {
97  // pCallStack: [ret ptr], this, params
98  char * pCppStack = (char *)pCallStack;
99 
100  // return
101  typelib_TypeDescription * pReturnTypeDescr = 0;
102  if (pReturnTypeRef)
103  TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
104 
105  void * pUnoReturn = 0;
106  void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
107 
108  int paramsOffset;
109  if (pReturnTypeDescr)
110  {
111  if (CPPU_CURRENT_NAMESPACE::return_in_hidden_param( pReturnTypeRef ) )
112  {
113  pCppReturn = *(void**)pCppStack; // complex return via ptr (pCppReturn)
115  pReturnTypeDescr )
116  ? alloca( pReturnTypeDescr->nSize )
117  : pCppReturn); // direct way
118  pCppStack += sizeof( void* );
119  paramsOffset = 2;
120  }
121  else
122  {
123  pUnoReturn = pRegisterReturn; // direct way for simple types
124  paramsOffset = 1;
125  }
126  }
127  else
128  {
129  paramsOffset = 1;
130  }
131  // pop this
132  pCppStack += sizeof( void* );
133 
134  // stack space
135  static_assert(sizeof(void *) == sizeof(sal_Int64), "### unexpected size!");
136  // parameters
137  void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
138  void ** pCppArgs = pUnoArgs + nParams;
139  // indices of values this have to be converted (interface conversion cpp<=>uno)
140  sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
141  // type descriptions for reconversions
142  typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
143 
144  sal_Int32 nTempIndices = 0;
145 
146  for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
147  {
148  const typelib_MethodParameter & rParam = pParams[nPos];
149  typelib_TypeDescription * pParamTypeDescr = 0;
150  TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
151 
152  if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value
153  {
154  pCppArgs[nPos] = pUnoArgs[nPos] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack, pParamTypeDescr);
155  switch (pParamTypeDescr->eTypeClass) {
156  case typelib_TypeClass_FLOAT:
157  case typelib_TypeClass_DOUBLE:
158  {
159  int paramArrayIdx = nPos + paramsOffset;
160  assert(paramArrayIdx < nParams + paramsOffset);
161  switch (paramArrayIdx) {
162  // Cannot be 0 - paramsOffset >= 1
163  case 1:
164  GET_FP(2, pCppStack);
165  break;
166  case 2:
167  GET_FP(4, pCppStack);
168  break;
169  case 3:
170  GET_FP(6, pCppStack);
171  break;
172  case 4:
173  GET_FP(8, pCppStack);
174  break;
175  case 5:
176  GET_FP(10, pCppStack);
177  break;
178  case 6:
179  GET_FP(12, pCppStack);
180  break;
181  case 7:
182  GET_FP(14, pCppStack);
183  break;
184  case 8:
185  GET_FP(16, pCppStack);
186  break;
187  case 9:
188  GET_FP(18, pCppStack);
189  break;
190  case 10:
191  GET_FP(20, pCppStack);
192  break;
193  case 11:
194  GET_FP(22, pCppStack);
195  break;
196  case 12:
197  GET_FP(24, pCppStack);
198  break;
199  case 13:
200  GET_FP(26, pCppStack);
201  break;
202  case 14:
203  GET_FP(28, pCppStack);
204  break;
205  case 15:
206  GET_FP(30, pCppStack);
207  break;
208  // Anything larger is passed on the stack
209  }
210  break;
211  }
212  default:
213  break;
214  }
215  // no longer needed
216  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
217  }
218  else // ptr to complex value | ref
219  {
220  pCppArgs[nPos] = *(void **)pCppStack;
221 
222  if (! rParam.bIn) // is pure out
223  {
224  // uno out is unconstructed mem!
225  pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
226  pTempIndices[nTempIndices] = nPos;
227  // will be released at reconversion
228  ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
229  }
230  // is in/inout
232  pParamTypeDescr ))
233  {
234  uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
235  *(void **)pCppStack, pParamTypeDescr,
236  pThis->getBridge()->getCpp2Uno() );
237  pTempIndices[nTempIndices] = nPos; // has to be reconverted
238  // will be released at reconversion
239  ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
240  }
241  else // direct way
242  {
243  pUnoArgs[nPos] = *(void **)pCppStack;
244  // no longer needed
245  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
246  }
247  }
248  pCppStack += sizeof(sal_Int64); // standard parameter length
249  }
250 
251  // ExceptionHolder
252  uno_Any aUnoExc; // Any will be constructed by callee
253  uno_Any * pUnoExc = &aUnoExc;
254 
255  // invoke uno dispatch call
256  (*pThis->getUnoI()->pDispatcher)(pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
257 
258  // in case an exception occurred...
259  if (pUnoExc)
260  {
261  // destruct temporary in/inout params
262  for ( ; nTempIndices--; )
263  {
264  sal_Int32 nIndex = pTempIndices[nTempIndices];
265 
266  if (pParams[nIndex].bIn) // is in/inout => was constructed
267  uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
268  TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
269  }
270  if (pReturnTypeDescr)
271  TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
273  // has to destruct the any
274  // is here for dummy
275  return typelib_TypeClass_VOID;
276  }
277  else // else no exception occurred...
278  {
279  // temporary params
280  for ( ; nTempIndices--; )
281  {
282  sal_Int32 nIndex = pTempIndices[nTempIndices];
283  typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
284 
285  if (pParams[nIndex].bOut) // inout/out
286  {
287  // convert and assign
288  uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
289  uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
290  pThis->getBridge()->getUno2Cpp() );
291  }
292  // destroy temp uno param
293  uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
294 
295  TYPELIB_DANGER_RELEASE( pParamTypeDescr );
296  }
297  // return
298  if (pCppReturn) // has complex return
299  {
300  if (pUnoReturn != pCppReturn) // needs reconversion
301  {
302  uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
303  pThis->getBridge()->getUno2Cpp() );
304  // destroy temp uno return
305  uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
306  }
307  // complex return ptr is set to eax
308  *(void **)pRegisterReturn = pCppReturn;
309  }
310  if (pReturnTypeDescr)
311  {
312  typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
313  TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
314  return eRet;
315  }
316  else
317  return typelib_TypeClass_VOID;
318  }
319 }
320 
321 
322 static typelib_TypeClass cpp_mediate(
323  sal_Int32 nFunctionIndex,
324  sal_Int32 nVtableOffset,
325  void ** pCallStack,
326  sal_Int64 * pRegisterReturn /* space for register return */ )
327 {
328  static_assert(sizeof(sal_Int64)==sizeof(void *), "### unexpected!");
329 
330  // pCallStack: [ret*], this, params
331  void * pThis;
332  if (nFunctionIndex & 0x80000000)
333  {
334  nFunctionIndex &= 0x7fffffff;
335  pThis = pCallStack[1];
336  }
337  else
338  {
339  pThis = pCallStack[0];
340  }
341 
342  pThis = static_cast< char * >(pThis) - nVtableOffset;
345 
346  typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
347 
348  if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
349  {
350  SAL_WARN(
351  "bridges",
352  "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
353  << " vtable index " << nFunctionIndex << "/"
354  << pTypeDescr->nMapFunctionIndexToMemberIndex);
355  throw RuntimeException(
356  ("illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
357  + " vtable index " + OUString::number(nFunctionIndex) + "/"
358  + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
359  (XInterface *)pCppI);
360  }
361 
362  // determine called method
363  sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
364  assert(nMemberPos < pTypeDescr->nAllMembers);
365 
366  TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
367 
368 #if defined BRIDGES_DEBUG
369  OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
370  fprintf( stderr, "calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
371 #endif
372 
373  typelib_TypeClass eRet;
374  switch (aMemberDescr.get()->eTypeClass)
375  {
376  case typelib_TypeClass_INTERFACE_ATTRIBUTE:
377  {
378  if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
379  {
380  // is GET method
381  eRet = cpp2uno_call(
382  pCppI, aMemberDescr.get(),
383  ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
384  0, 0, // no params
385  pCallStack, pRegisterReturn );
386  }
387  else
388  {
389  // is SET method
390  typelib_MethodParameter aParam;
391  aParam.pTypeRef =
392  ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
393  aParam.bIn = sal_True;
394  aParam.bOut = sal_False;
395 
396  eRet = cpp2uno_call(
397  pCppI, aMemberDescr.get(),
398  0, // indicates void return
399  1, &aParam,
400  pCallStack, pRegisterReturn );
401  }
402  break;
403  }
404  case typelib_TypeClass_INTERFACE_METHOD:
405  {
406  // is METHOD
407  switch (nFunctionIndex)
408  {
409  case 1: // acquire()
410  pCppI->acquireProxy(); // non virtual call!
411  eRet = typelib_TypeClass_VOID;
412  break;
413  case 2: // release()
414  pCppI->releaseProxy(); // non virtual call!
415  eRet = typelib_TypeClass_VOID;
416  break;
417  case 0: // queryInterface() opt
418  {
419  typelib_TypeDescription * pTD = 0;
420  TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[2] )->getTypeLibType() );
421  if (pTD)
422  {
423  XInterface * pInterface = 0;
424  (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
425  pCppI->getBridge()->getCppEnv(),
426  (void **)&pInterface, pCppI->getOid().pData, (typelib_InterfaceTypeDescription *)pTD );
427 
428  if (pInterface)
429  {
430  ::uno_any_construct(
431  reinterpret_cast< uno_Any * >( pCallStack[0] ),
432  &pInterface, pTD, cpp_acquire );
433  pInterface->release();
434  TYPELIB_DANGER_RELEASE( pTD );
435  *(void **)pRegisterReturn = pCallStack[0];
436  eRet = typelib_TypeClass_ANY;
437  break;
438  }
439  TYPELIB_DANGER_RELEASE( pTD );
440  }
441  } // else perform queryInterface()
442  default:
443  eRet = cpp2uno_call(
444  pCppI, aMemberDescr.get(),
445  ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
446  ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
447  ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
448  pCallStack, pRegisterReturn );
449  }
450  break;
451  }
452  default:
453  {
454  throw RuntimeException( "no member description found!", (XInterface *)pCppI );
455  }
456  }
457  return eRet;
458 }
459 
460 
461 
466 static void cpp_vtable_call(int nFunctionIndex, void** pCallStack, int vTableOffset)
467 {
468  sal_Int64 nRegReturn[4] = { 0 };
469  void * pRegReturn = &nRegReturn[0];
470 
471  //__asm__( "st %%i0, %0\n\t"
472  // "stx %%i1, %1\n\t"
473  // "st %%i2, %2\n\t"
474  // : : "m"(nFunctionIndex), "m"(pCallStack), "m"(vTableOffset) );
475 
476 // fprintf(stderr,"cpp_mediate nFunctionIndex=%x\n",nFunctionIndex);
477 // fflush(stderr);
478 
479  //const sal_Bool bComplex = (nFunctionIndex & 0x80000000) ? sal_True : sal_False;
480  typelib_TypeClass aType =
481  cpp_mediate( nFunctionIndex, vTableOffset, pCallStack+16, (sal_Int64*)&nRegReturn );
482 
483  switch( aType )
484  {
485  case typelib_TypeClass_BOOLEAN:
486  case typelib_TypeClass_BYTE:
487  __asm__( "ldx %0, %%l0\n\t"
488  "ldsb [%%l0], %%i0\n"
489  : : "m"(pRegReturn) );
490  break;
491  case typelib_TypeClass_CHAR:
492  case typelib_TypeClass_SHORT:
493  case typelib_TypeClass_UNSIGNED_SHORT:
494  __asm__( "ldx %0, %%l0\n\t"
495  "ldsh [%%l0], %%i0\n"
496  : : "m"(pRegReturn) );
497  break;
498  case typelib_TypeClass_ENUM:
499  case typelib_TypeClass_LONG:
500  case typelib_TypeClass_UNSIGNED_LONG:
501  __asm__( "ldx %0, %%l0\n\t"
502  "ld [%%l0], %%i0\n"
503  : : "m"(pRegReturn) );
504  break;
505  case typelib_TypeClass_HYPER:
506  case typelib_TypeClass_UNSIGNED_HYPER:
507  __asm__( "ldx %0, %%l0\n\t"
508  "ldx [%%l0], %%i0\n\t"
509  : : "m"(pRegReturn) );
510  break;
511  case typelib_TypeClass_FLOAT:
512  __asm__( "ldx %0, %%l0\n\t"
513  "ld [%%l0], %%f0\n"
514  : : "m"(pRegReturn) );
515  break;
516  case typelib_TypeClass_DOUBLE:
517  __asm__( "ldx %0, %%l0\n\t"
518  "ldd [%%l0], %%f0\n"
519  : : "m"(pRegReturn) );
520  break;
521  case typelib_TypeClass_VOID:
522  break;
523  case typelib_TypeClass_STRUCT:
524  case typelib_TypeClass_EXCEPTION:
525  __asm__( "ldx %0, %%l0\n\t"
526  "ldx [%%l0 ], %%i0\n\t"
527  "ldx [%%l0+ 8], %%i1\n\t"
528  "ldx [%%l0+16], %%i2\n\t"
529  "ldx [%%l0+24], %%i3\n\t"
530  "ldd [%%l0 ], %%f0\n\t"
531  "ldd [%%l0+ 8], %%f2\n\t"
532  "ldd [%%l0+16], %%f4\n\t"
533  "ldd [%%l0+24], %%f6\n\t"
534  : : "m"(pRegReturn) );
535  break;
536  default:
537  break;
538  }
539 
540  //if( bComplex )
541  //{
542  // __asm__( "add %i7, 4, %i7\n\t" );
543  // // after call to complex return valued function there is an unimp instruction
544  //}
545 
546 }
547 
548 extern "C" void privateSnippetExecutor(...);
549 
550 int const codeSnippetSize = 120;
551 unsigned char * codeSnippet(
552  unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
553  bool bHasHiddenParam, sal_Int32 nParams)
554 {
555  sal_uInt32 index = functionIndex;
556  if (bHasHiddenParam) {
557  index |= 0x80000000;
558  }
559  unsigned int * p = reinterpret_cast< unsigned int * >(code);
560  static_assert(sizeof (unsigned int) == 4, "boo");
561  static_assert(sizeof (unsigned long long) == 8, "boo");
562  ++nParams; // implicit this ptr
563  if (bHasHiddenParam) {
564  ++nParams;
565  }
566  long long frameSize;
567  if (nParams > 6) {
568  frameSize = 128 + nParams * 8;
569  } else {
570  frameSize = 176;
571  }
572  assert(frameSize <= 4096);
573  frameSize = -frameSize;
574  switch (nParams) {
575  default:
576  assert(nParams >= 6);
577  // stx %o5, [%sp+168+2047]:
578  *p++ = 0xDA73A8A7;
579  case 5:
580  // stx %o4, [%sp+160+2047]:
581  *p++ = 0xD873A89F;
582  case 4:
583  // stx %o3, [%sp+152+2047]:
584  *p++ = 0xD673A897;
585  case 3:
586  // stx %o2, [%sp+144+2047]:
587  *p++ = 0xD473A88F;
588  case 2:
589  // stx %o1, [%sp+136+2047]:
590  *p++ = 0xD273A887;
591  case 1:
592  // stx %o0, [%sp+128+2047]:
593  *p++ = 0xD073A87F;
594  case 0:
595  break;
596  }
597  // sethi %hi(index), %o0:
598  *p++ = 0x11000000 | (index >> 10);
599  // or %o0, %lo(index), %o0:
600  *p++ = 0x90122000 | (index & 0x3FF);
601  // sethi %hh(cpp_vtable_call), %o3:
602  *p++ = 0x17000000 | (reinterpret_cast< unsigned long long >(cpp_vtable_call) >> 42);
603  // or %o3, %hm(cpp_vtable_call), %o3:
604  *p++ = 0x9612E000 | ((reinterpret_cast< unsigned long long >(cpp_vtable_call) >> 32) & 0x3FF);
605  // sllx %o3, 32, %o3
606  *p++ = 0x972AF020;
607  // sethi %lm(cpp_vtable_call), %o2:
608  *p++ = 0x15000000 | ((reinterpret_cast< unsigned long long >(cpp_vtable_call) >> 10) & 0x3FFFFF);
609  // or %o2, %lo(cpp_vtable_call), %o2:
610  *p++ = 0x9412A000 | (reinterpret_cast< unsigned long long >(cpp_vtable_call) & 0x3FF);
611  // or %o2, %o3, %o3:
612  *p++ = 0x9612800B;
613  // sethi %hh(privateSnippetExecutor), %o1:
614  *p++ = 0x13000000 | (reinterpret_cast< unsigned long long >(privateSnippetExecutor) >> 42);
615  // or %o1, %hm(privateSnippetExecutor), %o1:
616  *p++ = 0x92126000 | ((reinterpret_cast< unsigned long long >(privateSnippetExecutor) >> 32) & 0x3FF);
617  // sllx %o1, 32, %o1:
618  *p++ = 0x932a7020;
619  // sethi %lm(privateSnippetExecutor), %o2:
620  *p++ = 0x15000000 | ((reinterpret_cast< unsigned long long >(privateSnippetExecutor) >> 10) & 0x3FFFFF);
621  // or %o2, %lo(privateSnippetExecutor), %o2:
622  *p++ = 0x9412A000 | (reinterpret_cast< unsigned long long >(privateSnippetExecutor) & 0x3FF);
623  // or %o2, %o1, %o1:
624  *p++ = 0x92128009;
625  // sethi %hh(frameSize), %o4:
626  *p++ = 0x19000000 | (*reinterpret_cast< unsigned long long * >(&frameSize) >> 42);
627  // or %o4, %hm(frameSize), %o4:
628  *p++ = 0x98132000 | ((*reinterpret_cast< unsigned long long * >(&frameSize) >> 32) & 0x3FF);
629  // sllx %o4, 32, %o4
630  *p++ = 0x992B3020;
631  // sethi %lm(frameSize), %o2:
632  *p++ = 0x15000000 | ((*reinterpret_cast< unsigned long long * >(&frameSize) >> 10) & 0x3FFFFF);
633  // or %o2, %lo(frameSize), %o2:
634  *p++ = 0x9412A000 | (*reinterpret_cast< unsigned long long * >(&frameSize) & 0x3FF);
635  // or %o2, %o4, %o4:
636  *p++ = 0x9812800C;
637  // sethi %hi(vtableOffset), %o2:
638  *p++ = 0x15000000 | (vtableOffset >> 10);
639  // or %o2, %lo(vtableOffset), %o2:
640  *p++ = 0x9412A000 | (vtableOffset & 0x3FF);
641  // save %sp, -frameSize, %sp
642  //*p++ = 0x9DE3A000 | (*reinterpret_cast< unsigned int * >(&frameSize) & 0x1FFF);
643  // jmpl %o1, %g0:
644  *p++ = 0x81C24000;
645  // add %sp, 2047, %o1:
646  *p++ = 0x9203A7FF;
647  assert(reinterpret_cast< unsigned char * >(p) - code <= codeSnippetSize);
648  return code + codeSnippetSize;
649 }
650 
651 } //end of namespace
652 
654 
657 {
658  return static_cast< Slot * >(block) + 2;
659 }
660 
662  sal_Int32 slotCount)
663 {
664  return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
665 }
666 
669  void * block, sal_Int32 slotCount, sal_Int32,
670  typelib_InterfaceTypeDescription *)
671 {
672  Slot * slots = mapBlockToVtable(block);
673  slots[-2].fn = 0; //null
674  slots[-1].fn = 0; //destructor
675  return slots + slotCount;
676 }
677 
679  Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
680  typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
681  sal_Int32 functionCount, sal_Int32 vTableOffset)
682 {
683  (*slots) -= functionCount;
684  Slot * s = *slots;
685  for (sal_Int32 i = 0; i < type->nMembers; ++i) {
686  typelib_TypeDescription * member = 0;
687  TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
688  assert(member != 0);
689  switch (member->eTypeClass) {
690  case typelib_TypeClass_INTERFACE_ATTRIBUTE:
691  // Getter:
692  (s++)->fn = code + writetoexecdiff;
693  code = codeSnippet(
694  code, functionOffset++, vTableOffset,
696  reinterpret_cast<
697  typelib_InterfaceAttributeTypeDescription * >(
698  member)->pAttributeTypeRef), 0);
699  // Setter:
700  if (!reinterpret_cast<
701  typelib_InterfaceAttributeTypeDescription * >(
702  member)->bReadOnly)
703  {
704  (s++)->fn = code + writetoexecdiff;
705  code = codeSnippet(code, functionOffset++, vTableOffset, false, 1);
706  }
707  break;
708 
709  case typelib_TypeClass_INTERFACE_METHOD:
710  (s++)->fn = code + writetoexecdiff;
711  code = codeSnippet(
712  code, functionOffset++, vTableOffset,
714  reinterpret_cast<
715  typelib_InterfaceMethodTypeDescription * >(
716  member)->pReturnTypeRef),
717  reinterpret_cast<
718  typelib_InterfaceMethodTypeDescription * >(
719  member)->nParams);
720  break;
721 
722  default:
723  assert(false);
724  break;
725  }
726  TYPELIB_DANGER_RELEASE(member);
727  }
728  return code;
729 }
730 
731 // use flush code from cc50_solaris_sparc
732 
733 extern "C" void doFlushCode(unsigned long address, unsigned long count);
734 
736  unsigned char const * begin, unsigned char const * end)
737 {
738  unsigned long n = end - begin;
739  if (n != 0) {
740  unsigned long adr = reinterpret_cast< unsigned long >(begin);
741  unsigned long off = adr & 7;
742  doFlushCode(adr - off, (n + off + 7) >> 3);
743  }
744 }
745 
746 /* 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()
static bool is_complex_struct(const typelib_TypeDescription *type)
sal_Int64 n
#define GET_FP(n, p)
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
return NULL
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.
typelib_TypeClass __cdecl cpp_mediate(void **pCallStack, const sal_Int32 nFunctionIndex, const sal_Int32 nVtableOffset, sal_Int64 *const pRegisterReturn)
char * adjustPointer(char *pIn, typelib_TypeDescription *pType)
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()
tuple index
struct _typelib_TypeDescription typelib_TypeDescription
Definition: msvc/except.hxx:52
uno_Mapping * getCpp2Uno()
Definition: bridge.hxx:72
XPropertyListType t
register sal_uInt32 r28 __asm__("%r28")
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef)
Does function that returns this type use a hidden parameter, or registers?
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)
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
void doFlushCode(unsigned long address, unsigned long count)
ResultType type
#define SAL_WARN(area, stream)
static CppInterfaceProxy * castInterfaceToProxy(void *pInterface)
sal_uInt16 nPos