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>
56 uno::TypeDescription
const& description, typelib_TypeDescriptionReference* returnType,
57 sal_Int32 count, typelib_MethodParameter* parameters, sal_uInt64* gpr, sal_uInt64* fpr,
58 sal_uInt64* stack,
void* indirectRet)
62 TYPELIB_DANGER_GET(&rtd, returnType);
68 : rtd == 0 ? 0 : alloca(rtd->nSize);
69 void**
args =
static_cast<void**
>(alloca(count *
sizeof(
void*)));
70 void** cppArgs =
static_cast<void**
>(alloca(count *
sizeof(
void*)));
77 for (sal_Int32 i = 0;
i !=
count; ++
i)
81 switch (parameters[i].pTypeRef->eTypeClass)
83 case typelib_TypeClass_BOOLEAN:
84 case typelib_TypeClass_BYTE:
85 case typelib_TypeClass_SHORT:
86 case typelib_TypeClass_UNSIGNED_SHORT:
87 case typelib_TypeClass_LONG:
88 case typelib_TypeClass_UNSIGNED_LONG:
89 case typelib_TypeClass_HYPER:
90 case typelib_TypeClass_UNSIGNED_HYPER:
91 case typelib_TypeClass_CHAR:
92 case typelib_TypeClass_ENUM:
93 args[
i] = ngpr == 8 ? stack + sp++ : gpr + ngpr++;
95 case typelib_TypeClass_FLOAT:
96 case typelib_TypeClass_DOUBLE:
97 args[
i] = nfpr == 8 ? stack + sp++ : fpr + nfpr++;
106 cppArgs[
i] =
reinterpret_cast<void*
>(ngpr == 8 ? stack[sp++] : gpr[ngpr++]);
108 TYPELIB_DANGER_GET(&ptd, parameters[i].pTypeRef);
109 if (!parameters[i].bIn)
111 args[
i] = alloca(ptd->nSize);
116 args[
i] = alloca(ptd->nSize);
124 TYPELIB_DANGER_RELEASE(ptd);
131 proxy->
getUnoI()->pDispatcher(proxy->
getUnoI(), description.get(), retin, args, &pexc);
134 for (sal_Int32 i = 0;
i !=
count; ++
i)
138 if (parameters[i].bIn)
140 TYPELIB_DANGER_RELEASE(argtds[i]);
143 TYPELIB_DANGER_RELEASE(rtd);
144 assert(pexc == &exc);
148 for (sal_Int32 i = 0;
i !=
count; ++
i)
152 if (parameters[i].bOut)
155 reinterpret_cast<uno_ReleaseFunc
>(uno::cpp_release));
160 TYPELIB_DANGER_RELEASE(argtds[i]);
168 switch (rtd == 0 ? typelib_TypeClass_VOID : rtd->eTypeClass)
170 case typelib_TypeClass_VOID:
172 case typelib_TypeClass_BOOLEAN:
173 case typelib_TypeClass_BYTE:
174 case typelib_TypeClass_SHORT:
175 case typelib_TypeClass_UNSIGNED_SHORT:
176 case typelib_TypeClass_LONG:
177 case typelib_TypeClass_UNSIGNED_LONG:
178 case typelib_TypeClass_HYPER:
179 case typelib_TypeClass_UNSIGNED_HYPER:
180 case typelib_TypeClass_CHAR:
181 case typelib_TypeClass_ENUM:
182 std::memcpy(gpr, retin, rtd->nSize);
185 case typelib_TypeClass_FLOAT:
186 case typelib_TypeClass_DOUBLE:
187 std::memcpy(fpr, retin, rtd->nSize);
190 case typelib_TypeClass_STRUCT:
197 std::memcpy(gpr, retin, rtd->nSize);
209 std::memcpy(fpr + 3,
static_cast<char*
>(retin) + 12, 4);
212 std::memcpy(fpr + 2,
static_cast<char*
>(retin) + 8, 4);
215 std::memcpy(fpr + 1,
static_cast<char*
>(retin) + 4, 4);
218 std::memcpy(fpr, retin, 4);
227 std::memcpy(fpr, retin, rtd->nSize);
231 retout = indirectRet;
242 TYPELIB_DANGER_RELEASE(rtd);
245extern "C" void vtableCall(sal_Int32 functionIndex, sal_Int32 vtableOffset, sal_uInt64* gpr,
246 sal_uInt64* fpr, sal_uInt64* stack,
void* indirectRet)
250 reinterpret_cast<char*
>(gpr[0]) - vtableOffset);
251 typelib_InterfaceTypeDescription* pInterfaceTD = proxy->
getTypeDescr();
252 assert(functionIndex < pInterfaceTD->nMapFunctionIndexToMemberIndex);
253 sal_Int32 nMemberPos = pInterfaceTD->pMapFunctionIndexToMemberIndex[functionIndex];
254 assert(nMemberPos < pInterfaceTD->nAllMembers);
255 uno::TypeDescription aMemberDescr(pInterfaceTD->ppAllMembers[nMemberPos]);
257 switch (aMemberDescr.get()->eTypeClass)
259 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
261 typelib_TypeDescriptionReference* pAttrTypeRef
262 =
reinterpret_cast<typelib_InterfaceAttributeTypeDescription*
>(aMemberDescr.get())
265 if (pInterfaceTD->pMapMemberIndexToFunctionIndex[nMemberPos] == functionIndex)
268 call(proxy, aMemberDescr, pAttrTypeRef, 0, 0, gpr, fpr, stack, indirectRet);
273 typelib_MethodParameter param = { 0, pAttrTypeRef,
true,
false };
274 call(proxy, aMemberDescr, 0, 1, ¶m, gpr, fpr, stack, indirectRet);
278 case typelib_TypeClass_INTERFACE_METHOD:
279 switch (functionIndex)
290 TYPELIB_DANGER_GET(&td,
291 (
reinterpret_cast<uno::Type*
>(gpr[1])->getTypeLibType()));
292 if (td != 0 && td->eTypeClass == typelib_TypeClass_INTERFACE)
294 uno::XInterface* ifc =
nullptr;
298 reinterpret_cast<typelib_InterfaceTypeDescription*
>(td));
302 reinterpret_cast<uno_AcquireFunc
>(uno::cpp_acquire));
304 TYPELIB_DANGER_RELEASE(td);
307 TYPELIB_DANGER_RELEASE(td);
312 typelib_InterfaceMethodTypeDescription* pMethodTD
313 =
reinterpret_cast<typelib_InterfaceMethodTypeDescription*
>(
315 call(proxy, aMemberDescr, pMethodTD->pReturnTypeRef, pMethodTD->nParams,
316 pMethodTD->pParams, gpr, fpr, stack, indirectRet);
326unsigned char* GenerateVTableSlotTrampoline(
unsigned char* code, sal_Int32 functionIndex,
327 sal_Int32 vtableOffset)
330 reinterpret_cast<unsigned int*
>(
code)[0] = 0xD2800009 | ((functionIndex & 0xFFFF) << 5);
332 reinterpret_cast<unsigned int*
>(
code)[1] = 0xF2A00009 | ((functionIndex >> 16) << 5);
334 reinterpret_cast<unsigned int*
>(
code)[2] = 0xD280000A | ((vtableOffset & 0xFFFF) << 5);
336 reinterpret_cast<unsigned int*
>(
code)[3] = 0xF2A0000A | ((vtableOffset >> 16) << 5);
338 reinterpret_cast<unsigned int*
>(
code)[4] = 0x5800004B;
340 reinterpret_cast<unsigned int*
>(
code)[5] = 0xD61F0160;
356 return static_cast<Slot*
>(block) + 1;
366 assert(
reinterpret_cast<sal_uIntPtr
>(
p) >=
reinterpret_cast<sal_uIntPtr
>(&
__ImageBase)
367 &&
reinterpret_cast<sal_uIntPtr
>(
p) -
reinterpret_cast<sal_uIntPtr
>(&
__ImageBase)
368 <= std::numeric_limits<sal_uInt32>::max());
369 return reinterpret_cast<sal_uIntPtr
>(
p) -
reinterpret_cast<sal_uIntPtr
>(&
__ImageBase);
385struct RttiClassHierarchyDescriptor;
388#pragma warning(disable : 4324)
390struct alignas(16) RttiBaseClassDescriptor
395 sal_uInt32
n3 = 0xFFFFFFFF;
397 sal_uInt32
n5 = 0x40;
399 RttiBaseClassDescriptor(RttiClassHierarchyDescriptor
const*
chd)
405struct alignas(4) RttiBaseClassArray
409 RttiBaseClassArray(RttiBaseClassDescriptor
const*
bcd)
415struct alignas(8) RttiClassHierarchyDescriptor
421 RttiClassHierarchyDescriptor(RttiBaseClassArray
const*
bca)
427struct alignas(16) RttiCompleteObjectLocator
435 RttiCompleteObjectLocator(RttiClassHierarchyDescriptor
const*
chd)
443 RttiBaseClassDescriptor
bcd;
445 RttiClassHierarchyDescriptor
chd;
446 RttiCompleteObjectLocator
col;
462 typelib_InterfaceTypeDescription*)
466 Slot* slots = mapBlockToVtable(block);
467 slots[-1].fn = &rtti.col;
468 return slots + slotCount;
472 typelib_InterfaceTypeDescription
const* type,
473 sal_Int32 functionOffset, sal_Int32 functionCount,
474 sal_Int32 vtableOffset)
476 (*slots) -= functionCount;
478 for (sal_Int32 i = 0;
i !=
type->nMembers; ++
i)
481 TYPELIB_DANGER_GET(&td,
type->ppMembers[i]);
483 switch (td->eTypeClass)
485 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
487 typelib_InterfaceAttributeTypeDescription* atd
488 =
reinterpret_cast<typelib_InterfaceAttributeTypeDescription*
>(td);
491 code = GenerateVTableSlotTrampoline(code, functionOffset++, vtableOffset);
496 code = GenerateVTableSlotTrampoline(code, functionOffset++, vtableOffset);
500 case typelib_TypeClass_INTERFACE_METHOD:
502 code = GenerateVTableSlotTrampoline(code, functionOffset++, vtableOffset);
507 TYPELIB_DANGER_RELEASE(td);
514 FlushInstructionCache(GetCurrentProcess(), begin, end - begin);
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
void msvc_raiseException(uno_Any *pUnoExc, uno_Mapping *pUno2Cpp)
RttiClassHierarchyDescriptor chd
IMAGE_DOS_HEADER const __ImageBase
RttiCompleteObjectLocator col
RttiBaseClassDescriptor bcd
ReturnKind getReturnKind(typelib_TypeDescription const *type)
static sal_uInt32 imageRelative(void const *p)
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,...