summaryrefslogtreecommitdiff
path: root/bridges
diff options
context:
space:
mode:
authorFridrich Štrba <fridrich.strba@bluewin.ch>2013-06-04 14:20:53 +0200
committerFridrich Štrba <fridrich.strba@bluewin.ch>2013-06-04 14:22:03 +0200
commit5bf53717eca49920ff8f42998e4e80ec6be6e354 (patch)
treebd508f4de3d7e6f2fa5827a9bc8fb6e2b1c534df /bridges
parentd1e62483e4fb11109b2465c5411d48211e3fb18b (diff)
Some configury and non-working stubs to start to compiler for Win64 with MinGW
Change-Id: I907c3ea083e8d7f9e48fc62dd6d5b783639438cb
Diffstat (limited to 'bridges')
-rw-r--r--bridges/Library_cpp_uno.mk6
-rw-r--r--bridges/source/cpp_uno/mingw_x86-64/call.s279
-rw-r--r--bridges/source/cpp_uno/mingw_x86-64/callvirtualmethod.cxx139
-rw-r--r--bridges/source/cpp_uno/mingw_x86-64/callvirtualmethod.hxx40
-rw-r--r--bridges/source/cpp_uno/mingw_x86-64/cpp2uno.cxx510
-rw-r--r--bridges/source/cpp_uno/mingw_x86-64/dllinit.cxx45
-rw-r--r--bridges/source/cpp_uno/mingw_x86-64/except.cxx312
-rw-r--r--bridges/source/cpp_uno/mingw_x86-64/share.hxx100
-rw-r--r--bridges/source/cpp_uno/mingw_x86-64/smallstruct.cxx71
-rw-r--r--bridges/source/cpp_uno/mingw_x86-64/smallstruct.hxx29
-rw-r--r--bridges/source/cpp_uno/mingw_x86-64/uno2cpp.cxx379
11 files changed, 1910 insertions, 0 deletions
diff --git a/bridges/Library_cpp_uno.mk b/bridges/Library_cpp_uno.mk
index 8835eeb0a78a..abfc9a131115 100644
--- a/bridges/Library_cpp_uno.mk
+++ b/bridges/Library_cpp_uno.mk
@@ -133,6 +133,12 @@ bridges_SELECTED_BRIDGE := msvc_win32_x86-64
bridge_exception_objects := cpp2uno dllinit uno2cpp
bridge_noopt_objects := except
bridge_asm_objects := call
+else ifeq ($(OS)$(COM),WNTGCC)
+bridges_SELECTED_BRIDGE := mingw_x86-64
+#bridge_asm_objects := call
+bridge_noopt_objects := uno2cpp
+bridge_exception_objects := callvirtualmethod cpp2uno dllinit except smallstruct
+#bridge_exception_objects := cpp2uno dllinit except smallstruct
endif
else ifeq ($(OS)$(CPU),SOLARISI)
diff --git a/bridges/source/cpp_uno/mingw_x86-64/call.s b/bridges/source/cpp_uno/mingw_x86-64/call.s
new file mode 100644
index 000000000000..345efb870686
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_x86-64/call.s
@@ -0,0 +1,279 @@
+/*
+ * 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 .
+ */
+
+ .text
+
+.globl _privateSnippetExecutorGeneral
+_privateSnippetExecutorGeneral:
+.LFBg:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFIg0:
+ movl %esp,%ebp
+.LCFIg1:
+ subl $0x4,%esp # 32bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call _cpp_vtable_call
+ movl 16(%esp),%eax # 32bit returnValue
+ leave
+ ret
+.LFEg:
+ .long .-_privateSnippetExecutorGeneral
+
+.globl _privateSnippetExecutorVoid
+_privateSnippetExecutorVoid:
+.LFBv:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFIv0:
+ movl %esp,%ebp
+.LCFIv1:
+ pushl $0 # 32bit null pointer (returnValue not used)
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call _cpp_vtable_call
+ leave
+ ret
+.LFEv:
+ .long .-_privateSnippetExecutorVoid
+
+.globl _privateSnippetExecutorHyper
+_privateSnippetExecutorHyper:
+.LFBh:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFIh0:
+ movl %esp,%ebp
+.LCFIh1:
+ subl $0x8,%esp # 64bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call _cpp_vtable_call
+ movl 16(%esp),%eax # 64bit returnValue, lower half
+ movl 20(%esp),%edx # 64bit returnValue, upper half
+ leave
+ ret
+.LFEh:
+ .long .-_privateSnippetExecutorHyper
+
+.globl _privateSnippetExecutorFloat
+_privateSnippetExecutorFloat:
+.LFBf:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFIf0:
+ movl %esp,%ebp
+.LCFIf1:
+ subl $0x4,%esp # 32bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call _cpp_vtable_call
+ flds 16(%esp) # 32bit returnValue
+ leave
+ ret
+.LFEf:
+ .long .-_privateSnippetExecutorFloat
+
+.globl _privateSnippetExecutorDouble
+_privateSnippetExecutorDouble:
+.LFBd:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFId0:
+ movl %esp,%ebp
+.LCFId1:
+ subl $0x8,%esp # 64bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call _cpp_vtable_call
+ fldl 16(%esp) # 64bit returnValue
+ leave
+ ret
+.LFEd:
+ .long .-_privateSnippetExecutorDouble
+
+.globl _privateSnippetExecutorClass
+_privateSnippetExecutorClass:
+.LFBc:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFIc0:
+ movl %esp,%ebp
+.LCFIc1:
+ subl $0x4,%esp # 32bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call _cpp_vtable_call
+ movl 16(%esp),%eax # 32bit returnValue
+ leave
+ ret $4
+.LFEc:
+ .long .-_privateSnippetExecutorClass
+
+ .section .eh_frame,"dr"
+.Lframe1:
+ .long .LECIE1-.LSCIE1 # length
+.LSCIE1:
+ .long 0 # CIE_ID
+ .byte 1 # version
+ .string "zR" # augmentation
+ .uleb128 1 # code_alignment_factor
+ .sleb128 -4 # data_alignment_factor
+ .byte 8 # return_address_register
+ .uleb128 1 # augmentation size 1:
+ .byte 0x1B # FDE Encoding (pcrel sdata4)
+ # initial_instructions:
+ .byte 0x0C # DW_CFA_def_cfa %esp, 4
+ .uleb128 4
+ .uleb128 4
+ .byte 0x88 # DW_CFA_offset ret, 1
+ .uleb128 1
+ .align 4
+.LECIE1:
+.LSFDEg:
+ .long .LEFDEg-.LASFDEg # length
+.LASFDEg:
+ .long .LASFDEg-.Lframe1 # CIE_pointer
+ .long .LFBg-. # initial_location
+ .long .LFEg-.LFBg # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIg0-.LFBg
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIg1-.LCFIg0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEg:
+.LSFDEv:
+ .long .LEFDEv-.LASFDEv # length
+.LASFDEv:
+ .long .LASFDEv-.Lframe1 # CIE_pointer
+ .long .LFBv-. # initial_location
+ .long .LFEv-.LFBv # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIv0-.LFBv
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIv1-.LCFIv0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEv:
+.LSFDEh:
+ .long .LEFDEh-.LASFDEh # length
+.LASFDEh:
+ .long .LASFDEh-.Lframe1 # CIE_pointer
+ .long .LFBh-. # initial_location
+ .long .LFEh-.LFBh # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIh0-.LFBh
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIh1-.LCFIh0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEh:
+.LSFDEf:
+ .long .LEFDEf-.LASFDEf # length
+.LASFDEf:
+ .long .LASFDEf-.Lframe1 # CIE_pointer
+ .long .LFBf-. # initial_location
+ .long .LFEf-.LFBf # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIf0-.LFBf
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIf1-.LCFIf0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEf:
+.LSFDEd:
+ .long .LEFDEd-.LASFDEd # length
+.LASFDEd:
+ .long .LASFDEd-.Lframe1 # CIE_pointer
+ .long .LFBd-. # initial_location
+ .long .LFEd-.LFBd # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFId0-.LFBd
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFId1-.LCFId0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEd:
+.LSFDEc:
+ .long .LEFDEc-.LASFDEc # length
+.LASFDEc:
+ .long .LASFDEc-.Lframe1 # CIE_pointer
+ .long .LFBc-. # initial_location
+ .long .LFEc-.LFBc # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIc0-.LFBc
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIc1-.LCFIc0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEc:
diff --git a/bridges/source/cpp_uno/mingw_x86-64/callvirtualmethod.cxx b/bridges/source/cpp_uno/mingw_x86-64/callvirtualmethod.cxx
new file mode 100644
index 000000000000..c1bb9b6e07ad
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_x86-64/callvirtualmethod.cxx
@@ -0,0 +1,139 @@
+/* -*- 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 .
+ */
+
+#include "sal/config.h"
+
+#include "cppu/macros.hxx"
+#include "osl/diagnose.h"
+#include "sal/types.h"
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+
+#include "callvirtualmethod.hxx"
+#include "share.hxx"
+#include "smallstruct.hxx"
+
+// For some reason, callVirtualMethod needs to be in a source file of its own,
+// so that stack unwinding upon a thrown exception from within the asm block
+// call works, at least with GCC 4.7.0 and --enable-dbgutil.
+
+// The call instruction within the asm section of callVirtualMethod may throw
+// exceptions. So that the compiler handles this correctly, it is important
+// that (a) callVirtualMethod might call dummy_can_throw_anything (although this
+// never happens at runtime), which in turn can throw exceptions, and (b)
+// callVirtualMethod is not inlined at its call site (so that any exceptions are
+// caught which are thrown from the instruction calling callVirtualMethod). [It
+// is unclear how much of this comment is still relevent -- see the above
+// comment.]
+void CPPU_CURRENT_NAMESPACE::callVirtualMethod(
+ void * pAdjustedThisPtr, sal_Int32 nVtableIndex, void * pRegisterReturn,
+ typelib_TypeDescription const * returnType, sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs)
+{
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ OSL_ENSURE( pStackLongs && pAdjustedThisPtr, "### null ptr!" );
+ OSL_ENSURE( (sizeof(void *) == 4) && (sizeof(sal_Int32) == 4), "### unexpected size of int!" );
+ OSL_ENSURE( nStackLongs && pStackLongs, "### no stack in callVirtualMethod !" );
+
+ // never called
+ if (! pAdjustedThisPtr) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+ volatile long edx = 0, eax = 0; // for register returns
+ void * stackptr;
+ asm volatile (
+ "mov %%esp, %6\n\t"
+ // copy values
+ "mov %0, %%eax\n\t"
+ "mov %%eax, %%edx\n\t"
+ "dec %%edx\n\t"
+ "shl $2, %%edx\n\t"
+ "add %1, %%edx\n"
+ "Lcopy:\n\t"
+ "pushl 0(%%edx)\n\t"
+ "sub $4, %%edx\n\t"
+ "dec %%eax\n\t"
+ "jne Lcopy\n\t"
+ // do the actual call
+ "mov %2, %%edx\n\t"
+ "mov 0(%%edx), %%edx\n\t"
+ "mov %3, %%eax\n\t"
+ "shl $2, %%eax\n\t"
+ "add %%eax, %%edx\n\t"
+ "mov 0(%%edx), %%edx\n\t"
+ "call *%%edx\n\t"
+ // save return registers
+ "mov %%eax, %4\n\t"
+ "mov %%edx, %5\n\t"
+ // cleanup stack
+ "mov %6, %%esp\n\t"
+ :
+ : "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr),
+ "m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr)
+ : "eax", "ecx", "edx" );
+ switch( returnType->eTypeClass )
+ {
+ case typelib_TypeClass_VOID:
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = edx;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = eax;
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = eax;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = eax;
+ break;
+ case typelib_TypeClass_FLOAT:
+ asm ( "fstps %0" : : "m"(*(char *)pRegisterReturn) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) );
+ break;
+ case typelib_TypeClass_STRUCT:
+ if (bridges::cpp_uno::shared::isSmallStruct(returnType)) {
+ if (returnType->nSize <= 1) {
+ *(unsigned char*)pRegisterReturn = eax;
+ }
+ else if (returnType->nSize <= 2) {
+ *(unsigned short*)pRegisterReturn = eax;
+ }
+ else if (returnType->nSize <= 8) {
+ ((long*)pRegisterReturn)[0] = eax;
+ if (returnType->nSize > 4) {
+ ((long*)pRegisterReturn)[1] = edx;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/mingw_x86-64/callvirtualmethod.hxx b/bridges/source/cpp_uno/mingw_x86-64/callvirtualmethod.hxx
new file mode 100644
index 000000000000..76df8d96421c
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_x86-64/callvirtualmethod.hxx
@@ -0,0 +1,40 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_MINGW_INTEL_CALLVIRTUALMETHOD_HXX
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_MINGW_INTEL_CALLVIRTUALMETHOD_HXX
+
+#include "sal/config.h"
+
+#include "cppu/macros.hxx"
+#include "sal/types.h"
+#include "typelib/typedescription.h"
+
+namespace CPPU_CURRENT_NAMESPACE {
+
+void callVirtualMethod(
+ void * pAdjustedThisPtr, sal_Int32 nVtableIndex, void * pRegisterReturn,
+ typelib_TypeDescription const * returnType, sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs);
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/mingw_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/mingw_x86-64/cpp2uno.cxx
new file mode 100644
index 000000000000..e87512a571fc
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_x86-64/cpp2uno.cxx
@@ -0,0 +1,510 @@
+/* -*- 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 .
+ */
+
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+#include <sal/alloca.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+#include "smallstruct.hxx"
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+void 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 ** pCallStack,
+ void * pReturnValue )
+{
+ // pCallStack: ret, [return ptr], this, params
+ char * pCppStack = (char *)(pCallStack +1);
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pReturnValue; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ if (!bridges::cpp_uno::shared::isSmallStruct(pReturnTypeDescr)) {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+ }
+ else {
+ pCppReturn = pReturnValue;
+ }
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // 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_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ // value
+ {
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ default:
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ pCppArgs[nPos] = *(void **)pCppStack;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occurred...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException(
+ &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ }
+ else // else no exception occurred...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ if (pReturnValue != pCppReturn)
+ // complex return ptr is set to eax
+ *static_cast< void ** >(pReturnValue) = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+ }
+}
+
+
+//==================================================================================================
+extern "C" void cpp_vtable_call(
+ int nFunctionIndex, int nVtableOffset, void** pCallStack,
+ void * pReturnValue )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: ret adr, [ret *], this, params
+ void * pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = pCallStack[2];
+ }
+ else
+ {
+ pThis = pCallStack[1];
+ }
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ OUString( "illegal vtable index!" ),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pReturnValue );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pReturnValue );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pCallStack[1] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *static_cast< void ** >(pReturnValue) = pCallStack[1];
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pReturnValue );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ OUString( "no member description found!" ),
+ (XInterface *)pThis );
+ }
+ }
+}
+
+//==================================================================================================
+extern "C" void privateSnippetExecutorGeneral();
+extern "C" void privateSnippetExecutorVoid();
+extern "C" void privateSnippetExecutorHyper();
+extern "C" void privateSnippetExecutorFloat();
+extern "C" void privateSnippetExecutorDouble();
+extern "C" void privateSnippetExecutorClass();
+extern "C" typedef void (*PrivateSnippetExecutor)();
+
+int const codeSnippetSize = 16;
+
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ typelib_TypeDescriptionReference * returnType)
+{
+ typelib_TypeDescription * returnTypeDescr = 0;
+ if (returnType)
+ TYPELIB_DANGER_GET( &returnTypeDescr, returnType );
+
+ typelib_TypeClass returnTypeClass = returnType ? returnType->eTypeClass : typelib_TypeClass_VOID;
+ if (!bridges::cpp_uno::shared::isSimpleType(returnTypeClass) &&
+ !bridges::cpp_uno::shared::isSmallStruct(returnTypeDescr)) {
+ functionIndex |= 0x80000000;
+ }
+ PrivateSnippetExecutor exec = privateSnippetExecutorGeneral;
+ switch (returnTypeClass) {
+ case typelib_TypeClass_VOID:
+ exec = privateSnippetExecutorVoid;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ exec = privateSnippetExecutorHyper;
+ break;
+ case typelib_TypeClass_FLOAT:
+ exec = privateSnippetExecutorFloat;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ exec = privateSnippetExecutorDouble;
+ break;
+ case typelib_TypeClass_STRUCT:
+ if (bridges::cpp_uno::shared::isSmallStruct(returnTypeDescr)) {
+ if (returnType->pType->nSize <= 4) {
+ exec = privateSnippetExecutorGeneral;
+ }
+ else if (returnType->pType->nSize <= 8) {
+ exec = privateSnippetExecutorHyper;
+ }
+ }
+ else {
+ exec = privateSnippetExecutorClass;
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ exec = privateSnippetExecutorClass;
+ break;
+ default:
+ exec = privateSnippetExecutorGeneral;
+ break;
+ }
+ if (returnType)
+ TYPELIB_DANGER_RELEASE( returnTypeDescr );
+ unsigned char * p = code;
+ OSL_ASSERT(sizeof (sal_Int32) == 4);
+ // mov function_index, %eax:
+ *p++ = 0xB8;
+ *reinterpret_cast< sal_Int32 * >(p) = functionIndex;
+ p += sizeof (sal_Int32);
+ // mov vtable_offset, %edx:
+ *p++ = 0xBA;
+ *reinterpret_cast< sal_Int32 * >(p) = vtableOffset;
+ p += sizeof (sal_Int32);
+ // jmp privateSnippetExecutor:
+ *p++ = 0xE9;
+ *reinterpret_cast< sal_Int32 * >(p)
+ = ((unsigned char *) exec) - p - sizeof (sal_Int32);
+ p += sizeof (sal_Int32);
+ OSL_ASSERT(p - code <= codeSnippetSize);
+ return code + codeSnippetSize;
+}
+
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef);
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ NULL);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef);
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *, unsigned char const *)
+{}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/mingw_x86-64/dllinit.cxx b/bridges/source/cpp_uno/mingw_x86-64/dllinit.cxx
new file mode 100644
index 000000000000..0b004d7de92e
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_x86-64/dllinit.cxx
@@ -0,0 +1,45 @@
+/* -*- 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 .
+ */
+
+#include <windows.h>
+
+
+void dso_init(void);
+void dso_exit(void);
+
+
+extern "C" BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpvReserved)
+{
+ switch(dwReason) {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hModule);
+
+ dso_init();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ if (!lpvReserved)
+ dso_exit();
+ break;
+ }
+
+ return TRUE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/mingw_x86-64/except.cxx b/bridges/source/cpp_uno/mingw_x86-64/except.cxx
new file mode 100644
index 000000000000..ae82fbb13483
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_x86-64/except.cxx
@@ -0,0 +1,312 @@
+/* -*- 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 .
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+
+#include <cxxabi.h>
+#ifndef _GLIBCXX_CDTOR_CALLABI // new in GCC 4.7 cxxabi.h
+#define _GLIBCXX_CDTOR_CALLABI
+#endif
+
+#include <boost/unordered_map.hpp>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW(())
+{
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef boost::unordered_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+public:
+ RTTI() SAL_THROW(());
+ ~RTTI() SAL_THROW(());
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW(());
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW(())
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW(())
+{
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW(())
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iRttiFind( m_rttis.find( unoName ) );
+ if (iRttiFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( "__ZTIN" );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
+ if (iFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with __ZTI
+ char const * rttiName = symName.getStr() +5;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind->second;
+ }
+ }
+ else
+ {
+ rtti = iRttiFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+extern "C" {
+static void _GLIBCXX_CDTOR_CALLABI deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occurred: %s\n", cstr.getStr() );
+#endif
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ {
+ throw RuntimeException(
+ OUString("cannot get typedescription for type ") +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ {
+ throw RuntimeException(
+ OUString("no rtti for type ") +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+{
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString("no exception header!"),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_FAIL( cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occurred: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString("exception type not found: ") + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_FAIL( cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/mingw_x86-64/share.hxx b/bridges/source/cpp_uno/mingw_x86-64/share.hxx
new file mode 100644
index 000000000000..3ddc011dbbea
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_x86-64/share.hxx
@@ -0,0 +1,100 @@
+/* -*- 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 .
+ */
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+#include "cppu/macros.hxx"
+#include "uno/any2.h"
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * );
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+
+}
+
+extern "C" CPPU_CURRENT_NAMESPACE::__cxa_eh_globals *__cxa_get_globals () throw();
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+// The following are in cxxabi.h since GCC 4.7 (they are wrapped in
+// CPPU_CURRENT_NAMESPACE here as different GCC versions have slightly different
+// declarations for them, e.g., with or without throw() specification, so would
+// complain about redeclarations of these somewhat implicitly declared
+// functions):
+#if __GNUC__ == 4 && __GNUC_MINOR__ <= 6
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, void *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+#endif
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/mingw_x86-64/smallstruct.cxx b/bridges/source/cpp_uno/mingw_x86-64/smallstruct.cxx
new file mode 100644
index 000000000000..2f617e96cd37
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_x86-64/smallstruct.cxx
@@ -0,0 +1,71 @@
+/* -*- 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 .
+ */
+
+
+#include "bridges/cpp_uno/shared/types.hxx"
+
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+namespace {
+bool isSimpleStruct(typelib_TypeDescription const * type) {
+ switch (type->eTypeClass) {
+ case typelib_TypeClass_STRUCT:
+ {
+ typelib_CompoundTypeDescription const * p
+ = reinterpret_cast< typelib_CompoundTypeDescription const * >(
+ type);
+ for (sal_Int32 i = 0; i < p->nMembers; ++i) {
+ switch (p->ppTypeRefs[i]->eTypeClass) {
+ case typelib_TypeClass_STRUCT:
+ {
+ typelib_TypeDescription * t = 0;
+ TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
+ bool b = isSimpleStruct(t);
+ TYPELIB_DANGER_RELEASE(t);
+ if (!b) {
+ return false;
+ }
+ }
+ break;
+
+ default:
+ if (!isSimpleType(p->ppTypeRefs[i]->eTypeClass))
+ return false;
+ break;
+ }
+ }
+ }
+ return true;
+
+ default:
+ return false;
+ }
+}
+}
+
+bool isSmallStruct(typelib_TypeDescription const * type) {
+ return (type->nSize <= 8 && isSimpleStruct(type));
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/mingw_x86-64/smallstruct.hxx b/bridges/source/cpp_uno/mingw_x86-64/smallstruct.hxx
new file mode 100644
index 000000000000..68bab382732f
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_x86-64/smallstruct.hxx
@@ -0,0 +1,29 @@
+/* -*- 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 .
+ */
+
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+bool isSmallStruct(typelib_TypeDescription const * type);
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/mingw_x86-64/uno2cpp.cxx b/bridges/source/cpp_uno/mingw_x86-64/uno2cpp.cxx
new file mode 100644
index 000000000000..60a57a4b5a3b
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_x86-64/uno2cpp.cxx
@@ -0,0 +1,379 @@
+/* -*- 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 .
+ */
+
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <sal/alloca.h>
+
+#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 "callvirtualmethod.hxx"
+#include "share.hxx"
+#include "smallstruct.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack =
+#ifdef BROKEN_ALLOCA
+ (char *)malloc( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+#else
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+#endif
+ char * pCppStackStart = pCppStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn
+ = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+#ifdef BROKEN_ALLOCA
+ ? malloc( pReturnTypeDescr->nSize )
+#else
+ ? alloca( pReturnTypeDescr->nSize )
+#endif
+ : pUnoReturn); // direct way
+ if (!bridges::cpp_uno::shared::isSmallStruct(pReturnTypeDescr)) {
+ *(void **)pCppStack = pCppReturn;
+ pCppStack += sizeof(void *);
+ }
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+#ifdef BROKEN_ALLOCA
+ void ** pCppArgs = (void **)malloc( 3 * sizeof(void *) * nParams );
+#else
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+#endif
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ 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(
+#ifdef BROKEN_ALLOCA
+ *(void **)pCppStack = pCppArgs[nPos] = malloc( pParamTypeDescr->nSize ),
+#else
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+#endif
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+#ifdef BROKEN_ALLOCA
+ *(void **)pCppStack = pCppArgs[nPos] = malloc( pParamTypeDescr->nSize ),
+#else
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+#endif
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ CPPU_CURRENT_NAMESPACE::callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occurred...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+#ifdef BROKEN_ALLOCA
+ free( pCppArgs[nIndex] );
+#endif
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( __cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+#ifdef BROKEN_ALLOCA
+ free( pCppArgs[nIndex] );
+#endif
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+#ifdef BROKEN_ALLOCA
+ free( pCppReturn );
+#endif
+ }
+#ifdef BROKEN_ALLOCA
+ free( pCppStackStart );
+#endif
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName("void");
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; // get, then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString("illegal member type description!"),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */