30 #include <com/sun/star/uno/XInterface.hpp>
31 #include <com/sun/star/uno/genfunc.hxx>
34 #include <typelib/typeclass.h>
35 #include <typelib/typedescription.h>
36 #include <typelib/typedescription.hxx>
50 css::uno::TypeDescription
const & description,
51 typelib_TypeDescriptionReference * returnType, sal_Int32 count,
52 typelib_MethodParameter * parameters,
unsigned long * gpr,
53 unsigned long * fpr,
unsigned long * stack,
void * indirectRet)
56 if (returnType !=
nullptr) {
57 TYPELIB_DANGER_GET(&rtd, returnType);
61 bool retConv = rtd !=
nullptr
64 ? indirectRet : rtd ==
nullptr ?
nullptr : alloca(rtd->nSize);
65 void **
args =
static_cast< void **
>(alloca(count *
sizeof (
void *)));
66 void ** cppArgs =
static_cast< void **
>(alloca(count *
sizeof (
void *)));
75 for (sal_Int32 i = 0;
i != count; ++
i) {
76 if (!parameters[i].bOut
79 switch (parameters[i].pTypeRef->eTypeClass) {
81 case typelib_TypeClass_BOOLEAN:
82 case typelib_TypeClass_BYTE:
90 args[i] =
reinterpret_cast<void *
>(
reinterpret_cast<uintptr_t
>(stack + sp) + subsp);
99 case typelib_TypeClass_SHORT:
100 case typelib_TypeClass_UNSIGNED_SHORT:
101 case typelib_TypeClass_CHAR:
104 args[i] = gpr + ngpr;
109 subsp = (subsp + 1) & ~0x1;
115 args[i] =
reinterpret_cast<void *
>(
reinterpret_cast<uintptr_t
>(stack + sp) + subsp);
124 case typelib_TypeClass_LONG:
125 case typelib_TypeClass_UNSIGNED_LONG:
126 case typelib_TypeClass_ENUM:
129 args[i] = gpr + ngpr;
134 subsp = (subsp + 3) & ~0x3;
140 args[i] =
reinterpret_cast<void *
>(
reinterpret_cast<uintptr_t
>(stack + sp) + subsp);
149 case typelib_TypeClass_HYPER:
150 case typelib_TypeClass_UNSIGNED_HYPER:
153 args[i] = gpr + ngpr;
163 args[i] = stack + sp;
167 case typelib_TypeClass_FLOAT:
170 args[i] = fpr + nfpr;
175 subsp = (subsp + 3) & ~0x3;
181 args[i] =
reinterpret_cast<void *
>(
reinterpret_cast<uintptr_t
>(stack + sp) + subsp);
190 case typelib_TypeClass_DOUBLE:
193 args[i] = fpr + nfpr;
203 args[i] = stack + sp;
208 case typelib_TypeClass_BOOLEAN:
209 case typelib_TypeClass_BYTE:
210 case typelib_TypeClass_SHORT:
211 case typelib_TypeClass_UNSIGNED_SHORT:
212 case typelib_TypeClass_LONG:
213 case typelib_TypeClass_UNSIGNED_LONG:
214 case typelib_TypeClass_HYPER:
215 case typelib_TypeClass_UNSIGNED_HYPER:
216 case typelib_TypeClass_CHAR:
217 case typelib_TypeClass_ENUM:
218 args[i] = ngpr == 8 ? stack + sp++ : gpr + ngpr++;
220 case typelib_TypeClass_FLOAT:
221 case typelib_TypeClass_DOUBLE:
222 args[i] = nfpr == 8 ? stack + sp++ : fpr + nfpr++;
237 cppArgs[i] =
reinterpret_cast<void *
>(
238 ngpr == 8 ? stack[sp++] : gpr[ngpr++]);
240 TYPELIB_DANGER_GET(&ptd, parameters[i].pTypeRef);
241 if (!parameters[i].bIn) {
242 args[i] = alloca(ptd->nSize);
245 args[i] = alloca(ptd->nSize);
250 args[i] = cppArgs[i];
252 TYPELIB_DANGER_RELEASE(ptd);
259 proxy->
getUnoI(), description.get(), retin, args, &pexc);
260 if (pexc !=
nullptr) {
261 for (sal_Int32 i = 0; i != count; ++i) {
262 if (argtds[i] !=
nullptr) {
263 if (parameters[i].bIn) {
266 TYPELIB_DANGER_RELEASE(argtds[i]);
269 if (rtd !=
nullptr) {
270 TYPELIB_DANGER_RELEASE(rtd);
274 for (sal_Int32 i = 0; i != count; ++i) {
275 if (argtds[i] !=
nullptr) {
276 if (parameters[i].bOut) {
278 cppArgs[i], argtds[i],
279 reinterpret_cast<uno_ReleaseFunc>(css::uno::cpp_release));
281 cppArgs[i], args[i], argtds[i],
285 TYPELIB_DANGER_RELEASE(argtds[i]);
288 void * retout =
nullptr;
291 switch (rtd ==
nullptr ? typelib_TypeClass_VOID : rtd->eTypeClass) {
292 case typelib_TypeClass_VOID:
295 case typelib_TypeClass_BOOLEAN:
296 assert(rtd->nSize == sizeof (
bool));
297 *gpr =
static_cast<unsigned long>(*
static_cast<bool *
>(retin));
300 case typelib_TypeClass_BYTE:
301 assert(rtd->nSize == sizeof (
sal_Int8));
302 *gpr = *
static_cast<sal_Int8 *
>(retin);
305 case typelib_TypeClass_SHORT:
306 assert(rtd->nSize == sizeof (sal_Int16));
307 *gpr = *
static_cast<sal_Int16 *
>(retin);
310 case typelib_TypeClass_UNSIGNED_SHORT:
311 assert(rtd->nSize == sizeof (sal_uInt16));
312 *gpr = *
static_cast<sal_uInt16 *
>(retin);
315 case typelib_TypeClass_CHAR:
321 case typelib_TypeClass_BOOLEAN:
322 case typelib_TypeClass_BYTE:
323 case typelib_TypeClass_SHORT:
324 case typelib_TypeClass_UNSIGNED_SHORT:
325 case typelib_TypeClass_CHAR:
327 case typelib_TypeClass_LONG:
328 case typelib_TypeClass_UNSIGNED_LONG:
329 case typelib_TypeClass_HYPER:
330 case typelib_TypeClass_UNSIGNED_HYPER:
331 case typelib_TypeClass_ENUM:
332 std::memcpy(gpr, retin, rtd->nSize);
335 case typelib_TypeClass_FLOAT:
336 case typelib_TypeClass_DOUBLE:
337 std::memcpy(fpr, retin, rtd->nSize);
340 case typelib_TypeClass_STRUCT:
344 std::memcpy(gpr, retin, rtd->nSize);
352 assert(rtd !=
nullptr);
353 switch (rtd->nSize) {
355 std::memcpy(fpr + 3, static_cast<char *>(retin) + 12, 4);
358 std::memcpy(fpr + 2, static_cast<char *>(retin) + 8, 4);
361 std::memcpy(fpr + 1, static_cast<char *>(retin) + 4, 4);
364 std::memcpy(fpr, retin, 4);
372 assert(rtd !=
nullptr);
373 std::memcpy(fpr, retin, rtd->nSize);
377 retout = indirectRet;
385 if (rtd !=
nullptr) {
386 TYPELIB_DANGER_RELEASE(rtd);
393 sal_Int32 functionIndex, sal_Int32 vtableOffset,
394 unsigned long * gpr,
unsigned long * fpr,
unsigned long * stack,
399 reinterpret_cast<char *>(gpr[0]) - vtableOffset);
401 assert(functionIndex < type->nMapFunctionIndexToMemberIndex);
402 sal_Int32
pos = type->pMapFunctionIndexToMemberIndex[functionIndex];
403 css::uno::TypeDescription desc(type->ppAllMembers[pos]);
404 switch (desc.get()->eTypeClass) {
405 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
406 if (type->pMapMemberIndexToFunctionIndex[pos] == functionIndex) {
410 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>(
411 desc.get())->pAttributeTypeRef,
412 0,
nullptr, gpr, fpr, stack, indirectRet);
415 typelib_MethodParameter param = {
417 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *
>(
418 desc.get())->pAttributeTypeRef,
420 call(proxy, desc,
nullptr, 1, ¶m, gpr, fpr, stack, indirectRet);
423 case typelib_TypeClass_INTERFACE_METHOD:
424 switch (functionIndex) {
436 (reinterpret_cast<css::uno::Type *>(gpr[1])
437 ->getTypeLibType()));
438 if (td !=
nullptr && td->eTypeClass == typelib_TypeClass_INTERFACE) {
439 css::uno::XInterface * ifc =
nullptr;
442 reinterpret_cast<void **
>(&ifc), proxy->
getOid().pData,
443 reinterpret_cast<typelib_InterfaceTypeDescription *
>(
445 if (ifc !=
nullptr) {
447 static_cast<uno_Any *>(indirectRet), &ifc, td,
448 reinterpret_cast<uno_AcquireFunc>(
449 css::uno::cpp_acquire));
451 TYPELIB_DANGER_RELEASE(td);
454 TYPELIB_DANGER_RELEASE(td);
461 reinterpret_cast<typelib_InterfaceMethodTypeDescription *>(
462 desc.get())->pReturnTypeRef,
463 reinterpret_cast<typelib_InterfaceMethodTypeDescription *>(
464 desc.get())->nParams,
465 reinterpret_cast<typelib_InterfaceMethodTypeDescription *>(
466 desc.get())->pParams,
467 gpr, fpr, stack, indirectRet);
479 unsigned char * generateCodeSnippet(
480 unsigned char *
code, sal_Int32 functionIndex, sal_Int32 vtableOffset)
483 reinterpret_cast<unsigned int *
>(code)[0] = 0xD2800009
484 | ((functionIndex & 0xFFFF) << 5);
486 reinterpret_cast<unsigned int *
>(code)[1] = 0xF2A00009
487 | ((functionIndex >> 16) << 5);
489 reinterpret_cast<unsigned int *
>(code)[2] = 0xD280000A
490 | ((vtableOffset & 0xFFFF) << 5);
492 reinterpret_cast<unsigned int *
>(code)[3] = 0xF2A0000A
493 | ((vtableOffset >> 16) << 5);
495 reinterpret_cast<unsigned int *
>(code)[4] = 0x5800004B;
497 reinterpret_cast<unsigned int *
>(code)[5] = 0xD61F0160;
498 reinterpret_cast<unsigned long *
>(code)[3]
509 return static_cast<Slot *
>(block) + 2;
520 void * block, sal_Int32 slotCount, sal_Int32,
521 typelib_InterfaceTypeDescription *)
523 Slot * slots = mapBlockToVtable(block);
524 slots[-2].fn =
nullptr;
525 slots[-1].fn =
nullptr;
526 return slots + slotCount;
530 Slot ** slots,
unsigned char *
code,
532 sal_PtrDiff writetoexecdiff,
534 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
535 sal_Int32 functionCount, sal_Int32 vtableOffset)
537 #ifndef USE_DOUBLE_MMAP
538 constexpr sal_PtrDiff writetoexecdiff = 0;
540 (*slots) -= functionCount;
542 for (sal_Int32 i = 0; i != type->nMembers; ++i) {
544 TYPELIB_DANGER_GET(&td, type->ppMembers[i]);
545 assert(td !=
nullptr);
546 switch (td->eTypeClass) {
547 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
549 typelib_InterfaceAttributeTypeDescription * atd
551 typelib_InterfaceAttributeTypeDescription *
>(td);
553 (s++)->fn = code + writetoexecdiff;
554 code = generateCodeSnippet(
555 code, functionOffset++, vtableOffset);
557 if (!atd->bReadOnly) {
558 (s++)->fn = code + writetoexecdiff;
559 code = generateCodeSnippet(
560 code, functionOffset++, vtableOffset);
564 case typelib_TypeClass_INTERFACE_METHOD:
565 (s++)->fn = code + writetoexecdiff;
566 code = generateCodeSnippet(code, functionOffset++, vtableOffset);
571 TYPELIB_DANGER_RELEASE(td);
577 unsigned char const *
begin,
unsigned char const *
end)
579 #if !defined ANDROID && !defined MACOSX
580 static void (*clear_cache)(
unsigned char const *,
unsigned char const *)
581 = (
void (*)(
unsigned char const *,
unsigned char const *)) dlsym(
582 RTLD_DEFAULT,
"__clear_cache");
583 (*clear_cache)(begin, end);
593 __builtin___clear_cache(
594 reinterpret_cast<char *>(const_cast<unsigned char *>(begin)),
595 reinterpret_cast<char *>(const_cast<unsigned char *>(end)));
void vtableCall(sal_Int32 functionIndex, sal_Int32 vtableOffset, unsigned long *gpr, unsigned long *fpr, unsigned long *stack, void *indirectRet)
void SAL_CALL uno_destructData(void *pValue, typelib_TypeDescription *pTypeDescr, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
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...
static std::size_t getBlockSize(sal_Int32 slotCount)
Calculate the size of a raw vtable block.
const int codeSnippetSize
void SAL_CALL uno_any_construct(uno_Any *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_AcquireFunc acquire) SAL_THROW_EXTERN_C()
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).
enumrange< T >::Iterator begin(enumrange< T >)
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.
uno_Mapping * getUno2Cpp()
uno_ExtEnvironment * getCppEnv()
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()
uno_Interface * getUnoI()
struct _typelib_TypeDescription typelib_TypeDescription
uno_Mapping * getCpp2Uno()
enumrange< T >::Iterator end(enumrange< T >)
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 CppInterfaceProxy * castInterfaceToProxy(void *pInterface)
const OUString & getOid() const
ReturnKind getReturnKind(typelib_TypeDescription const *type)