bridges:Fixed test fail caused by bridges on the loongarch64

Some failed test are caused by the bridges when testing on the
loongarch64 machine. After adjust the function parameters and return
value processing according to the characteristics of the loongarch64
architercture. I tested in version 7.4.3 on the loongarch64 machine, and
all tests passed.

Change-Id: I9c67287cd7cc89fd79a907afdbffa507bb6052e3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144986
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
This commit is contained in:
wjh-la 2023-01-03 17:22:11 +08:00 committed by Stephan Bergmann
parent fbabd95906
commit d3152ea3ae
8 changed files with 288 additions and 173 deletions

View file

@ -119,7 +119,7 @@ else ifeq ($(CPUNAME),LOONGARCH64)
ifneq ($(filter LINUX,$(OS)),)
bridges_SELECTED_BRIDGE := gcc3_linux_loongarch64
bridge_asm_objects := call
bridge_noopt_objects := cpp2uno uno2cpp
bridge_noopt_objects := abi cpp2uno uno2cpp
bridge_exception_objects := except
endif

View file

@ -0,0 +1,137 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <sal/config.h>
#include "abi.hxx"
int loongarch64::flatten_struct(typelib_TypeDescription* pTypeDescr, Registers& regs)
{
const typelib_CompoundTypeDescription* p
= reinterpret_cast<const typelib_CompoundTypeDescription*>(pTypeDescr);
int sum = p->nMembers;
for (sal_Int32 i = 0; i < p->nMembers; ++i)
{
typelib_TypeDescriptionReference* pTypeInStruct = p->ppTypeRefs[i];
switch (pTypeInStruct->eTypeClass)
{
case typelib_TypeClass_STRUCT:
{
typelib_TypeDescription* t = 0;
TYPELIB_DANGER_GET(&t, pTypeInStruct);
sum--;
sum += flatten_struct(t, regs);
TYPELIB_DANGER_RELEASE(t);
}
break;
case typelib_TypeClass_CHAR:
case typelib_TypeClass_BOOLEAN:
case typelib_TypeClass_BYTE:
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
case typelib_TypeClass_ENUM:
regs.nr_int++;
if (!regs.priorInt && !regs.priorFp)
regs.priorInt = true;
break;
case typelib_TypeClass_FLOAT:
case typelib_TypeClass_DOUBLE:
regs.nr_fp++;
if (!regs.priorInt && !regs.priorFp)
regs.priorFp = true;
break;
default:
break;
}
}
return sum;
}
loongarch64::ReturnKind loongarch64::getReturnKind(typelib_TypeDescriptionReference* pTypeRef)
{
switch (pTypeRef->eTypeClass)
{
case typelib_TypeClass_CHAR:
case typelib_TypeClass_BOOLEAN:
case typelib_TypeClass_BYTE:
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
case typelib_TypeClass_ENUM:
return ReturnKind::RegistersInt;
case typelib_TypeClass_FLOAT:
case typelib_TypeClass_DOUBLE:
return ReturnKind::RegistersFp;
case typelib_TypeClass_STRUCT:
{
Registers regs = { 0, 0, false, false };
typelib_TypeDescription* pTypeDescr = nullptr;
TYPELIB_DANGER_GET(&pTypeDescr, pTypeRef);
int sum = flatten_struct(pTypeDescr, regs);
TYPELIB_DANGER_RELEASE(pTypeDescr);
if ((sum == 1 || sum == 2) && sum == regs.nr_fp)
return ReturnKind::RegistersFp;
if (sum == 2 && regs.nr_fp == regs.nr_int)
{
if (regs.priorInt)
return ReturnKind::RegistersIntFp;
if (regs.priorFp)
return ReturnKind::RegistersFpInt;
}
return ReturnKind::RegistersInt;
}
default:
return ReturnKind::RegistersInt;
}
}
void loongarch64::fillReturn(typelib_TypeDescriptionReference* pTypeRef, sal_Int64* gret,
double* fret, void* pRegisterReturn)
{
ReturnKind returnKind = getReturnKind(pTypeRef);
switch (returnKind)
{
case ReturnKind::RegistersFp:
reinterpret_cast<double*>(pRegisterReturn)[0] = fret[0];
reinterpret_cast<double*>(pRegisterReturn)[1] = fret[1];
break;
case ReturnKind::RegistersFpInt:
reinterpret_cast<double*>(pRegisterReturn)[0] = fret[0];
reinterpret_cast<sal_Int64*>(pRegisterReturn)[1] = gret[0];
break;
case ReturnKind::RegistersIntFp:
reinterpret_cast<sal_Int64*>(pRegisterReturn)[0] = gret[0];
reinterpret_cast<double*>(pRegisterReturn)[1] = fret[0];
break;
default:
reinterpret_cast<sal_Int64*>(pRegisterReturn)[0] = gret[0];
reinterpret_cast<sal_Int64*>(pRegisterReturn)[1] = gret[1];
break;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */

View file

@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#pragma once
#include <typelib/typedescription.hxx>
#define MAX_GP_REGS 8
#define MAX_FP_REGS 8
namespace loongarch64
{
enum class ReturnKind
{
RegistersInt,
RegistersFp,
RegistersFpInt,
RegistersIntFp
};
typedef struct Registers
{
bool priorInt;
bool priorFp;
int nr_fp;
int nr_int;
} Registers;
int flatten_struct(typelib_TypeDescription* pTypeDescr, Registers& regs);
ReturnKind getReturnKind(typelib_TypeDescriptionReference* type);
void fillReturn(typelib_TypeDescriptionReference* pTypeRef, sal_Int64* gret, double* fret,
void* pRegisterReturn);
} // namespace loongarch64
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */

View file

@ -25,9 +25,9 @@
namespace
{
extern "C" typelib_TypeClass
cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void** gpreg, void** fpreg,
void** ovrflw, sal_uInt64* pRegisterReturn /* space for register return */);
extern "C" int cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void** gpreg,
void** fpreg, void** ovrflw,
sal_uInt64* pRegisterReturn /* space for register return */);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */

View file

@ -30,6 +30,9 @@ privateSnippetExecutor:
st.d $ra,$sp,152
.cfi_offset 1, -8
.LEHB0 = .
// Clear return value space
st.d $zero,$sp,0
st.d $zero,$sp,8
// Save the float point registers
fst.d $f0,$sp,80
fst.d $f1,$sp,88
@ -67,11 +70,21 @@ privateSnippetExecutor:
.LEHE0 = .
// Perform return value
beq $a0,$zero,.Lintfp
blt $zero,$a0,.Lfpint
fld.d $f0,$sp,0
fld.d $f1,$sp,8
ld.d $a0,$sp,0
ld.d $a1,$sp,8
b .Lfinish
.Lintfp:
ld.d $a0,$sp,0
fld.d $f0,$sp,8
b .Lfinish
.Lfpint:
fld.d $f0,$sp,0
ld.d $a0,$sp,8
.Lfinish:
ld.d $ra,$sp,152
.cfi_restore 1
addi.d $sp,$sp,160

View file

@ -28,6 +28,7 @@
#include "vtablefactory.hxx"
#include "call.hxx"
#include "share.hxx"
#include "abi.hxx"
#include <stdio.h>
#include <string.h>
@ -85,19 +86,25 @@ bool return_in_hidden_param(typelib_TypeDescriptionReference* pTypeRef)
namespace
{
static typelib_TypeClass
cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
const typelib_TypeDescription* pMemberTypeDescr,
typelib_TypeDescriptionReference* pReturnTypeRef, // 0 indicates void return
sal_Int32 nParams, typelib_MethodParameter* pParams, void** gpreg, void** fpreg,
void** ovrflw, sal_uInt64* pRegisterReturn /* space for register return */)
static int cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
const typelib_TypeDescription* pMemberTypeDescr,
typelib_TypeDescriptionReference* pReturnTypeRef, // 0 indicates void return
sal_Int32 nParams, typelib_MethodParameter* pParams, void** gpreg,
void** fpreg, void** ovrflw,
sal_uInt64* pRegisterReturn /* space for register return */)
{
unsigned int nREG = 0;
sal_Int32 gCount = 0;
sal_Int32 fCount = 0;
sal_Int32 sp = 0;
// return
typelib_TypeDescription* pReturnTypeDescr = 0;
if (pReturnTypeRef)
TYPELIB_DANGER_GET(&pReturnTypeDescr, pReturnTypeRef);
loongarch64::ReturnKind returnKind
= (pReturnTypeRef == nullptr || pReturnTypeRef->eTypeClass == typelib_TypeClass_VOID)
? loongarch64::ReturnKind::RegistersInt
: loongarch64::getReturnKind(pReturnTypeRef);
void* pUnoReturn = 0;
void* pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
@ -106,9 +113,7 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
{
if (CPPU_CURRENT_NAMESPACE::return_in_hidden_param(pReturnTypeRef))
{
pCppReturn = gpreg[nREG]; // complex return via ptr (pCppReturn)
nREG++;
pCppReturn = gpreg[gCount++]; // complex return via ptr (pCppReturn)
pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(pReturnTypeDescr)
? alloca(pReturnTypeDescr->nSize)
: pCppReturn); // direct way
@ -120,7 +125,7 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
}
// pop this
nREG++;
gCount++;
// stack space
static_assert(sizeof(void*) == sizeof(sal_Int64), "### unexpected size!");
@ -148,31 +153,15 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
{
case typelib_TypeClass_FLOAT:
case typelib_TypeClass_DOUBLE:
if (nREG < MAX_FP_REGS)
{
pCppArgs[nPos] = &(fpreg[nREG]);
pUnoArgs[nPos] = &(fpreg[nREG]);
}
else
{
pCppArgs[nPos] = &(ovrflw[nREG - MAX_FP_REGS]);
pUnoArgs[nPos] = &(ovrflw[nREG - MAX_FP_REGS]);
}
nREG++;
pCppArgs[nPos]
= fCount != MAX_FP_REGS
? &(fpreg[fCount++])
: (gCount != MAX_GP_REGS ? &(gpreg[gCount++]) : &(ovrflw[sp++]));
pUnoArgs[nPos] = pCppArgs[nPos];
break;
default:
if (nREG < MAX_GP_REGS)
{
pCppArgs[nPos] = &(gpreg[nREG]);
pUnoArgs[nPos] = &(gpreg[nREG]);
}
else
{
pCppArgs[nPos] = &(ovrflw[nREG - MAX_GP_REGS]);
pUnoArgs[nPos] = &(ovrflw[nREG - MAX_GP_REGS]);
}
nREG++;
pCppArgs[nPos] = gCount == MAX_GP_REGS ? &(ovrflw[sp++]) : &(gpreg[gCount++]);
pUnoArgs[nPos] = pCppArgs[nPos];
break;
}
// no longer needed
@ -181,16 +170,8 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
else // ptr to complex value | ref
{
void* pCppStack;
if (nREG < MAX_GP_REGS)
{
pCppArgs[nPos] = pCppStack = gpreg[nREG];
}
else
{
pCppArgs[nPos] = pCppStack = ovrflw[nREG - MAX_GP_REGS];
}
nREG++;
pCppStack = gCount == MAX_GP_REGS ? ovrflw[sp++] : gpreg[gCount++];
pCppArgs[nPos] = pCppStack;
if (!rParam.bIn) // is pure out
{
// uno out is unconstructed mem!
@ -241,7 +222,7 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
CPPU_CURRENT_NAMESPACE::raiseException(&aUnoExc, pThis->getBridge()->getUno2Cpp());
// has to destruct the any
// is here for dummy
return typelib_TypeClass_VOID;
return -1;
}
else // else no exception occurred...
{
@ -278,12 +259,17 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
}
if (pReturnTypeDescr)
{
typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
TYPELIB_DANGER_RELEASE(pReturnTypeDescr);
return eRet;
}
else
return typelib_TypeClass_VOID;
switch (returnKind)
{
case loongarch64::ReturnKind::RegistersIntFp:
return 0;
case loongarch64::ReturnKind::RegistersFpInt:
return 1;
default:
return -1;
}
}
}
@ -291,9 +277,8 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
* is called on incoming vtable calls
* (called by asm snippets)
*/
typelib_TypeClass cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void** gpreg,
void** fpreg, void** ovrflw,
sal_uInt64* pRegisterReturn /* space for register return */)
int cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void** gpreg, void** fpreg,
void** ovrflw, sal_uInt64* pRegisterReturn /* space for register return */)
{
static_assert(sizeof(sal_Int64) == sizeof(void*), "### unexpected!");
@ -332,7 +317,7 @@ typelib_TypeClass cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOff
TypeDescription aMemberDescr(pTypeDescr->ppAllMembers[nMemberPos]);
typelib_TypeClass eRet;
int eRet;
switch (aMemberDescr.get()->eTypeClass)
{
case typelib_TypeClass_INTERFACE_ATTRIBUTE:
@ -368,11 +353,11 @@ typelib_TypeClass cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOff
{
case 1: // acquire()
pCppI->acquireProxy(); // non virtual call!
eRet = typelib_TypeClass_VOID;
eRet = -1;
break;
case 2: // release()
pCppI->releaseProxy(); // non virtual call!
eRet = typelib_TypeClass_VOID;
eRet = -1;
break;
case 0: // queryInterface() opt
{
@ -395,7 +380,7 @@ typelib_TypeClass cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOff
TYPELIB_DANGER_RELEASE(pTD);
reinterpret_cast<void**>(pRegisterReturn)[0] = gpreg[0];
eRet = typelib_TypeClass_ANY;
eRet = -1;
break;
}
TYPELIB_DANGER_RELEASE(pTD);

View file

@ -24,9 +24,6 @@
#include <exception>
#include <cstddef>
#define MAX_GP_REGS (8)
#define MAX_FP_REGS (8)
namespace CPPU_CURRENT_NAMESPACE
{
void dummy_can_throw_anything(char const*);

View file

@ -36,108 +36,22 @@
#include "vtables.hxx"
#include "share.hxx"
#define INSERT_FLOAT_DOUBLE(pSV, nr, pFPR, pDS) \
if (nr < MAX_FP_REGS) \
pFPR[nr++] = *reinterpret_cast<double*>(pSV); \
else \
*pDS++ = *reinterpret_cast<sal_uInt64*>(pSV); // verbatim!
#define INSERT_INT64(pSV, nr, pGPR, pDS) \
if (nr < MAX_GP_REGS) \
pGPR[nr++] = *reinterpret_cast<sal_Int64*>(pSV); \
else \
*pDS++ = *reinterpret_cast<sal_Int64*>(pSV);
#define INSERT_INT32(pSV, nr, pGPR, pDS) \
if (nr < MAX_GP_REGS) \
pGPR[nr++] = *reinterpret_cast<sal_Int32*>(pSV); \
else \
*pDS++ = *reinterpret_cast<sal_Int32*>(pSV);
#define INSERT_INT16(pSV, nr, pGPR, pDS) \
if (nr < MAX_GP_REGS) \
pGPR[nr++] = *reinterpret_cast<sal_Int16*>(pSV); \
else \
*pDS++ = *reinterpret_cast<sal_Int16*>(pSV);
#define INSERT_UINT16(pSV, nr, pGPR, pDS) \
if (nr < MAX_GP_REGS) \
pGPR[nr++] = *reinterpret_cast<sal_uInt16*>(pSV); \
else \
*pDS++ = *reinterpret_cast<sal_uInt16*>(pSV);
#define INSERT_INT8(pSV, nr, pGPR, pDS) \
if (nr < MAX_GP_REGS) \
pGPR[nr++] = *reinterpret_cast<sal_Int8*>(pSV); \
else \
*pDS++ = *reinterpret_cast<sal_Int8*>(pSV);
#include "abi.hxx"
using namespace ::com::sun::star::uno;
namespace
{
bool isReturnInFPR(const typelib_TypeDescription* pTypeDescr, sal_uInt32& nSize)
void pushArgs(unsigned long value, unsigned long* const stack, sal_Int32* const sp,
unsigned long* const regs, sal_Int32* const nregs)
{
const typelib_CompoundTypeDescription* p
= reinterpret_cast<const typelib_CompoundTypeDescription*>(pTypeDescr);
for (sal_Int32 i = 0; i < p->nMembers; ++i)
{
typelib_TypeDescriptionReference* pTypeInStruct = p->ppTypeRefs[i];
switch (pTypeInStruct->eTypeClass)
{
case typelib_TypeClass_STRUCT:
case typelib_TypeClass_EXCEPTION:
{
typelib_TypeDescription* t = 0;
TYPELIB_DANGER_GET(&t, pTypeInStruct);
bool isFPR = isReturnInFPR(t, nSize);
TYPELIB_DANGER_RELEASE(t);
if (!isFPR)
return false;
}
break;
case typelib_TypeClass_FLOAT:
case typelib_TypeClass_DOUBLE:
if (nSize >= 16)
return false;
nSize += 8;
break;
default:
return false;
}
}
return true;
}
void fillReturn(const typelib_TypeDescription* pTypeDescr, sal_Int64* gret, double* fret,
void* pRegisterReturn)
{
sal_uInt32 nSize = 0;
if (isReturnInFPR(pTypeDescr, nSize))
{
reinterpret_cast<double*>(pRegisterReturn)[0] = fret[0];
reinterpret_cast<double*>(pRegisterReturn)[1] = fret[1];
}
else
{
reinterpret_cast<sal_Int64*>(pRegisterReturn)[0] = gret[0];
reinterpret_cast<sal_Int64*>(pRegisterReturn)[1] = gret[1];
}
(*nregs != 8 ? regs[(*nregs)++] : stack[(*sp)++]) = value;
}
static void callVirtualMethod(void* pAdjustedThisPtr, sal_Int32 nVtableIndex, void* pRegisterReturn,
typelib_TypeDescriptionReference* pReturnTypeRef, bool bSimpleReturn,
sal_uInt64* pStack, sal_uInt32 nStack, sal_uInt64* pGPR, double* pFPR,
sal_uInt32 nREG)
sal_uInt64* pStack, sal_uInt32 nStack, sal_uInt64* pGPR, double* pFPR)
{
// Should not happen, but...
static_assert(MAX_GP_REGS == MAX_FP_REGS, "must be the same size");
if (nREG > MAX_GP_REGS)
nREG = MAX_GP_REGS;
// Get pointer to method
sal_uInt64 pMethod = *((sal_uInt64*)pAdjustedThisPtr);
pMethod += 8 * nVtableIndex;
@ -211,10 +125,7 @@ static void callVirtualMethod(void* pAdjustedThisPtr, sal_Int32 nVtableIndex, vo
sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize;
if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0)
{
typelib_TypeDescription* pTypeDescr = 0;
TYPELIB_DANGER_GET(&pTypeDescr, pReturnTypeRef);
fillReturn(pTypeDescr, gret, fret, pRegisterReturn);
TYPELIB_DANGER_RELEASE(pTypeDescr);
loongarch64::fillReturn(pReturnTypeRef, gret, fret, pRegisterReturn);
}
break;
}
@ -232,10 +143,12 @@ static void cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy* pThis,
// max space for: [complex ret ptr], values|ptr ...
sal_uInt64* pStack = (sal_uInt64*)__builtin_alloca(((nParams + 3) * sizeof(sal_Int64)));
sal_uInt64* pStackStart = pStack;
sal_Int32 sp = 0;
sal_uInt64 pGPR[MAX_GP_REGS];
sal_Int32 gCount = 0;
double pFPR[MAX_FP_REGS];
sal_uInt32 nREG = 0;
sal_Int32 fCount = 0;
// return
typelib_TypeDescription* pReturnTypeDescr = 0;
@ -254,7 +167,7 @@ static void cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy* pThis,
pCppReturn = bridges::cpp_uno::shared::relatesToInterfaceType(pReturnTypeDescr)
? __builtin_alloca(pReturnTypeDescr->nSize)
: pUnoReturn;
INSERT_INT64(&pCppReturn, nREG, pGPR, pStack);
pGPR[gCount++] = reinterpret_cast<unsigned long>(pCppReturn);
}
else
{
@ -264,7 +177,7 @@ static void cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy* pThis,
// push this
void* pAdjustedThisPtr = reinterpret_cast<void**>(pThis->getCppI()) + aVtableSlot.offset;
INSERT_INT64(&pAdjustedThisPtr, nREG, pGPR, pStack);
pGPR[gCount++] = reinterpret_cast<unsigned long>(pAdjustedThisPtr);
// args
void** pCppArgs = (void**)alloca(3 * sizeof(void*) * nParams);
@ -290,30 +203,49 @@ static void cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy* pThis,
switch (pParamTypeDescr->eTypeClass)
{
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
INSERT_INT64(pCppArgs[nPos], nREG, pGPR, pStack);
break;
case typelib_TypeClass_ENUM:
INSERT_INT32(pCppArgs[nPos], nREG, pGPR, pStack);
pushArgs(*static_cast<sal_Int32*>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
break;
case typelib_TypeClass_UNSIGNED_LONG:
pushArgs(*static_cast<sal_uInt32*>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
break;
case typelib_TypeClass_CHAR:
pushArgs(*static_cast<sal_Unicode*>(pCppArgs[nPos]), pStack, &sp, pGPR,
&gCount);
break;
case typelib_TypeClass_SHORT:
INSERT_INT16(pCppArgs[nPos], nREG, pGPR, pStack);
pushArgs(*static_cast<sal_Int16*>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
break;
case typelib_TypeClass_UNSIGNED_SHORT:
INSERT_UINT16(pCppArgs[nPos], nREG, pGPR, pStack);
pushArgs(*static_cast<sal_uInt16*>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
break;
case typelib_TypeClass_BOOLEAN:
pushArgs(static_cast<unsigned long>(*static_cast<sal_Bool*>(pCppArgs[nPos])),
pStack, &sp, pGPR, &gCount);
break;
case typelib_TypeClass_BYTE:
INSERT_INT8(pCppArgs[nPos], nREG, pGPR, pStack);
pushArgs(*static_cast<sal_Int8*>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
break;
case typelib_TypeClass_FLOAT:
case typelib_TypeClass_DOUBLE:
INSERT_FLOAT_DOUBLE(pCppArgs[nPos], nREG, pFPR, pStack);
if (fCount != MAX_FP_REGS)
{
pFPR[fCount++] = *static_cast<double*>(pCppArgs[nPos]);
}
else if (gCount != MAX_GP_REGS)
{
pGPR[gCount++] = *static_cast<unsigned long*>(pCppArgs[nPos]);
}
else
{
pStack[sp++] = *static_cast<unsigned long*>(pCppArgs[nPos]);
}
break;
case typelib_TypeClass_HYPER:
pushArgs(*static_cast<sal_Int64*>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
break;
case typelib_TypeClass_UNSIGNED_HYPER:
INSERT_INT64(pCppArgs[nPos], nREG, pGPR, pStack);
pushArgs(*static_cast<sal_uInt64*>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
break;
default:
break;
@ -349,7 +281,7 @@ static void cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy* pThis,
// no longer needed
TYPELIB_DANGER_RELEASE(pParamTypeDescr);
}
INSERT_INT64(&(pCppArgs[nPos]), nREG, pGPR, pStack);
pushArgs(reinterpret_cast<unsigned long>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
}
}
@ -358,7 +290,7 @@ static void cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy* pThis,
try
{
callVirtualMethod(pAdjustedThisPtr, aVtableSlot.index, pCppReturn, pReturnTypeRef,
bSimpleReturn, pStackStart, (pStack - pStackStart), pGPR, pFPR, nREG);
bSimpleReturn, pStackStart, sp, pGPR, pFPR);
}
catch (css::uno::Exception&)
{