31#include <com/sun/star/uno/XInterface.hpp>
32#include <com/sun/star/uno/genfunc.hxx>
35#include <typelib/typeclass.h>
36#include <typelib/typedescription.h>
37#include <typelib/typedescription.hxx>
51 css::uno::TypeDescription
const & description,
52 typelib_TypeDescriptionReference * returnType, sal_Int32 count,
53 typelib_MethodParameter * parameters,
unsigned long * gpr,
54 unsigned long * fpr,
unsigned long * stack,
void * indirectRet)
57 if (returnType !=
nullptr) {
58 TYPELIB_DANGER_GET(&rtd, returnType);
62 bool retConv = rtd !=
nullptr
65 ? indirectRet : rtd ==
nullptr ? nullptr : alloca(rtd->nSize);
66 void **
args =
static_cast< void **
>(alloca(count *
sizeof (
void *)));
67 void ** cppArgs =
static_cast< void **
>(alloca(count *
sizeof (
void *)));
76 for (sal_Int32 i = 0;
i !=
count; ++
i) {
77 if (!parameters[i].bOut
80 switch (parameters[i].pTypeRef->eTypeClass) {
82 case typelib_TypeClass_BOOLEAN:
83 case typelib_TypeClass_BYTE:
91 args[
i] =
reinterpret_cast<void *
>(
reinterpret_cast<uintptr_t
>(stack + sp) + subsp);
100 case typelib_TypeClass_SHORT:
101 case typelib_TypeClass_UNSIGNED_SHORT:
102 case typelib_TypeClass_CHAR:
105 args[
i] = gpr + ngpr;
110 subsp = (subsp + 1) & ~0x1;
116 args[
i] =
reinterpret_cast<void *
>(
reinterpret_cast<uintptr_t
>(stack + sp) + subsp);
125 case typelib_TypeClass_LONG:
126 case typelib_TypeClass_UNSIGNED_LONG:
127 case typelib_TypeClass_ENUM:
130 args[
i] = gpr + ngpr;
135 subsp = (subsp + 3) & ~0x3;
141 args[
i] =
reinterpret_cast<void *
>(
reinterpret_cast<uintptr_t
>(stack + sp) + subsp);
150 case typelib_TypeClass_HYPER:
151 case typelib_TypeClass_UNSIGNED_HYPER:
154 args[
i] = gpr + ngpr;
164 args[
i] = stack + sp;
168 case typelib_TypeClass_FLOAT:
171 args[
i] = fpr + nfpr;
176 subsp = (subsp + 3) & ~0x3;
182 args[
i] =
reinterpret_cast<void *
>(
reinterpret_cast<uintptr_t
>(stack + sp) + subsp);
191 case typelib_TypeClass_DOUBLE:
194 args[
i] = fpr + nfpr;
204 args[
i] = stack + sp;
209 case typelib_TypeClass_BOOLEAN:
210 case typelib_TypeClass_BYTE:
211 case typelib_TypeClass_SHORT:
212 case typelib_TypeClass_UNSIGNED_SHORT:
213 case typelib_TypeClass_LONG:
214 case typelib_TypeClass_UNSIGNED_LONG:
215 case typelib_TypeClass_HYPER:
216 case typelib_TypeClass_UNSIGNED_HYPER:
217 case typelib_TypeClass_CHAR:
218 case typelib_TypeClass_ENUM:
219 args[
i] = ngpr == 8 ? stack + sp++ : gpr + ngpr++;
221 case typelib_TypeClass_FLOAT:
222 case typelib_TypeClass_DOUBLE:
223 args[
i] = nfpr == 8 ? stack + sp++ : fpr + nfpr++;
238 cppArgs[
i] =
reinterpret_cast<void *
>(
239 ngpr == 8 ? stack[sp++] : gpr[ngpr++]);
241 TYPELIB_DANGER_GET(&ptd, parameters[i].pTypeRef);
242 if (!parameters[i].bIn) {
243 args[
i] = alloca(ptd->nSize);
246 args[
i] = alloca(ptd->nSize);
253 TYPELIB_DANGER_RELEASE(ptd);
260 proxy->
getUnoI(), description.get(), retin, args, &pexc);
261 if (pexc !=
nullptr) {
262 for (sal_Int32 i = 0;
i !=
count; ++
i) {
263 if (argtds[i] !=
nullptr) {
264 if (parameters[i].bIn) {
267 TYPELIB_DANGER_RELEASE(argtds[i]);
270 if (rtd !=
nullptr) {
271 TYPELIB_DANGER_RELEASE(rtd);
275 for (sal_Int32 i = 0;
i !=
count; ++
i) {
276 if (argtds[i] !=
nullptr) {
277 if (parameters[i].bOut) {
279 cppArgs[i], argtds[i],
280 reinterpret_cast<uno_ReleaseFunc
>(css::uno::cpp_release));
282 cppArgs[i], args[i], argtds[i],
286 TYPELIB_DANGER_RELEASE(argtds[i]);
289 void * retout =
nullptr;
292 switch (rtd ==
nullptr ? typelib_TypeClass_VOID : rtd->eTypeClass) {
293 case typelib_TypeClass_VOID:
296 case typelib_TypeClass_BOOLEAN:
297 assert(rtd->nSize == sizeof (
bool));
298 *gpr =
static_cast<unsigned long>(*
static_cast<bool *
>(retin));
301 case typelib_TypeClass_BYTE:
302 assert(rtd->nSize == sizeof (
sal_Int8));
303 *gpr = *
static_cast<sal_Int8 *
>(retin);
306 case typelib_TypeClass_SHORT:
307 assert(rtd->nSize == sizeof (sal_Int16));
308 *gpr = *
static_cast<sal_Int16 *
>(retin);
311 case typelib_TypeClass_UNSIGNED_SHORT:
312 assert(rtd->nSize == sizeof (sal_uInt16));
313 *gpr = *
static_cast<sal_uInt16 *
>(retin);
316 case typelib_TypeClass_CHAR:
322 case typelib_TypeClass_BOOLEAN:
323 case typelib_TypeClass_BYTE:
324 case typelib_TypeClass_SHORT:
325 case typelib_TypeClass_UNSIGNED_SHORT:
326 case typelib_TypeClass_CHAR:
328 case typelib_TypeClass_LONG:
329 case typelib_TypeClass_UNSIGNED_LONG:
330 case typelib_TypeClass_HYPER:
331 case typelib_TypeClass_UNSIGNED_HYPER:
332 case typelib_TypeClass_ENUM:
333 std::memcpy(gpr, retin, rtd->nSize);
336 case typelib_TypeClass_FLOAT:
337 case typelib_TypeClass_DOUBLE:
338 std::memcpy(fpr, retin, rtd->nSize);
341 case typelib_TypeClass_STRUCT:
345 std::memcpy(gpr, retin, rtd->nSize);
353 assert(rtd !=
nullptr);
354 switch (rtd->nSize) {
356 std::memcpy(fpr + 3,
static_cast<char *
>(retin) + 12, 4);
359 std::memcpy(fpr + 2,
static_cast<char *
>(retin) + 8, 4);
362 std::memcpy(fpr + 1,
static_cast<char *
>(retin) + 4, 4);
365 std::memcpy(fpr, retin, 4);
373 assert(rtd !=
nullptr);
374 std::memcpy(fpr, retin, rtd->nSize);
378 retout = indirectRet;
386 if (rtd !=
nullptr) {
387 TYPELIB_DANGER_RELEASE(rtd);
394 sal_Int32 functionIndex, sal_Int32 vtableOffset,
395 unsigned long * gpr,
unsigned long * fpr,
unsigned long * stack,
400 reinterpret_cast<char *
>(gpr[0]) - vtableOffset);
402 assert(functionIndex < type->nMapFunctionIndexToMemberIndex);
403 sal_Int32
pos =
type->pMapFunctionIndexToMemberIndex[functionIndex];
404 css::uno::TypeDescription desc(
type->ppAllMembers[
pos]);
405 switch (desc.get()->eTypeClass) {
406 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
407 if (
type->pMapMemberIndexToFunctionIndex[
pos] == functionIndex) {
411 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *
>(
412 desc.get())->pAttributeTypeRef,
413 0,
nullptr, gpr, fpr, stack, indirectRet);
416 typelib_MethodParameter param = {
418 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *
>(
419 desc.get())->pAttributeTypeRef,
421 call(proxy, desc,
nullptr, 1, ¶m, gpr, fpr, stack, indirectRet);
424 case typelib_TypeClass_INTERFACE_METHOD:
425 switch (functionIndex) {
437 (
reinterpret_cast<css::uno::Type *
>(gpr[1])
438 ->getTypeLibType()));
439 if (td !=
nullptr && td->eTypeClass == typelib_TypeClass_INTERFACE) {
440 css::uno::XInterface * ifc =
nullptr;
443 reinterpret_cast<void **
>(&ifc), proxy->
getOid().pData,
444 reinterpret_cast<typelib_InterfaceTypeDescription *
>(
446 if (ifc !=
nullptr) {
448 static_cast<uno_Any *
>(indirectRet), &ifc, td,
449 reinterpret_cast<uno_AcquireFunc
>(
450 css::uno::cpp_acquire));
452 TYPELIB_DANGER_RELEASE(td);
455 TYPELIB_DANGER_RELEASE(td);
462 reinterpret_cast<typelib_InterfaceMethodTypeDescription *
>(
463 desc.get())->pReturnTypeRef,
464 reinterpret_cast<typelib_InterfaceMethodTypeDescription *
>(
465 desc.get())->nParams,
466 reinterpret_cast<typelib_InterfaceMethodTypeDescription *
>(
467 desc.get())->pParams,
468 gpr, fpr, stack, indirectRet);
480unsigned char * generateCodeSnippet(
481 unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset)
484 reinterpret_cast<unsigned int *
>(
code)[0] = 0xD2800009
485 | ((functionIndex & 0xFFFF) << 5);
487 reinterpret_cast<unsigned int *
>(
code)[1] = 0xF2A00009
488 | ((functionIndex >> 16) << 5);
490 reinterpret_cast<unsigned int *
>(
code)[2] = 0xD280000A
491 | ((vtableOffset & 0xFFFF) << 5);
493 reinterpret_cast<unsigned int *
>(
code)[3] = 0xF2A0000A
494 | ((vtableOffset >> 16) << 5);
496 reinterpret_cast<unsigned int *
>(
code)[4] = 0x5800004B;
498 reinterpret_cast<unsigned int *
>(
code)[5] = 0xD61F0160;
499 reinterpret_cast<unsigned long *
>(
code)[3]
510 return static_cast<Slot *
>(block) + 2;
527 void * block, sal_Int32 slotCount, sal_Int32,
528 typelib_InterfaceTypeDescription *)
530 Slot * slots = mapBlockToVtable(block);
531 slots[-2].fn =
nullptr;
532 slots[-1].fn = &
typeid(ProxyRtti);
533 return slots + slotCount;
537 Slot ** slots,
unsigned char * code,
539 sal_PtrDiff writetoexecdiff,
541 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
542 sal_Int32 functionCount, sal_Int32 vtableOffset)
544#ifndef USE_DOUBLE_MMAP
545 constexpr sal_PtrDiff writetoexecdiff = 0;
547 (*slots) -= functionCount;
549 for (sal_Int32 i = 0;
i !=
type->nMembers; ++
i) {
551 TYPELIB_DANGER_GET(&td,
type->ppMembers[i]);
552 assert(td !=
nullptr);
553 switch (td->eTypeClass) {
554 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
556 typelib_InterfaceAttributeTypeDescription * atd
558 typelib_InterfaceAttributeTypeDescription *
>(td);
560 (s++)->fn = code + writetoexecdiff;
561 code = generateCodeSnippet(
562 code, functionOffset++, vtableOffset);
564 if (!atd->bReadOnly) {
565 (s++)->fn = code + writetoexecdiff;
566 code = generateCodeSnippet(
567 code, functionOffset++, vtableOffset);
571 case typelib_TypeClass_INTERFACE_METHOD:
572 (s++)->fn = code + writetoexecdiff;
573 code = generateCodeSnippet(code, functionOffset++, vtableOffset);
578 TYPELIB_DANGER_RELEASE(td);
584 unsigned char const * begin,
unsigned char const * end)
586#if !defined ANDROID && !defined MACOSX
587 static void (*clear_cache)(
unsigned char const *,
unsigned char const *)
588 = (
void (*)(
unsigned char const *,
unsigned char const *)) dlsym(
589 RTLD_DEFAULT,
"__clear_cache");
600 __builtin___clear_cache(
601 reinterpret_cast<char *
>(
const_cast<unsigned char *
>(begin)),
602 reinterpret_cast<char *
>(
const_cast<unsigned char *
>(end)));
void SAL_CALL uno_any_construct(uno_Any *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_AcquireFunc acquire) SAL_THROW_EXTERN_C()
uno_Mapping * getUno2Cpp()
uno_ExtEnvironment * getCppEnv()
uno_Mapping * getCpp2Uno()
A cpp proxy wrapping a uno interface.
uno_Interface * getUnoI()
static CppInterfaceProxy * castInterfaceToProxy(void *pInterface)
typelib_InterfaceTypeDescription * getTypeDescr()
const OUString & getOid() const
static Slot * mapBlockToVtable(void *block)
Given a pointer to a block, turn it into a vtable pointer.
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.
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...
static Slot * initializeBlock(void *block, sal_Int32 slotCount, sal_Int32 vtableNumber, typelib_InterfaceTypeDescription *type)
Initialize a raw vtable block.
static std::size_t getBlockSize(sal_Int32 slotCount)
Calculate the size of a raw vtable block.
void SAL_CALL uno_destructData(void *pValue, typelib_TypeDescription *pTypeDescr, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
void SAL_CALL uno_copyAndConvertData(void *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_Mapping *mapping) SAL_THROW_EXTERN_C()
void vtableCall(sal_Int32 functionIndex, sal_Int32 vtableOffset, unsigned long *gpr, unsigned long *fpr, unsigned long *stack, void *indirectRet)
const int codeSnippetSize
struct _typelib_TypeDescription typelib_TypeDescription
ReturnKind getReturnKind(typelib_TypeDescription const *type)
void raiseException(uno_Any *any, uno_Mapping *mapping)
bool isSimpleType(typelib_TypeClass typeClass)
Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT, UNSIGNED SHORT,...
bool relatesToInterfaceType(typelib_TypeDescription const *type)
Determines whether a type relates to an interface type (is itself an interface type,...
enumrange< T >::Iterator begin(enumrange< T >)