diff options
author | Ivo Hinkelmann <ihi@openoffice.org> | 2008-04-24 15:27:05 +0000 |
---|---|---|
committer | Ivo Hinkelmann <ihi@openoffice.org> | 2008-04-24 15:27:05 +0000 |
commit | 22fb957e1e4dbe5f9a359b54892dd47e9c68c5a3 (patch) | |
tree | 96ebf7d6ec4da9206612db2e15ab500fe0182e83 | |
parent | 59855767038217496db09226008de6f0fc143cee (diff) |
INTEGRATION: CWS sb85 (1.1.2); FILE ADDED
2008/03/13 13:03:15 sb 1.1.2.2: #i86117# restrict exception handling to UNO exceptions
2008/03/12 10:53:49 sb 1.1.2.1: #i86117# Solaris SPARC64 bridge
-rw-r--r-- | bridges/source/cpp_uno/cc5_solaris_sparc64/uno2cpp.cxx | 517 |
1 files changed, 517 insertions, 0 deletions
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/uno2cpp.cxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/uno2cpp.cxx new file mode 100644 index 000000000000..fa32a0a41eb3 --- /dev/null +++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/uno2cpp.cxx @@ -0,0 +1,517 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: uno2cpp.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: ihi $ $Date: 2008-04-24 16:27:05 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2008 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "precompiled_bridges.hxx" +#include "sal/config.h" + +#include <algorithm> +#include <cstddef> +#include <cstring> + +#include "bridges/cpp_uno/shared/bridge.hxx" +#include "bridges/cpp_uno/shared/types.hxx" +#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx" +#include "bridges/cpp_uno/shared/vtables.hxx" +#include "com/sun/star/uno/Exception.hpp" +#include "com/sun/star/uno/genfunc.hxx" +#include "osl/diagnose.h" +#include "rtl/ustring.h" +#include "rtl/ustring.hxx" +#include "sal/alloca.h" +#include "sal/types.h" +#include "typelib/typeclass.h" +#include "typelib/typedescription.h" +#include "uno/any2.h" +#include "uno/data.h" + +#include "callvirtualmethod.hxx" +#include "exceptions.hxx" +#include "fp.hxx" +#include "isdirectreturntype.hxx" + +namespace { + +namespace css = com::sun::star; + +void storeFpRegsToStruct(typelib_TypeDescription * type, void * data) { + for (typelib_CompoundTypeDescription * t = + reinterpret_cast< typelib_CompoundTypeDescription * >(type); + t != NULL; t = t->pBaseTypeDescription) + { + for (sal_Int32 i = 0; i < t->nMembers; ++i) { + switch (t->ppTypeRefs[i]->eTypeClass) { + case typelib_TypeClass_FLOAT: + switch (t->pMemberOffsets[i]) { + case 0: + fp_storef0(reinterpret_cast< float * >(data)); + break; + case 4: + fp_storef1(reinterpret_cast< float * >(data) + 1); + break; + case 8: + fp_storef2(reinterpret_cast< float * >(data) + 2); + break; + case 12: + fp_storef3(reinterpret_cast< float * >(data) + 3); + break; + case 16: + fp_storef4(reinterpret_cast< float * >(data) + 4); + break; + case 20: + fp_storef5(reinterpret_cast< float * >(data) + 5); + break; + case 24: + fp_storef6(reinterpret_cast< float * >(data) + 6); + break; + case 28: + fp_storef7(reinterpret_cast< float * >(data) + 7); + break; + default: + OSL_ASSERT(false); + break; + } + break; + case typelib_TypeClass_DOUBLE: + switch (t->pMemberOffsets[i]) { + case 0: + fp_stored0(reinterpret_cast< double * >(data)); + break; + case 8: + fp_stored2(reinterpret_cast< double * >(data) + 1); + break; + case 16: + fp_stored4(reinterpret_cast< double * >(data) + 2); + break; + case 24: + fp_stored6(reinterpret_cast< double * >(data) + 3); + break; + default: + OSL_ASSERT(false); + break; + } + break; + case typelib_TypeClass_STRUCT: + { + typelib_TypeDescription * td = NULL; + TYPELIB_DANGER_GET(&td, t->ppTypeRefs[i]); + storeFpRegsToStruct(td, data); + TYPELIB_DANGER_RELEASE(td); + break; + } + } + } + } +} + +void call( + bridges::cpp_uno::shared::UnoInterfaceProxy * proxy, + bridges::cpp_uno::shared::VtableSlot slot, + typelib_TypeDescriptionReference * returnType, sal_Int32 count, + typelib_MethodParameter * parameters, void * returnValue, void ** arguments, + uno_Any ** exception) +{ + bool directRet = bridges::cpp_uno::cc5_solaris_sparc64::isDirectReturnType( + returnType); + long * stack = static_cast< long * >( + alloca( + std::max< sal_Int32 >(count + (directRet ? 1 : 2), 4) * + sizeof (long))); + sal_Int32 sp = 0; + typelib_TypeDescription * rtd = NULL; + TYPELIB_DANGER_GET(&rtd, returnType); + bool retconv = bridges::cpp_uno::shared::relatesToInterfaceType(rtd); + OSL_ASSERT(!(directRet && retconv)); + void * ret; + if (!directRet) { + ret = retconv ? alloca(rtd->nSize) : returnValue; + stack[sp++] = reinterpret_cast< long >(ret); + } + unsigned long ** thisPtr = reinterpret_cast< unsigned long ** >( + proxy->getCppI()) + slot.offset; + stack[sp++] = reinterpret_cast< long >(thisPtr); + void ** cppArgs = static_cast< void ** >(alloca(count * sizeof (void *))); + typelib_TypeDescription ** ptds = + static_cast< typelib_TypeDescription ** >( + alloca(count * sizeof (typelib_TypeDescription *))); + for (sal_Int32 i = 0; i < count; ++i) { + if (!parameters[i].bOut && + bridges::cpp_uno::shared::isSimpleType(parameters[i].pTypeRef)) + { + cppArgs[i] = NULL; + switch (parameters[i].pTypeRef->eTypeClass) { + case typelib_TypeClass_BOOLEAN: + stack[sp] = *static_cast< sal_Bool * >(arguments[i]); + break; + case typelib_TypeClass_BYTE: + stack[sp] = *static_cast< sal_Int8 * >(arguments[i]); + break; + case typelib_TypeClass_SHORT: + stack[sp] = *static_cast< sal_Int16 * >(arguments[i]); + break; + case typelib_TypeClass_UNSIGNED_SHORT: + stack[sp] = *static_cast< sal_uInt16 * >(arguments[i]); + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_ENUM: + stack[sp] = *static_cast< sal_Int32 * >(arguments[i]); + break; + case typelib_TypeClass_UNSIGNED_LONG: + stack[sp] = *static_cast< sal_uInt32 * >(arguments[i]); + break; + case typelib_TypeClass_HYPER: + stack[sp] = *static_cast< sal_Int64 * >(arguments[i]); + break; + case typelib_TypeClass_UNSIGNED_HYPER: + stack[sp] = *static_cast< sal_uInt64 * >(arguments[i]); + break; + case typelib_TypeClass_FLOAT: + { + float * f = static_cast< float * >(arguments[i]); + switch (sp) { + case 1: + fp_loadf3(f); + break; + case 2: + fp_loadf5(f); + break; + case 3: + fp_loadf7(f); + break; + case 4: + fp_loadf9(f); + break; + case 5: + fp_loadf11(f); + break; + case 6: + fp_loadf13(f); + break; + case 7: + fp_loadf15(f); + break; + case 8: + fp_loadf17(f); + break; + case 9: + fp_loadf19(f); + break; + case 10: + fp_loadf21(f); + break; + case 11: + fp_loadf23(f); + break; + case 12: + fp_loadf25(f); + break; + case 13: + fp_loadf27(f); + break; + case 14: + fp_loadf29(f); + break; + case 15: + fp_loadf31(f); + break; + default: + reinterpret_cast< float * >(stack + sp)[1] = *f; + break; + } + break; + } + case typelib_TypeClass_DOUBLE: + { + double * d = static_cast< double * >(arguments[i]); + switch (sp) { + case 1: + fp_loadd2(d); + break; + case 2: + fp_loadd4(d); + break; + case 3: + fp_loadd6(d); + break; + case 4: + fp_loadd8(d); + break; + case 5: + fp_loadd10(d); + break; + case 6: + fp_loadd12(d); + break; + case 7: + fp_loadd14(d); + break; + case 8: + fp_loadd16(d); + break; + case 9: + fp_loadd18(d); + break; + case 10: + fp_loadd20(d); + break; + case 11: + fp_loadd22(d); + break; + case 12: + fp_loadd24(d); + break; + case 13: + fp_loadd26(d); + break; + case 14: + fp_loadd28(d); + break; + case 15: + fp_loadd30(d); + break; + default: + *reinterpret_cast< double * >(stack + sp) = *d; + break; + } + break; + } + case typelib_TypeClass_CHAR: + stack[sp] = *static_cast< sal_Unicode * >(arguments[i]); + break; + default: + OSL_ASSERT(false); + break; + } + } else { + typelib_TypeDescription * ptd = NULL; + TYPELIB_DANGER_GET(&ptd, parameters[i].pTypeRef); + if (!parameters[i].bIn) { + cppArgs[i] = alloca(ptd->nSize); + uno_constructData(cppArgs[i], ptd); + ptds[i] = ptd; + *reinterpret_cast< void ** >(stack + sp) = cppArgs[i]; + } else if (bridges::cpp_uno::shared::relatesToInterfaceType(ptd)) { + cppArgs[i] = alloca(ptd->nSize); + uno_copyAndConvertData( + cppArgs[i], arguments[i], ptd, + proxy->getBridge()->getUno2Cpp()); + ptds[i] = ptd; + *reinterpret_cast< void ** >(stack + sp) = cppArgs[i]; + } else { + cppArgs[i] = NULL; + *reinterpret_cast< void ** >(stack + sp) = arguments[i]; + TYPELIB_DANGER_RELEASE(ptd); + } + } + ++sp; + } + try { + callVirtualMethod( + (*thisPtr)[slot.index + 2], stack, + std::max< sal_Int32 >(sp - 6, 0) * sizeof (long)); + } catch (css::uno::Exception &) { + void * exc = __Crun::ex_get(); + char const * name = __Cimpl::ex_name(); + bridges::cpp_uno::cc5_solaris_sparc64::fillUnoException( + exc, name, *exception, proxy->getBridge()->getCpp2Uno()); + for (sal_Int32 i = 0; i < count; ++i) { + if (cppArgs[i] != NULL) { + uno_destructData( + cppArgs[i], ptds[i], + reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release)); + TYPELIB_DANGER_RELEASE(ptds[i]); + } + } + TYPELIB_DANGER_RELEASE(rtd); + return; + } + *exception = NULL; + for (sal_Int32 i = 0; i < count; ++i) { + if (cppArgs[i] != NULL) { + if (parameters[i].bOut) { + if (parameters[i].bIn) { + uno_destructData(arguments[i], ptds[i], NULL); + } + uno_copyAndConvertData( + arguments[i], cppArgs[i], ptds[i], + proxy->getBridge()->getCpp2Uno()); + } + uno_destructData( + cppArgs[i], ptds[i], + reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release)); + TYPELIB_DANGER_RELEASE(ptds[i]); + } + } + if (directRet) { + switch (rtd->eTypeClass) { + case typelib_TypeClass_FLOAT: + fp_storef0(reinterpret_cast< float * >(returnValue)); + break; + case typelib_TypeClass_DOUBLE: + fp_stored0(reinterpret_cast< double * >(returnValue)); + break; + case typelib_TypeClass_STRUCT: + storeFpRegsToStruct(rtd, stack); + // fall through + case typelib_TypeClass_ANY: + std::memcpy(returnValue, stack, rtd->nSize); + break; + default: + OSL_ASSERT(rtd->nSize <= 8); + std::memcpy( + returnValue, + reinterpret_cast< char * >(stack) + (8 - rtd->nSize), + rtd->nSize); + break; + } + } else if (retconv) { + uno_copyAndConvertData( + returnValue, ret, rtd, proxy->getBridge()->getCpp2Uno()); + uno_destructData( + ret, rtd, + reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release)); + } + TYPELIB_DANGER_RELEASE(rtd); +} + +} + +namespace bridges { namespace cpp_uno { namespace shared { + +void unoInterfaceProxyDispatch( + uno_Interface * pUnoI, typelib_TypeDescription const * pMemberDescr, + void * pReturn, void * pArgs[], uno_Any ** ppException) +{ + bridges::cpp_uno::shared::UnoInterfaceProxy * proxy = + static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI); + switch (pMemberDescr->eTypeClass) { + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + { + VtableSlot slot( + getVtableSlot( + reinterpret_cast< + typelib_InterfaceAttributeTypeDescription const * >( + pMemberDescr))); + if (pReturn != NULL) { + // Getter: + call( + proxy, slot, + (reinterpret_cast< + typelib_InterfaceAttributeTypeDescription const * >( + pMemberDescr)->pAttributeTypeRef), + 0, NULL, pReturn, pArgs, ppException); + } else { + // Setter: + typelib_MethodParameter param = { + NULL, + (reinterpret_cast< + typelib_InterfaceAttributeTypeDescription const * >( + pMemberDescr)->pAttributeTypeRef), + true, false }; + typelib_TypeDescriptionReference * rtd = NULL; + typelib_typedescriptionreference_new( + &rtd, typelib_TypeClass_VOID, + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("void")).pData); + slot.index += 1; + call(proxy, slot, rtd, 1, ¶m, pReturn, pArgs, ppException); + typelib_typedescriptionreference_release(rtd); + } + break; + } + case typelib_TypeClass_INTERFACE_METHOD: + { + VtableSlot slot( + getVtableSlot( + reinterpret_cast< + typelib_InterfaceMethodTypeDescription const * >( + pMemberDescr))); + switch (slot.index) { + case 1: + pUnoI->acquire(pUnoI); + *ppException = NULL; + break; + case 2: + pUnoI->release(pUnoI); + *ppException = NULL; + break; + case 0: + { + typelib_TypeDescription * td = NULL; + TYPELIB_DANGER_GET( + &td, + reinterpret_cast< css::uno::Type * >( + pArgs[0])->getTypeLibType()); + if (td != NULL) { + uno_Interface * ifc = NULL; + proxy->pBridge->getUnoEnv()->getRegisteredInterface( + proxy->pBridge->getUnoEnv(), + reinterpret_cast< void ** >(&ifc), + proxy->oid.pData, + (reinterpret_cast< + typelib_InterfaceTypeDescription * >(td))); + if (ifc != NULL) { + uno_any_construct( + reinterpret_cast< uno_Any * >(pReturn), + &ifc, td, NULL); + ifc->release(ifc); + TYPELIB_DANGER_RELEASE(td); + *ppException = NULL; + break; + } + TYPELIB_DANGER_RELEASE(td); + } + } // fall through + default: + call( + proxy, slot, + (reinterpret_cast< + typelib_InterfaceMethodTypeDescription const * >( + pMemberDescr)->pReturnTypeRef), + (reinterpret_cast< + typelib_InterfaceMethodTypeDescription const * >( + pMemberDescr)->nParams), + (reinterpret_cast< + typelib_InterfaceMethodTypeDescription const * >( + pMemberDescr)->pParams), + pReturn, pArgs, ppException); + } + break; + } + default: + OSL_ASSERT(false); + break; + } +} + +} } } |