summaryrefslogtreecommitdiff
path: root/bridges/source/cpp_uno/msvc_win32_x86-64
diff options
context:
space:
mode:
Diffstat (limited to 'bridges/source/cpp_uno/msvc_win32_x86-64')
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx170
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx3
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx23
3 files changed, 157 insertions, 39 deletions
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
index de8ceca10f1c..a2310cbd8d7d 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
@@ -90,12 +90,12 @@ static inline typelib_TypeClass cpp2uno_call(
// parameters
void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
void ** pCppArgs = pUnoArgs + nParams;
- // indizes of values this have to be converted (interface conversion cpp<=>uno)
- sal_Int64 * pTempIndizes = (sal_Int64 *)(pUnoArgs + (2 * nParams));
+ // indexes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int64 * pTempIndexes = (sal_Int64 *)(pUnoArgs + (2 * nParams));
// type descriptions for reconversions
typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
- sal_Int32 nTempIndizes = 0;
+ sal_Int32 nTempIndexes = 0;
for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
{
@@ -130,9 +130,9 @@ static inline typelib_TypeClass cpp2uno_call(
{
// uno out is unconstructed mem!
pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
- pTempIndizes[nTempIndizes] = nPos;
+ pTempIndexes[nTempIndexes] = nPos;
// will be released at reconversion
- ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ ppTempParamTypeDescr[nTempIndexes++] = pParamTypeDescr;
}
// is in/inout
else if (bridges::cpp_uno::shared::relatesToInterfaceType(
@@ -142,9 +142,9 @@ static inline typelib_TypeClass cpp2uno_call(
pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
*(void **)pCppStack, pParamTypeDescr,
pThis->getBridge()->getCpp2Uno() );
- pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ pTempIndexes[nTempIndexes] = nPos; // has to be reconverted
// will be released at reconversion
- ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ ppTempParamTypeDescr[nTempIndexes++] = pParamTypeDescr;
}
else // direct way
{
@@ -168,15 +168,15 @@ static inline typelib_TypeClass cpp2uno_call(
if (pUnoExc)
{
// destruct temporary in/inout params
- while (nTempIndizes--)
+ while (nTempIndexes--)
{
- sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ sal_Int32 nIndex = pTempIndexes[nTempIndexes];
if (pParams[nIndex].bIn) // is in/inout => was constructed
{
- ::uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ ::uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndexes], 0 );
}
- TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndexes] );
}
if (pReturnTypeDescr)
{
@@ -192,10 +192,10 @@ static inline typelib_TypeClass cpp2uno_call(
else // else no exception occurred...
{
// temporary params
- while (nTempIndizes--)
+ while (nTempIndexes--)
{
- sal_Int32 nIndex = pTempIndizes[nTempIndizes];
- typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+ sal_Int32 nIndex = pTempIndexes[nTempIndexes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndexes];
if (pParams[nIndex].bOut) // inout/out
{
@@ -362,31 +362,75 @@ extern void *cpp_vtable_call;
//==================================================================================================
int const codeSnippetSize = 28;
-#if 0
+// This function generates the code that acts as a proxy for the UNO function to be called.
+// The generated code does the following:
+// - Save register parametrs.
unsigned char * codeSnippet(
unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset)
{
unsigned char * p = code;
- // mov rax, functionIndex:
+
+ // mov eax, functionIndex:
*p++ = 0xB8;
- *reinterpret_cast< sal_Int64 * >(p) = functionIndex;
- p += sizeof (sal_Int64);
- // mov rdx, vtableOffset:
+ *reinterpret_cast< sal_Int32 * >(p) = functionIndex;
+ p += sizeof (sal_Int32);
+
+ // mov edx, vtableOffset:
*p++ = 0xBA;
- *reinterpret_cast< sal_Int64 * >(p) = vtableOffset;
- p += sizeof (sal_Int64);
+ *reinterpret_cast< sal_Int32 * >(p) = vtableOffset;
+ p += sizeof (sal_Int32);
+
+#if 0
+ sub esp, 8 // space for immediate return type
+ push esp
+ push edx // vtable offset
+ push eax // function index
+ mov eax, esp
+ add eax, 20
+ push eax // original stack ptr
+
+ call cpp_mediate
+ add esp, 16
+
+ cmp eax, typelib_TypeClass_FLOAT
+ je Lfloat
+ cmp eax, typelib_TypeClass_DOUBLE
+ je Ldouble
+ cmp eax, typelib_TypeClass_HYPER
+ je Lhyper
+ cmp eax, typelib_TypeClass_UNSIGNED_HYPER
+ je Lhyper
+ // rest is eax
+ pop eax
+ add esp, 4
+ ret
+Lhyper:
+ pop eax
+ pop edx
+ ret
+Lfloat:
+ fld dword ptr [esp]
+ add esp, 8
+ ret
+Ldouble:
+ fld qword ptr [esp]
+ add esp, 8
+ ret
+
+#endif
+
+#if 0
// jmp rel64 cpp_vtable_call:
*p++ = 0xE9;
*reinterpret_cast< sal_Int64 * >(p)
= ((unsigned char *) cpp_vtable_call) - p - sizeof (sal_Int64);
p += sizeof (sal_Int64);
+#endif
OSL_ASSERT(p - code <= codeSnippetSize);
return code + codeSnippetSize;
}
-#endif
-
}
struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
@@ -437,18 +481,88 @@ static void whatthefuck(sal_Int64 i, ...)
unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
Slot ** slots, unsigned char * code,
- typelib_InterfaceTypeDescription const *, sal_Int32 functionOffset,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
sal_Int32 functionCount, sal_Int32 vtableOffset)
{
(*slots) -= functionCount;
Slot * s = *slots;
- for (sal_Int32 i = 0; i < functionCount; ++i) {
+
+ for (int i = 0; i < functionCount; ++i) {
+ typelib_TypeDescription * pTD = 0;
+
+ TYPELIB_DANGER_GET( &pTD, type->ppMembers[ i ] );
+ OSL_ASSERT( pTD );
+
+ CPPU_CURRENT_NAMESPACE::RegParamKind param_kind[4];
+ int nr = 0;
+
+ if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE )
+ {
+ typelib_InterfaceAttributeTypeDescription *pAttrTD =
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
+
+ // get method
+#if 0
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset);
+#else
+ (s++)->fn = whatthefuck;
+#endif
+
+ if ( ! pAttrTD->bReadOnly )
+ {
+ // set method
+#if 0
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset);
+#else
+ (s++)->fn = whatthefuck;
+#endif
+ }
+ }
+ else if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_METHOD )
+ {
+ typelib_InterfaceMethodTypeDescription *pMethodTD =
+ reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD );
+
+ typelib_TypeDescription *pReturnTD = 0;
+ TYPELIB_DANGER_GET( &pReturnTD, pMethodTD->pReturnTypeRef );
+ OSL_ASSERT( pReturnTD );
+
+ if ( pReturnTD->nSize > 8 ) {
+ // Hidden return value
+ param_kind[nr++] = CPPU_CURRENT_NAMESPACE::REGPARAM_INT;
+ }
+ TYPELIB_DANGER_RELEASE( pReturnTD );
+
+ // 'this'
+ param_kind[nr++] = CPPU_CURRENT_NAMESPACE::REGPARAM_INT;
+
+ for (int j = 0; nr < 4 && j < pMethodTD->nParams; ++j)
+ {
+ typelib_TypeDescription *pParamTD = 0;
+
+ TYPELIB_DANGER_GET( &pParamTD, pMethodTD->pParams[j].pTypeRef );
+ OSL_ASSERT( pParamTD );
+
+ if ( pParamTD->eTypeClass == typelib_TypeClass_FLOAT ||
+ pParamTD->eTypeClass == typelib_TypeClass_DOUBLE )
+ param_kind[nr++] = CPPU_CURRENT_NAMESPACE::REGPARAM_FLT;
+ else
+ param_kind[nr++] = CPPU_CURRENT_NAMESPACE::REGPARAM_INT;
+
+ TYPELIB_DANGER_RELEASE( pParamTD );
+
#if 0
- (s++)->fn = code;
- code = codeSnippet(code, functionOffset++, vtableOffset);
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset);
#else
- (s++)->fn = whatthefuck;
+ (s++)->fn = whatthefuck;
#endif
+ }
+ }
+ else
+ OSL_ASSERT( false );
}
return code;
}
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx b/bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx
index 7b450c650d30..044bd4bb1316 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx
@@ -43,6 +43,9 @@ namespace CPPU_CURRENT_NAMESPACE
const DWORD MSVC_ExceptionCode = 0xe06d7363;
const long MSVC_magic_number = 0x19930520L;
+typedef enum { REGPARAM_INT, REGPARAM_FLT } RegParamKind;
+
+
//==============================================================================
type_info * mscx_getRTTI( ::rtl::OUString const & rUNOname );
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx
index 033559aad0e9..de6f5f212ec4 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx
@@ -223,19 +223,20 @@ static void cpp_call(
// The Windows x64 calling convention is very regular and
// elegant (even if perhaps then slightly slower than the
// Linux x64 one): The first four parameters, never more, are
- // passed in registers, as long as they are a qword ins size
+ // passed in registers, as long as they are a qword in size
// or less. (If larger, a pointer to a temp copy is passed, so
// it's equivalent anyway.) Floating point values are passed
- // in XMM0..3 register, others in RCX, RDX, R8, R9. Now, the
- // nice thing for us is that for varargs functions,
- // floating-point parameters among the four first ones are
- // always passed *both* in XMM and integer registers. So we
- // don't need to bother here calling the method different ways
- // depending on what types of parameters it actually expects,
- // just pretend parameters 3..4 are doubles and they will be
- // passed both in XMM and integer registers, callee will find
- // them where it expects. (The callee is not actually varargs,
- // of course.)
+ // in XMM0..3 registers, others in RCX, RDX, R8, R9.
+
+ // Now, the nice thing for us is that when calling varargs
+ // functions, floating-point parameters among the four first
+ // ones are always passed *both* in an XMM and integer
+ // register. So we don't need to bother here calling the
+ // method different ways depending on what types of parameters
+ // it actually expects. We just pretend parameters 3..4 are
+ // doubles, and they will be passed both in XMM and integer
+ // registers, and the callee will find them where it
+ // expects. (The callee is not actually varargs, of course.)
sal_Int64 (*pMethod)(sal_Int64, ...) =
(sal_Int64 (*)(sal_Int64, ...))