/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * 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 .
*/
// parameter list is mixed list of * and values // reference parameters are pointers
unsignedlong * mfunc; // actual function to be invoked void (*ptr)(); int gpr[4]; // storage for gpregisters, map to a0-a3 int off; // offset used to find function int nw; // number of words mapped long *p; // pointer to parameter overflow area int iret, iret2; // temporary function return values
// never called if (! pAdjustedThisPtr ) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
// Because of the MIPS O32 calling conventions we could be passing // parameters in both register types and on the stack. To create the // stack parameter area we need we now simply allocate local // variable storage param[] that is at least the size of the parameter stack // (more than enough space) which we can overwrite the parameters into.
/* p = sp - 512; new sp will be p - 16, but we don't change sp * at this time to avoid breaking ABI--not sure whether changing sp will break * references to local variables. For the same reason, we use absolute value.
*/
__asm__ __volatile__ ( "addiu $2,$29,-512\n\t" "move %0,$2\n\t"
:"=r"(p): : "$2","$29" );
#ifdef BRDEBUG if (nStackLongs * 4 > 512 )
fprintf(stderr,"too many arguments"); #endif
// now begin to load the C++ function arguments into storage
nw = 0;
// now we need to parse the entire signature string */ // until we get the END indicator */
// treat complex return pointer like any other parameter
#ifdef BRDEBUG
fprintf(stderr,"overflow area pointer p=%p\n",p);
/* Let's figure out what is really going on here*/
fprintf(stderr,"callVirtualMethod parameters string is %s\n",pPT); int k = nStackLongs; long * q = (long *)pStackLongs; while (k > 0) {
fprintf(stderr,"uno stack is: %x\n",(unsignedint)*q);
k--;
q++;
} #endif
/* parse the argument list up to the ending ) */ while (*pPT != 'X') { int c = *pPT; // character of parameter type being decoded switch (c) { case'D': /* type is double */ /* treat the same as long long */ case'H': /* type is long long */ if (nw & 1) nw++; /* note even elements gpr[] will map to
odd registers*/ if (nw < 4) {
gpr[nw++] = *pStackLongs;
gpr[nw++] = *(pStackLongs+1);
} else { if (((long) p) & 4)
p++;
*p++ = *pStackLongs;
*p++ = *(pStackLongs+1);
}
pStackLongs += 2; break;
/* figure out the address of the function we need to invoke */
off = nVtableIndex;
off = off * 4; // 4 bytes per slot
mfunc = *((unsignedlong **)pAdjustedThisPtr); // get the address of the vtable
mfunc = (unsignedlong *)((char *)mfunc + off); // get the address from the vtable entry at offset
mfunc = *((unsignedlong **)mfunc); // the function is stored at the address
ptr = (void (*)())mfunc;
#ifdef BRDEBUG
fprintf(stderr,"calling function %p\n",mfunc); #endif
/* Set up the machine registers and invoke the function */
switch( eReturnType )
{ case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER:
((long*)pRegisterReturn)[1] = iret2; // fall through case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: case typelib_TypeClass_ENUM:
((long*)pRegisterReturn)[0] = iret; break; case typelib_TypeClass_CHAR: case typelib_TypeClass_SHORT: case typelib_TypeClass_UNSIGNED_SHORT:
*(unsignedshort*)pRegisterReturn = (unsignedshort)iret; break; case typelib_TypeClass_BOOLEAN: case typelib_TypeClass_BYTE:
*(unsignedchar*)pRegisterReturn = (unsignedchar)iret; break; case typelib_TypeClass_FLOAT:
*(float*)pRegisterReturn = fret; break; case typelib_TypeClass_DOUBLE:
*(double*)pRegisterReturn = dret; break; default: break;
}
}
// need to know parameter types for callVirtualMethod so generate a signature string char * pParamType = (char *) alloca(nParams+2); char * pPT = pParamType;
// we need to know type of each param so that we know whether to use // gpr or fpr to pass in parameters: // Key: I - int, long, pointer, etc means pass in gpr // B - byte value passed in gpr // S - short value passed in gpr // F - float value pass in fpr // D - double value pass in fpr // H - long long int pass in proper pairs of gpr (3,4) (5,6), etc // X - indicates end of parameter description string
case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: case typelib_TypeClass_ENUM:
*pPT++ = 'I'; break; case typelib_TypeClass_SHORT: case typelib_TypeClass_CHAR: case typelib_TypeClass_UNSIGNED_SHORT:
*pPT++ = 'S'; break; case typelib_TypeClass_BOOLEAN: case typelib_TypeClass_BYTE:
*pPT++ = 'B'; break; case typelib_TypeClass_FLOAT:
*pPT++ = 'F'; break; case typelib_TypeClass_DOUBLE:
*pPT++ = 'D';
pCppStack += sizeof(sal_Int32); // extra long break; case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER:
*pPT++ = 'H';
pCppStack += sizeof(sal_Int32); // extra long break; default: break;
}
// no longer needed
TYPELIB_DANGER_RELEASE( pParamTypeDescr );
} else// ptr to complex value | ref
{ if (! rParam.bIn) // is pure out
{ // cpp out is constructed mem, uno out is not!
uno_constructData(
*(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
pParamTypeDescr );
pTempIndices[nTempIndices] = nPos; // default constructed for cpp call // will be released at reconversion
ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
} // is in/inout elseif (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
{
uno_copyAndConvertData(
*(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
pUnoArgs[nPos], pParamTypeDescr,
pThis->getBridge()->getUno2Cpp() );
pTempIndices[nTempIndices] = nPos; // has to be reconverted // will be released at reconversion
ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
} else// direct way
{
*(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos]; // no longer needed
TYPELIB_DANGER_RELEASE( pParamTypeDescr );
} // KBH: FIXME: is this the right way to pass these
*pPT++='I';
}
pCppStack += sizeof(sal_Int32); // standard parameter length
}
// terminate the signature string
*pPT++='X';
*pPT=0;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.