summaryrefslogtreecommitdiff
path: root/bridges/source
diff options
context:
space:
mode:
Diffstat (limited to 'bridges/source')
-rw-r--r--bridges/source/bridge_exports.map8
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/call.s248
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/cc50_solaris_intel.hxx76
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/cpp2uno.cxx530
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/except.cxx452
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/hash.cxx266
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/makefile.mk79
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/uno2cpp.cxx421
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/call.s199
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/cc50_solaris_sparc.hxx90
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/cpp2uno.cxx533
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx448
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/flushcode.hxx51
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/hash.cxx267
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/makefile.mk84
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx399
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.hxx40
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.s63
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/cpp2uno.cxx615
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.cxx463
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.hxx76
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/flushcode.hxx52
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/fp.hxx117
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/fp.s606
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.cxx85
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.hxx45
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/makefile.mk65
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/uno2cpp.cxx513
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.hxx39
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.s55
-rw-r--r--bridges/source/cpp_uno/gcc3_freebsd_intel/call.s268
-rw-r--r--bridges/source/cpp_uno/gcc3_freebsd_intel/cpp2uno.cxx493
-rw-r--r--bridges/source/cpp_uno/gcc3_freebsd_intel/except.cxx341
-rw-r--r--bridges/source/cpp_uno/gcc3_freebsd_intel/makefile.mk88
-rw-r--r--bridges/source/cpp_uno/gcc3_freebsd_intel/share.hxx93
-rw-r--r--bridges/source/cpp_uno/gcc3_freebsd_intel/uno2cpp.cxx447
-rw-r--r--bridges/source/cpp_uno/gcc3_freebsd_x86-64/abi.cxx806
-rw-r--r--bridges/source/cpp_uno/gcc3_freebsd_x86-64/abi.hxx70
-rw-r--r--bridges/source/cpp_uno/gcc3_freebsd_x86-64/call.s93
-rw-r--r--bridges/source/cpp_uno/gcc3_freebsd_x86-64/cpp2uno.cxx544
-rw-r--r--bridges/source/cpp_uno/gcc3_freebsd_x86-64/except.cxx341
-rw-r--r--bridges/source/cpp_uno/gcc3_freebsd_x86-64/makefile.mk84
-rw-r--r--bridges/source/cpp_uno/gcc3_freebsd_x86-64/share.hxx93
-rw-r--r--bridges/source/cpp_uno/gcc3_freebsd_x86-64/uno2cpp.cxx561
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_arm/armhelper.s22
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_arm/cpp2uno.cxx535
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_arm/except.cxx344
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_arm/makefile.mk88
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_arm/share.hxx96
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_arm/uno2cpp.cxx633
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_hppa/call.cxx145
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_hppa/cpp2uno.cxx728
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_hppa/except.cxx337
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_hppa/makefile.mk86
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_hppa/share.hxx102
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_hppa/uno2cpp.cxx524
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_ia64/call.s20
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_ia64/cpp2uno.cxx687
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_ia64/except.cxx290
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_ia64/makefile.mk87
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_ia64/share.hxx133
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_ia64/uno2cpp.cxx693
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/call.s268
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx492
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/except.cxx333
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk88
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/share.hxx93
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx447
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_m68k/cpp2uno.cxx539
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_m68k/except.cxx337
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_m68k/makefile.mk84
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_m68k/share.hxx94
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_m68k/uno2cpp.cxx496
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_mips/cpp2uno.cxx806
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_mips/except.cxx328
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_mips/makefile.mk85
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_mips/share.hxx94
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_mips/uno2cpp.cxx600
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx737
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc/except.cxx290
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc/makefile.mk84
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc/share.hxx94
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc/uno2cpp.cxx637
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx725
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc64/except.cxx290
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc64/makefile.mk83
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx99
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx603
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx698
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390/except.cxx290
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390/makefile.mk81
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390/share.hxx95
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390/uno2cpp.cxx638
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390x/cpp2uno.cxx655
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390x/except.cxx291
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390x/makefile.mk81
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390x/share.hxx102
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390x/uno2cpp.cxx541
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_sparc/call.s10
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx578
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_sparc/except.cxx331
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_sparc/makefile.mk85
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_sparc/share.hxx100
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_sparc/uno2cpp.cxx603
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx806
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx70
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/call.s96
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx525
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx333
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/makefile.mk84
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx93
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx574
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_intel/call.s331
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_intel/cpp2uno.cxx522
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_intel/except.cxx332
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_intel/makefile.mk83
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_intel/share.hxx95
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_intel/uno2cpp.cxx498
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_powerpc/cpp2uno.cxx733
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_powerpc/except.cxx289
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_powerpc/makefile.mk82
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_powerpc/share.hxx94
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_powerpc/uno2cpp.cxx637
-rw-r--r--bridges/source/cpp_uno/gcc3_netbsd_intel/cpp2uno.cxx566
-rw-r--r--bridges/source/cpp_uno/gcc3_netbsd_intel/except.cxx334
-rw-r--r--bridges/source/cpp_uno/gcc3_netbsd_intel/makefile.mk79
-rw-r--r--bridges/source/cpp_uno/gcc3_netbsd_intel/share.hxx89
-rw-r--r--bridges/source/cpp_uno/gcc3_netbsd_intel/uno2cpp.cxx436
-rw-r--r--bridges/source/cpp_uno/gcc3_os2_intel/cpp2uno.cxx528
-rw-r--r--bridges/source/cpp_uno/gcc3_os2_intel/defs/gcc3_uno.def915
-rw-r--r--bridges/source/cpp_uno/gcc3_os2_intel/except.cxx352
-rw-r--r--bridges/source/cpp_uno/gcc3_os2_intel/makefile.mk77
-rw-r--r--bridges/source/cpp_uno/gcc3_os2_intel/share.hxx93
-rw-r--r--bridges/source/cpp_uno/gcc3_os2_intel/uno2cpp.cxx454
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_intel/cpp2uno.cxx526
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_intel/except.cxx332
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_intel/makefile.mk77
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_intel/share.hxx93
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_intel/uno2cpp.cxx430
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_sparc/cpp2uno.cxx567
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_sparc/except.cxx330
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_sparc/makefile.mk81
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_sparc/share.hxx100
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_sparc/uno2cpp.cxx598
-rw-r--r--bridges/source/cpp_uno/mingw_intel/call.s261
-rw-r--r--bridges/source/cpp_uno/mingw_intel/cpp2uno.cxx521
-rw-r--r--bridges/source/cpp_uno/mingw_intel/dllinit.cxx59
-rw-r--r--bridges/source/cpp_uno/mingw_intel/except.cxx317
-rw-r--r--bridges/source/cpp_uno/mingw_intel/makefile.mk98
-rw-r--r--bridges/source/cpp_uno/mingw_intel/share.hxx93
-rw-r--r--bridges/source/cpp_uno/mingw_intel/smallstruct.cxx82
-rw-r--r--bridges/source/cpp_uno/mingw_intel/smallstruct.hxx38
-rw-r--r--bridges/source/cpp_uno/mingw_intel/uno2cpp.cxx503
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx491
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/dllinit.cxx61
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/except.cxx635
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/makefile.mk87
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/msci.hxx60
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx468
-rw-r--r--bridges/source/cpp_uno/shared/bridge.cxx229
-rw-r--r--bridges/source/cpp_uno/shared/component.cxx275
-rw-r--r--bridges/source/cpp_uno/shared/component.hxx42
-rw-r--r--bridges/source/cpp_uno/shared/cppinterfaceproxy.cxx208
-rw-r--r--bridges/source/cpp_uno/shared/guardedarray.hxx55
-rw-r--r--bridges/source/cpp_uno/shared/makefile.mk57
-rw-r--r--bridges/source/cpp_uno/shared/types.cxx129
-rw-r--r--bridges/source/cpp_uno/shared/unointerfaceproxy.cxx145
-rw-r--r--bridges/source/cpp_uno/shared/vtablefactory.cxx385
-rw-r--r--bridges/source/cpp_uno/shared/vtables.cxx157
-rw-r--r--bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_info_holder.java55
-rw-r--r--bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_proxy.java221
-rw-r--r--bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/makefile.mk57
-rw-r--r--bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/manifest1
-rw-r--r--bridges/source/jni_uno/java_uno.map27
-rw-r--r--bridges/source/jni_uno/jni_base.h295
-rw-r--r--bridges/source/jni_uno/jni_bridge.cxx572
-rw-r--r--bridges/source/jni_uno/jni_bridge.h127
-rw-r--r--bridges/source/jni_uno/jni_data.cxx2579
-rw-r--r--bridges/source/jni_uno/jni_helper.h165
-rw-r--r--bridges/source/jni_uno/jni_info.cxx999
-rw-r--r--bridges/source/jni_uno/jni_info.h378
-rw-r--r--bridges/source/jni_uno/jni_java2uno.cxx707
-rw-r--r--bridges/source/jni_uno/jni_uno2java.cxx876
-rw-r--r--bridges/source/jni_uno/makefile.mk89
-rw-r--r--bridges/source/jni_uno/nativethreadpool.cxx233
-rw-r--r--bridges/source/remote/context/context.cxx502
-rw-r--r--bridges/source/remote/context/exports.dxp5
-rw-r--r--bridges/source/remote/context/makefile.mk69
-rwxr-xr-xbridges/source/remote/context/rmcxt.map10
-rw-r--r--bridges/source/remote/idl/corba.idl91
-rw-r--r--bridges/source/remote/static/helper.cxx212
-rw-r--r--bridges/source/remote/static/makefile.mk65
-rw-r--r--bridges/source/remote/static/mapping.cxx221
-rw-r--r--bridges/source/remote/static/proxy.cxx347
-rw-r--r--bridges/source/remote/static/remote.cxx170
-rw-r--r--bridges/source/remote/static/remote_types.cxx99
-rw-r--r--bridges/source/remote/static/remote_types.hxx92
-rw-r--r--bridges/source/remote/static/stub.cxx339
-rw-r--r--bridges/source/remote/urp/makefile.mk82
-rw-r--r--bridges/source/remote/urp/urp_bridgeimpl.cxx253
-rw-r--r--bridges/source/remote/urp/urp_bridgeimpl.hxx136
-rw-r--r--bridges/source/remote/urp/urp_cache.h60
-rw-r--r--bridges/source/remote/urp/urp_cache.hxx163
-rw-r--r--bridges/source/remote/urp/urp_dispatch.cxx119
-rw-r--r--bridges/source/remote/urp/urp_dispatch.hxx81
-rw-r--r--bridges/source/remote/urp/urp_environment.cxx554
-rw-r--r--bridges/source/remote/urp/urp_job.cxx942
-rw-r--r--bridges/source/remote/urp/urp_job.hxx381
-rw-r--r--bridges/source/remote/urp/urp_log.cxx150
-rw-r--r--bridges/source/remote/urp/urp_log.hxx53
-rw-r--r--bridges/source/remote/urp/urp_marshal.cxx238
-rw-r--r--bridges/source/remote/urp/urp_marshal.hxx346
-rw-r--r--bridges/source/remote/urp/urp_marshal_decl.hxx109
-rw-r--r--bridges/source/remote/urp/urp_property.hxx96
-rw-r--r--bridges/source/remote/urp/urp_propertyobject.cxx796
-rw-r--r--bridges/source/remote/urp/urp_propertyobject.hxx111
-rw-r--r--bridges/source/remote/urp/urp_reader.cxx835
-rw-r--r--bridges/source/remote/urp/urp_reader.hxx81
-rw-r--r--bridges/source/remote/urp/urp_replycontainer.hxx78
-rw-r--r--bridges/source/remote/urp/urp_threadid.cxx51
-rw-r--r--bridges/source/remote/urp/urp_threadid.hxx62
-rw-r--r--bridges/source/remote/urp/urp_unmarshal.cxx710
-rw-r--r--bridges/source/remote/urp/urp_unmarshal.hxx283
-rw-r--r--bridges/source/remote/urp/urp_writer.cxx272
-rw-r--r--bridges/source/remote/urp/urp_writer.hxx86
225 files changed, 66383 insertions, 0 deletions
diff --git a/bridges/source/bridge_exports.map b/bridges/source/bridge_exports.map
new file mode 100644
index 000000000000..df39965a2b51
--- /dev/null
+++ b/bridges/source/bridge_exports.map
@@ -0,0 +1,8 @@
+UDK_3_0_0 {
+ global:
+ component_canUnload;
+ uno_initEnvironment;
+ uno_ext_getMapping;
+ local:
+ *;
+};
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/call.s b/bridges/source/cpp_uno/cc50_solaris_intel/call.s
new file mode 100644
index 000000000000..95bf79632031
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/call.s
@@ -0,0 +1,248 @@
+ .align 4
+ .globl privateSnippetExecutorGeneral
+privateSnippetExecutorGeneral:
+ movl %esp,%ecx
+ pushl %ebp / proper stack frame needed for exception handling
+ movl %esp,%ebp
+ andl $0xFFFFFFF8,%esp / align following 64bit arg
+ subl $0x8,%esp / 64bit nRegReturn
+ pushl %ecx / 32bit pCallStack
+ pushl %edx / 32bit nVtableOffset
+ pushl %eax / 32bit nFunctionIndex
+ call cpp_vtable_call
+ movl 12(%esp),%eax / 64 bit nRegReturn, lower half
+ leave
+ ret
+ .type privateSnippetExecutorGeneral, @function
+ .size privateSnippetExecutorGeneral, .-privateSnippetExecutorGeneral
+
+ .align 4
+ .globl privateSnippetExecutorVoid
+privateSnippetExecutorVoid:
+ movl %esp,%ecx
+ pushl %ebp / proper stack frame needed for exception handling
+ movl %esp,%ebp
+ andl $0xFFFFFFF8,%esp / align following 64bit arg
+ subl $0x8,%esp / 64bit nRegReturn
+ pushl %ecx / 32bit pCallStack
+ pushl %edx / 32bit nVtableOffset
+ pushl %eax / 32bit nFunctionIndex
+ call cpp_vtable_call
+ leave
+ ret
+ .type privateSnippetExecutorVoid, @function
+ .size privateSnippetExecutorVoid, .-privateSnippetExecutorVoid
+
+ .align 4
+ .globl privateSnippetExecutorHyper
+privateSnippetExecutorHyper:
+ movl %esp,%ecx
+ pushl %ebp / proper stack frame needed for exception handling
+ movl %esp,%ebp
+ andl $0xFFFFFFF8,%esp / align following 64bit arg
+ subl $0x8,%esp / 64bit nRegReturn
+ pushl %ecx / 32bit pCallStack
+ pushl %edx / 32bit nVtableOffset
+ pushl %eax / 32bit nFunctionIndex
+ call cpp_vtable_call
+ movl 12(%esp),%eax / 64 bit nRegReturn, lower half
+ movl 16(%esp),%edx / 64 bit nRegReturn, upper half
+ leave
+ ret
+ .type privateSnippetExecutorHyper, @function
+ .size privateSnippetExecutorHyper, .-privateSnippetExecutorHyper
+
+ .align 4
+ .globl privateSnippetExecutorFloat
+privateSnippetExecutorFloat:
+ movl %esp,%ecx
+ pushl %ebp / proper stack frame needed for exception handling
+ movl %esp,%ebp
+ andl $0xFFFFFFF8,%esp / align following 64bit arg
+ subl $0x8,%esp / 64bit nRegReturn
+ pushl %ecx / 32bit pCallStack
+ pushl %edx / 32bit nVtableOffset
+ pushl %eax / 32bit nFunctionIndex
+ call cpp_vtable_call
+ flds 12(%esp) / 64 bit nRegReturn, lower half
+ leave
+ ret
+ .type privateSnippetExecutorFloat, @function
+ .size privateSnippetExecutorFloat, .-privateSnippetExecutorFloat
+
+ .align 4
+ .globl privateSnippetExecutorDouble
+privateSnippetExecutorDouble:
+ movl %esp,%ecx
+ pushl %ebp / proper stack frame needed for exception handling
+ movl %esp,%ebp
+ andl $0xFFFFFFF8,%esp / align following 64bit arg
+ subl $0x8,%esp / 64bit nRegReturn
+ pushl %ecx / 32bit pCallStack
+ pushl %edx / 32bit nVtableOffset
+ pushl %eax / 32bit nFunctionIndex
+ call cpp_vtable_call
+ fldl 12(%esp) / 64 bit nRegReturn
+ leave
+ ret
+ .type privateSnippetExecutorDouble, @function
+ .size privateSnippetExecutorDouble, .-privateSnippetExecutorDouble
+
+ .align 4
+ .globl privateSnippetExecutorStruct
+privateSnippetExecutorStruct:
+ movl %esp,%ecx
+ pushl %ebp / proper stack frame needed for exception handling
+ movl %esp,%ebp
+ andl $0xFFFFFFF8,%esp / align following 64bit arg
+ subl $0x8,%esp / 64bit nRegReturn
+ pushl %ecx / 32bit pCallStack
+ pushl %edx / 32bit nVtableOffset
+ pushl %eax / 32bit nFunctionIndex
+ call cpp_vtable_call
+ movl 12(%esp),%eax / 64 bit nRegReturn, lower half
+ leave
+ ret $4
+ .type privateSnippetExecutorStruct, @function
+ .size privateSnippetExecutorStruct, .-privateSnippetExecutorStruct
+
+ .align 4
+ .globl callVirtualMethod
+callVirtualMethod:
+ pushl %ebp
+ movl %esp, %ebp
+ subl $24, %esp
+ movl %edx, -4(%ebp)
+ movl %ecx, -8(%ebp)
+ movl %eax, -12(%ebp)
+ movl %esp, -16(%ebp)
+ movl %ebx, -20(%ebp)
+
+ / set ebx to GOT
+.L_GOT_BEGIN_2:
+ call .L_GOT_END_2
+.L_GOT_END_2:
+ popl %ebx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-.L_GOT_END_2],%ebx
+.callBeginPosition:
+ movl 28(%ebp), %eax
+ movl %eax, %edx
+ dec %edx
+ shl $2, %edx
+ add 24(%ebp), %edx
+.copyLong:
+ movl 0(%edx), %ecx
+ sub $4, %edx
+ push %ecx
+ dec %eax
+ jne .copyLong
+.doCall:
+ movl 8(%ebp), %edx
+ movl 0(%edx), %edx
+ movl 12(%ebp), %eax
+ add $2, %eax
+ shl $2, %eax
+ add %eax, %edx
+ movl 0(%edx), %edx
+
+ call *%edx
+
+.callVirtualMethodExceptionPosition:
+ / handle returns
+ movl 20(%ebp), %ecx
+
+ / byte types
+ cmp $2, %ecx / typelib_TypeClass_BOOLEAN
+ je .handleByte
+ cmp $3, %ecx
+ je .handleByte / typelib_TypeClass_BYTE
+
+ / half word types
+ cmp $4, %ecx / typelib_TypeClass_SHORT
+ je .handleShort
+ cmp $5, %ecx / typelib_TypeClass_UNSIGNED_SHORT
+ je .handleShort
+
+ / word types
+ cmp $6, %ecx / typelib_TypeClass_LONG
+ je .handleWord
+ cmp $7, %ecx / typelib_TypeClass_UNSIGNED_LONG
+ je .handleWord
+ cmp $1, %ecx / typelib_TypeClass_CHAR (wchar_t)
+ je .handleWord
+ cmp $15, %ecx / typelib_TypeClass_ENUM
+ je .handleWord
+
+ / double word types
+ cmp $8, %ecx / typelib_TypeClass_HYPER
+ je .handleDoubleWord
+ cmp $9, %ecx / typelib_TypeClass_UNSIGNED_HYPER
+ je .handleDoubleWord
+
+ / float
+ cmp $10, %ecx / typelib_TypeClass_FLOAT
+ je .handleFloat
+
+ / double
+ cmp $11, %ecx / typelib_TypeClass_DOUBLE
+ je .handleDouble
+
+ / default: return void
+ jmp .doRestore
+.handleByte:
+ movl 16(%ebp), %ecx
+ movb %al, 0(%ecx)
+ jmp .doRestore
+.handleShort:
+ movl 16(%ebp), %ecx
+ movw %ax, 0(%ecx)
+ jmp .doRestore
+.handleWord:
+ movl 16(%ebp), %ecx
+ movl %eax, 0(%ecx)
+ jmp .doRestore
+.handleDoubleWord:
+ movl 16(%ebp), %ecx
+ movl %eax, 0(%ecx)
+ movl %edx, 4(%ecx)
+ jmp .doRestore
+.handleFloat:
+ movl 16(%ebp), %ecx
+ fstps 0(%ecx)
+ jmp .doRestore
+.handleDouble:
+ movl 16(%ebp), %ecx
+ fstpl 0(%ecx)
+ jmp .doRestore
+.doRestore:
+ movl -4(%ebp), %edx
+ movl -8(%ebp), %ecx
+ movl -12(%ebp), %eax
+ movl -20(%ebp), %ebx
+ movl %ebp, %esp
+ popl %ebp
+ ret
+ .type callVirtualMethod, @function
+ .size callVirtualMethod, .-callVirtualMethod
+
+ .globl callVirtualMethodExceptionHandler
+callVirtualMethodExceptionHandler:
+ movl -4(%ebp), %edx
+ movl -8(%ebp), %ecx
+ movl -12(%ebp), %eax
+ movl -16(%ebp), %esp
+ movl -20(%ebp), %ebx
+ call __1cG__CrunMex_rethrow_q6F_v_@PLT
+ ret
+
+ .type callVirtualMethodExceptionHandler, @function
+ .size callVirtualMethodExceptionHandler, .-callVirtualMethodExceptionHandler
+
+
+ .section .exception_ranges,"aw"
+ .align 4
+
+ .4byte .callBeginPosition@rel
+ .4byte .callVirtualMethodExceptionPosition-.callBeginPosition
+ .4byte callVirtualMethodExceptionHandler-.callBeginPosition
+ .zero 8
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/cc50_solaris_intel.hxx b/bridges/source/cpp_uno/cc50_solaris_intel/cc50_solaris_intel.hxx
new file mode 100644
index 000000000000..cdc13d106e0f
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/cc50_solaris_intel.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cc50_solaris_intel.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <cstddef>
+#include <rtl/string.hxx>
+#include <typeinfo>
+
+typedef struct _uno_Any uno_Any;
+typedef struct _uno_Mapping uno_Mapping;
+
+// private C50 structures and functions
+namespace __Crun
+{
+ struct static_type_info
+ {
+ std::ptrdiff_t m_pClassName;
+ int m_nSkip1; // must be 0
+ void* m_pMagic; // points to some magic data
+ int m_nMagic[ 4 ];
+ int m_nSkip2[2]; // must be 0
+ };
+ void* ex_alloc(unsigned);
+ void ex_throw( void*, const static_type_info*, void(*)(void*));
+ void* ex_get();
+ void ex_rethrow_q();
+}
+
+namespace __Cimpl
+{
+ const char* ex_name();
+}
+
+extern "C" void _ex_register( void*, int );
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+//##################################################################################################
+//#### exceptions ##################################################################################
+//##################################################################################################
+
+void cc50_solaris_intel_raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+
+void cc50_solaris_intel_fillUnoException(
+ void*, const char*,
+ uno_Any*, uno_Mapping * pCpp2Uno );
+}
+
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/cpp2uno.cxx b/bridges/source/cpp_uno/cc50_solaris_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..c5b08cf2fee6
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/cpp2uno.cxx
@@ -0,0 +1,530 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.17 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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 "cc50_solaris_intel.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,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // 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 = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void**)pCppStack;
+ pCppStack += sizeof( void* );
+ 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 ] = 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
+ }
+ // 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 no exception occured...
+ 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::cc50_solaris_intel_raiseException(
+ &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ }
+ else // else no exception occured...
+ {
+ // 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,
+ reinterpret_cast< uno_ReleaseFunc >(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 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+ }
+}
+
+
+//==================================================================================================
+extern "C" void cpp_vtable_call(
+ int nFunctionIndex, int nVtableOffset, void** pCallStack,
+ sal_Int64 nRegReturn )
+{
+ 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( rtl::OUString::createFromAscii("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, &nRegReturn );
+ }
+ 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, &nRegReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ // standard XInterface vtable calls
+ 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,
+ reinterpret_cast< uno_AcquireFunc >(cpp_acquire) );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)&nRegReturn = 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, &nRegReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException( rtl::OUString::createFromAscii("no member description found!"), (XInterface *)pThis );
+ }
+ }
+}
+
+//==================================================================================================
+bool isSimpleStruct(typelib_TypeDescriptionReference * type) {
+ typelib_TypeDescription * td = 0;
+ TYPELIB_DANGER_GET(&td, type);
+ OSL_ASSERT(td != 0);
+ for (typelib_CompoundTypeDescription * ctd
+ = reinterpret_cast< typelib_CompoundTypeDescription * >(td);
+ ctd != 0; ctd = ctd->pBaseTypeDescription)
+ {
+ OSL_ASSERT(ctd->aBase.eTypeClass == typelib_TypeClass_STRUCT);
+ for (sal_Int32 i = 0; i < ctd->nMembers; ++i) {
+ typelib_TypeClass c = ctd->ppTypeRefs[i]->eTypeClass;
+ switch (c) {
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ return false;
+ case typelib_TypeClass_STRUCT:
+ if (!isSimpleStruct(ctd->ppTypeRefs[i])) {
+ return false;
+ }
+ break;
+ default:
+ OSL_ASSERT(
+ c <= typelib_TypeClass_DOUBLE
+ || c == typelib_TypeClass_ENUM);
+ break;
+ }
+ }
+ }
+ TYPELIB_DANGER_RELEASE(td);
+ return true;
+}
+
+extern "C" void privateSnippetExecutorGeneral();
+extern "C" void privateSnippetExecutorVoid();
+extern "C" void privateSnippetExecutorHyper();
+extern "C" void privateSnippetExecutorFloat();
+extern "C" void privateSnippetExecutorDouble();
+extern "C" void privateSnippetExecutorStruct();
+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_TypeClass c = returnType == 0
+ ? typelib_TypeClass_VOID : returnType->eTypeClass;
+ if (returnType != 0 && !bridges::cpp_uno::shared::isSimpleType(c)) {
+ functionIndex |= 0x80000000;
+ }
+ PrivateSnippetExecutor exec;
+ switch (c) {
+ 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:
+ OSL_ASSERT(returnType != 0);
+ // For "simple" (more-or-less POD, but not exactly) structs, the caller
+ // pops the pointer to the return value off the stack, as documented in
+ // the Intel SYSV ABI; for other structs (which includes STRING, TYPE,
+ // ANY, sequences, and interfaces, btw.), the callee pops the pointer to
+ // the return value off the stack:
+ exec = isSimpleStruct(returnType)
+ ? privateSnippetExecutorStruct : privateSnippetExecutorGeneral;
+ break;
+ default:
+ exec = privateSnippetExecutorGeneral;
+ break;
+ }
+ 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;
+#pragma disable_warn
+ void * e = reinterpret_cast< void * >(exec);
+#pragma enable_warn
+ *reinterpret_cast< sal_Int32 * >(p)
+ = static_cast< unsigned char * >(e) - 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) + 1;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 3) * 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) + 2;
+ slots[-3].fn = 0; // RTTI
+ slots[-2].fn = 0; // null
+ slots[-1].fn = 0; // destructor
+ 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, 0);
+ }
+ 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 *)
+{}
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx b/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx
new file mode 100644
index 000000000000..66a0d62cd66c
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx
@@ -0,0 +1,452 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.18 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <cstddef>
+#include <dlfcn.h>
+#include <new.h>
+#include <typeinfo>
+#include <list>
+#include <map>
+#include <rtl/alloc.h>
+#include <osl/diagnose.h>
+
+#include <rtl/strbuf.hxx>
+#include <typelib/typedescription.hxx>
+#include <com/sun/star/uno/Any.hxx>
+
+#include "bridges/cpp_uno/shared/arraypointer.hxx"
+
+#include "cc50_solaris_intel.hxx"
+
+#include <hash.cxx>
+
+// need a += operator for OString and sal_Char
+namespace rtl
+{
+ inline OString& operator+=( OString& rString, sal_Char cAdd )
+ {
+ sal_Char add[2];
+ add[0] = cAdd;
+ add[1] = 0;
+ return rString += add;
+ }
+}
+
+using namespace std;
+using namespace osl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+static OString toUNOname( const OString & rRTTIname )
+{
+ OString aRet;
+
+ const sal_Char* pRTTI = rRTTIname.getStr();
+ const sal_Char* pOrg = pRTTI;
+ const sal_Char* pLast = pRTTI;
+
+ while( 1 )
+ {
+ if( *pRTTI == ':' || ! *pRTTI )
+ {
+ if( aRet.getLength() )
+ aRet += ".";
+ aRet += rRTTIname.copy( pLast - pOrg, pRTTI - pLast );
+ while( *pRTTI == ':' )
+ pRTTI++;
+ pLast = pRTTI;
+ if( ! *pRTTI )
+ break;
+ }
+ else
+ pRTTI++;
+ }
+
+ return aRet;
+}
+//==================================================================================================
+static OString toRTTIname( const OString & rUNOname )
+{
+ OStringBuffer aRet( rUNOname.getLength()*2 );
+
+ sal_Int32 nIndex = 0;
+ do
+ {
+ if( nIndex > 0 )
+ aRet.append( "::" );
+ aRet.append( rUNOname.getToken( 0, '.', nIndex ) );
+ } while( nIndex != -1 );
+
+ return aRet.makeStringAndClear();
+}
+//==================================================================================================
+
+static OString toRTTImangledname( const OString & rRTTIname )
+{
+ if( ! rRTTIname.getLength() )
+ return OString();
+
+ OStringBuffer aRet( rRTTIname.getLength()*2 );
+
+ aRet.append( "__1n" );
+ sal_Int32 nIndex = 0;
+ do
+ {
+ OString aToken( rRTTIname.getToken( 0, ':', nIndex ) );
+ int nBytes = aToken.getLength();
+ if( nBytes )
+ {
+ if( nBytes > 25 )
+ {
+ aRet.append( (sal_Char)( nBytes/26 + 'a' ) );
+ aRet.append( (sal_Char)( nBytes%26 + 'A' ) );
+ }
+ else
+ aRet.append( (sal_Char)( nBytes + 'A' ) );
+ for (sal_Int32 i = 0; i < aToken.getLength(); ++i) {
+ char c = aToken[i];
+ if (c == 'Q') {
+ aRet.append("QdD");
+ } else {
+ aRet.append(c);
+ }
+ }
+ }
+ } while( nIndex != -1 );
+
+ aRet.append( '_' );
+
+ return aRet.makeStringAndClear();
+}
+
+//##################################################################################################
+//#### RTTI simulation #############################################################################
+//##################################################################################################
+
+class RTTIHolder
+{
+ std::map< OString, void* > aAllRTTI;
+public:
+ ~RTTIHolder();
+
+ void* getRTTI( const OString& rTypename );
+ void* getRTTI_UnoName( const OString& rUnoTypename )
+ { return getRTTI( toRTTIname( rUnoTypename ) ); }
+
+ void* insertRTTI( const OString& rTypename );
+ void* insertRTTI_UnoName( const OString& rTypename )
+ { return insertRTTI( toRTTIname( rTypename ) ); }
+ void* generateRTTI( typelib_CompoundTypeDescription* pCompTypeDescr );
+};
+
+RTTIHolder::~RTTIHolder()
+{
+ for ( std::map< OString, void* >::const_iterator iPos( aAllRTTI.begin() );
+ iPos != aAllRTTI.end(); ++iPos )
+ {
+ delete[] static_cast< char * >(iPos->second);
+ }
+}
+
+#if OSL_DEBUG_LEVEL > 1
+#include <stdio.h>
+#endif
+
+void* RTTIHolder::getRTTI( const OString& rTypename )
+{
+ std::map< OString, void* >::iterator element;
+
+ element = aAllRTTI.find( rTypename );
+ if( element != aAllRTTI.end() )
+ return (*element).second;
+
+ // create rtti structure
+ element = aAllRTTI.find( rTypename );
+ if( element != aAllRTTI.end() )
+ return (*element).second;
+
+ return NULL;
+}
+
+static long nMagicId = 1;
+
+void* RTTIHolder::insertRTTI( const OString& rTypename )
+{
+ OString aMangledName( toRTTImangledname( rTypename ) );
+ NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
+
+
+ // rSuperTypename MUST exist !!!
+ std::size_t const RTTI_SIZE = 19; // 14???
+ void** pRTTI = reinterpret_cast< void ** >(
+ new char[RTTI_SIZE * sizeof (void *) + strlen(rTypename.getStr()) + 1]);
+ pRTTI[ 0 ] = reinterpret_cast< void * >(RTTI_SIZE * sizeof (void *));
+ pRTTI[ 1 ] = NULL;
+ pRTTI[ 2 ] = (void*)(7*sizeof(void*));
+ pRTTI[ 3 ] = (void*)aHash.getHash()[0];
+ pRTTI[ 4 ] = (void*)aHash.getHash()[1];
+ pRTTI[ 5 ] = (void*)aHash.getHash()[2];
+ pRTTI[ 6 ] = (void*)aHash.getHash()[3];
+ pRTTI[ 7 ] = NULL;
+ pRTTI[ 8 ] = NULL;
+
+ pRTTI[ 9 ] = pRTTI[ 3 ];
+ pRTTI[ 10 ] = pRTTI[ 4 ];
+ pRTTI[ 11 ] = pRTTI[ 5 ];
+ pRTTI[ 12 ] = pRTTI[ 6 ];
+ pRTTI[ 13 ] = (void*)0x80000000;
+ strcpy(reinterpret_cast< char * >(pRTTI + RTTI_SIZE), rTypename.getStr());
+
+ aAllRTTI[ rTypename ] = (void*)pRTTI;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,
+ "generating base RTTI for type %s:\n"
+ " mangled: %s\n"
+ " hash: %.8x %.8x %.8x %.8x\n",
+ rTypename.getStr(),
+ aMangledName.getStr(),
+ pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ]
+ );
+#endif
+ return pRTTI;
+}
+
+void* RTTIHolder::generateRTTI( typelib_CompoundTypeDescription * pCompTypeDescr )
+{
+ OString aUNOCompTypeName( OUStringToOString( pCompTypeDescr->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ OString aRTTICompTypeName( toRTTIname( aUNOCompTypeName ) );
+
+ void* pHaveRTTI = getRTTI( aRTTICompTypeName );
+ if( pHaveRTTI )
+ return pHaveRTTI;
+
+ if( ! pCompTypeDescr->pBaseTypeDescription )
+ // this is a base type
+ return insertRTTI( aRTTICompTypeName );
+
+ // get base class RTTI
+ void* pSuperRTTI = generateRTTI( pCompTypeDescr->pBaseTypeDescription );
+ OSL_ENSURE( pSuperRTTI, "could not generate RTTI for supertype !" );
+
+ // find out the size to allocate for RTTI
+ void** pInherit = (void**)((sal_uInt32)pSuperRTTI + ((sal_uInt32*)pSuperRTTI)[2] + 8);
+ int nInherit;
+ for( nInherit = 1; pInherit[ nInherit*5-1 ] != (void*)0x80000000; nInherit++ )
+ ;
+
+ OString aMangledName( toRTTImangledname( aRTTICompTypeName ) );
+ NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
+
+ std::size_t const rttiSize = 14 + nInherit * 5;
+ void** pRTTI = reinterpret_cast< void ** >(
+ new char[
+ rttiSize * sizeof (void *)
+ + strlen(aRTTICompTypeName.getStr()) + 1]);
+ pRTTI[ 0 ] = reinterpret_cast< void * >(rttiSize * sizeof (void *));
+ pRTTI[ 1 ] = NULL;
+ pRTTI[ 2 ] = (void*)(7*sizeof(void*));
+ pRTTI[ 3 ] = (void*)aHash.getHash()[0];
+ pRTTI[ 4 ] = (void*)aHash.getHash()[1];
+ pRTTI[ 5 ] = (void*)aHash.getHash()[2];
+ pRTTI[ 6 ] = (void*)aHash.getHash()[3];
+ pRTTI[ 7 ] = NULL;
+ pRTTI[ 8 ] = NULL;
+
+ memcpy( pRTTI+9, pInherit, 4*nInherit*5 );
+ pRTTI[ 8 +nInherit*5 ] = NULL;
+ pRTTI[ 9 +nInherit*5 ] = pRTTI[ 3 ];
+ pRTTI[ 10+nInherit*5 ] = pRTTI[ 4 ];
+ pRTTI[ 11+nInherit*5 ] = pRTTI[ 5 ];
+ pRTTI[ 12+nInherit*5 ] = pRTTI[ 6 ];
+ pRTTI[ 13+nInherit*5 ] = (void*)0x80000000;
+ strcpy(
+ reinterpret_cast< char * >(pRTTI + rttiSize),
+ aRTTICompTypeName.getStr());
+
+ aAllRTTI[ aRTTICompTypeName ] = (void*)pRTTI;
+
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,
+ "generating struct RTTI for type %s:\n"
+ " mangled: %s\n"
+ " hash: %.8x %.8x %.8X %.8x\n",
+ aRTTICompTypeName.getStr(),
+ aMangledName.getStr(),
+ pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ]
+ );
+#endif
+
+ return pRTTI;
+}
+
+//__________________________________________________________________________________________________
+
+static void deleteException(
+ void* pExc, unsigned char* thunk, typelib_TypeDescription* pType )
+{
+ uno_destructData(
+ pExc, pType, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ typelib_typedescription_release( pType );
+ delete[] thunk;
+}
+
+//__________________________________________________________________________________________________
+
+//##################################################################################################
+//#### exported ####################################################################################
+//##################################################################################################
+
+void cc50_solaris_intel_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 occured: %s\n", cstr.getStr() );
+#endif
+ bridges::cpp_uno::shared::ArrayPointer< unsigned char > thunkPtr(
+ new unsigned char[24]);
+ typelib_TypeDescription * pTypeDescr = 0;
+ // will be released by deleteException
+ typelib_typedescriptionreference_getDescription( &pTypeDescr, pUnoExc->pType );
+
+ void* pRTTI;
+ {
+ static ::osl::Mutex aMutex;
+ ::osl::Guard< ::osl::Mutex > guard( aMutex );
+
+ static RTTIHolder * s_pRTTI = 0;
+ if (! s_pRTTI)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_pRTTI = new RTTIHolder();
+#else
+ static RTTIHolder s_aRTTI;
+ s_pRTTI = &s_aRTTI;
+#endif
+ }
+
+ pRTTI = s_pRTTI->generateRTTI( (typelib_CompoundTypeDescription *)pTypeDescr );
+ }
+
+ // a must be
+ OSL_ENSURE( sizeof(sal_Int32) == sizeof(void *), "### pointer size differs from sal_Int32!" );
+
+ void * pCppExc = __Crun::ex_alloc( pTypeDescr->nSize );
+ uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ uno_any_destruct( pUnoExc, 0 );
+
+ unsigned char * thunk = thunkPtr.release();
+ // movl %esp, %ecx:
+ thunk[0] = 0x8B;
+ thunk[1] = 0xCC;
+ // pushl pTypeDescr:
+ thunk[2] = 0x68;
+ *reinterpret_cast< void ** >(thunk + 3) = pTypeDescr;
+ // pushl thunk:
+ thunk[7] = 0x68;
+ *reinterpret_cast< void ** >(thunk + 8) = thunk;
+ // pushl 4(%ecx):
+ thunk[12] = 0xFF;
+ thunk[13] = 0x71;
+ thunk[14] = 0x04;
+ // call deleteException:
+ thunk[15] = 0xE8;
+#pragma disable_warn
+ void * d = reinterpret_cast< void * >(deleteException);
+#pragma enable_warn
+ *reinterpret_cast< std::ptrdiff_t * >(thunk + 16) =
+ static_cast< unsigned char * >(d) - (thunk + 20);
+ // addl $12, %esp:
+ thunk[20] = 0x83;
+ thunk[21] = 0xC4;
+ thunk[22] = 0x0C;
+ // ret:
+ thunk[23] = 0xC3;
+
+#pragma disable_warn
+ void (* f)(void *) = reinterpret_cast< void (*)(void *) >(thunk);
+#pragma enable_warn
+ __Crun::ex_throw(pCppExc, (const __Crun::static_type_info*)pRTTI, f);
+}
+
+void cc50_solaris_intel_fillUnoException(
+ void* pCppExc,
+ const char* pInfo,
+ uno_Any* pUnoExc,
+ uno_Mapping * pCpp2Uno )
+{
+ OSL_ASSERT( pInfo != 0 );
+ OString uno_name( toUNOname( pInfo ) );
+ OUString aName( OStringToOUString(
+ uno_name, RTL_TEXTENCODING_ASCII_US ) );
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ typelib_typedescription_getByName( &pExcTypeDescr, aName.pData );
+
+ if (pExcTypeDescr == 0) // the thing that should not be
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "exception type not found: ") ) + aName,
+ 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_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "> c++ exception occured: %s\n",
+ ::rtl::OUStringToOString(
+ pExcTypeDescr->pTypeName,
+ RTL_TEXTENCODING_ASCII_US ).getStr() );
+#endif
+ // construct uno exception any
+ uno_any_constructAndConvert(
+ pUnoExc, pCppExc, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/hash.cxx b/bridges/source/cpp_uno/cc50_solaris_intel/hash.cxx
new file mode 100644
index 000000000000..e7239d6dcb62
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/hash.cxx
@@ -0,0 +1,266 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: hash.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+
+#ifndef TEST
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+#else
+typedef unsigned int sal_uInt32;
+#endif
+
+#include <string.h>
+
+/*
+ * build a hash for a character buffer using the NIST algorithm
+ */
+
+class NIST_Hash
+{
+
+ // helper functions
+ sal_uInt32 f1( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
+ {
+ return z ^ ( x & ( y ^ z ) );
+ }
+
+ sal_uInt32 f2( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
+ {
+ return x ^ y ^ z;
+ }
+
+ sal_uInt32 f3( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
+ {
+ return ( x & y ) + ( z & ( x ^ y ) );
+ }
+
+ sal_uInt32 rotl( sal_uInt32 nValue, sal_uInt32 nBits )
+ {
+ return ( nValue << nBits ) | ( nValue >> (32-nBits) );
+ }
+
+ sal_uInt32 expand_nostore( sal_uInt32 index )
+ {
+ return data[index&15] ^ data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
+ }
+
+ sal_uInt32 expand_store( sal_uInt32 index )
+ {
+ return data[index&15] ^= data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
+ }
+
+ void subRound( sal_uInt32 a, sal_uInt32& b, sal_uInt32 c, sal_uInt32 d, sal_uInt32& e, sal_uInt32 constant, sal_uInt32 datum, sal_uInt32 nFunction )
+ {
+ e += rotl(a,5);
+ switch( nFunction )
+ {
+ case 1: e += f1( b, c, d );break;
+ case 2:
+ case 4: e += f2( b, c, d );break;
+ case 3: e += f3( b, c, d );break;
+ }
+ e += constant + datum;
+ b = rotl( b, 30 );
+ }
+
+ void transform();
+ void final();
+
+ // data members
+ sal_uInt32 data[16];
+ sal_uInt32 hashdata[5];
+public:
+ NIST_Hash( const char* pString, sal_uInt32 nLen );
+
+ sal_uInt32 *getHash() { return hashdata; }
+};
+
+void NIST_Hash::transform()
+{
+ // constants
+ const sal_uInt32 K2 = 0x5A827999;
+ const sal_uInt32 K3 = 0x6ED9EBA1;
+ const sal_uInt32 K5 = 0x8F1BBCDC;
+ const sal_uInt32 K10 = 0xCA62C1D6;
+
+ sal_uInt32 a, b, c, d, e;
+ a = hashdata[0];
+ b = hashdata[1];
+ c = hashdata[2];
+ d = hashdata[3];
+ e = hashdata[4];
+
+ subRound( a, b, c, d, e, K2, data[ 0], 1 );
+ subRound( e, a, b, c, d, K2, data[ 1], 1 );
+ subRound( d, e, a, b, c, K2, data[ 2], 1 );
+ subRound( c, d, e, a, b, K2, data[ 3], 1 );
+ subRound( b, c, d, e, a, K2, data[ 4], 1 );
+ subRound( a, b, c, d, e, K2, data[ 5], 1 );
+ subRound( e, a, b, c, d, K2, data[ 6], 1 );
+ subRound( d, e, a, b, c, K2, data[ 7], 1 );
+ subRound( c, d, e, a, b, K2, data[ 8], 1 );
+ subRound( b, c, d, e, a, K2, data[ 9], 1 );
+ subRound( a, b, c, d, e, K2, data[10], 1 );
+ subRound( e, a, b, c, d, K2, data[11], 1 );
+ subRound( d, e, a, b, c, K2, data[12], 1 );
+ subRound( c, d, e, a, b, K2, data[13], 1 );
+ subRound( b, c, d, e, a, K2, data[14], 1 );
+ subRound( a, b, c, d, e, K2, data[15], 1 );
+ subRound( e, a, b, c, d, K2, expand_store( 16 ), 1 );
+ subRound( d, e, a, b, c, K2, expand_store( 17 ), 1 );
+ subRound( c, d, e, a, b, K2, expand_store( 18 ), 1 );
+ subRound( b, c, d, e, a, K2, expand_store( 19 ), 1 );
+
+ subRound( a, b, c, d, e, K3, expand_store( 20 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 21 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 22 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 23 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 24 ), 2 );
+ subRound( a, b, c, d, e, K3, expand_store( 25 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 26 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 27 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 28 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 29 ), 2 );
+ subRound( a, b, c, d, e, K3, expand_store( 30 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 31 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 32 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 33 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 34 ), 2 );
+ subRound( a, b, c, d, e, K3, expand_store( 35 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 36 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 37 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 38 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 39 ), 2 );
+
+ subRound( a, b, c, d, e, K5, expand_store( 40 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 41 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 42 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 43 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 44 ), 3 );
+ subRound( a, b, c, d, e, K5, expand_store( 45 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 46 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 47 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 48 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 49 ), 3 );
+ subRound( a, b, c, d, e, K5, expand_store( 50 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 51 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 52 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 53 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 54 ), 3 );
+ subRound( a, b, c, d, e, K5, expand_store( 55 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 56 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 57 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 58 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 59 ), 3 );
+
+ subRound( a, b, c, d, e, K10, expand_store( 60 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 61 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_store( 62 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_store( 63 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_store( 64 ), 4 );
+ subRound( a, b, c, d, e, K10, expand_store( 65 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 66 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_store( 67 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_store( 68 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_store( 69 ), 4 );
+ subRound( a, b, c, d, e, K10, expand_store( 70 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 71 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_store( 72 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_store( 73 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_store( 74 ), 4 );
+ subRound( a, b, c, d, e, K10, expand_store( 75 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 76 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_nostore( 77 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_nostore( 78 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_nostore( 79 ), 4 );
+
+ hashdata[0] += a;
+ hashdata[1] += b;
+ hashdata[2] += c;
+ hashdata[3] += d;
+ hashdata[4] += e;
+}
+
+#define BLOCKSIZE sizeof( data )
+
+NIST_Hash::NIST_Hash( const char* pString, sal_uInt32 nLen )
+{
+ hashdata[0] = 0x67452301;
+ hashdata[1] = 0xefcdab89;
+ hashdata[2] = 0x98badcfe;
+ hashdata[3] = 0x10325476;
+ hashdata[4] = 0xc3d2e1f0;
+
+ sal_uInt32 nBytes = nLen;
+
+ while( nLen >= sizeof( data ) )
+ {
+ memcpy( data, pString, sizeof( data ) );
+ pString += sizeof( data );
+ nLen -= sizeof( data );
+ transform();
+ }
+ memcpy( data, pString, nLen );
+ ((char*)data)[nLen++] = 0x80;
+ if( nLen > sizeof( data ) - 8 )
+ {
+ memset( ((char*)data)+nLen, 0, sizeof( data ) - nLen );
+ transform();
+ memset( data, 0, sizeof( data ) - 8 );
+ }
+ else
+ memset( ((char*)data)+nLen, 0, sizeof( data ) - 8 - nLen );
+ data[14] = 0;
+ data[15] = nBytes << 3;
+ transform();
+}
+
+#ifdef TEST
+#include <stdio.h>
+int main( int argc, const char** argv )
+{
+ const char* pHash = argc < 2 ? argv[0] : argv[1];
+
+ NIST_Hash aHash( pHash, strlen( pHash ) );
+ sal_uInt32* pBits = aHash.getHash();
+
+ printf( "text : %s\n"
+ "bits : 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
+ pHash,
+ pBits[0], pBits[1], pBits[2],pBits[3],pBits[4]
+ );
+ return 0;
+}
+
+#endif
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/makefile.mk b/bridges/source/cpp_uno/cc50_solaris_intel/makefile.mk
new file mode 100644
index 000000000000..9a18ecc8615f
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/makefile.mk
@@ -0,0 +1,79 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.13 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=sunpro5_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+# disable check for PIC code as it would complain about
+# hand coded assembler
+CHECKFORPIC=
+
+.IF "$(COM)$(CPU)" == "C50I" || "$(COM)$(CPU)" == "C52I"
+
+CFLAGS += -O5 -xO5
+
+SLOFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB= i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH= URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+ CC -c -o $(SLO)$/$(@:b).o $< && touch $@
+
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/uno2cpp.cxx b/bridges/source/cpp_uno/cc50_solaris_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..8e439984bdb5
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/uno2cpp.cxx
@@ -0,0 +1,421 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.17 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.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 "cc50_solaris_intel.hxx"
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+namespace
+{
+
+extern "C" {
+ void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs
+ );
+}
+
+//==================================================================================================
+static inline 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 = (char *)alloca( ((nParams+3) * sizeof(sal_Int64)) );
+ 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
+
+ void * pReturnSpace = 0;
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack
+ = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+
+ const int nMaxParams = 32;
+ // args
+ void * args_buffer[3 * nMaxParams];
+ void ** pCppArgs = (void **)(nParams > nMaxParams ? rtl_allocateMemory( 3 * sizeof(void *) * nParams ) : args_buffer);
+ // 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;
+
+ const int nTempBufferSize = 256;
+ sal_Int32 nTempBufferPos = 0;
+ long params_buffer[nTempBufferSize];
+
+ 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 ))
+ {
+ pCppArgs[ nPos ] = pCppStack;
+ uno_copyAndConvertData( pCppArgs[nPos], 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
+ }
+ // 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!
+ if (pParamTypeDescr->nSize > (sizeof(long) * (nTempBufferSize - nTempBufferPos)))
+ {
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = rtl_allocateMemory( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos | 0x80000000; // default constructed for cpp call
+ }
+ else
+ {
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = (params_buffer + nTempBufferPos),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ nTempBufferPos += (pParamTypeDescr->nSize / sizeof(long)) +1;
+ }
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ if (pParamTypeDescr->nSize > (sizeof(long)*(nTempBufferSize - nTempBufferPos)))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = rtl_allocateMemory( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ pTempIndizes[nTempIndizes] = nPos | 0x80000000; // has to be reconverted
+ }
+ else
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = (params_buffer + nTempBufferPos),
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ nTempBufferPos += (pParamTypeDescr->nSize / sizeof(long)) +1;
+ }
+ // 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
+ {
+ int nStackLongs = (pCppStack - pCppStackStart)/sizeof(sal_Int32);
+ if( nStackLongs & 1 )
+ // stack has to be 8 byte aligned
+ nStackLongs++;
+
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn,
+ pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart,
+ nStackLongs
+ );
+
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ sal_Bool bAllocated = (nIndex & 0x80000000) != 0;
+ nIndex &= 0x7fffffff;
+ 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,
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+
+ if (bAllocated)
+ rtl_freeMemory( pCppArgs[nIndex] );
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData(
+ pCppReturn, pReturnTypeDescr,
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ }
+ }
+ catch( ... )
+ {
+ void* pExc = __Crun::ex_get();
+ const char* pName = __Cimpl::ex_name();
+
+ // get exception
+ CPPU_CURRENT_NAMESPACE::cc50_solaris_intel_fillUnoException(
+ pExc, pName, *ppUnoExc,
+ pThis->getBridge()->getCpp2Uno());
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ sal_Bool bAllocated = (nIndex & 0x80000000) != 0;
+ nIndex &= 0x7fffffff;
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData(
+ pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes],
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ if (bAllocated)
+ rtl_freeMemory( pCppArgs[nIndex] );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+
+ if (pCppArgs != (void **)args_buffer)
+ rtl_freeMemory( pCppArgs );
+ if (pReturnSpace)
+ rtl_freeMemory( pReturnSpace );
+}
+
+}
+
+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);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/call.s b/bridges/source/cpp_uno/cc50_solaris_sparc/call.s
new file mode 100644
index 000000000000..be4027fda070
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/call.s
@@ -0,0 +1,199 @@
+.global privateSnippetExecutor
+.type privateSnippetExecutor,2
+privateSnippetExecutor:
+ ! save %sp, -96, %sp already done in code snippet
+ st %i0, [%fp+68]
+ st %i1, [%fp+72]
+ st %i2, [%fp+76]
+ st %i3, [%fp+80]
+ st %i4, [%fp+84]
+ st %i5, [%fp+88]
+ ! %o0: functionIndex, stored by code snippet
+ ! %o1: vtableOffset, stored by code snippet
+ call cpp_vtable_call
+ add %fp, 68, %o2
+.privateSnippetExecutorExceptionPosition:
+ subcc %o0, 11, %g0
+ be .double
+ subcc %o0, 10, %g0
+ be .float
+ ld [%fp+72], %i0
+ ld [%fp+76], %i1
+ ret
+ restore
+.double:
+ ldd [%fp+72], %f0
+ ret
+ restore
+.float:
+ ld [%fp+72], %f0
+ ret
+ restore
+.size privateSnippetExecutor,(.-privateSnippetExecutor)
+.align 8
+
+
+.global callVirtualMethod
+.type callVirtualMethod,2
+callVirtualMethod:
+ ! allocate FIRST stack to have own local registers
+ sethi %hi(-96), %g1
+ or %g1, %lo(-96), %g1
+ subcc %g1, %o5, %g1
+ subcc %g1, %o5, %g1
+ subcc %g1, %o5, %g1
+ subcc %g1, %o5, %g1
+ save %sp, %g1, %sp
+ ! copy stack longs if necessary
+ subcc %i5, 6, %l5
+ ble .copyRegisters
+ nop
+
+ ! prepare source location
+ add %i4, 24, %l4
+
+ ! prepare real stack
+ add %sp, 92, %l3
+
+.copyLong:
+ ld [%l4+0], %l0
+ st %l0, [%l3]
+ add %l4, 4, %l4
+ add %l3, 4, %l3
+ deccc %l5
+ bne .copyLong
+ nop
+.copyRegisters:
+ mov %i5, %l5
+ mov %i4, %l4
+
+ ld [%l4], %o0
+ add %l4, 4, %l4
+ deccc %l5
+ ble .doCall
+
+ ld [%l4], %o1
+ add %l4, 4, %l4
+ deccc %l5
+ ble .doCall
+
+ ld [%l4], %o2
+ add %l4, 4, %l4
+ deccc %l5
+ ble .doCall
+
+ ld [%l4], %o3
+ add %l4, 4, %l4
+ deccc %l5
+ ble .doCall
+
+ ld [%l4], %o4
+ add %l4, 4, %l4
+ deccc %l5
+ ble .doCall
+
+ ld [%l4], %o5
+ add %l4, 4, %l4
+
+ ! prepare complex return pointer
+ st %i2, [%sp+64]
+.doCall:
+ ! get virtual table entry
+ mov %i1, %l1
+ add %l1, 2, %l1
+ sll %l1, 2, %l1
+ ld [%i0], %l3
+ add %l3, %l1, %l1
+ ld [%l1], %l0
+ jmpl %l0,%o7
+ nop
+.callVirtualMethodExceptionPosition:
+ ! handle returns
+
+ !byte types
+ subcc %i3, 2, %l3 ! typelib_TypeClass_BOOLEAN
+ be .handleByte
+ subcc %i3, 3, %l3 ! typelib_TypeClass_BYTE
+ be .handleByte
+
+ ! half word types
+ subcc %i3, 4, %l3 ! typelib_TypeClass_SHORT
+ be .handleShort
+ subcc %i3, 5, %l3 ! typelib_TypeClass_UNSIGNED_SHORT
+ be .handleShort
+ subcc %i3, 1, %l3 ! typelib_TypeClass_CHAR (sal_Unicode==sal_uInt16)
+ be .handleShort
+
+ ! word types
+ subcc %i3, 6, %l3 ! typelib_TypeClass_LONG
+ be .handleWord
+ subcc %i3, 7, %l3 ! typelib_TypeClass_UNSIGNED_LONG
+ be .handleWord
+ subcc %i3, 15, %l3 ! typelib_TypeClass_ENUM
+ be .handleWord
+
+ ! double word types
+ subcc %i3, 8, %l3 ! typelib_TypeClass_HYPER
+ be .handleDoubleWord
+ subcc %i3, 9, %l3 ! typelib_TypeClass_UNSIGNED_HYPER
+ be .handleDoubleWord
+
+ ! float
+ subcc %i3, 10, %l3 ! typelib_TypeClass_FLOAT
+ be .handleFloat
+
+ ! double
+ subcc %i3, 11, %l3 ! typelib_TypeClass_DOUBLE
+ be .handleDouble
+
+ ! default: return void
+ nop ! empty prefetch
+ ba .doRestore
+ nop
+.handleByte:
+ stb %o0, [%i2]
+ ba .doRestore
+ nop
+.handleShort:
+ sth %o0, [%i2]
+ ba .doRestore
+ nop
+.handleWord:
+ st %o0, [%i2]
+ ba .doRestore
+ nop
+.handleDoubleWord:
+ st %o0, [%i2]
+ st %o1, [%i2+4]
+ ba .doRestore
+ nop
+.handleFloat:
+ st %f0, [%i2]
+ ba .doRestore
+ nop
+.handleDouble:
+ std %f0, [%fp-8]
+ ldd [%fp-8], %o0
+ st %o0, [%i2]
+ st %o1, [%i2+4]
+ ba .doRestore
+ nop
+.doRestore:
+ ret
+ restore ! stack frame for own locals
+.size callVirtualMethod,(.-callVirtualMethod)
+.align 8
+
+.rethrow_handler:
+ call __1cG__CrunMex_rethrow_q6F_v_
+ nop
+
+.section ".exception_ranges",#alloc
+.word %r_disp32(.privateSnippetExecutorExceptionPosition)
+.word 0
+.word .rethrow_handler-.privateSnippetExecutorExceptionPosition
+.word 0,0
+.word %r_disp32(.callVirtualMethodExceptionPosition)
+.word 0
+.word .rethrow_handler-.callVirtualMethodExceptionPosition
+.word 0,0
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/cc50_solaris_sparc.hxx b/bridges/source/cpp_uno/cc50_solaris_sparc/cc50_solaris_sparc.hxx
new file mode 100644
index 000000000000..ebd68f9e6616
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/cc50_solaris_sparc.hxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cc50_solaris_sparc.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <cstddef>
+#include <rtl/string.hxx>
+#include <typeinfo>
+
+typedef struct _uno_Any uno_Any;
+typedef struct _uno_Mapping uno_Mapping;
+
+// private C50 structures and functions
+namespace __Crun
+{
+ struct static_type_info
+ {
+ std::ptrdiff_t m_pClassName;
+ int m_nSkip1; // must be 0
+ void* m_pMagic; // points to some magic data
+ int m_nMagic[ 4 ];
+ int m_nSkip2[2]; // must be 0
+ };
+ void* ex_alloc(unsigned);
+ void ex_throw( void*, const static_type_info*, void(*)(void*));
+ void* ex_get();
+ void ex_rethrow_q() throw();
+}
+
+namespace __Cimpl
+{
+ const char* ex_name();
+}
+
+extern "C" void _ex_register( void*, int );
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+inline char* adjustPointer( char* pIn, typelib_TypeDescription* pType )
+{
+ switch( pType->nSize )
+ {
+ case 1: return pIn + 3;
+ case 2: return pIn + 2;
+ case 3: return pIn + 1;
+ // Huh ? perhaps a char[3] ? Though that would be a pointer
+ // well, we have it anyway for symmetry
+ }
+ return pIn;
+}
+
+//##################################################################################################
+//#### exceptions ##################################################################################
+//##################################################################################################
+
+void cc50_solaris_sparc_raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+
+void cc50_solaris_sparc_fillUnoException(
+ void*, const char*,
+ uno_Any*, uno_Mapping * pCpp2Uno );
+
+}
+
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/cpp2uno.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/cpp2uno.cxx
new file mode 100644
index 000000000000..05a0a304de27
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/cpp2uno.cxx
@@ -0,0 +1,533 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.25 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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 "cc50_solaris_sparc.hxx"
+#include "flushcode.hxx"
+
+using namespace com::sun::star::uno;
+
+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 ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // pCallStack: [return ptr], this, params
+ char * pCppStack = (char *)pCallStack;
+
+ // 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 = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *pCallStack;
+ pCppStack += sizeof( void* );
+ 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 ] = pUnoArgs[ nPos ] =
+ CPPU_CURRENT_NAMESPACE::adjustPointer(
+ pCppStack, pParamTypeDescr );
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ }
+ // 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 no exception occured...
+ 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::cc50_solaris_sparc_raiseException(
+ &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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,
+ reinterpret_cast< uno_ReleaseFunc >(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 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: this, params
+ void * pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = pCallStack[1];
+ }
+ else
+ {
+ pThis = pCallStack[0];
+ }
+ 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)
+// {
+// RuntimeException aExc;
+// aExc.Message = OUString::createFromAscii("illegal vtable index!");
+// aExc.Context = (XInterface *)pThis;
+// throw aExc;
+// }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ // standard XInterface vtable calls
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[2] )->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[0] ),
+ &pInterface, pTD,
+ reinterpret_cast< uno_AcquireFunc >(cpp_acquire) );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = pCallStack[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+// default:
+// {
+// RuntimeException aExc;
+// aExc.Message = OUString::createFromAscii("no member description found!");
+// aExc.Context = (XInterface *)pThis;
+// throw aExc;
+// // is here for dummy
+// eRet = typelib_TypeClass_VOID;
+// }
+ }
+
+ return eRet;
+}
+
+}
+
+//==================================================================================================
+extern "C" int cpp_vtable_call(
+ int nFunctionIndex, int nVtableOffset, void** pCallStack )
+{
+ sal_Int64 nRegReturn;
+ typelib_TypeClass aType = cpp_mediate(
+ nFunctionIndex, nVtableOffset, pCallStack, &nRegReturn );
+ OSL_ASSERT( sizeof(void *) == sizeof(sal_Int32) );
+ switch( aType )
+ {
+ // move return value into register space
+ // (will be loaded by machine code snippet)
+ // Use pCallStack[1/2] instead of pCallStack[0/1], because the former is
+ // properly dword aligned:
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ pCallStack[1] = (void*)*(char*)&nRegReturn;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ pCallStack[1] = (void*)*(short*)&nRegReturn;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ // move long to %i1
+ pCallStack[2] = ((void **)&nRegReturn)[ 1 ];
+ case typelib_TypeClass_FLOAT:
+ default:
+ // move long to %i0
+ pCallStack[1] = ((void **)&nRegReturn)[ 0 ];
+ break;
+ }
+ return aType;
+}
+
+//==================================================================================================
+namespace {
+
+extern "C" void privateSnippetExecutor();
+
+int const codeSnippetSize = 7 * 4;
+
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool simpleRetType)
+{
+ sal_uInt32 index = functionIndex;
+ if (!simpleRetType) {
+ index |= 0x80000000;
+ }
+ unsigned int * p = reinterpret_cast< unsigned int * >(code);
+ OSL_ASSERT(sizeof (unsigned int) == 4);
+ // save %sp, -96, %sp ! 92 byte minimal stack frame, + 4 byte dword align:
+ *p++ = 0x9DE3BFA0;
+ // sethi %hi(privateSnippetExecutor), %l0:
+ *p++ = 0x21000000
+ | (reinterpret_cast< unsigned int >(privateSnippetExecutor) >> 10);
+ // sethi %hi(index), %o0:
+ *p++ = 0x11000000 | (index >> 10);
+ // or %o0, %lo(index), %o0:
+ *p++ = 0x90122000 | (index & 0x3FF);
+ // sethi %hi(vtableOffset), %o1:
+ *p++ = 0x13000000 | (vtableOffset >> 10);
+ // jmpl %l0, %lo(privateSnippetExecutor), %g0:
+ *p++ = 0x81C42000
+ | (reinterpret_cast< unsigned int >(privateSnippetExecutor) & 0x3FF);
+ // or %o1, %lo(vtableOffset), %o1:
+ *p++ = 0x92126000 | (vtableOffset & 0x3FF);
+ OSL_ASSERT(
+ reinterpret_cast< unsigned char * >(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) + 1;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 3) * 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) + 2;
+ slots[-3].fn = 0; // RTTI
+ slots[-2].fn = 0; // null
+ slots[-1].fn = 0; // destructor
+ 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,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ 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 * begin, unsigned char const * end)
+{
+ bridges::cpp_uno::cc50_solaris_sparc::flushCode(begin, end);
+}
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx
new file mode 100644
index 000000000000..26f501505f78
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx
@@ -0,0 +1,448 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.18 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <cstddef>
+#include <dlfcn.h>
+#include <new.h>
+#include <typeinfo>
+#include <list>
+#include <map>
+#include <rtl/alloc.h>
+#include <osl/diagnose.h>
+#include <typelib/typedescription.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#include "cc50_solaris_sparc.hxx"
+#include "flushcode.hxx"
+#include <rtl/strbuf.hxx>
+
+#include "bridges/cpp_uno/shared/arraypointer.hxx"
+
+#include <hash.cxx>
+
+// need a += operator for OString and sal_Char
+namespace rtl
+{
+ inline OString& operator+=( OString& rString, sal_Char cAdd )
+ {
+ sal_Char add[2];
+ add[0] = cAdd;
+ add[1] = 0;
+ return rString += add;
+ }
+}
+
+using namespace std;
+using namespace osl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+//==================================================================================================
+static OString toUNOname( const OString & rRTTIname )
+{
+ OString aRet;
+
+ const sal_Char* pRTTI = rRTTIname.getStr();
+ const sal_Char* pOrg = pRTTI;
+ const sal_Char* pLast = pRTTI;
+
+ while( 1 )
+ {
+ if( *pRTTI == ':' || ! *pRTTI )
+ {
+ if( aRet.getLength() )
+ aRet += ".";
+ aRet += rRTTIname.copy( pLast - pOrg, pRTTI - pLast );
+ while( *pRTTI == ':' )
+ pRTTI++;
+ pLast = pRTTI;
+ if( ! *pRTTI )
+ break;
+ }
+ else
+ pRTTI++;
+ }
+
+ return aRet;
+}
+//==================================================================================================
+static OString toRTTIname( const OString & rUNOname )
+{
+ OStringBuffer aRet( rUNOname.getLength()*2 );
+
+ sal_Int32 nIndex = 0;
+ do
+ {
+ if( nIndex > 0 )
+ aRet.append( "::" );
+ aRet.append( rUNOname.getToken( 0, '.', nIndex ) );
+ } while( nIndex != -1 );
+
+ return aRet.makeStringAndClear();
+}
+//==================================================================================================
+
+static OString toRTTImangledname( const OString & rRTTIname )
+{
+ if( ! rRTTIname.getLength() )
+ return OString();
+
+ OStringBuffer aRet( rRTTIname.getLength()*2 );
+
+ aRet.append( "__1n" );
+ sal_Int32 nIndex = 0;
+ do
+ {
+ OString aToken( rRTTIname.getToken( 0, ':', nIndex ) );
+ int nBytes = aToken.getLength();
+ if( nBytes )
+ {
+ if( nBytes > 25 )
+ {
+ aRet.append( (sal_Char)( nBytes/26 + 'a' ) );
+ aRet.append( (sal_Char)( nBytes%26 + 'A' ) );
+ }
+ else
+ aRet.append( (sal_Char)( nBytes + 'A' ) );
+ for (sal_Int32 i = 0; i < aToken.getLength(); ++i) {
+ char c = aToken[i];
+ if (c == 'Q') {
+ aRet.append("QdD");
+ } else {
+ aRet.append(c);
+ }
+ }
+ }
+ } while( nIndex != -1 );
+
+ aRet.append( '_' );
+
+ return aRet.makeStringAndClear();
+}
+
+
+//##################################################################################################
+//#### RTTI simulation #############################################################################
+//##################################################################################################
+
+class RTTIHolder
+{
+ std::map< OString, void* > aAllRTTI;
+public:
+ ~RTTIHolder();
+
+ void* getRTTI( const OString& rTypename );
+ void* getRTTI_UnoName( const OString& rUnoTypename )
+ { return getRTTI( toRTTIname( rUnoTypename ) ); }
+
+ void* insertRTTI( const OString& rTypename );
+ void* insertRTTI_UnoName( const OString& rTypename )
+ { return insertRTTI( toRTTIname( rTypename ) ); }
+ void* generateRTTI( typelib_CompoundTypeDescription* pCompTypeDescr );
+};
+
+RTTIHolder::~RTTIHolder()
+{
+ for ( std::map< OString, void* >::const_iterator iPos( aAllRTTI.begin() );
+ iPos != aAllRTTI.end(); ++iPos )
+ {
+ delete[] static_cast< char * >(iPos->second);
+ }
+}
+
+#if OSL_DEBUG_LEVEL > 1
+#include <stdio.h>
+#endif
+
+void* RTTIHolder::getRTTI( const OString& rTypename )
+{
+ std::map< OString, void* >::iterator element;
+
+ element = aAllRTTI.find( rTypename );
+ if( element != aAllRTTI.end() )
+ return (*element).second;
+
+ // create rtti structure
+ element = aAllRTTI.find( rTypename );
+ if( element != aAllRTTI.end() )
+ return (*element).second;
+
+ return NULL;
+}
+
+void* RTTIHolder::insertRTTI( const OString& rTypename )
+{
+ OString aMangledName( toRTTImangledname( rTypename ) );
+ NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
+
+ std::size_t const RTTI_SIZE = 19; // 14???
+ void** pRTTI = reinterpret_cast< void ** >(
+ new char[RTTI_SIZE * sizeof (void *) + strlen(rTypename.getStr()) + 1]);
+ pRTTI[ 0 ] = reinterpret_cast< void * >(RTTI_SIZE * sizeof (void *));
+ pRTTI[ 1 ] = NULL;
+ pRTTI[ 2 ] = (void*)(7*sizeof(void*));
+ pRTTI[ 3 ] = (void*)aHash.getHash()[0];
+ pRTTI[ 4 ] = (void*)aHash.getHash()[1];
+ pRTTI[ 5 ] = (void*)aHash.getHash()[2];
+ pRTTI[ 6 ] = (void*)aHash.getHash()[3];
+ pRTTI[ 7 ] = NULL;
+ pRTTI[ 8 ] = NULL;
+
+ pRTTI[ 9 ] = pRTTI[ 3 ];
+ pRTTI[ 10 ] = pRTTI[ 4 ];
+ pRTTI[ 11 ] = pRTTI[ 5 ];
+ pRTTI[ 12 ] = pRTTI[ 6 ];
+ pRTTI[ 13 ] = (void*)0x80000000;
+ strcpy(reinterpret_cast< char * >(pRTTI + RTTI_SIZE), rTypename.getStr());
+
+ aAllRTTI[ rTypename ] = (void*)pRTTI;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,
+ "generating base RTTI for type %s:\n"
+ " mangled: %s\n"
+ " hash: %.8x %.8x %.8x %.8x\n",
+ rTypename.getStr(),
+ aMangledName.getStr(),
+ pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ]
+ );
+#endif
+ return pRTTI;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+void* RTTIHolder::generateRTTI( typelib_CompoundTypeDescription * pCompTypeDescr )
+{
+ OString aUNOCompTypeName( OUStringToOString( pCompTypeDescr->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ OString aRTTICompTypeName( toRTTIname( aUNOCompTypeName ) );
+
+ void* pHaveRTTI = getRTTI( aRTTICompTypeName );
+ if( pHaveRTTI )
+ return pHaveRTTI;
+
+ if( ! pCompTypeDescr->pBaseTypeDescription )
+ // this is a base type
+ return insertRTTI( aRTTICompTypeName );
+
+ // get base class RTTI
+ void* pSuperRTTI = generateRTTI( pCompTypeDescr->pBaseTypeDescription );
+ OSL_ENSURE( pSuperRTTI, "could not generate RTTI for supertype !" );
+
+ // find out the size to allocate for RTTI
+ void** pInherit = (void**)((sal_uInt32)pSuperRTTI + ((sal_uInt32*)pSuperRTTI)[2] + 8);
+ int nInherit;
+ for( nInherit = 1; pInherit[ nInherit*5-1 ] != (void*)0x80000000; nInherit++ )
+ ;
+
+ OString aMangledName( toRTTImangledname( aRTTICompTypeName ) );
+ NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
+
+ std::size_t const rttiSize = 14 + nInherit * 5;
+ void** pRTTI = reinterpret_cast< void ** >(
+ new char[
+ rttiSize * sizeof (void *)
+ + strlen(aRTTICompTypeName.getStr()) + 1]);
+ pRTTI[ 0 ] = reinterpret_cast< void * >(rttiSize * sizeof (void *));
+ pRTTI[ 1 ] = NULL;
+ pRTTI[ 2 ] = (void*)(7*sizeof(void*));
+ pRTTI[ 3 ] = (void*)aHash.getHash()[0];
+ pRTTI[ 4 ] = (void*)aHash.getHash()[1];
+ pRTTI[ 5 ] = (void*)aHash.getHash()[2];
+ pRTTI[ 6 ] = (void*)aHash.getHash()[3];
+ pRTTI[ 7 ] = NULL;
+ pRTTI[ 8 ] = NULL;
+
+ memcpy( pRTTI+9, pInherit, 4*nInherit*5 );
+ pRTTI[ 8 +nInherit*5 ] = NULL;
+ pRTTI[ 9 +nInherit*5 ] = pRTTI[ 3 ];
+ pRTTI[ 10+nInherit*5 ] = pRTTI[ 4 ];
+ pRTTI[ 11+nInherit*5 ] = pRTTI[ 5 ];
+ pRTTI[ 12+nInherit*5 ] = pRTTI[ 6 ];
+ pRTTI[ 13+nInherit*5 ] = (void*)0x80000000;
+ strcpy(
+ reinterpret_cast< char * >(pRTTI + rttiSize),
+ aRTTICompTypeName.getStr());
+
+ aAllRTTI[ aRTTICompTypeName ] = (void*)pRTTI;
+
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,
+ "generating struct RTTI for type %s:\n"
+ " mangled: %s\n"
+ " hash: %.8x %.8x %.8X %.8x\n",
+ aRTTICompTypeName.getStr(),
+ aMangledName.getStr(),
+ pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ]
+ );
+#endif
+
+ return pRTTI;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+static void deleteException(
+ void* pExc, unsigned int* thunk, typelib_TypeDescription* pType )
+{
+ uno_destructData(
+ pExc, pType, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ typelib_typedescription_release( pType );
+ delete[] thunk;
+}
+
+//__________________________________________________________________________________________________
+
+//##################################################################################################
+//#### exported ####################################################################################
+//##################################################################################################
+
+void cc50_solaris_sparc_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 occured: %s\n", cstr.getStr() );
+#endif
+ bridges::cpp_uno::shared::ArrayPointer< unsigned int > thunkPtr(
+ new unsigned int[6]);
+
+ typelib_TypeDescription * pTypeDescr = 0;
+ // will be released by deleteException
+ typelib_typedescriptionreference_getDescription( &pTypeDescr, pUnoExc->pType );
+
+ void* pRTTI;
+ {
+ static ::osl::Mutex aMutex;
+ ::osl::Guard< ::osl::Mutex > guard( aMutex );
+
+ static RTTIHolder * s_pRTTI = 0;
+ if (! s_pRTTI)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_pRTTI = new RTTIHolder();
+#else
+ static RTTIHolder s_aRTTI;
+ s_pRTTI = &s_aRTTI;
+#endif
+ }
+
+ pRTTI = s_pRTTI->generateRTTI( (typelib_CompoundTypeDescription *)pTypeDescr );
+ }
+
+ // a must be
+ OSL_ENSURE( sizeof(sal_Int32) == sizeof(void *), "### pointer size differs from sal_Int32!" );
+
+ void * pCppExc = __Crun::ex_alloc( pTypeDescr->nSize );
+ uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ uno_any_destruct( pUnoExc, 0 );
+
+ unsigned int * thunk = thunkPtr.release();
+ // sethi %hi(thunk), %o1:
+ thunk[0] = 0x13000000 | (reinterpret_cast< unsigned int >(thunk) >> 10);
+ // or %o1, %lo(thunk), %o1:
+ thunk[1] = 0x92126000 | (reinterpret_cast< unsigned int >(thunk) & 0x3FF);
+ // sethi %hi(pTypeDescr), %o2:
+ thunk[2] = 0x15000000
+ | (reinterpret_cast< unsigned int >(pTypeDescr) >> 10);
+ // sethi %hi(deleteException), %o3
+ thunk[3] = 0x17000000
+ | (reinterpret_cast< unsigned int >(deleteException) >> 10);
+ // jmpl %o3, %lo(deleteException), %g0
+ thunk[4] = 0x81C2E000
+ | (reinterpret_cast< unsigned int >(deleteException) & 0x3FF);
+ // or %o2, %lo(pTypeDescr), %o2:
+ thunk[5] = 0x9412A000
+ | (reinterpret_cast< unsigned int >(pTypeDescr) & 0x3FF);
+ bridges::cpp_uno::cc50_solaris_sparc::flushCode(thunk, thunk + 6);
+
+#pragma disable_warn
+ void (* f)(void *) = reinterpret_cast< void (*)(void *) >(thunk);
+#pragma enable_warn
+ __Crun::ex_throw(pCppExc, (const __Crun::static_type_info*)pRTTI, f);
+}
+
+void cc50_solaris_sparc_fillUnoException(
+ void* pCppExc,
+ const char* pInfo,
+ uno_Any* pUnoExc,
+ uno_Mapping * pCpp2Uno )
+{
+ OSL_ASSERT( pInfo != 0 );
+ OString uno_name( toUNOname( pInfo ) );
+ OUString aName( OStringToOUString(
+ uno_name, RTL_TEXTENCODING_ASCII_US ) );
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ typelib_typedescription_getByName( &pExcTypeDescr, aName.pData );
+
+ if (pExcTypeDescr == 0) // the thing that should not be
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "exception type not found: ") ) + aName,
+ 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_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "> c++ exception occured: %s\n",
+ ::rtl::OUStringToOString(
+ pExcTypeDescr->pTypeName,
+ RTL_TEXTENCODING_ASCII_US ).getStr() );
+#endif
+ // construct uno exception any
+ uno_any_constructAndConvert(
+ pUnoExc, pCppExc, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+
+
+
+
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/flushcode.hxx b/bridges/source/cpp_uno/cc50_solaris_sparc/flushcode.hxx
new file mode 100644
index 000000000000..2945bd3648d6
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/flushcode.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: flushcode.hxx,v $
+ * $Revision: 1.4.20.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC50_SOLARIS_SPARC_FLUSHCODE_HXX
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC50_SOLARIS_SPARC_FLUSHCODE_HXX
+
+#include "sal/config.h"
+
+extern "C" void sync_instruction_memory(caddr_t addr, int len); // from libc
+
+namespace bridges { namespace cpp_uno { namespace cc50_solaris_sparc {
+
+/**
+ * Flush a region of memory into which code has been written dynamically.
+ */
+inline void flushCode(void const * begin, void const * end) {
+ sync_instruction_memory(
+ static_cast< caddr_t >(const_cast< void * >(begin)),
+ static_cast< char const * >(end) - static_cast< char const * >(begin));
+}
+
+} } }
+
+#endif
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/hash.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/hash.cxx
new file mode 100644
index 000000000000..0d3e4afe5e65
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/hash.cxx
@@ -0,0 +1,267 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: hash.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+
+#ifndef TEST
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+#else
+typedef unsigned int sal_uInt32;
+#endif
+
+#include <string.h>
+
+/*
+ * build a hash for a character buffer using the NIST algorithm
+ */
+
+class NIST_Hash
+{
+
+ // helper functions
+ sal_uInt32 f1( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
+ {
+ return z ^ ( x & ( y ^ z ) );
+ }
+
+ sal_uInt32 f2( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
+ {
+ return x ^ y ^ z;
+ }
+
+ sal_uInt32 f3( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
+ {
+ return ( x & y ) + ( z & ( x ^ y ) );
+ }
+
+ sal_uInt32 rotl( sal_uInt32 nValue, sal_uInt32 nBits )
+ {
+ return ( nValue << nBits ) | ( nValue >> (32-nBits) );
+ }
+
+ sal_uInt32 expand_nostore( sal_uInt32 index )
+ {
+ return data[index&15] ^ data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
+ }
+
+ sal_uInt32 expand_store( sal_uInt32 index )
+ {
+ return data[index&15] ^= data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
+ }
+
+ void subRound( sal_uInt32 a, sal_uInt32& b, sal_uInt32 c, sal_uInt32 d, sal_uInt32& e, sal_uInt32 constant, sal_uInt32 datum, sal_uInt32 nFunction )
+ {
+ e += rotl(a,5);
+ switch( nFunction )
+ {
+ case 1: e += f1( b, c, d );break;
+ case 2:
+ case 4: e += f2( b, c, d );break;
+ case 3: e += f3( b, c, d );break;
+ }
+ e += constant + datum;
+ b = rotl( b, 30 );
+ }
+
+ void transform();
+ void final();
+
+ // data members
+ sal_uInt32 data[16];
+ sal_uInt32 hashdata[5];
+public:
+ NIST_Hash( const char* pString, sal_uInt32 nLen );
+
+ sal_uInt32 *getHash() { return hashdata; }
+};
+
+void NIST_Hash::transform()
+{
+ // constants
+ const sal_uInt32 K2 = 0x5A827999;
+ const sal_uInt32 K3 = 0x6ED9EBA1;
+ const sal_uInt32 K5 = 0x8F1BBCDC;
+ const sal_uInt32 K10 = 0xCA62C1D6;
+
+ sal_uInt32 a, b, c, d, e;
+ a = hashdata[0];
+ b = hashdata[1];
+ c = hashdata[2];
+ d = hashdata[3];
+ e = hashdata[4];
+
+ subRound( a, b, c, d, e, K2, data[ 0], 1 );
+ subRound( e, a, b, c, d, K2, data[ 1], 1 );
+ subRound( d, e, a, b, c, K2, data[ 2], 1 );
+ subRound( c, d, e, a, b, K2, data[ 3], 1 );
+ subRound( b, c, d, e, a, K2, data[ 4], 1 );
+ subRound( a, b, c, d, e, K2, data[ 5], 1 );
+ subRound( e, a, b, c, d, K2, data[ 6], 1 );
+ subRound( d, e, a, b, c, K2, data[ 7], 1 );
+ subRound( c, d, e, a, b, K2, data[ 8], 1 );
+ subRound( b, c, d, e, a, K2, data[ 9], 1 );
+ subRound( a, b, c, d, e, K2, data[10], 1 );
+ subRound( e, a, b, c, d, K2, data[11], 1 );
+ subRound( d, e, a, b, c, K2, data[12], 1 );
+ subRound( c, d, e, a, b, K2, data[13], 1 );
+ subRound( b, c, d, e, a, K2, data[14], 1 );
+ subRound( a, b, c, d, e, K2, data[15], 1 );
+ subRound( e, a, b, c, d, K2, expand_store( 16 ), 1 );
+ subRound( d, e, a, b, c, K2, expand_store( 17 ), 1 );
+ subRound( c, d, e, a, b, K2, expand_store( 18 ), 1 );
+ subRound( b, c, d, e, a, K2, expand_store( 19 ), 1 );
+
+ subRound( a, b, c, d, e, K3, expand_store( 20 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 21 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 22 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 23 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 24 ), 2 );
+ subRound( a, b, c, d, e, K3, expand_store( 25 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 26 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 27 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 28 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 29 ), 2 );
+ subRound( a, b, c, d, e, K3, expand_store( 30 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 31 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 32 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 33 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 34 ), 2 );
+ subRound( a, b, c, d, e, K3, expand_store( 35 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 36 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 37 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 38 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 39 ), 2 );
+
+ subRound( a, b, c, d, e, K5, expand_store( 40 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 41 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 42 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 43 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 44 ), 3 );
+ subRound( a, b, c, d, e, K5, expand_store( 45 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 46 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 47 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 48 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 49 ), 3 );
+ subRound( a, b, c, d, e, K5, expand_store( 50 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 51 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 52 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 53 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 54 ), 3 );
+ subRound( a, b, c, d, e, K5, expand_store( 55 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 56 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 57 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 58 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 59 ), 3 );
+
+ subRound( a, b, c, d, e, K10, expand_store( 60 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 61 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_store( 62 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_store( 63 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_store( 64 ), 4 );
+ subRound( a, b, c, d, e, K10, expand_store( 65 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 66 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_store( 67 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_store( 68 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_store( 69 ), 4 );
+ subRound( a, b, c, d, e, K10, expand_store( 70 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 71 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_store( 72 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_store( 73 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_store( 74 ), 4 );
+ subRound( a, b, c, d, e, K10, expand_store( 75 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 76 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_nostore( 77 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_nostore( 78 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_nostore( 79 ), 4 );
+
+ hashdata[0] += a;
+ hashdata[1] += b;
+ hashdata[2] += c;
+ hashdata[3] += d;
+ hashdata[4] += e;
+}
+
+#define BLOCKSIZE sizeof( data )
+
+NIST_Hash::NIST_Hash( const char* pString, sal_uInt32 nLen )
+{
+ hashdata[0] = 0x67452301;
+ hashdata[1] = 0xefcdab89;
+ hashdata[2] = 0x98badcfe;
+ hashdata[3] = 0x10325476;
+ hashdata[4] = 0xc3d2e1f0;
+
+ sal_uInt32 nBytes = nLen;
+
+ while( nLen >= sizeof( data ) )
+ {
+ memcpy( data, pString, sizeof( data ) );
+ pString += sizeof( data );
+ nLen -= sizeof( data );
+ transform();
+ }
+ memcpy( data, pString, nLen );
+ ((char*)data)[nLen++] = 0x80;
+ if( nLen > sizeof( data ) - 8 )
+ {
+ memset( ((char*)data)+nLen, 0, sizeof( data ) - nLen );
+ transform();
+ memset( data, 0, sizeof( data ) - 8 );
+ }
+ else
+ memset( ((char*)data)+nLen, 0, sizeof( data ) - 8 - nLen );
+ data[14] = 0;
+ data[15] = nBytes << 3;
+ transform();
+}
+
+#ifdef TEST
+#include <stdio.h>
+int main( int argc, const char** argv )
+{
+ const char* pHash = argc < 2 ? argv[0] : argv[1];
+
+ NIST_Hash aHash( pHash, strlen( pHash ) );
+ sal_uInt32* pBits = aHash.getHash();
+
+ printf( "text : %s\n"
+ "bits : 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
+ pHash,
+ pBits[0], pBits[1], pBits[2],pBits[3],pBits[4]
+ );
+ return 0;
+}
+
+#endif
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/makefile.mk b/bridges/source/cpp_uno/cc50_solaris_sparc/makefile.mk
new file mode 100644
index 000000000000..2e569d4f008f
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/makefile.mk
@@ -0,0 +1,84 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.17.12.1 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=sunpro5_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+# disable check for PIC code as it would complain about
+# hand coded assembler
+CHECKFORPIC=
+
+.IF "$(COM)" == "C52" && "$(CPU)"=="S"
+
+#CFLAGS += -O5 -xO5
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+SLOFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB= i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH= URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+.INCLUDE : target.mk
+
+
+$(SLO)$/%.obj: %.s
+ CC -KPIC -c -o $(SLO)$/$(@:b).o $< && touch $@
+
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx
new file mode 100644
index 000000000000..bfcf4607ce7d
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx
@@ -0,0 +1,399 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.21 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.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 "cc50_solaris_sparc.hxx"
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+namespace
+{
+
+extern "C" void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs
+ );
+
+//==================================================================================================
+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 )
+{
+ // pCppI is cc50_solaris_sparc this pointer
+ OSL_ENSURE( pThis, "### no interface given!" );
+
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack = (char *)alloca( ((nParams+3) * sizeof(sal_Int64)) );
+ 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 = *(void **)pCppStack
+ = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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 ))
+ {
+ pCppArgs[ nPos ] = CPPU_CURRENT_NAMESPACE::adjustPointer(
+ pCppStack, pParamTypeDescr );
+ uno_copyAndConvertData( pCppArgs[nPos], 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
+ }
+ // 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 );
+ 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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
+ }
+
+// seems that EH registration for callVirtualMethod is not really
+// necessary
+
+// static unsigned long* pFrameInfo = NULL;
+
+// if( ! pFrameInfo )
+// {
+// pFrameInfo = new unsigned long[ 7 ];
+// pFrameInfo[ 0 ] = 0x40000000 | (((unsigned long)__Crun::ex_rethrow_q) >> 2);
+// pFrameInfo[ 1 ] = 0x01000000;
+// pFrameInfo[ 2 ] = (unsigned long)callVirtualMethodExceptionHandler;
+// pFrameInfo[ 3 ] = 0;
+// pFrameInfo[ 4 ] = (unsigned long)pFrameInfo - (unsigned long)callVirtualMethodExceptionHandler;
+// pFrameInfo[ 5 ] = 0;
+// pFrameInfo[ 6 ] = 0;
+// _ex_register( pFrameInfo+2, 1 );
+// }
+
+ try
+ {
+ int nStackLongs = (pCppStack - pCppStackStart)/sizeof(sal_Int32);
+ if( nStackLongs & 1 )
+ // stack has to be 8 byte aligned
+ nStackLongs++;
+
+ callVirtualMethod(
+ pAdjustedThisPtr,
+ aVtableSlot.index,
+ pCppReturn,
+ pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart,
+ nStackLongs
+ );
+
+ // NO exception occured...
+ *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,
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData(
+ pCppReturn, pReturnTypeDescr,
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ }
+ }
+ catch( ... )
+ {
+ void* pExc = __Crun::ex_get();
+ const char* pName = __Cimpl::ex_name();
+
+ // get exception
+ CPPU_CURRENT_NAMESPACE::cc50_solaris_sparc_fillUnoException(
+ pExc, pName, *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],
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+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);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.hxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.hxx
new file mode 100644
index 000000000000..d660e9b7dd94
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.hxx
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: callvirtualmethod.hxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_CALLVIRTUALMETHOD_Hx
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_CALLVIRTUALMETHOD_Hx
+
+#include "sal/config.h"
+
+extern "C" void callVirtualMethod(
+ unsigned long function, long * stack, sal_Int32 excess);
+
+#endif
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.s b/bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.s
new file mode 100644
index 000000000000..c680f092baeb
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.s
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: callvirtualmethod.s,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+.global callVirtualMethod
+.align 8
+callVirtualMethod:
+ ! %o0: unsigned long function
+ ! %o1: unsigned long * stack
+ ! %o2: sal_Int32 excess
+ add %o2, 176, %o3
+ neg %o3
+ save %sp, %o3, %sp
+ ldx [%i1 + 0 * 8], %o0
+ ldx [%i1 + 1 * 8], %o1
+ ldx [%i1 + 2 * 8], %o2
+ ldx [%i1 + 3 * 8], %o3
+ tst %i2
+ bz,pt %xcc, 1f
+ ldx [%i1 + 4 * 8], %o4
+ add %i1, 6 * 8, %l0
+ add %sp, 2047 + 176, %l1
+0: deccc 8, %i2
+ ldx [%l0 + %i2], %l2
+ bnz,pt %xcc, 0b
+ stx %l2, [%l1 + %i2]
+1: call %i0
+ ldx [%i1 + 5 * 8], %o5
+ stx %o0, [%i1 + 0 * 8]
+ stx %o1, [%i1 + 1 * 8]
+ stx %o2, [%i1 + 2 * 8]
+ stx %o3, [%i1 + 3 * 8]
+ ret
+ restore
+.size callVirtualMethod, . - callVirtualMethod
+.type callVirtualMethod, #function
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/cpp2uno.cxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/cpp2uno.cxx
new file mode 100644
index 000000000000..ad40d673513f
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/cpp2uno.cxx
@@ -0,0 +1,615 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_bridges.hxx"
+#include "sal/config.h"
+
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
+
+#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 "com/sun/star/uno/genfunc.hxx"
+#include "osl/diagnose.h"
+#include "sal/alloca.h"
+#include "sal/types.h"
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+#include "typelib/typedescription.hxx"
+#include "uno/any2.h"
+#include "uno/data.h"
+
+#include "exceptions.hxx"
+#include "flushcode.hxx"
+#include "fp.hxx"
+#include "isdirectreturntype.hxx"
+#include "vtableslotcall.hxx"
+
+namespace {
+
+namespace css = com::sun::star;
+
+void loadFpRegsFromStruct(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_loadf0(reinterpret_cast< float * >(data));
+ break;
+ case 4:
+ fp_loadf1(reinterpret_cast< float * >(data) + 1);
+ break;
+ case 8:
+ fp_loadf2(reinterpret_cast< float * >(data) + 2);
+ break;
+ case 12:
+ fp_loadf3(reinterpret_cast< float * >(data) + 3);
+ break;
+ case 16:
+ fp_loadf4(reinterpret_cast< float * >(data) + 4);
+ break;
+ case 20:
+ fp_loadf5(reinterpret_cast< float * >(data) + 5);
+ break;
+ case 24:
+ fp_loadf6(reinterpret_cast< float * >(data) + 6);
+ break;
+ case 28:
+ fp_loadf7(reinterpret_cast< float * >(data) + 7);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ switch (t->pMemberOffsets[i]) {
+ case 0:
+ fp_loadd0(reinterpret_cast< double * >(data));
+ break;
+ case 8:
+ fp_loadd2(reinterpret_cast< double * >(data) + 1);
+ break;
+ case 16:
+ fp_loadd4(reinterpret_cast< double * >(data) + 2);
+ break;
+ case 24:
+ fp_loadd6(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]);
+ loadFpRegsFromStruct(td, data);
+ TYPELIB_DANGER_RELEASE(td);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * proxy,
+ css::uno::TypeDescription const & description,
+ bool directReturn, typelib_TypeDescriptionReference * returnType,
+ sal_Int32 count, typelib_MethodParameter * parameters,
+ unsigned long * callStack)
+{
+ typelib_TypeDescription * rtd = NULL;
+ if (returnType != NULL) {
+ TYPELIB_DANGER_GET(&rtd, returnType);
+ }
+ bool retconv =
+ rtd != NULL && bridges::cpp_uno::shared::relatesToInterfaceType(rtd);
+ OSL_ASSERT(!(directReturn && retconv));
+ void * retin;
+ void * retout;
+ char retbuf[32];
+ if (directReturn) {
+ retin = returnType == NULL ? NULL : retbuf;
+ } else {
+ retout = reinterpret_cast< void * >(callStack[0]);
+ retin = retconv ? alloca(rtd->nSize) : retout;
+ }
+ void ** args = static_cast< void ** >(alloca(count * sizeof (void *)));
+ void ** cppArgs = static_cast< void ** >(alloca(count * sizeof (void *)));
+ typelib_TypeDescription ** argtds =
+ static_cast< typelib_TypeDescription ** >(
+ alloca(count * sizeof (typelib_TypeDescription *)));
+ union fp { float f; double d; };
+ fp copies[15];
+ sal_Int32 stackPos = directReturn ? 1 : 2; // skip return ptr and this ptr
+ for (sal_Int32 i = 0; i < count; ++i) {
+ typelib_TypeDescription * ptd = NULL;
+ TYPELIB_DANGER_GET(&ptd, parameters[i].pTypeRef);
+ if (!parameters[i].bOut && bridges::cpp_uno::shared::isSimpleType(ptd))
+ {
+ switch (ptd->eTypeClass) {
+ case typelib_TypeClass_FLOAT:
+ if (stackPos <= 15) {
+ switch (stackPos) {
+ case 1:
+ fp_storef3(&copies[0].f);
+ break;
+ case 2:
+ fp_storef5(&copies[1].f);
+ break;
+ case 3:
+ fp_storef7(&copies[2].f);
+ break;
+ case 4:
+ fp_storef9(&copies[3].f);
+ break;
+ case 5:
+ fp_storef11(&copies[4].f);
+ break;
+ case 6:
+ fp_storef13(&copies[5].f);
+ break;
+ case 7:
+ fp_storef15(&copies[6].f);
+ break;
+ case 8:
+ fp_storef17(&copies[7].f);
+ break;
+ case 9:
+ fp_storef19(&copies[8].f);
+ break;
+ case 10:
+ fp_storef21(&copies[9].f);
+ break;
+ case 11:
+ fp_storef23(&copies[10].f);
+ break;
+ case 12:
+ fp_storef25(&copies[11].f);
+ break;
+ case 13:
+ fp_storef27(&copies[12].f);
+ break;
+ case 14:
+ fp_storef29(&copies[13].f);
+ break;
+ case 15:
+ fp_storef31(&copies[14].f);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ args[i] = &copies[stackPos - 1].f;
+ } else {
+ args[i] = reinterpret_cast< char * >(callStack + stackPos) +
+ (sizeof (unsigned long) - sizeof (float));
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (stackPos <= 15) {
+ switch (stackPos) {
+ case 1:
+ fp_stored2(&copies[0].d);
+ break;
+ case 2:
+ fp_stored4(&copies[1].d);
+ break;
+ case 3:
+ fp_stored6(&copies[2].d);
+ break;
+ case 4:
+ fp_stored8(&copies[3].d);
+ break;
+ case 5:
+ fp_stored10(&copies[4].d);
+ break;
+ case 6:
+ fp_stored12(&copies[5].d);
+ break;
+ case 7:
+ fp_stored14(&copies[6].d);
+ break;
+ case 8:
+ fp_stored16(&copies[7].d);
+ break;
+ case 9:
+ fp_stored18(&copies[8].d);
+ break;
+ case 10:
+ fp_stored20(&copies[9].d);
+ break;
+ case 11:
+ fp_stored22(&copies[10].d);
+ break;
+ case 12:
+ fp_stored24(&copies[11].d);
+ break;
+ case 13:
+ fp_stored26(&copies[12].d);
+ break;
+ case 14:
+ fp_stored28(&copies[13].d);
+ break;
+ case 15:
+ fp_stored30(&copies[14].d);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ args[i] = &copies[stackPos - 1].d;
+ } else {
+ args[i] = reinterpret_cast< char * >(callStack + stackPos) +
+ (sizeof (unsigned long) - sizeof (double));
+ }
+ break;
+ default:
+ OSL_ASSERT(ptd->nSize <= 8);
+ args[i] = reinterpret_cast< char * >(callStack + stackPos) +
+ (sizeof (unsigned long) - ptd->nSize);
+ break;
+ }
+ argtds[i] = NULL;
+ TYPELIB_DANGER_RELEASE(ptd);
+ } else {
+ cppArgs[i] = reinterpret_cast< void * >(callStack[stackPos]);
+ if (!parameters[i].bIn) {
+ args[i] = alloca(ptd->nSize);
+ argtds[i] = ptd;
+ } else if (bridges::cpp_uno::shared::relatesToInterfaceType(ptd)) {
+ args[i] = alloca(ptd->nSize);
+ uno_copyAndConvertData(
+ args[i], reinterpret_cast< void * >(callStack[stackPos]),
+ ptd, proxy->getBridge()->getCpp2Uno());
+ argtds[i] = ptd;
+ } else {
+ args[i] = reinterpret_cast< void * >(callStack[stackPos]);
+ argtds[i] = NULL;
+ TYPELIB_DANGER_RELEASE(ptd);
+ }
+ }
+ ++stackPos;
+ }
+ uno_Any exc;
+ uno_Any * pexc = &exc;
+ proxy->getUnoI()->pDispatcher(
+ proxy->getUnoI(), description.get(), retin, args, &pexc);
+ if (pexc != NULL) {
+ for (sal_Int32 i = 0; i < count; ++i) {
+ if (argtds[i] != NULL) {
+ if (parameters[i].bIn) {
+ uno_destructData(args[i], argtds[i], NULL);
+ }
+ TYPELIB_DANGER_RELEASE(argtds[i]);
+ }
+ }
+ if (rtd != NULL) {
+ TYPELIB_DANGER_RELEASE(rtd);
+ }
+ bridges::cpp_uno::cc5_solaris_sparc64::raiseException(
+ &exc, proxy->getBridge()->getUno2Cpp());
+ std::abort(); // just in case
+ }
+ for (sal_Int32 i = 0; i < count; ++i) {
+ if (argtds[i] != NULL) {
+ if (parameters[i].bOut) {
+ uno_destructData(
+ cppArgs[i], argtds[i],
+ reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release));
+ uno_copyAndConvertData(
+ cppArgs[i], args[i], argtds[i],
+ proxy->getBridge()->getUno2Cpp());
+ }
+ uno_destructData(args[i], argtds[i], NULL);
+ TYPELIB_DANGER_RELEASE(argtds[i]);
+ }
+ }
+ if (directReturn) {
+ if (rtd != NULL) {
+ switch (rtd->eTypeClass) {
+ case typelib_TypeClass_VOID:
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ callStack[0] = *reinterpret_cast< sal_Bool * >(retbuf);
+ break;
+ case typelib_TypeClass_BYTE:
+ callStack[0] = *reinterpret_cast< sal_Int8 * >(retbuf);
+ break;
+ case typelib_TypeClass_SHORT:
+ callStack[0] = *reinterpret_cast< sal_Int16 * >(retbuf);
+ break;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ callStack[0] = *reinterpret_cast< sal_uInt16 * >(retbuf);
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_ENUM:
+ callStack[0] = *reinterpret_cast< sal_Int32 * >(retbuf);
+ break;
+ case typelib_TypeClass_UNSIGNED_LONG:
+ callStack[0] = *reinterpret_cast< sal_uInt32 * >(retbuf);
+ break;
+ case typelib_TypeClass_HYPER:
+ callStack[0] = *reinterpret_cast< sal_Int64 * >(retbuf);
+ break;
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ callStack[0] = *reinterpret_cast< sal_uInt64 * >(retbuf);
+ break;
+ case typelib_TypeClass_FLOAT:
+ fp_loadf0(reinterpret_cast< float * >(retbuf));
+ break;
+ case typelib_TypeClass_DOUBLE:
+ fp_loadd0(reinterpret_cast< double * >(retbuf));
+ break;
+ case typelib_TypeClass_CHAR:
+ callStack[0] = *reinterpret_cast< sal_Unicode * >(retbuf);
+ break;
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ callStack[0] = reinterpret_cast< unsigned long >(
+ *reinterpret_cast< void ** >(retbuf));
+ break;
+ case typelib_TypeClass_STRUCT:
+ loadFpRegsFromStruct(rtd, retbuf);
+ // fall through
+ case typelib_TypeClass_ANY:
+ std::memcpy(callStack, retbuf, rtd->nSize);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ }
+ } else if (retconv) {
+ uno_copyAndConvertData(
+ retout, retin, rtd, proxy->getBridge()->getUno2Cpp());
+ uno_destructData(retin, rtd, NULL);
+ }
+ if (rtd != NULL) {
+ TYPELIB_DANGER_RELEASE(rtd);
+ }
+}
+
+extern "C" void vtableCall(
+ sal_Int32 functionIndex, sal_Int32 vtableOffset, unsigned long * callStack)
+{
+ bool direct = static_cast< sal_uInt32 >((functionIndex) & 0x80000000) == 0;
+ functionIndex = static_cast< sal_uInt32 >(functionIndex) & 0x7FFFFFFF;
+ bridges::cpp_uno::shared::CppInterfaceProxy * proxy
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ reinterpret_cast< char * >(callStack[direct ? 0 : 1]) -
+ vtableOffset);
+ typelib_InterfaceTypeDescription * type = proxy->getTypeDescr();
+ OSL_ASSERT(functionIndex < type->nMapFunctionIndexToMemberIndex);
+ sal_Int32 pos = type->pMapFunctionIndexToMemberIndex[functionIndex];
+ css::uno::TypeDescription desc(type->ppAllMembers[pos]);
+ switch (desc.get()->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ if (type->pMapMemberIndexToFunctionIndex[pos] == functionIndex) {
+ // Getter:
+ call(
+ proxy, desc, direct,
+ reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
+ desc.get())->pAttributeTypeRef,
+ 0, NULL, callStack);
+ } else {
+ // Setter:
+ typelib_MethodParameter param = {
+ NULL,
+ reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
+ desc.get())->pAttributeTypeRef,
+ true, false };
+ call(proxy, desc, true, NULL, 1, &param, callStack);
+ }
+ break;
+ case typelib_TypeClass_INTERFACE_METHOD:
+ switch (functionIndex) {
+ case 1:
+ proxy->acquireProxy();
+ break;
+ case 2:
+ proxy->releaseProxy();
+ break;
+ case 0:
+ {
+ typelib_TypeDescription * td = NULL;
+ TYPELIB_DANGER_GET(
+ &td,
+ reinterpret_cast< css::uno::Type * >(
+ callStack[2])->getTypeLibType());
+ if (td != NULL) {
+ css::uno::XInterface * ifc = NULL;
+ proxy->getBridge()->getCppEnv()->getRegisteredInterface(
+ proxy->getBridge()->getCppEnv(),
+ reinterpret_cast< void ** >(&ifc),
+ proxy->getOid().pData,
+ reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ td));
+ if (ifc != NULL) {
+ uno_any_construct(
+ reinterpret_cast< uno_Any * >(callStack[0]), &ifc,
+ td,
+ reinterpret_cast< uno_AcquireFunc >(
+ css::uno::cpp_acquire));
+ ifc->release();
+ TYPELIB_DANGER_RELEASE(td);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(td);
+ }
+ } // fall through
+ default:
+ call(
+ proxy, desc, direct,
+ reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
+ desc.get())->pReturnTypeRef,
+ reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
+ desc.get())->nParams,
+ reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
+ desc.get())->pParams,
+ callStack);
+ }
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+}
+
+int const codeSnippetSize = 10 * 4;
+
+unsigned char * generateCodeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool directReturn)
+{
+ sal_uInt32 index = functionIndex;
+ if (!directReturn) {
+ index |= 0x80000000;
+ }
+ unsigned int * p = reinterpret_cast< unsigned int * >(code);
+ OSL_ASSERT(sizeof (unsigned int) == 4);
+ // 0*4: save %sp, -176, %sp ! minimal stack frame:
+ *p++ = 0x9DE3BF50;
+ // 1*4: rd %pc, %l0:
+ *p++ = 0xA1414000;
+ // 2*4: ldx %l0, (8-1)*4, %l0:
+ *p++ = 0xE05C201C;
+ // 3*4: sethi %hi(index), %o0:
+ *p++ = 0x11000000 | (index >> 10);
+ // 4*4: or %o0, %lo(index), %o0:
+ *p++ = 0x90122000 | (index & 0x3FF);
+ // 5*4: sethi %hi(vtableOffset), %o1:
+ *p++ = 0x13000000 | (vtableOffset >> 10);
+ // 6*4: jmpl %l0, %g0, %g0:
+ *p++ = 0x81C40000;
+ // 7*4: or %o1, %lo(vtableOffset), %o1:
+ *p++ = 0x92126000 | (vtableOffset & 0x3FF);
+ // 8*4: .xword privateSnippetExecutor:
+ *reinterpret_cast< unsigned long * >(p) =
+ reinterpret_cast< unsigned long >(vtableSlotCall);
+ 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) + 1;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 3) * 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) + 2;
+ slots[-3].fn = NULL; // RTTI
+ slots[-2].fn = NULL; // null
+ slots[-1].fn = NULL; // destructor
+ 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 = generateCodeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::cc5_solaris_sparc64::isDirectReturnType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = generateCodeSnippet(
+ code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = generateCodeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::cc5_solaris_sparc64::isDirectReturnType(
+ 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 * begin, unsigned char const * end)
+{
+ bridges::cpp_uno::cc5_solaris_sparc64::flushCode(begin, end);
+}
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.cxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.cxx
new file mode 100644
index 000000000000..ef56f2b05831
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.cxx
@@ -0,0 +1,463 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: exceptions.cxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_bridges.hxx"
+#include "sal/config.h"
+
+#include <cstddef>
+#include <cstring>
+#include <map>
+#include <utility>
+#include <vector>
+
+#include "bridges/cpp_uno/shared/arraypointer.hxx"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/uno/genfunc.hxx"
+#include "osl/diagnose.h"
+#include "osl/mutex.hxx"
+#include "rtl/strbuf.hxx"
+#include "rtl/string.hxx"
+#include "rtl/textenc.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+#include "uno/any2.h"
+#include "uno/data.h"
+#include "uno/mapping.h"
+
+#include "exceptions.hxx"
+#include "flushcode.hxx"
+
+namespace {
+
+namespace css = com::sun::star;
+
+typedef void (* Function)(void *);
+
+Function toFunction(void * pointer) {
+#pragma disable_warn
+ return reinterpret_cast< Function >(pointer);
+#pragma enable_warn
+}
+
+bool toUnoName(char const * rttiName, rtl::OUString * unoName) {
+ rtl::OStringBuffer buf;
+ for (;;) {
+ char const * p = std::strchr(rttiName, ':');
+ if (p == NULL) {
+ buf.append(rttiName);
+ break;
+ }
+ if (p - rttiName > SAL_MAX_INT32) {
+ return false;
+ }
+ buf.append(rttiName, sal::static_int_cast< sal_Int32 >(p - rttiName));
+ buf.append(".");
+ while (*p == ':') {
+ ++p;
+ }
+ rttiName = p;
+ }
+ *unoName = rtl::OStringToOUString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_UTF8);
+ //TODO: check conversion failure
+ return true;
+}
+
+class NistHash {
+public:
+ NistHash(rtl::OString const & text);
+
+ sal_uInt32 hashdata[5];
+
+private:
+ static sal_uInt32 f1(sal_uInt32 x, sal_uInt32 y, sal_uInt32 z)
+ { return z ^ (x & (y ^ z)); }
+
+ static sal_uInt32 f2(sal_uInt32 x, sal_uInt32 y, sal_uInt32 z)
+ { return x ^ y ^ z; }
+
+ static sal_uInt32 f3(sal_uInt32 x, sal_uInt32 y, sal_uInt32 z)
+ { return (x & y) + (z & (x ^ y)); }
+
+ static sal_uInt32 rotl(sal_uInt32 value, sal_uInt32 bits)
+ { return (value << bits) | (value >> (32 - bits)); }
+
+ sal_uInt32 expand_nostore(sal_uInt32 index) {
+ return data[index & 15] ^ data[(index - 14) & 15] ^
+ data[(index - 8) & 15] ^ data[(index - 3) & 15];
+ }
+
+ sal_uInt32 expand_store(sal_uInt32 index) {
+ return data[index & 15] ^= data[(index - 14) & 15] ^
+ data[(index - 8) & 15] ^ data[(index - 3) & 15];
+ }
+
+ void subRound(
+ sal_uInt32 a, sal_uInt32 & b, sal_uInt32 c, sal_uInt32 d,
+ sal_uInt32 & e, sal_uInt32 constant, sal_uInt32 datum,
+ sal_uInt32 function)
+ {
+ e += rotl(a, 5);
+ switch (function) {
+ case 1:
+ e += f1(b, c, d);
+ break;
+ case 2:
+ case 4:
+ e += f2(b, c, d);
+ break;
+ case 3:
+ e += f3(b, c, d);
+ break;
+ }
+ e += constant + datum;
+ b = rotl(b, 30);
+ }
+
+ void transform();
+
+ sal_uInt32 data[16];
+};
+
+NistHash::NistHash(rtl::OString const & text) {
+ hashdata[0] = 0x67452301;
+ hashdata[1] = 0xefcdab89;
+ hashdata[2] = 0x98badcfe;
+ hashdata[3] = 0x10325476;
+ hashdata[4] = 0xc3d2e1f0;
+ char const * p = text.getStr();
+ sal_Int32 n = text.getLength();
+ while (n >= sizeof data) {
+ std::memcpy(data, p, sizeof data);
+ p += sizeof data;
+ n -= sizeof data;
+ transform();
+ }
+ std::memcpy(data, p, n);
+ reinterpret_cast< unsigned char *>(data)[n++] = 0x80;
+ if (n > sizeof data - 8) {
+ std::memset(reinterpret_cast< char * >(data) + n, 0, sizeof data - n);
+ transform();
+ std::memset(data, 0, sizeof data - 8);
+ } else {
+ std::memset(
+ reinterpret_cast< char * >(data) + n, 0, sizeof data - 8 - n);
+ }
+ data[14] = 0;
+ data[15] = text.getLength() << 3;
+ transform();
+}
+
+void NistHash::transform() {
+ sal_uInt32 const K2 = 0x5A827999;
+ sal_uInt32 const K3 = 0x6ED9EBA1;
+ sal_uInt32 const K5 = 0x8F1BBCDC;
+ sal_uInt32 const K10 = 0xCA62C1D6;
+ sal_uInt32 a = hashdata[0];
+ sal_uInt32 b = hashdata[1];
+ sal_uInt32 c = hashdata[2];
+ sal_uInt32 d = hashdata[3];
+ sal_uInt32 e = hashdata[4];
+ subRound(a, b, c, d, e, K2, data[ 0], 1);
+ subRound(e, a, b, c, d, K2, data[ 1], 1);
+ subRound(d, e, a, b, c, K2, data[ 2], 1);
+ subRound(c, d, e, a, b, K2, data[ 3], 1);
+ subRound(b, c, d, e, a, K2, data[ 4], 1);
+ subRound(a, b, c, d, e, K2, data[ 5], 1);
+ subRound(e, a, b, c, d, K2, data[ 6], 1);
+ subRound(d, e, a, b, c, K2, data[ 7], 1);
+ subRound(c, d, e, a, b, K2, data[ 8], 1);
+ subRound(b, c, d, e, a, K2, data[ 9], 1);
+ subRound(a, b, c, d, e, K2, data[10], 1);
+ subRound(e, a, b, c, d, K2, data[11], 1);
+ subRound(d, e, a, b, c, K2, data[12], 1);
+ subRound(c, d, e, a, b, K2, data[13], 1);
+ subRound(b, c, d, e, a, K2, data[14], 1);
+ subRound(a, b, c, d, e, K2, data[15], 1);
+ subRound(e, a, b, c, d, K2, expand_store(16), 1);
+ subRound(d, e, a, b, c, K2, expand_store(17), 1);
+ subRound(c, d, e, a, b, K2, expand_store(18), 1);
+ subRound(b, c, d, e, a, K2, expand_store(19), 1);
+ subRound(a, b, c, d, e, K3, expand_store(20), 2);
+ subRound(e, a, b, c, d, K3, expand_store(21), 2);
+ subRound(d, e, a, b, c, K3, expand_store(22), 2);
+ subRound(c, d, e, a, b, K3, expand_store(23), 2);
+ subRound(b, c, d, e, a, K3, expand_store(24), 2);
+ subRound(a, b, c, d, e, K3, expand_store(25), 2);
+ subRound(e, a, b, c, d, K3, expand_store(26), 2);
+ subRound(d, e, a, b, c, K3, expand_store(27), 2);
+ subRound(c, d, e, a, b, K3, expand_store(28), 2);
+ subRound(b, c, d, e, a, K3, expand_store(29), 2);
+ subRound(a, b, c, d, e, K3, expand_store(30), 2);
+ subRound(e, a, b, c, d, K3, expand_store(31), 2);
+ subRound(d, e, a, b, c, K3, expand_store(32), 2);
+ subRound(c, d, e, a, b, K3, expand_store(33), 2);
+ subRound(b, c, d, e, a, K3, expand_store(34), 2);
+ subRound(a, b, c, d, e, K3, expand_store(35), 2);
+ subRound(e, a, b, c, d, K3, expand_store(36), 2);
+ subRound(d, e, a, b, c, K3, expand_store(37), 2);
+ subRound(c, d, e, a, b, K3, expand_store(38), 2);
+ subRound(b, c, d, e, a, K3, expand_store(39), 2);
+ subRound(a, b, c, d, e, K5, expand_store(40), 3);
+ subRound(e, a, b, c, d, K5, expand_store(41), 3);
+ subRound(d, e, a, b, c, K5, expand_store(42), 3);
+ subRound(c, d, e, a, b, K5, expand_store(43), 3);
+ subRound(b, c, d, e, a, K5, expand_store(44), 3);
+ subRound(a, b, c, d, e, K5, expand_store(45), 3);
+ subRound(e, a, b, c, d, K5, expand_store(46), 3);
+ subRound(d, e, a, b, c, K5, expand_store(47), 3);
+ subRound(c, d, e, a, b, K5, expand_store(48), 3);
+ subRound(b, c, d, e, a, K5, expand_store(49), 3);
+ subRound(a, b, c, d, e, K5, expand_store(50), 3);
+ subRound(e, a, b, c, d, K5, expand_store(51), 3);
+ subRound(d, e, a, b, c, K5, expand_store(52), 3);
+ subRound(c, d, e, a, b, K5, expand_store(53), 3);
+ subRound(b, c, d, e, a, K5, expand_store(54), 3);
+ subRound(a, b, c, d, e, K5, expand_store(55), 3);
+ subRound(e, a, b, c, d, K5, expand_store(56), 3);
+ subRound(d, e, a, b, c, K5, expand_store(57), 3);
+ subRound(c, d, e, a, b, K5, expand_store(58), 3);
+ subRound(b, c, d, e, a, K5, expand_store(59), 3);
+ subRound(a, b, c, d, e, K10, expand_store(60), 4);
+ subRound(e, a, b, c, d, K10, expand_store(61), 4);
+ subRound(d, e, a, b, c, K10, expand_store(62), 4);
+ subRound(c, d, e, a, b, K10, expand_store(63), 4);
+ subRound(b, c, d, e, a, K10, expand_store(64), 4);
+ subRound(a, b, c, d, e, K10, expand_store(65), 4);
+ subRound(e, a, b, c, d, K10, expand_store(66), 4);
+ subRound(d, e, a, b, c, K10, expand_store(67), 4);
+ subRound(c, d, e, a, b, K10, expand_store(68), 4);
+ subRound(b, c, d, e, a, K10, expand_store(69), 4);
+ subRound(a, b, c, d, e, K10, expand_store(70), 4);
+ subRound(e, a, b, c, d, K10, expand_store(71), 4);
+ subRound(d, e, a, b, c, K10, expand_store(72), 4);
+ subRound(c, d, e, a, b, K10, expand_store(73), 4);
+ subRound(b, c, d, e, a, K10, expand_store(74), 4);
+ subRound(a, b, c, d, e, K10, expand_store(75), 4);
+ subRound(e, a, b, c, d, K10, expand_store(76), 4);
+ subRound(d, e, a, b, c, K10, expand_nostore(77), 4);
+ subRound(c, d, e, a, b, K10, expand_nostore(78), 4);
+ subRound(b, c, d, e, a, K10, expand_nostore(79), 4);
+ hashdata[0] += a;
+ hashdata[1] += b;
+ hashdata[2] += c;
+ hashdata[3] += d;
+ hashdata[4] += e;
+}
+
+class RttiMap {
+public:
+ static __Crun::static_type_info const * get(
+ typelib_CompoundTypeDescription const * type);
+
+private:
+ RttiMap(); // not defined
+ RttiMap(RttiMap &); // not defined
+ ~RttiMap(); // not defined
+ void operator =(RttiMap &); // not defined
+
+ struct Data {
+ __Crun::static_type_info * info;
+ rtl::OString cppName;
+ std::vector< __Crun::class_base_descr > bases;
+ };
+ typedef std::map< rtl::OUString, Data > Map;
+
+ static void toCppNames(
+ rtl::OUString const & unoName, rtl::OString * cppName,
+ rtl::OString * rttiName);
+
+ static Data const & get_(typelib_CompoundTypeDescription const * type);
+
+ static osl::Mutex m_mutex;
+ static Map * m_map;
+};
+
+osl::Mutex RttiMap::m_mutex;
+RttiMap::Map * RttiMap::m_map;
+
+__Crun::static_type_info const * RttiMap::get(
+ typelib_CompoundTypeDescription const * type)
+{
+ osl::MutexGuard g(m_mutex);
+ if (m_map == NULL) {
+ m_map = new Map; // leaked
+ }
+ return get_(type).info;
+}
+
+void RttiMap::toCppNames(
+ rtl::OUString const & unoName, rtl::OString * cppName,
+ rtl::OString * rttiName)
+{
+ OSL_ASSERT(cppName != NULL && rttiName != NULL);
+ rtl::OStringBuffer bc;
+ rtl::OStringBuffer br;
+ br.append("__1n");
+ for (sal_Int32 i = 0; i != -1;) {
+ rtl::OUString tok(unoName.getToken(0, '.', i));
+ bc.append(rtl::OUStringToOString(tok, RTL_TEXTENCODING_UTF8));
+ // conversion should never fail, as tok should be well-formed ASCII
+ if (i != -1) {
+ bc.append("::");
+ }
+ sal_Int32 len = tok.getLength();
+ sal_Int32 pos = br.getLength();
+ for (sal_Int32 n = len / 26; n > 0; n /= 26) {
+ br.insert(pos, static_cast< char >('a' + (n % 26)));
+ }
+ br.append(static_cast< char >('A' + (len % 26)));
+ for (sal_Int32 j = 0; j < len; ++j) {
+ sal_Unicode c = tok[j];
+ OSL_ASSERT(
+ c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c == '_' ||
+ c >= 'a' && c <= 'z');
+ if (c == 'Q') {
+ br.append("QdD");
+ } else {
+ br.append(static_cast< char >(c));
+ }
+ }
+ }
+ br.append('_');
+ *cppName = bc.makeStringAndClear();
+ *rttiName = br.makeStringAndClear();
+}
+
+RttiMap::Data const & RttiMap::get_(
+ typelib_CompoundTypeDescription const * type)
+{
+ rtl::OUString name(type->aBase.pTypeName);
+ Map::iterator it(m_map->find(name));
+ if (it == m_map->end()) {
+ it = m_map->insert(std::make_pair(name, Data())).first;
+ Data & data = it->second;
+ rtl::OString rttiName;
+ toCppNames(name, &data.cppName, &rttiName);
+ data.info = new __Crun::static_type_info;
+ data.info->ty_name = data.cppName.getStr() -
+ reinterpret_cast< char * >(&data.info->ty_name);
+ data.info->reserved = 0;
+ NistHash hash(rttiName);
+ data.info->type_hash[0] = hash.hashdata[0];
+ data.info->type_hash[1] = hash.hashdata[1];
+ data.info->type_hash[2] = hash.hashdata[2];
+ data.info->type_hash[3] = hash.hashdata[3];
+ data.info->flags = 0;
+ data.info->cv_qualifiers = 0;
+ if (type->pBaseTypeDescription != NULL) {
+ data.bases = get_(type->pBaseTypeDescription).bases;
+ OSL_ASSERT(!data.bases.empty());
+ data.bases.back().offset = 0;
+ }
+ __Crun::class_base_descr last;
+ last.type_hash[0] = data.info->type_hash[0];
+ last.type_hash[1] = data.info->type_hash[1];
+ last.type_hash[2] = data.info->type_hash[2];
+ last.type_hash[3] = data.info->type_hash[3];
+ last.offset = 0x8000000000000000;
+ data.bases.push_back(last);
+ data.info->base_table = reinterpret_cast< char * >(&data.bases[0]) -
+ reinterpret_cast< char * >(&data.info->base_table);
+ }
+ return it->second;
+}
+
+void deleteException(
+ void * exception, unsigned int * thunk, typelib_TypeDescription * type)
+{
+ uno_destructData(
+ exception, type,
+ reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release));
+ typelib_typedescription_release(type);
+ delete[] thunk;
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace cc5_solaris_sparc64 {
+
+void raiseException(uno_Any * exception, uno_Mapping * unoToCpp) {
+ bridges::cpp_uno::shared::ArrayPointer< unsigned long > thunkPtr(
+ new unsigned long[4]);
+ typelib_TypeDescription * type = NULL;
+ typelib_typedescriptionreference_getDescription(&type, exception->pType);
+ __Crun::static_type_info const * rtti = RttiMap::get(
+ reinterpret_cast< typelib_CompoundTypeDescription * >(type));
+ void * exc = __Crun::ex_alloc(type->nSize);
+ uno_copyAndConvertData(exc, exception->pData, type, unoToCpp);
+ uno_any_destruct(exception, NULL);
+ unsigned long * thunk = thunkPtr.release();
+ // 0*4: rd %pc, %o1:
+ // 1*4: ldx %o1, (6-0)*4, %o3:
+ thunk[0] = 0x93414000D65A6018;
+ // 2*4: jmpl %o3, %g0, %g0:
+ // 3*4: ldx %o1, (4-0)*4, %o2:
+ thunk[1] = 0x81C2C000D45A6010;
+ // 4*4: .xword type:
+ thunk[2] = reinterpret_cast< unsigned long >(type);
+ // 6*4: .xword deleteException:
+ thunk[3] = reinterpret_cast< unsigned long >(deleteException);
+ flushCode(thunk, thunk + 4);
+ __Crun::ex_throw(exc, rtti, toFunction(thunk));
+}
+
+void fillUnoException(
+ void * cppException, char const * cppName, uno_Any * unoException,
+ uno_Mapping * cppToUno)
+{
+ rtl::OUString name;
+ typelib_TypeDescription * type = NULL;
+ if (toUnoName(cppName, &name)) {
+ typelib_typedescription_getByName(&type, name.pData);
+ }
+ if (type == NULL || type->eTypeClass != typelib_TypeClass_EXCEPTION) {
+ css::uno::RuntimeException exc(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("Not a UNO exception type: ")) +
+ name),
+ css::uno::Reference< css::uno::XInterface >());
+ uno_type_any_constructAndConvert(
+ unoException, &exc, getCppuType(&exc).getTypeLibType(), cppToUno);
+ } else {
+ uno_any_constructAndConvert(unoException, cppException, type, cppToUno);
+ }
+ if (type != NULL) {
+ typelib_typedescription_release(type);
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.hxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.hxx
new file mode 100644
index 000000000000..bdbbeee8afe6
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: exceptions.hxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_EXCEPTIONS_HXX
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_EXCEPTIONS_HXX
+
+#include "sal/config.h"
+
+#include <cstddef>
+
+#include "typelib/typedescription.h"
+#include "uno/any2.h"
+#include "uno/mapping.h"
+
+// Private CC5 structures and functions:
+namespace __Crun {
+ struct class_base_descr {
+ int type_hash[4];
+ std::size_t offset;
+ };
+ struct static_type_info {
+ std::ptrdiff_t ty_name;
+ std::ptrdiff_t reserved;
+ std::ptrdiff_t base_table;
+ int type_hash[4];
+ unsigned int flags;
+ unsigned int cv_qualifiers;
+ };
+ void * ex_alloc(unsigned long);
+ void ex_throw(void *, static_type_info const *, void (*)(void *));
+ void * ex_get();
+ void ex_rethrow_q() throw ();
+}
+namespace __Cimpl {
+ char const * ex_name();
+}
+
+namespace bridges { namespace cpp_uno { namespace cc5_solaris_sparc64 {
+
+void raiseException(uno_Any * exception, uno_Mapping * unoToCpp);
+
+void fillUnoException(
+ void * cppException, char const * cppName, uno_Any * unoException,
+ uno_Mapping * cppToUno);
+
+} } }
+
+#endif
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/flushcode.hxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/flushcode.hxx
new file mode 100644
index 000000000000..ac87b8200c30
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/flushcode.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: flushcode.hxx,v $
+ *
+ * $Revision: 1.3.18.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_FLUSHCODE_HXX
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_FLUSHCODE_HXX
+
+#include "sal/config.h"
+
+extern "C" void sync_instruction_memory(caddr_t addr, int len); // from libc
+
+namespace bridges { namespace cpp_uno { namespace cc5_solaris_sparc64 {
+
+/**
+ * Flush a region of memory into which code has been written dynamically.
+ */
+inline void flushCode(void const * begin, void const * end) {
+ sync_instruction_memory(
+ static_cast< caddr_t >(const_cast< void * >(begin)),
+ static_cast< char const * >(end) - static_cast< char const * >(begin));
+}
+
+} } }
+
+#endif
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/fp.hxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/fp.hxx
new file mode 100644
index 000000000000..098cc1a116ee
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/fp.hxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: fp.hxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_FP_HXX
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_FP_HXX
+
+#include "sal/config.h"
+
+extern "C" {
+
+void fp_loadf0(float *);
+void fp_loadf1(float *);
+void fp_loadf2(float *);
+void fp_loadf3(float *);
+void fp_loadf4(float *);
+void fp_loadf5(float *);
+void fp_loadf6(float *);
+void fp_loadf7(float *);
+void fp_loadf9(float *);
+void fp_loadf11(float *);
+void fp_loadf13(float *);
+void fp_loadf15(float *);
+void fp_loadf17(float *);
+void fp_loadf19(float *);
+void fp_loadf21(float *);
+void fp_loadf23(float *);
+void fp_loadf25(float *);
+void fp_loadf27(float *);
+void fp_loadf29(float *);
+void fp_loadf31(float *);
+
+void fp_storef0(float *);
+void fp_storef1(float *);
+void fp_storef2(float *);
+void fp_storef3(float *);
+void fp_storef4(float *);
+void fp_storef5(float *);
+void fp_storef6(float *);
+void fp_storef7(float *);
+void fp_storef9(float *);
+void fp_storef11(float *);
+void fp_storef13(float *);
+void fp_storef15(float *);
+void fp_storef17(float *);
+void fp_storef19(float *);
+void fp_storef21(float *);
+void fp_storef23(float *);
+void fp_storef25(float *);
+void fp_storef27(float *);
+void fp_storef29(float *);
+void fp_storef31(float *);
+
+void fp_loadd0(double *);
+void fp_loadd2(double *);
+void fp_loadd4(double *);
+void fp_loadd6(double *);
+void fp_loadd8(double *);
+void fp_loadd10(double *);
+void fp_loadd12(double *);
+void fp_loadd14(double *);
+void fp_loadd16(double *);
+void fp_loadd18(double *);
+void fp_loadd20(double *);
+void fp_loadd22(double *);
+void fp_loadd24(double *);
+void fp_loadd26(double *);
+void fp_loadd28(double *);
+void fp_loadd30(double *);
+
+void fp_stored0(double *);
+void fp_stored2(double *);
+void fp_stored4(double *);
+void fp_stored6(double *);
+void fp_stored8(double *);
+void fp_stored10(double *);
+void fp_stored12(double *);
+void fp_stored14(double *);
+void fp_stored16(double *);
+void fp_stored18(double *);
+void fp_stored20(double *);
+void fp_stored22(double *);
+void fp_stored24(double *);
+void fp_stored26(double *);
+void fp_stored28(double *);
+void fp_stored30(double *);
+
+}
+
+#endif
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/fp.s b/bridges/source/cpp_uno/cc5_solaris_sparc64/fp.s
new file mode 100644
index 000000000000..5ed11e3756e2
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/fp.s
@@ -0,0 +1,606 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: fp.s,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+.global fp_loadf0
+.align 8
+fp_loadf0:
+ retl
+ ld [%o0], %f0
+.size fp_loadf0, . - fp_loadf0
+.type fp_loadf0, #function
+
+.global fp_loadf1
+.align 8
+fp_loadf1:
+ retl
+ ld [%o0], %f1
+.size fp_loadf1, . - fp_loadf1
+.type fp_loadf1, #function
+
+.global fp_loadf2
+.align 8
+fp_loadf2:
+ retl
+ ld [%o0], %f2
+.size fp_loadf2, . - fp_loadf2
+.type fp_loadf2, #function
+
+.global fp_loadf3
+.align 8
+fp_loadf3:
+ retl
+ ld [%o0], %f3
+.size fp_loadf3, . - fp_loadf3
+.type fp_loadf3, #function
+
+.global fp_loadf4
+.align 8
+fp_loadf4:
+ retl
+ ld [%o0], %f4
+.size fp_loadf4, . - fp_loadf4
+.type fp_loadf4, #function
+
+.global fp_loadf5
+.align 8
+fp_loadf5:
+ retl
+ ld [%o0], %f5
+.size fp_loadf5, . - fp_loadf5
+.type fp_loadf5, #function
+
+.global fp_loadf6
+.align 8
+fp_loadf6:
+ retl
+ ld [%o0], %f6
+.size fp_loadf6, . - fp_loadf6
+.type fp_loadf6, #function
+
+.global fp_loadf7
+.align 8
+fp_loadf7:
+ retl
+ ld [%o0], %f7
+.size fp_loadf7, . - fp_loadf7
+.type fp_loadf7, #function
+
+.global fp_loadf9
+.align 8
+fp_loadf9:
+ retl
+ ld [%o0], %f9
+.size fp_loadf9, . - fp_loadf9
+.type fp_loadf9, #function
+
+.global fp_loadf11
+.align 8
+fp_loadf11:
+ retl
+ ld [%o0], %f11
+.size fp_loadf11, . - fp_loadf11
+.type fp_loadf11, #function
+
+.global fp_loadf13
+.align 8
+fp_loadf13:
+ retl
+ ld [%o0], %f13
+.size fp_loadf13, . - fp_loadf13
+.type fp_loadf13, #function
+
+.global fp_loadf15
+.align 8
+fp_loadf15:
+ retl
+ ld [%o0], %f15
+.size fp_loadf15, . - fp_loadf15
+.type fp_loadf15, #function
+
+.global fp_loadf17
+.align 8
+fp_loadf17:
+ retl
+ ld [%o0], %f17
+.size fp_loadf17, . - fp_loadf17
+.type fp_loadf17, #function
+
+.global fp_loadf19
+.align 8
+fp_loadf19:
+ retl
+ ld [%o0], %f19
+.size fp_loadf19, . - fp_loadf19
+.type fp_loadf19, #function
+
+.global fp_loadf21
+.align 8
+fp_loadf21:
+ retl
+ ld [%o0], %f21
+.size fp_loadf21, . - fp_loadf21
+.type fp_loadf21, #function
+
+.global fp_loadf23
+.align 8
+fp_loadf23:
+ retl
+ ld [%o0], %f23
+.size fp_loadf23, . - fp_loadf23
+.type fp_loadf23, #function
+
+.global fp_loadf25
+.align 8
+fp_loadf25:
+ retl
+ ld [%o0], %f25
+.size fp_loadf25, . - fp_loadf25
+.type fp_loadf25, #function
+
+.global fp_loadf27
+.align 8
+fp_loadf27:
+ retl
+ ld [%o0], %f27
+.size fp_loadf27, . - fp_loadf27
+.type fp_loadf27, #function
+
+.global fp_loadf29
+.align 8
+fp_loadf29:
+ retl
+ ld [%o0], %f29
+.size fp_loadf29, . - fp_loadf29
+.type fp_loadf29, #function
+
+.global fp_loadf31
+.align 8
+fp_loadf31:
+ retl
+ ld [%o0], %f31
+.size fp_loadf31, . - fp_loadf31
+.type fp_loadf31, #function
+
+.global fp_storef0
+.align 8
+fp_storef0:
+ retl
+ st %f0, [%o0]
+.size fp_storef0, . - fp_storef0
+.type fp_storef0, #function
+
+.global fp_storef1
+.align 8
+fp_storef1:
+ retl
+ st %f1, [%o0]
+.size fp_storef1, . - fp_storef1
+.type fp_storef1, #function
+
+.global fp_storef2
+.align 8
+fp_storef2:
+ retl
+ st %f2, [%o0]
+.size fp_storef2, . - fp_storef2
+.type fp_storef2, #function
+
+.global fp_storef3
+.align 8
+fp_storef3:
+ retl
+ st %f3, [%o0]
+.size fp_storef3, . - fp_storef3
+.type fp_storef3, #function
+
+.global fp_storef4
+.align 8
+fp_storef4:
+ retl
+ st %f4, [%o0]
+.size fp_storef4, . - fp_storef4
+.type fp_storef4, #function
+
+.global fp_storef5
+.align 8
+fp_storef5:
+ retl
+ st %f5, [%o0]
+.size fp_storef5, . - fp_storef5
+.type fp_storef5, #function
+
+.global fp_storef6
+.align 8
+fp_storef6:
+ retl
+ st %f6, [%o0]
+.size fp_storef6, . - fp_storef6
+.type fp_storef6, #function
+
+.global fp_storef7
+.align 8
+fp_storef7:
+ retl
+ st %f7, [%o0]
+.size fp_storef7, . - fp_storef7
+.type fp_storef7, #function
+
+.global fp_storef9
+.align 8
+fp_storef9:
+ retl
+ st %f9, [%o0]
+.size fp_storef9, . - fp_storef9
+.type fp_storef9, #function
+
+.global fp_storef11
+.align 8
+fp_storef11:
+ retl
+ st %f11, [%o0]
+.size fp_storef11, . - fp_storef11
+.type fp_storef11, #function
+
+.global fp_storef13
+.align 8
+fp_storef13:
+ retl
+ st %f13, [%o0]
+.size fp_storef13, . - fp_storef13
+.type fp_storef13, #function
+
+.global fp_storef15
+.align 8
+fp_storef15:
+ retl
+ st %f15, [%o0]
+.size fp_storef15, . - fp_storef15
+.type fp_storef15, #function
+
+.global fp_storef17
+.align 8
+fp_storef17:
+ retl
+ st %f17, [%o0]
+.size fp_storef17, . - fp_storef17
+.type fp_storef17, #function
+
+.global fp_storef19
+.align 8
+fp_storef19:
+ retl
+ st %f19, [%o0]
+.size fp_storef19, . - fp_storef19
+.type fp_storef19, #function
+
+.global fp_storef21
+.align 8
+fp_storef21:
+ retl
+ st %f21, [%o0]
+.size fp_storef21, . - fp_storef21
+.type fp_storef21, #function
+
+.global fp_storef23
+.align 8
+fp_storef23:
+ retl
+ st %f23, [%o0]
+.size fp_storef23, . - fp_storef23
+.type fp_storef23, #function
+
+.global fp_storef25
+.align 8
+fp_storef25:
+ retl
+ st %f25, [%o0]
+.size fp_storef25, . - fp_storef25
+.type fp_storef25, #function
+
+.global fp_storef27
+.align 8
+fp_storef27:
+ retl
+ st %f27, [%o0]
+.size fp_storef27, . - fp_storef27
+.type fp_storef27, #function
+
+.global fp_storef29
+.align 8
+fp_storef29:
+ retl
+ st %f29, [%o0]
+.size fp_storef29, . - fp_storef29
+.type fp_storef29, #function
+
+.global fp_storef31
+.align 8
+fp_storef31:
+ retl
+ st %f31, [%o0]
+.size fp_storef31, . - fp_storef31
+.type fp_storef31, #function
+
+.global fp_loadd0
+.align 8
+fp_loadd0:
+ retl
+ ldd [%o0], %f0
+.size fp_loadd0, . - fp_loadd0
+.type fp_loadd0, #function
+
+.global fp_loadd2
+.align 8
+fp_loadd2:
+ retl
+ ldd [%o0], %f2
+.size fp_loadd2, . - fp_loadd2
+.type fp_loadd2, #function
+
+.global fp_loadd4
+.align 8
+fp_loadd4:
+ retl
+ ldd [%o0], %f4
+.size fp_loadd4, . - fp_loadd4
+.type fp_loadd4, #function
+
+.global fp_loadd6
+.align 8
+fp_loadd6:
+ retl
+ ldd [%o0], %f6
+.size fp_loadd6, . - fp_loadd6
+.type fp_loadd6, #function
+
+.global fp_loadd8
+.align 8
+fp_loadd8:
+ retl
+ ldd [%o0], %f8
+.size fp_loadd8, . - fp_loadd8
+.type fp_loadd8, #function
+
+.global fp_loadd10
+.align 8
+fp_loadd10:
+ retl
+ ldd [%o0], %f10
+.size fp_loadd10, . - fp_loadd10
+.type fp_loadd10, #function
+
+.global fp_loadd12
+.align 8
+fp_loadd12:
+ retl
+ ldd [%o0], %f12
+.size fp_loadd12, . - fp_loadd12
+.type fp_loadd12, #function
+
+.global fp_loadd14
+.align 8
+fp_loadd14:
+ retl
+ ldd [%o0], %f14
+.size fp_loadd14, . - fp_loadd14
+.type fp_loadd14, #function
+
+.global fp_loadd16
+.align 8
+fp_loadd16:
+ retl
+ ldd [%o0], %f16
+.size fp_loadd16, . - fp_loadd16
+.type fp_loadd16, #function
+
+.global fp_loadd18
+.align 8
+fp_loadd18:
+ retl
+ ldd [%o0], %f18
+.size fp_loadd18, . - fp_loadd18
+.type fp_loadd18, #function
+
+.global fp_loadd20
+.align 8
+fp_loadd20:
+ retl
+ ldd [%o0], %f20
+.size fp_loadd20, . - fp_loadd20
+.type fp_loadd20, #function
+
+.global fp_loadd22
+.align 8
+fp_loadd22:
+ retl
+ ldd [%o0], %f22
+.size fp_loadd22, . - fp_loadd22
+.type fp_loadd22, #function
+
+.global fp_loadd24
+.align 8
+fp_loadd24:
+ retl
+ ldd [%o0], %f24
+.size fp_loadd24, . - fp_loadd24
+.type fp_loadd24, #function
+
+.global fp_loadd26
+.align 8
+fp_loadd26:
+ retl
+ ldd [%o0], %f26
+.size fp_loadd26, . - fp_loadd26
+.type fp_loadd26, #function
+
+.global fp_loadd28
+.align 8
+fp_loadd28:
+ retl
+ ldd [%o0], %f28
+.size fp_loadd28, . - fp_loadd28
+.type fp_loadd28, #function
+
+.global fp_loadd30
+.align 8
+fp_loadd30:
+ retl
+ ldd [%o0], %f30
+.size fp_loadd30, . - fp_loadd30
+.type fp_loadd30, #function
+
+.global fp_stored0
+.align 8
+fp_stored0:
+ retl
+ std %f0, [%o0]
+.size fp_stored0, . - fp_stored0
+.type fp_stored0, #function
+
+.global fp_stored2
+.align 8
+fp_stored2:
+ retl
+ std %f2, [%o0]
+.size fp_stored2, . - fp_stored2
+.type fp_stored2, #function
+
+.global fp_stored4
+.align 8
+fp_stored4:
+ retl
+ std %f4, [%o0]
+.size fp_stored4, . - fp_stored4
+.type fp_stored4, #function
+
+.global fp_stored6
+.align 8
+fp_stored6:
+ retl
+ std %f6, [%o0]
+.size fp_stored6, . - fp_stored6
+.type fp_stored6, #function
+
+.global fp_stored8
+.align 8
+fp_stored8:
+ retl
+ std %f8, [%o0]
+.size fp_stored8, . - fp_stored8
+.type fp_stored8, #function
+
+.global fp_stored10
+.align 8
+fp_stored10:
+ retl
+ std %f10, [%o0]
+.size fp_stored10, . - fp_stored10
+.type fp_stored10, #function
+
+.global fp_stored12
+.align 8
+fp_stored12:
+ retl
+ std %f12, [%o0]
+.size fp_stored12, . - fp_stored12
+.type fp_stored12, #function
+
+.global fp_stored14
+.align 8
+fp_stored14:
+ retl
+ std %f14, [%o0]
+.size fp_stored14, . - fp_stored14
+.type fp_stored14, #function
+
+.global fp_stored16
+.align 8
+fp_stored16:
+ retl
+ std %f16, [%o0]
+.size fp_stored16, . - fp_stored16
+.type fp_stored16, #function
+
+.global fp_stored18
+.align 8
+fp_stored18:
+ retl
+ std %f18, [%o0]
+.size fp_stored18, . - fp_stored18
+.type fp_stored18, #function
+
+.global fp_stored20
+.align 8
+fp_stored20:
+ retl
+ std %f20, [%o0]
+.size fp_stored20, . - fp_stored20
+.type fp_stored20, #function
+
+.global fp_stored22
+.align 8
+fp_stored22:
+ retl
+ std %f22, [%o0]
+.size fp_stored22, . - fp_stored22
+.type fp_stored22, #function
+
+.global fp_stored24
+.align 8
+fp_stored24:
+ retl
+ std %f24, [%o0]
+.size fp_stored24, . - fp_stored24
+.type fp_stored24, #function
+
+.global fp_stored26
+.align 8
+fp_stored26:
+ retl
+ std %f26, [%o0]
+.size fp_stored26, . - fp_stored26
+.type fp_stored26, #function
+
+.global fp_stored28
+.align 8
+fp_stored28:
+ retl
+ std %f28, [%o0]
+.size fp_stored28, . - fp_stored28
+.type fp_stored28, #function
+
+.global fp_stored30
+.align 8
+fp_stored30:
+ retl
+ std %f30, [%o0]
+.size fp_stored30, . - fp_stored30
+.type fp_stored30, #function
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.cxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.cxx
new file mode 100644
index 000000000000..bb996e52eaff
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.cxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: isdirectreturntype.cxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_bridges.hxx"
+#include "sal/config.h"
+
+#include <cstddef>
+
+#include "sal/types.h"
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+
+#include "isdirectreturntype.hxx"
+
+namespace {
+
+bool isPodStruct(typelib_CompoundTypeDescription * type) {
+ for (; type != NULL; type = type->pBaseTypeDescription) {
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ if (!bridges::cpp_uno::cc5_solaris_sparc64::isDirectReturnType(
+ type->ppTypeRefs[i]))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace cc5_solaris_sparc64 {
+
+bool isDirectReturnType(typelib_TypeDescriptionReference * type) {
+ // Is POD of size <= 32 bytes:
+ switch (type->eTypeClass) {
+ default:
+ return true;
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ return false;
+ case typelib_TypeClass_STRUCT:
+ {
+ typelib_TypeDescription * t = NULL;
+ TYPELIB_DANGER_GET(&t, type);
+ bool b = t->nSize <= 32 && isPodStruct(
+ reinterpret_cast< typelib_CompoundTypeDescription * >(t));
+ TYPELIB_DANGER_RELEASE(t);
+ return b;
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.hxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.hxx
new file mode 100644
index 000000000000..5c405911c722
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.hxx
@@ -0,0 +1,45 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: isdirectreturntype.hxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_ISDIRECTRETURNTYPE_x
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_ISDIRECTRETURNTYPE_x
+
+#include "sal/config.h"
+
+#include "typelib/typedescription.h"
+
+namespace bridges { namespace cpp_uno { namespace cc5_solaris_sparc64 {
+
+bool isDirectReturnType(typelib_TypeDescriptionReference * type);
+
+} } }
+
+#endif
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/makefile.mk b/bridges/source/cpp_uno/cc5_solaris_sparc64/makefile.mk
new file mode 100644
index 000000000000..f1f98f32ca7d
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/makefile.mk
@@ -0,0 +1,65 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.4.12.1 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ := ..$/..$/..
+PRJNAME := bridges
+TARGET := sunpro5_uno
+ENABLE_EXCEPTIONS := TRUE
+
+.INCLUDE: settings.mk
+
+.IF "$(COM)" == "C52" && "$(CPU)" == "U"
+
+SHL1TARGET = $(TARGET)
+SHL1OBJS = \
+ $(SLO)$/callvirtualmethod.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/exceptions.obj \
+ $(SLO)$/fp.obj \
+ $(SLO)$/isdirectreturntype.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/vtableslotcall.obj
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+SHL1STDLIBS = $(CPPULIB) $(SALLIB)
+SHL1RPATH = URELIB
+SHL1VERSIONMAP = ..$/..$/bridge_exports.map
+SHL1IMPLIB= i$(SHL1TARGET)
+DEF1NAME = $(SHL1TARGET)
+
+SLOFILES = $(SHL1OBJS)
+
+.ENDIF
+
+.INCLUDE: target.mk
+
+$(SLO)$/%.obj: %.s
+ CC -m64 -KPIC -c -o $(SLO)$/$(@:b).o $<
+ touch $@
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..8921bea4330c
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/uno2cpp.cxx
@@ -0,0 +1,513 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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, &param, 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;
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.hxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.hxx
new file mode 100644
index 000000000000..5e0a52be81dd
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.hxx
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: vtableslotcall.hxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_VTABLESLOTCALL_HXX
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_VTABLESLOTCALL_HXX
+
+#include "sal/config.h"
+
+extern "C" void vtableSlotCall();
+
+#endif
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.s b/bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.s
new file mode 100644
index 000000000000..ffcbbec5be3f
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.s
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: vtableslotcall.s,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+.global vtableCall
+
+.global vtableSlotCall
+.align 8
+vtableSlotCall:
+ ! save %sp, -176, %sp already done in code snippet
+ stx %i0, [%fp + 2047 + 128]
+ stx %i1, [%fp + 2047 + 136]
+ stx %i2, [%fp + 2047 + 144]
+ stx %i3, [%fp + 2047 + 152]
+ stx %i4, [%fp + 2047 + 160]
+ stx %i5, [%fp + 2047 + 168]
+ ! %o0: functionIndex, stored by code snippet
+ ! %o1: vtableOffset, stored by code snippet
+ call vtableCall
+ add %fp, 2047 + 128, %o2
+ ldx [%fp + 2047 + 128], %i0
+ ldx [%fp + 2047 + 136], %i1
+ ldx [%fp + 2047 + 144], %i2
+ ldx [%fp + 2047 + 152], %i3
+ ret
+ restore
+.size vtableSlotCall, . - vtableSlotCall
+.type vtableSlotCall, #function
diff --git a/bridges/source/cpp_uno/gcc3_freebsd_intel/call.s b/bridges/source/cpp_uno/gcc3_freebsd_intel/call.s
new file mode 100644
index 000000000000..f345e3a764ac
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_freebsd_intel/call.s
@@ -0,0 +1,268 @@
+ .text
+
+.globl privateSnippetExecutorGeneral
+ .type privateSnippetExecutorGeneral,@function
+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:
+ .size privateSnippetExecutorGeneral,.-privateSnippetExecutorGeneral
+
+.globl privateSnippetExecutorVoid
+ .type privateSnippetExecutorVoid,@function
+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:
+ .size privateSnippetExecutorVoid,.-privateSnippetExecutorVoid
+
+.globl privateSnippetExecutorHyper
+ .type privateSnippetExecutorHyper,@function
+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:
+ .size privateSnippetExecutorHyper,.-privateSnippetExecutorHyper
+
+.globl privateSnippetExecutorFloat
+ .type privateSnippetExecutorFloat,@function
+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:
+ .size privateSnippetExecutorFloat,.-privateSnippetExecutorFloat
+
+.globl privateSnippetExecutorDouble
+ .type privateSnippetExecutorDouble,@function
+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:
+ .size privateSnippetExecutorDouble,.-privateSnippetExecutorDouble
+
+.globl privateSnippetExecutorClass
+ .type privateSnippetExecutorClass,@function
+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:
+ .size privateSnippetExecutorClass,.-privateSnippetExecutorClass
+
+ .section .eh_frame,"a",@progbits
+.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:
+ .section .note.GNU-stack,"",@progbits
diff --git a/bridges/source/cpp_uno/gcc3_freebsd_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_freebsd_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..c424b77ccd1b
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_freebsd_intel/cpp2uno.cxx
@@ -0,0 +1,493 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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"
+
+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)
+ {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+
+ 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 occured...
+ 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 occured...
+ {
+ // 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 );
+ }
+ // 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(
+ rtl::OUString::createFromAscii("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(
+ rtl::OUString::createFromAscii("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_TypeClass returnTypeClass)
+{
+ if (!bridges::cpp_uno::shared::isSimpleType(returnTypeClass)) {
+ functionIndex |= 0x80000000;
+ }
+ PrivateSnippetExecutor exec;
+ 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_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_INTERFACE:
+ exec = privateSnippetExecutorClass;
+ break;
+ default:
+ exec = privateSnippetExecutorGeneral;
+ break;
+ }
+ 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->eTypeClass);
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ typelib_TypeClass_VOID);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef->eTypeClass);
+ 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 *)
+{}
diff --git a/bridges/source/cpp_uno/gcc3_freebsd_intel/except.cxx b/bridges/source/cpp_uno/gcc3_freebsd_intel/except.cxx
new file mode 100644
index 000000000000..cce600e964cf
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_freebsd_intel/except.cxx
@@ -0,0 +1,341 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+#include <sys/param.h>
+
+#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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+#if __FreeBSD_version < 602103
+ : m_hApp( dlopen( 0, RTLD_NOW | RTLD_GLOBAL ) )
+#else
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+#endif
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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( RTL_CONSTASCII_STRINGPARAM("_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() );
+#if __FreeBSD_version < 602103 /* #i22253# */
+ rtti = (type_info *)dlsym( RTLD_DEFAULT, symName.getStr() );
+#else
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+#endif
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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() +4;
+#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;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 occured: %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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, 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 occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_freebsd_intel/makefile.mk b/bridges/source/cpp_uno/gcc3_freebsd_intel/makefile.mk
new file mode 100644
index 000000000000..cc10bdaf74be
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_freebsd_intel/makefile.mk
@@ -0,0 +1,88 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.9 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCFREEBSDIgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+#cmc: Ideally --noexecstack would be in operations, but with #i51385# pyuno
+#remote bridgeing breaks
+# $(CC) -Wa,--noexecstack -c -o $(SLO)$/$(@:b).o $<
+ $(CC) -c -o $(SLO)$/$(@:b).o $<
+ touch $@
diff --git a/bridges/source/cpp_uno/gcc3_freebsd_intel/share.hxx b/bridges/source/cpp_uno/gcc3_freebsd_intel/share.hxx
new file mode 100644
index 000000000000..1a171ffe08a2
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_freebsd_intel/share.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
diff --git a/bridges/source/cpp_uno/gcc3_freebsd_intel/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_freebsd_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..514b41fb4a58
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_freebsd_intel/uno2cpp.cxx
@@ -0,0 +1,447 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdlib.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.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 "share.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+// 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):
+void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs ) __attribute__((noinline));
+
+void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ 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", "edx" );
+ switch( eReturnType )
+ {
+ 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;
+ default:
+ break;
+ }
+}
+
+//==================================================================================================
+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 =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ 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 = *(void **)pCppStack
+ = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ 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
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *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 );
+
+ 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( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/gcc3_freebsd_x86-64/abi.cxx b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/abi.cxx
new file mode 100644
index 000000000000..df2c51b67b5f
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/abi.cxx
@@ -0,0 +1,806 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: abi.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+// This is an implementation of the x86-64 ABI as described in 'System V
+// Application Binary Interface, AMD64 Architecture Processor Supplement'
+// (http://www.x86-64.org/documentation/abi-0.95.pdf)
+//
+// The code in this file is a modification of src/x86/ffi64.c from libffi
+// (http://sources.redhat.com/libffi/) which is under the following license:
+
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 2002 Bo Thorsen <bo@suse.de>
+
+ x86-64 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <abi.hxx>
+
+#include <rtl/ustring.hxx>
+
+using namespace x86_64;
+
+typedef struct
+{
+ /* Registers for argument passing. */
+ long gpr[MAX_GPR_REGS];
+ __int128_t sse[MAX_SSE_REGS];
+
+ /* Stack space for arguments. */
+ char argspace[0];
+} stackLayout;
+
+/* Register class used for passing given 64bit part of the argument.
+ These represent classes as documented by the PS ABI, with the exception
+ of SSESF, SSEDF classes, that are basically SSE class, just gcc will
+ use SF or DFmode move instead of DImode to avoid reformating penalties.
+
+ Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
+ whenever possible (upper half does contain padding).
+ */
+enum x86_64_reg_class
+{
+ X86_64_NO_CLASS,
+ X86_64_INTEGER_CLASS,
+ X86_64_INTEGERSI_CLASS,
+ X86_64_SSE_CLASS,
+ X86_64_SSESF_CLASS,
+ X86_64_SSEDF_CLASS,
+ X86_64_SSEUP_CLASS,
+ X86_64_X87_CLASS,
+ X86_64_X87UP_CLASS,
+ X86_64_MEMORY_CLASS
+};
+
+#define MAX_CLASSES 4
+
+#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
+
+/* x86-64 register passing implementation. See x86-64 ABI for details. Goal
+ of this code is to classify each 8bytes of incoming argument by the register
+ class and assign registers accordingly. */
+
+/* Return the union class of CLASS1 and CLASS2.
+ See the x86-64 PS ABI for details. */
+
+static enum x86_64_reg_class
+merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
+{
+ /* Rule #1: If both classes are equal, this is the resulting class. */
+ if (class1 == class2)
+ return class1;
+
+ /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
+ the other class. */
+ if (class1 == X86_64_NO_CLASS)
+ return class2;
+ if (class2 == X86_64_NO_CLASS)
+ return class1;
+
+ /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
+ if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
+ return X86_64_MEMORY_CLASS;
+
+ /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
+ if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
+ || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
+ return X86_64_INTEGERSI_CLASS;
+ if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
+ || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
+ return X86_64_INTEGER_CLASS;
+
+ /* Rule #5: If one of the classes is X87 or X87UP class, MEMORY is used. */
+ if (class1 == X86_64_X87_CLASS || class1 == X86_64_X87UP_CLASS
+ || class2 == X86_64_X87_CLASS || class2 == X86_64_X87UP_CLASS)
+ return X86_64_MEMORY_CLASS;
+
+ /* Rule #6: Otherwise class SSE is used. */
+ return X86_64_SSE_CLASS;
+}
+
+/* Classify the argument of type TYPE and mode MODE.
+ CLASSES will be filled by the register class used to pass each word
+ of the operand. The number of words is returned. In case the parameter
+ should be passed in memory, 0 is returned. As a special case for zero
+ sized containers, classes[0] will be NO_CLASS and 1 is returned.
+
+ See the x86-64 PS ABI for details.
+*/
+static int
+classify_argument( typelib_TypeDescriptionReference *pTypeRef, enum x86_64_reg_class classes[], int &rByteOffset )
+{
+ /* First, align to the right place. */
+ rByteOffset = ALIGN( rByteOffset, pTypeRef->pType->nAlignment );
+
+ switch ( pTypeRef->eTypeClass )
+ {
+ case typelib_TypeClass_VOID:
+ classes[0] = X86_64_NO_CLASS;
+ return 1;
+ 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:
+ if ( ( rByteOffset % 8 + pTypeRef->pType->nSize ) <= 4 )
+ classes[0] = X86_64_INTEGERSI_CLASS;
+ else
+ classes[0] = X86_64_INTEGER_CLASS;
+ return 1;
+ case typelib_TypeClass_FLOAT:
+ if ( ( rByteOffset % 8 ) == 0 )
+ classes[0] = X86_64_SSESF_CLASS;
+ else
+ classes[0] = X86_64_SSE_CLASS;
+ return 1;
+ case typelib_TypeClass_DOUBLE:
+ classes[0] = X86_64_SSEDF_CLASS;
+ return 1;
+ /*case LONGDOUBLE:
+ classes[0] = X86_64_X87_CLASS;
+ classes[1] = X86_64_X87UP_CLASS;
+ return 2;*/
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_TYPEDEF:
+ case typelib_TypeClass_UNION:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_ARRAY:
+ case typelib_TypeClass_INTERFACE:
+ return 0;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+ const int UNITS_PER_WORD = 8;
+ int words = ( pTypeDescr->nSize + UNITS_PER_WORD - 1 ) / UNITS_PER_WORD;
+ enum x86_64_reg_class subclasses[MAX_CLASSES];
+
+ /* If the struct is larger than 16 bytes, pass it on the stack. */
+ if ( pTypeDescr->nSize > 16 )
+ {
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ return 0;
+ }
+
+ for ( int i = 0; i < words; i++ )
+ classes[i] = X86_64_NO_CLASS;
+
+ const typelib_CompoundTypeDescription *pStruct = reinterpret_cast<const typelib_CompoundTypeDescription*>( pTypeDescr );
+
+ /* Merge the fields of structure. */
+ for ( sal_Int32 nMember = 0; nMember < pStruct->nMembers; ++nMember )
+ {
+ typelib_TypeDescriptionReference *pTypeInStruct = pStruct->ppTypeRefs[ nMember ];
+
+ int num = classify_argument( pTypeInStruct, subclasses, rByteOffset );
+
+ if ( num == 0 )
+ {
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ return 0;
+ }
+
+ for ( int i = 0; i < num; i++ )
+ {
+ int pos = rByteOffset / 8;
+ classes[i + pos] = merge_classes( subclasses[i], classes[i + pos] );
+ }
+
+ if ( pTypeInStruct->eTypeClass != typelib_TypeClass_STRUCT )
+ rByteOffset = pStruct->pMemberOffsets[ nMember ];
+ }
+
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+
+ /* Final merger cleanup. */
+ for ( int i = 0; i < words; i++ )
+ {
+ /* If one class is MEMORY, everything should be passed in
+ memory. */
+ if ( classes[i] == X86_64_MEMORY_CLASS )
+ return 0;
+
+ /* The X86_64_SSEUP_CLASS should be always preceded by
+ X86_64_SSE_CLASS. */
+ if ( classes[i] == X86_64_SSEUP_CLASS
+ && ( i == 0 || classes[i - 1] != X86_64_SSE_CLASS ) )
+ classes[i] = X86_64_SSE_CLASS;
+
+ /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */
+ if ( classes[i] == X86_64_X87UP_CLASS
+ && ( i == 0 || classes[i - 1] != X86_64_X87_CLASS ) )
+ classes[i] = X86_64_SSE_CLASS;
+ }
+ return words;
+ }
+
+ default:
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "Unhandled case: pType->eTypeClass == %d\n", pTypeRef->eTypeClass );
+#endif
+ OSL_ASSERT(0);
+ }
+ return 0; /* Never reached. */
+}
+
+/* Examine the argument and return set number of register required in each
+ class. Return 0 iff parameter should be passed in memory. */
+bool x86_64::examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedSSE )
+{
+ enum x86_64_reg_class classes[MAX_CLASSES];
+ int offset = 0;
+ int n;
+
+ n = classify_argument( pTypeRef, classes, offset );
+
+ if ( n == 0 )
+ return false;
+
+ nUsedGPR = 0;
+ nUsedSSE = 0;
+ for ( n--; n >= 0; n-- )
+ switch ( classes[n] )
+ {
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ nUsedGPR++;
+ break;
+ case X86_64_SSE_CLASS:
+ case X86_64_SSESF_CLASS:
+ case X86_64_SSEDF_CLASS:
+ nUsedSSE++;
+ break;
+ case X86_64_NO_CLASS:
+ case X86_64_SSEUP_CLASS:
+ break;
+ case X86_64_X87_CLASS:
+ case X86_64_X87UP_CLASS:
+ if ( !bInReturn )
+ return false;
+ break;
+ default:
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "Unhandled case: classes[n] == %d\n", classes[n] );
+#endif
+ OSL_ASSERT(0);
+ }
+ return true;
+}
+
+bool x86_64::return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
+{
+ int g, s;
+
+ return examine_argument( pTypeRef, true, g, s ) == 0;
+}
+
+void x86_64::fill_struct( typelib_TypeDescriptionReference *pTypeRef, void * const *pGPR, void * const *pSSE, void *pStruct )
+{
+ enum x86_64_reg_class classes[MAX_CLASSES];
+ int offset = 0;
+ int n;
+
+ n = classify_argument( pTypeRef, classes, offset );
+
+ sal_uInt64 *pStructAlign = reinterpret_cast<sal_uInt64 *>( pStruct );
+ for ( n--; n >= 0; n-- )
+ switch ( classes[n] )
+ {
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ *pStructAlign++ = *reinterpret_cast<sal_uInt64 *>( *pGPR++ );
+ break;
+ case X86_64_SSE_CLASS:
+ case X86_64_SSESF_CLASS:
+ case X86_64_SSEDF_CLASS:
+ *pStructAlign++ = *reinterpret_cast<sal_uInt64 *>( *pSSE++ );
+ break;
+ }
+}
+
+#if 0
+
+/* Functions to load floats and double to an SSE register placeholder. */
+extern void float2sse (float, __int128_t *);
+extern void double2sse (double, __int128_t *);
+extern void floatfloat2sse (void *, __int128_t *);
+
+/* Functions to put the floats and doubles back. */
+extern float sse2float (__int128_t *);
+extern double sse2double (__int128_t *);
+extern void sse2floatfloat(__int128_t *, void *);
+
+/*@-exportheader@*/
+void
+ffi_prep_args (stackLayout *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+ int gprcount, ssecount, i, g, s;
+ void **p_argv;
+ void *argp = &stack->argspace;
+ ffi_type **p_arg;
+
+ /* First check if the return value should be passed in memory. If so,
+ pass the pointer as the first argument. */
+ gprcount = ssecount = 0;
+ if (ecif->cif->rtype->type != FFI_TYPE_VOID
+ && examine_argument (ecif->cif->rtype, 1, &g, &s) == 0)
+ (void *)stack->gpr[gprcount++] = ecif->rvalue;
+
+ for (i=ecif->cif->nargs, p_arg=ecif->cif->arg_types, p_argv = ecif->avalue;
+ i!=0; i--, p_arg++, p_argv++)
+ {
+ int in_register = 0;
+
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_POINTER:
+ if (gprcount < MAX_GPR_REGS)
+ {
+ stack->gpr[gprcount] = 0;
+ stack->gpr[gprcount++] = *(long long *)(*p_argv);
+ in_register = 1;
+ }
+ break;
+
+ case FFI_TYPE_FLOAT:
+ if (ssecount < MAX_SSE_REGS)
+ {
+ float2sse (*(float *)(*p_argv), &stack->sse[ssecount++]);
+ in_register = 1;
+ }
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ if (ssecount < MAX_SSE_REGS)
+ {
+ double2sse (*(double *)(*p_argv), &stack->sse[ssecount++]);
+ in_register = 1;
+ }
+ break;
+ }
+
+ if (in_register)
+ continue;
+
+ /* Either all places in registers where filled, or this is a
+ type that potentially goes into a memory slot. */
+ if (examine_argument (*p_arg, 0, &g, &s) == 0
+ || gprcount + g > MAX_GPR_REGS || ssecount + s > MAX_SSE_REGS)
+ {
+ /* Pass this argument in memory. */
+ argp = (void *)ALIGN(argp, (*p_arg)->alignment);
+ memcpy (argp, *p_argv, (*p_arg)->size);
+ argp += (*p_arg)->size;
+ }
+ else
+ {
+ /* All easy cases are eliminated. Now fire the big guns. */
+
+ enum x86_64_reg_class classes[MAX_CLASSES];
+ int offset = 0, j, num;
+ void *a;
+
+ num = classify_argument (*p_arg, classes, &offset);
+ for (j=0, a=*p_argv; j<num; j++, a+=8)
+ {
+ switch (classes[j])
+ {
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ stack->gpr[gprcount++] = *(long long *)a;
+ break;
+ case X86_64_SSE_CLASS:
+ floatfloat2sse (a, &stack->sse[ssecount++]);
+ break;
+ case X86_64_SSESF_CLASS:
+ float2sse (*(float *)a, &stack->sse[ssecount++]);
+ break;
+ case X86_64_SSEDF_CLASS:
+ double2sse (*(double *)a, &stack->sse[ssecount++]);
+ break;
+ default:
+ abort();
+ }
+ }
+ }
+ }
+}
+
+/* Perform machine dependent cif processing. */
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+ int gprcount, ssecount, i, g, s;
+
+ gprcount = ssecount = 0;
+
+ /* Reset the byte count. We handle this size estimation here. */
+ cif->bytes = 0;
+
+ /* If the return value should be passed in memory, pass the pointer
+ as the first argument. The actual memory isn't allocated here. */
+ if (cif->rtype->type != FFI_TYPE_VOID
+ && examine_argument (cif->rtype, 1, &g, &s) == 0)
+ gprcount = 1;
+
+ /* Go over all arguments and determine the way they should be passed.
+ If it's in a register and there is space for it, let that be so. If
+ not, add it's size to the stack byte count. */
+ for (i=0; i<cif->nargs; i++)
+ {
+ if (examine_argument (cif->arg_types[i], 0, &g, &s) == 0
+ || gprcount + g > MAX_GPR_REGS || ssecount + s > MAX_SSE_REGS)
+ {
+ /* This is passed in memory. First align to the basic type. */
+ cif->bytes = ALIGN(cif->bytes, cif->arg_types[i]->alignment);
+
+ /* Stack arguments are *always* at least 8 byte aligned. */
+ cif->bytes = ALIGN(cif->bytes, 8);
+
+ /* Now add the size of this argument. */
+ cif->bytes += cif->arg_types[i]->size;
+ }
+ else
+ {
+ gprcount += g;
+ ssecount += s;
+ }
+ }
+
+ /* Set the flag for the closures return. */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_STRUCT:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ case FFI_TYPE_LONGDOUBLE:
+ cif->flags = (unsigned) cif->rtype->type;
+ break;
+
+ case FFI_TYPE_UINT64:
+ cif->flags = FFI_TYPE_SINT64;
+ break;
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+typedef struct
+{
+ long gpr[2];
+ __int128_t sse[2];
+ long double st0;
+} return_value;
+
+//#endif
+
+void
+ffi_fill_return_value (return_value *rv, extended_cif *ecif)
+{
+ enum x86_64_reg_class classes[MAX_CLASSES];
+ int i = 0, num;
+ long *gpr = rv->gpr;
+ __int128_t *sse = rv->sse;
+ signed char sc;
+ signed short ss;
+
+ /* This is needed because of the way x86-64 handles signed short
+ integers. */
+ switch (ecif->cif->rtype->type)
+ {
+ case FFI_TYPE_SINT8:
+ sc = *(signed char *)gpr;
+ *(long long *)ecif->rvalue = (long long)sc;
+ return;
+ case FFI_TYPE_SINT16:
+ ss = *(signed short *)gpr;
+ *(long long *)ecif->rvalue = (long long)ss;
+ return;
+ default:
+ /* Just continue. */
+ ;
+ }
+
+ num = classify_argument (ecif->cif->rtype, classes, &i);
+
+ if (num == 0)
+ /* Return in memory. */
+ ecif->rvalue = (void *) rv->gpr[0];
+ else if (num == 2 && classes[0] == X86_64_X87_CLASS &&
+ classes[1] == X86_64_X87UP_CLASS)
+ /* This is a long double (this is easiest to handle this way instead
+ of an eightbyte at a time as in the loop below. */
+ *((long double *)ecif->rvalue) = rv->st0;
+ else
+ {
+ void *a;
+
+ for (i=0, a=ecif->rvalue; i<num; i++, a+=8)
+ {
+ switch (classes[i])
+ {
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ *(long long *)a = *gpr;
+ gpr++;
+ break;
+ case X86_64_SSE_CLASS:
+ sse2floatfloat (sse++, a);
+ break;
+ case X86_64_SSESF_CLASS:
+ *(float *)a = sse2float (sse++);
+ break;
+ case X86_64_SSEDF_CLASS:
+ *(double *)a = sse2double (sse++);
+ break;
+ default:
+ abort();
+ }
+ }
+ }
+}
+
+//#if 0
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_UNIX64(void (*)(stackLayout *, extended_cif *),
+ void (*) (return_value *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, /*@out@*/ unsigned *, void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+ int dummy;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) &&
+ (examine_argument (cif->rtype, 1, &dummy, &dummy) == 0))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+ /* Stack must always be 16byte aligned. Make it so. */
+ cif->bytes = ALIGN(cif->bytes, 16);
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /* Calling 32bit code from 64bit is not possible */
+ FFI_ASSERT(0);
+ break;
+
+ case FFI_UNIX64:
+ /*@-usedef@*/
+ ffi_call_UNIX64 (ffi_prep_args, ffi_fill_return_value, &ecif,
+ cif->bytes, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+extern void ffi_closure_UNIX64(void);
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*, void*, void**, void*),
+ void *user_data)
+{
+ volatile unsigned short *tramp;
+
+ /* FFI_ASSERT (cif->abi == FFI_OSF); */
+
+ tramp = (volatile unsigned short *) &closure->tramp[0];
+ tramp[0] = 0xbb49; /* mov <code>, %r11 */
+ tramp[5] = 0xba49; /* mov <data>, %r10 */
+ tramp[10] = 0xff49; /* jmp *%r11 */
+ tramp[11] = 0x00e3;
+ *(void * volatile *) &tramp[1] = ffi_closure_UNIX64;
+ *(void * volatile *) &tramp[6] = closure;
+
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
+
+ return FFI_OK;
+}
+
+int
+ffi_closure_UNIX64_inner(ffi_closure *closure, va_list l, void *rp)
+{
+ ffi_cif *cif;
+ void **avalue;
+ ffi_type **arg_types;
+ long i, avn, argn;
+
+ cif = closure->cif;
+ avalue = alloca(cif->nargs * sizeof(void *));
+
+ argn = 0;
+
+ i = 0;
+ avn = cif->nargs;
+ arg_types = cif->arg_types;
+
+ /* Grab the addresses of the arguments from the stack frame. */
+ while (i < avn)
+ {
+ switch (arg_types[i]->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_POINTER:
+ {
+ if (l->gp_offset > 48-8)
+ {
+ avalue[i] = l->overflow_arg_area;
+ l->overflow_arg_area = (char *)l->overflow_arg_area + 8;
+ }
+ else
+ {
+ avalue[i] = (char *)l->reg_save_area + l->gp_offset;
+ l->gp_offset += 8;
+ }
+ }
+ break;
+
+ case FFI_TYPE_STRUCT:
+ /* FIXME */
+ FFI_ASSERT(0);
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ {
+ if (l->fp_offset > 176-16)
+ {
+ avalue[i] = l->overflow_arg_area;
+ l->overflow_arg_area = (char *)l->overflow_arg_area + 8;
+ }
+ else
+ {
+ avalue[i] = (char *)l->reg_save_area + l->fp_offset;
+ l->fp_offset += 16;
+ }
+ }
+#if DEBUG_FFI
+ fprintf (stderr, "double arg %d = %g\n", i, *(double *)avalue[i]);
+#endif
+ break;
+
+ case FFI_TYPE_FLOAT:
+ {
+ if (l->fp_offset > 176-16)
+ {
+ avalue[i] = l->overflow_arg_area;
+ l->overflow_arg_area = (char *)l->overflow_arg_area + 8;
+ }
+ else
+ {
+ avalue[i] = (char *)l->reg_save_area + l->fp_offset;
+ l->fp_offset += 16;
+ }
+ }
+#if DEBUG_FFI
+ fprintf (stderr, "float arg %d = %g\n", i, *(float *)avalue[i]);
+#endif
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+
+ argn += ALIGN(arg_types[i]->size, SIZEOF_ARG) / SIZEOF_ARG;
+ i++;
+ }
+
+ /* Invoke the closure. */
+ (closure->fun) (cif, rp, avalue, closure->user_data);
+
+ /* FIXME: Structs not supported. */
+ FFI_ASSERT(cif->rtype->type != FFI_TYPE_STRUCT);
+
+ /* Tell ffi_closure_UNIX64 how to perform return type promotions. */
+
+ return cif->rtype->type;
+}
+
+#endif
diff --git a/bridges/source/cpp_uno/gcc3_freebsd_x86-64/abi.hxx b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/abi.hxx
new file mode 100644
index 000000000000..5fffe680c28a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/abi.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: abi.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
+#define _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
+
+// This is an implementation of the x86-64 ABI as described in 'System V
+// Application Binary Interface, AMD64 Architecture Processor Supplement'
+// (http://www.x86-64.org/documentation/abi-0.95.pdf)
+
+#include <typelib/typedescription.hxx>
+
+namespace x86_64
+{
+
+/* 6 general purpose registers are used for parameter passing */
+const sal_uInt32 MAX_GPR_REGS = 6;
+
+/* 8 SSE registers are used for parameter passing */
+const sal_uInt32 MAX_SSE_REGS = 8;
+
+/* Count number of required registers.
+
+ Examine the argument and return set number of register required in each
+ class.
+
+ Return false iff parameter should be passed in memory.
+*/
+bool examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedSSE );
+
+/** Does function that returns this type use a hidden parameter, or registers?
+
+ The value can be returned either in a hidden 1st parameter (which is a
+ pointer to a structure allocated by the caller), or in registers (rax, rdx
+ for the integers, xmm0, xmm1 for the floating point numbers).
+*/
+bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
+
+void fill_struct( typelib_TypeDescriptionReference *pTypeRef, void * const *pGPR, void * const *pSSE, void *pStruct );
+
+} // namespace x86_64
+
+#endif // _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
diff --git a/bridges/source/cpp_uno/gcc3_freebsd_x86-64/call.s b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/call.s
new file mode 100644
index 000000000000..736230705d5a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/call.s
@@ -0,0 +1,93 @@
+ .text
+ .align 2
+.globl privateSnippetExecutor
+ .type privateSnippetExecutor, @function
+privateSnippetExecutor:
+.LFB3:
+ pushq %rbp
+.LCFI0:
+ movq %rsp, %rbp
+.LCFI1:
+ subq $160, %rsp
+.LCFI2:
+ movq %r10, -152(%rbp) # Save (nVtableOffset << 32) + nFunctionIndex
+
+ movq %rdi, -112(%rbp) # Save GP registers
+ movq %rsi, -104(%rbp)
+ movq %rdx, -96(%rbp)
+ movq %rcx, -88(%rbp)
+ movq %r8 , -80(%rbp)
+ movq %r9 , -72(%rbp)
+
+ movsd %xmm0, -64(%rbp) # Save FP registers
+ movsd %xmm1, -56(%rbp)
+ movsd %xmm2, -48(%rbp)
+ movsd %xmm3, -40(%rbp)
+ movsd %xmm4, -32(%rbp)
+ movsd %xmm5, -24(%rbp)
+ movsd %xmm6, -16(%rbp)
+ movsd %xmm7, -8(%rbp)
+
+ leaq -144(%rbp), %r9 # 6th param: sal_uInt64 * pRegisterReturn
+ leaq 16(%rbp), %r8 # 5rd param: void ** ovrflw
+ leaq -64(%rbp), %rcx # 4th param: void ** fpreg
+ leaq -112(%rbp), %rdx # 3rd param: void ** gpreg
+ movl -148(%rbp), %esi # 2nd param: sal_int32 nVtableOffset
+ movl -152(%rbp), %edi # 1st param: sal_int32 nFunctionIndex
+
+ call cpp_vtable_call
+
+ cmp $10, %rax # typelib_TypeClass_FLOAT
+ je .Lfloat
+ cmp $11, %rax # typelib_TypeClass_DOUBLE
+ je .Lfloat
+
+ movq -144(%rbp), %rax # Return value (int case)
+ jmp .Lfinish
+.Lfloat:
+ movlpd -144(%rbp), %xmm0 # Return value (float/double case)
+
+.Lfinish:
+ leave
+ ret
+.LFE3:
+ .size privateSnippetExecutor, .-privateSnippetExecutor
+ .section .eh_frame,"a",@progbits
+.Lframe1:
+ .long .LECIE1-.LSCIE1
+.LSCIE1:
+ .long 0x0
+ .byte 0x1
+ .string "zR"
+ .uleb128 0x1
+ .sleb128 -8
+ .byte 0x10
+ .uleb128 0x1
+ .byte 0x1b
+ .byte 0xc
+ .uleb128 0x7
+ .uleb128 0x8
+ .byte 0x90
+ .uleb128 0x1
+ .align 8
+.LECIE1:
+.LSFDE1:
+ .long .LEFDE1-.LASFDE1
+.LASFDE1:
+ .long .LASFDE1-.Lframe1
+ .long .LFB3-.
+ .long .LFE3-.LFB3
+ .uleb128 0x0
+ .byte 0x4
+ .long .LCFI0-.LFB3
+ .byte 0xe
+ .uleb128 0x10
+ .byte 0x86
+ .uleb128 0x2
+ .byte 0x4
+ .long .LCFI1-.LCFI0
+ .byte 0xd
+ .uleb128 0x6
+ .align 8
+.LEFDE1:
+ .section .note.GNU-stack,"",@progbits
diff --git a/bridges/source/cpp_uno/gcc3_freebsd_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/cpp2uno.cxx
new file mode 100644
index 000000000000..9b326ff34b0d
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/cpp2uno.cxx
@@ -0,0 +1,544 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <hash_map>
+
+#include <rtl/alloc.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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 "abi.hxx"
+#include "share.hxx"
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+//==================================================================================================
+
+// Perform the UNO call
+//
+// We must convert the paramaters stored in gpreg, fpreg and ovrflw to UNO
+// arguments and call pThis->getUnoI()->pDispatcher.
+//
+// gpreg: [ret *], this, [gpr params]
+// fpreg: [fpr params]
+// ovrflw: [gpr or fpr params (properly aligned)]
+//
+// [ret *] is present when we are returning a structure bigger than 16 bytes
+// Simple types are returned in rax, rdx (int), or xmm0, xmm1 (fp).
+// Similarly structures <= 16 bytes are in rax, rdx, xmm0, xmm1 as necessary.
+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 */ )
+{
+ int nr_gpr = 0; //number of gpr registers used
+ int nr_fpr = 0; //number of fpr regsiters used
+
+ // 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 ( x86_64::return_in_hidden_param( pReturnTypeRef ) )
+ {
+ pCppReturn = *gpreg++;
+ nr_gpr++;
+
+ pUnoReturn = ( bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn ); // direct way
+ }
+ else
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+
+ // pop this
+ gpreg++;
+ nr_gpr++;
+
+ // stack space
+ // 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 );
+
+ int nUsedGPR = 0;
+ int nUsedSSE = 0;
+ bool bFitsRegisters = x86_64::examine_argument( rParam.pTypeRef, false, nUsedGPR, nUsedSSE );
+ if ( !rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ) ) // value
+ {
+ // Simple types must fit exactly one register on x86_64
+ OSL_ASSERT( bFitsRegisters && ( ( nUsedSSE == 1 && nUsedGPR == 0 ) || ( nUsedSSE == 0 && nUsedGPR == 1 ) ) );
+
+ if ( nUsedSSE == 1 )
+ {
+ if ( nr_fpr < x86_64::MAX_SSE_REGS )
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
+ nr_fpr++;
+ }
+ else
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
+ }
+ else if ( nUsedGPR == 1 )
+ {
+ if ( nr_gpr < x86_64::MAX_GPR_REGS )
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
+ nr_gpr++;
+ }
+ else
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // struct <= 16 bytes || ptr to complex value || ref
+ {
+ void *pCppStack;
+ char pTmpStruct[16];
+
+ if ( bFitsRegisters && !rParam.bOut &&
+ ( pParamTypeDescr->eTypeClass == typelib_TypeClass_STRUCT ||
+ pParamTypeDescr->eTypeClass == typelib_TypeClass_EXCEPTION ) )
+ {
+ if ( ( nr_gpr + nUsedGPR <= x86_64::MAX_GPR_REGS ) && ( nr_fpr + nUsedSSE <= x86_64::MAX_SSE_REGS ) )
+ {
+ x86_64::fill_struct( rParam.pTypeRef, gpreg, fpreg, pTmpStruct );
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "nUsedGPR == %d, nUsedSSE == %d, pTmpStruct[0] == 0x%x, pTmpStruct[1] == 0x%x, **gpreg == 0x%lx\n",
+ nUsedGPR, nUsedSSE, pTmpStruct[0], pTmpStruct[1], *(sal_uInt64*)*gpreg );
+#endif
+
+ pCppArgs[nPos] = pCppStack = reinterpret_cast<void *>( pTmpStruct );
+ gpreg += nUsedGPR;
+ fpreg += nUsedSSE;
+ }
+ else
+ pCppArgs[nPos] = pCppStack = *ovrflw++;
+ }
+ else if ( nr_gpr < x86_64::MAX_GPR_REGS )
+ {
+ pCppArgs[nPos] = pCppStack = *gpreg++;
+ nr_gpr++;
+ }
+ else
+ pCppArgs[nPos] = pCppStack = *ovrflw++;
+
+ 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;
+ }
+ else if ( bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ) ) // is in/inout
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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] = pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+ // 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 occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if ( pReturnTypeDescr )
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+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 */ )
+{
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+ void * pThis;
+ if ( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+ }
+ else
+ {
+ pThis = gpreg[0];
+ }
+ 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!\n" );
+ if ( nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex )
+ {
+ throw RuntimeException( OUString::createFromAscii("illegal vtable index!"),
+ reinterpret_cast<XInterface *>( pCppI ) );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!\n" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch ( aMemberDescr.get()->eTypeClass )
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ typelib_TypeDescriptionReference *pAttrTypeRef =
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( aMemberDescr.get() )->pAttributeTypeRef;
+
+ if ( pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex )
+ {
+ // is GET method
+ eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef = pAttrTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch ( nFunctionIndex )
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast<Type *>( gpreg[2] )->getTypeLibType() );
+ if ( pTD )
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
+ ( pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface,
+ pCppI->getOid().pData,
+ reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
+
+ if ( pInterface )
+ {
+ ::uno_any_construct( reinterpret_cast<uno_Any *>( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+
+ reinterpret_cast<void **>( pRegisterReturn )[0] = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ {
+ typelib_InterfaceMethodTypeDescription *pMethodTD =
+ reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( aMemberDescr.get() );
+
+ eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
+ pMethodTD->pReturnTypeRef,
+ pMethodTD->nParams,
+ pMethodTD->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException( OUString::createFromAscii("no member description found!"),
+ reinterpret_cast<XInterface *>( pCppI ) );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+extern "C" void privateSnippetExecutor( ... );
+
+const int codeSnippetSize = 24;
+
+// Generate a trampoline that redirects method calls to
+// privateSnippetExecutor().
+//
+// privateSnippetExecutor() saves all the registers that are used for
+// parameter passing on x86_64, and calls the cpp_vtable_call().
+// When it returns, privateSnippetExecutor() sets the return value.
+//
+// Note: The code snippet we build here must not create a stack frame,
+// otherwise the UNO exceptions stop working thanks to non-existing
+// unwinding info.
+unsigned char * codeSnippet( unsigned char * code,
+ sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ bool bHasHiddenParam ) SAL_THROW( () )
+{
+ sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
+
+ if ( bHasHiddenParam )
+ nOffsetAndIndex |= 0x80000000;
+
+ // movq $<nOffsetAndIndex>, %r10
+ *reinterpret_cast<sal_uInt16 *>( code ) = 0xba49;
+ *reinterpret_cast<sal_uInt64 *>( code + 2 ) = nOffsetAndIndex;
+
+ // movq $<address of the privateSnippetExecutor>, %r11
+ *reinterpret_cast<sal_uInt16 *>( code + 10 ) = 0xbb49;
+ *reinterpret_cast<sal_uInt64 *>( code + 12 ) = reinterpret_cast<sal_uInt64>( privateSnippetExecutor );
+
+ // jmpq *%r11
+ *reinterpret_cast<sal_uInt32 *>( code + 20 ) = 0x00e3ff49;
+
+ 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 nFunctionOffset,
+ sal_Int32 functionCount, sal_Int32 nVtableOffset )
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+
+ for ( sal_Int32 nPos = 0; nPos < type->nMembers; ++nPos )
+ {
+ typelib_TypeDescription * pTD = 0;
+
+ TYPELIB_DANGER_GET( &pTD, type->ppMembers[ nPos ] );
+ OSL_ASSERT( pTD );
+
+ if ( typelib_TypeClass_INTERFACE_ATTRIBUTE == pTD->eTypeClass )
+ {
+ typelib_InterfaceAttributeTypeDescription *pAttrTD =
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
+
+ // get method
+ (s++)->fn = code;
+ code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
+ x86_64::return_in_hidden_param( pAttrTD->pAttributeTypeRef ) );
+
+ if ( ! pAttrTD->bReadOnly )
+ {
+ // set method
+ (s++)->fn = code;
+ code = codeSnippet( code, nFunctionOffset++, nVtableOffset, false );
+ }
+ }
+ else if ( typelib_TypeClass_INTERFACE_METHOD == pTD->eTypeClass )
+ {
+ typelib_InterfaceMethodTypeDescription *pMethodTD =
+ reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD );
+
+ (s++)->fn = code;
+ code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
+ x86_64::return_in_hidden_param( pMethodTD->pReturnTypeRef ) );
+ }
+ else
+ OSL_ASSERT( false );
+
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ return code;
+}
+
+//==================================================================================================
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *, unsigned char const * )
+{
+}
diff --git a/bridges/source/cpp_uno/gcc3_freebsd_x86-64/except.cxx b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/except.cxx
new file mode 100644
index 000000000000..59ac557924d4
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/except.cxx
@@ -0,0 +1,341 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+#include <sys/param.h>
+
+#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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+#if __FreeBSD_version < 602103
+ : m_hApp( dlopen( 0, RTLD_NOW | RTLD_GLOBAL ) )
+#else
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+#endif
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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 iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_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() );
+#if __FreeBSD_version < 602103 /* #i22253# */
+ rtti = (type_info *)dlsym( RTLD_DEFAULT, symName.getStr() );
+#else
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+#endif
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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() +4;
+#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 = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 occured: %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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, 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 occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_freebsd_x86-64/makefile.mk b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/makefile.mk
new file mode 100644
index 000000000000..34d3846f6274
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/makefile.mk
@@ -0,0 +1,84 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCFREEBSDXgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer
+
+SLOFILES= \
+ $(SLO)$/abi.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+ $(CC) -c -o $(SLO)$/$(@:b).o $<
+ touch $@
diff --git a/bridges/source/cpp_uno/gcc3_freebsd_x86-64/share.hxx b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/share.hxx
new file mode 100644
index 000000000000..6aa69f0470e4
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/share.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
diff --git a/bridges/source/cpp_uno/gcc3_freebsd_x86-64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/uno2cpp.cxx
new file mode 100644
index 000000000000..232ca94d4bc9
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_freebsd_x86-64/uno2cpp.cxx
@@ -0,0 +1,561 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rtl/alloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.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 "abi.hxx"
+#include "share.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+//==================================================================================================
+static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
+ sal_uInt64 *pStack, sal_uInt32 nStack,
+ sal_uInt64 *pGPR, sal_uInt32 nGPR,
+ double *pFPR, sal_uInt32 nFPR) __attribute__((noinline));
+
+static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
+ sal_uInt64 *pStack, sal_uInt32 nStack,
+ sal_uInt64 *pGPR, sal_uInt32 nGPR,
+ double *pFPR, sal_uInt32 nFPR)
+{
+#if OSL_DEBUG_LEVEL > 1
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
+ for ( int i = 0; i < nGPR; ++i )
+ fprintf( stderr, "0x%lx, ", pGPR[i] );
+ fprintf( stderr, "\nFPR's (%d): ", nFPR );
+ for ( int i = 0; i < nFPR; ++i )
+ fprintf( stderr, "%f, ", pFPR[i] );
+ fprintf( stderr, "\nStack (%d): ", nStack );
+ for ( int i = 0; i < nStack; ++i )
+ fprintf( stderr, "0x%lx, ", pStack[i] );
+ fprintf( stderr, "\n" );
+ }
+#endif
+
+ // 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):
+ if ( !pThis )
+ CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything( "xxx" ); // address something
+
+ // Should not happen, but...
+ if ( nFPR > x86_64::MAX_SSE_REGS )
+ nFPR = x86_64::MAX_SSE_REGS;
+ if ( nGPR > x86_64::MAX_GPR_REGS )
+ nGPR = x86_64::MAX_GPR_REGS;
+
+ // Get pointer to method
+ sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
+ pMethod += 8 * nVtableIndex;
+ pMethod = *((sal_uInt64 *)pMethod);
+
+ // Load parameters to stack, if necessary
+ if ( nStack )
+ {
+ // 16-bytes aligned
+ sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 16;
+ sal_uInt64 *pCallStack = (sal_uInt64 *) __builtin_alloca( nStackBytes );
+ memcpy( pCallStack, pStack, nStackBytes );
+ }
+
+ // Return values
+ sal_uInt64 rax;
+ sal_uInt64 rdx;
+ double xmm0;
+
+ asm volatile (
+
+ // Fill the xmm registers
+ "movq %2, %%rax\n\t"
+
+ "movsd (%%rax), %%xmm0\n\t"
+ "movsd 8(%%rax), %%xmm1\n\t"
+ "movsd 16(%%rax), %%xmm2\n\t"
+ "movsd 24(%%rax), %%xmm3\n\t"
+ "movsd 32(%%rax), %%xmm4\n\t"
+ "movsd 40(%%rax), %%xmm5\n\t"
+ "movsd 48(%%rax), %%xmm6\n\t"
+ "movsd 56(%%rax), %%xmm7\n\t"
+
+ // Fill the general purpose registers
+ "movq %1, %%rax\n\t"
+
+ "movq (%%rax), %%rdi\n\t"
+ "movq 8(%%rax), %%rsi\n\t"
+ "movq 16(%%rax), %%rdx\n\t"
+ "movq 24(%%rax), %%rcx\n\t"
+ "movq 32(%%rax), %%r8\n\t"
+ "movq 40(%%rax), %%r9\n\t"
+
+ // Perform the call
+ "movq %0, %%r11\n\t"
+ "movq %3, %%rax\n\t"
+ "call *%%r11\n\t"
+
+ // Fill the return values
+ "movq %%rax, %4\n\t"
+ "movq %%rdx, %5\n\t"
+ "movsd %%xmm0, %6\n\t"
+ :
+ : "m" ( pMethod ), "m" ( pGPR ), "m" ( pFPR ), "m" ( nFPR ),
+ "m" ( rax ), "m" ( rdx ), "m" ( xmm0 )
+ : "rax", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11"
+ );
+
+ switch (pReturnTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = rax;
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt32*>( &rax );
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt16*>( &rax );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt8*>( &rax );
+ break;
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_DOUBLE:
+ *reinterpret_cast<double *>( pRegisterReturn ) = xmm0;
+ break;
+ default:
+ {
+ sal_Int32 const nRetSize = pReturnTypeDescr->nSize;
+ if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0)
+ {
+ if (nRetSize > 8)
+ static_cast<sal_uInt64 *>(pRegisterReturn)[1] = rdx;
+ static_cast<sal_uInt64 *>(pRegisterReturn)[0] = rax;
+ }
+ break;
+ }
+ }
+}
+
+//==================================================================================================
+
+// Macros for easier insertion of values to registers or stack
+// pSV - pointer to the source
+// nr - order of the value [will be increased if stored to register]
+// pFPR, pGPR - pointer to the registers
+// pDS - pointer to the stack [will be increased if stored here]
+
+// The value in %xmm register is already prepared to be retrieved as a float,
+// thus we treat float and double the same
+#define INSERT_FLOAT_DOUBLE( pSV, nr, pFPR, pDS ) \
+ if ( nr < x86_64::MAX_SSE_REGS ) \
+ pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
+
+#define INSERT_INT64( pSV, nr, pGPR, pDS ) \
+ if ( nr < x86_64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
+ if ( nr < x86_64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
+ if ( nr < x86_64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS ) \
+ if ( nr < x86_64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+//==================================================================================================
+
+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 )
+{
+ // Maxium space for [complex ret ptr], values | ptr ...
+ // (but will be used less - some of the values will be in pGPR and pFPR)
+ sal_uInt64 *pStack = (sal_uInt64 *)__builtin_alloca( (nParams + 3) * sizeof(sal_uInt64) );
+ sal_uInt64 *pStackStart = pStack;
+
+ sal_uInt64 pGPR[x86_64::MAX_GPR_REGS];
+ sal_uInt32 nGPR = 0;
+
+ double pFPR[x86_64::MAX_SSE_REGS];
+ sal_uInt32 nFPR = 0;
+
+ // 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 (see below)
+
+ bool bSimpleReturn = true;
+ if ( pReturnTypeDescr )
+ {
+ if ( x86_64::return_in_hidden_param( pReturnTypeRef ) )
+ bSimpleReturn = false;
+
+ if ( bSimpleReturn )
+ pCppReturn = pUnoReturn; // direct way for simple types
+ else
+ {
+ // complex return via ptr
+ pCppReturn = bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )?
+ __builtin_alloca( pReturnTypeDescr->nSize ) : pUnoReturn;
+ INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack );
+ }
+ }
+
+ // Push "this" pointer
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
+ INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack );
+
+ // Args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_DOUBLE:
+ INSERT_FLOAT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack );
+ 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(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr, bSimpleReturn,
+ pStackStart, ( pStack - pStackStart ),
+ pGPR, nGPR,
+ pFPR, nFPR );
+ // NO exception occured...
+ *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 );
+
+ 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( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+//==================================================================================================
+
+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);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; // get, then set method
+ cpp_call(
+ pThis, aVtableSlot, // get, then set method
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ 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->getBridge()->getUnoEnv()->getRegisteredInterface)(
+ pThis->getBridge()->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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/gcc3_linux_arm/armhelper.s b/bridges/source/cpp_uno/gcc3_linux_arm/armhelper.s
new file mode 100644
index 000000000000..8fd1a38e4f51
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_arm/armhelper.s
@@ -0,0 +1,22 @@
+@ ARM support code for OpenOffice C++/UNO bridging
+@
+@ Written by Peter Naulls <peter@chocky.org>
+@ Modified by Caolan McNamara <caolanm@redhat.com>
+ .file "armhelper.s"
+ .text
+ .align 4
+ .global privateSnippetExecutor
+ .type privateSnippetExecutor, %function
+privateSnippetExecutor:
+ stmfd sp!, {r0-r3} @ follow other parameters on stack
+ mov r0, ip @ r0 points to functionoffset/vtable
+ mov ip, sp @ fix up the ip
+ stmfd sp!, {fp,ip,lr,pc} @ 8 x 4 => stack remains 8 aligned
+ sub fp, ip, #4 @ set frame pointer
+
+ add r1, sp, #16 @ r1 points to this and params
+ bl cpp_vtable_call(PLT)
+
+ add sp, sp, #32 @ restore stack
+ ldr fp, [sp, #-32] @ restore frame pointer
+ ldr pc, [sp, #-24] @ return
diff --git a/bridges/source/cpp_uno/gcc3_linux_arm/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_arm/cpp2uno.cxx
new file mode 100644
index 000000000000..23e33acafaa4
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_arm/cpp2uno.cxx
@@ -0,0 +1,535 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <malloc.h>
+#include <hash_map>
+
+#include <rtl/alloc.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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 <dlfcn.h>
+
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+ static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+ {
+ // pCallStack: ret, [return ptr], this, params
+ char * pTopStack = (char *)(pCallStack + 0);
+ char * pCppStack = pTopStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+ void * pCppReturn = 0;
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+
+ 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 ))
+ {
+#ifdef __ARM_EABI__
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ if ((pCppStack - pTopStack) % 8) pCppStack+=sizeof(sal_Int32); //align to 8
+ break;
+ default:
+ break;
+ }
+#endif
+
+ 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 occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet =
+ (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+ }
+
+
+ //=====================================================================
+ static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+ {
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: [ret *], this, params
+ // _this_ ptr is patched cppu_XInterfaceProxy object
+ void *pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = pCallStack[1];
+ }
+ else
+ {
+ pThis = pCallStack[0];
+ }
+
+ 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::createFromAscii("illegal vtable index!"),
+ (XInterface *)pCppI );
+ }
+
+ // determine called method
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ sal_Int32 nMemberPos =
+ pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers,
+ "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] ==
+ nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET(&pTD,
+ reinterpret_cast<Type *>(pCallStack[2])->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[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = pCallStack[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ OUString::createFromAscii("no member description found!"),
+ (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+ }
+}
+
+//=======================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+
+extern "C" sal_Int64 cpp_vtable_call( long *pFunctionAndOffset,
+ void **pCallStack )
+{
+ sal_Int64 nRegReturn;
+ cpp_mediate( pFunctionAndOffset[0], pFunctionAndOffset[1], pCallStack,
+ &nRegReturn );
+ return nRegReturn;
+}
+
+extern "C" void privateSnippetExecutor(void);
+
+namespace
+{
+ const int codeSnippetSize = 20;
+
+ unsigned char *codeSnippet(unsigned char* code, sal_Int32 functionIndex,
+ sal_Int32 vtableOffset, bool simple_ret_type )
+ {
+ if (!simple_ret_type)
+ functionIndex |= 0x80000000;
+
+ unsigned long * p = (unsigned long *)code;
+
+ *p++ = 0xE1A0C00F;
+ *p++ = 0xE59FF004;
+ *p++ = (unsigned long)functionIndex;
+ *p++ = (unsigned long)vtableOffset;
+ *p++ = (unsigned long)privateSnippetExecutor;
+
+ 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, sal_PtrDiff writetoexecdiff,
+ 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 + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset, true);
+ }
+ break;
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ (s++)->fn = code + writetoexecdiff;
+
+ typelib_InterfaceMethodTypeDescription *pMethodTD =
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(member);
+
+ bool issimple = bridges::cpp_uno::shared::isSimpleType(
+ pMethodTD->pReturnTypeRef);
+
+ code = codeSnippet(code, functionOffset++, vtableOffset,
+ issimple);
+ break;
+ }
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *beg, unsigned char const *end)
+{
+ static void (*clear_cache)(unsigned char const*, unsigned char const*)
+ = (void (*)(unsigned char const*, unsigned char const*))
+ dlsym(RTLD_DEFAULT, "__clear_cache");
+ (*clear_cache)(beg, end);
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_arm/except.cxx b/bridges/source/cpp_uno/gcc3_linux_arm/except.cxx
new file mode 100644
index 000000000000..30173ed8cd18
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_arm/except.cxx
@@ -0,0 +1,344 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#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;
+
+extern sal_Int32 * pHack;
+extern sal_Int32 nHack;
+
+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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+ public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI(typelib_CompoundTypeDescription *) SAL_THROW( () );
+ };
+ //____________________________________________________________________
+ RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+ {
+ }
+ //____________________________________________________________________
+ RTTI::~RTTI() SAL_THROW( () )
+ {
+ dlclose( m_hApp );
+ }
+
+ //____________________________________________________________________
+ 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 iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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() +4;
+#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 = iFind->second;
+ }
+
+ return rtti;
+ }
+
+ //------------------------------------------------------------------
+ static void 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 occured: %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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+ }
+
+#ifdef __ARM_EABI__
+ static void* getAdjustedPtr(__cxa_exception* header)
+ {
+ return (void*)header->unwindHeader.barrier_cache.bitpattern[0];
+ }
+#else
+ static void* getAdjustedPtr(__cxa_exception* header)
+ {
+ return header->adjustedPtr;
+ }
+#endif
+
+ //===================================================================
+ void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+ {
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, 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 occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, getAdjustedPtr(header), pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+ }
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_arm/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_arm/makefile.mk
new file mode 100644
index 000000000000..6ebd13698b37
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_arm/makefile.mk
@@ -0,0 +1,88 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.5 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+NO_BSYMBOLIC=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCLINUXRgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSCXX += -fno-omit-frame-pointer
+
+NOOPTFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/uno2cpp.obj
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/armhelper.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+ $(CXX) -c -o $(SLO)$/$(@:b).o $< -fPIC ; touch $@
diff --git a/bridges/source/cpp_uno/gcc3_linux_arm/share.hxx b/bridges/source/cpp_uno/gcc3_linux_arm/share.hxx
new file mode 100644
index 000000000000..a930897232df
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_arm/share.hxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _ARM_SHARE_HXX
+#define _ARM_SHARE_HXX
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+#include <unwind.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 __cxa_exception
+ {
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+#ifdef __ARM_EABI__
+ __cxa_exception *nextPropagatingException;
+ int propagationCount;
+#else
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+#endif
+ _Unwind_Exception unwindHeader;
+ };
+
+ extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+ extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo,
+ void (*dest) (void *) ) __attribute__((noreturn));
+
+ struct __cxa_eh_globals
+ {
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+#ifdef __ARM_EABI__
+ __cxa_exception *propagatingExceptions;
+#endif
+ };
+ extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+ // -----
+
+ //====================================================================
+ void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+ //====================================================================
+ void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+#endif
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_arm/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_arm/uno2cpp.cxx
new file mode 100644
index 000000000000..f59a16b2ac38
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_arm/uno2cpp.cxx
@@ -0,0 +1,633 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <malloc.h>
+#include <rtl/alloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.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 "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+/*
+ * Based on http://gcc.gnu.org/PR41443
+ * References to __SOFTFP__ are incorrect for EABI; the __SOFTFP__ code
+ * should be used for *soft-float ABI* whether or not VFP is enabled,
+ * and __SOFTFP__ does specifically mean soft-float not soft-float ABI.
+ *
+ * Changing the conditionals to __SOFTFP__ || __ARM_EABI__ then
+ * -mfloat-abi=softfp should work. -mfloat-abi=hard won't; that would
+ * need both a new macro to identify the hard-VFP ABI.
+ */
+#if !defined(__ARM_EABI__) && !defined(__SOFTFP__)
+#error Not Implemented
+
+/*
+ some possibly handy code to detect that we have VFP registers
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <elf.h>
+
+#define HWCAP_ARM_VFP 64
+
+int hasVFP(void)
+{
+ int fd = open ("/proc/self/auxv", O_RDONLY);
+ if (fd == -1)
+ return -1;
+
+ int ret = -1;
+
+ Elf32_auxv_t buf[128];
+ ssize_t n;
+ while ((ret == -1) && ((n = read(fd, buf, sizeof (buf))) > 0))
+ {
+ for (int i = 0; i < 128; ++i)
+ {
+ if (buf[i].a_type == AT_HWCAP)
+ {
+ ret = (buf[i].a_un.a_val & HWCAP_ARM_VFP) ? true : false;
+ break;
+ }
+ else if (buf[i].a_type == AT_NULL)
+ {
+ ret = -2;
+ break;
+ }
+ }
+ }
+
+ close (fd);
+ return ret;
+}
+
+#endif
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace arm
+{
+ enum armlimits { MAX_GPR_REGS = 4 };
+}
+
+void MapReturn(long r0, long r1, typelib_TypeClass eReturnType, void *pRegisterReturn)
+{
+#if !defined(__ARM_EABI__) && !defined(__SOFTFP__)
+ register float fret asm("f0");
+ register double dret asm("f0");
+#endif
+
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = r1;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = r0;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = (unsigned short)r0;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)r0;
+ break;
+ case typelib_TypeClass_FLOAT:
+#if defined(__ARM_EABI__) || defined(__SOFTFP__)
+ ((long*)pRegisterReturn)[0] = r0;
+#else
+ *(float*)pRegisterReturn = fret;
+#endif
+ break;
+ case typelib_TypeClass_DOUBLE:
+#if defined(__ARM_EABI__) || defined(__SOFTFP__)
+ ((long*)pRegisterReturn)[1] = r1;
+ ((long*)pRegisterReturn)[0] = r0;
+#else
+ *(double*)pRegisterReturn = dret;
+#endif
+ break;
+ default:
+ break;
+ }
+}
+
+namespace
+{
+//================================================================
+
+void callVirtualMethod(
+ void * pThis,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_uInt32 *pStack,
+ sal_uInt32 nStack,
+ sal_uInt32 *pGPR,
+ sal_uInt32 nGPR) __attribute__((noinline));
+
+void callVirtualMethod(
+ void * pThis,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_uInt32 *pStack,
+ sal_uInt32 nStack,
+ sal_uInt32 *pGPR,
+ sal_uInt32 nGPR)
+{
+ // never called
+ if (! pThis)
+ CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+ if ( nStack )
+ {
+ // 8-bytes aligned
+ sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 8;
+ sal_uInt32 *stack = (sal_uInt32 *) __builtin_alloca( nStackBytes );
+ memcpy( stack, pStack, nStackBytes );
+ }
+
+ // Should not happen, but...
+ if ( nGPR > arm::MAX_GPR_REGS )
+ nGPR = arm::MAX_GPR_REGS;
+
+ sal_uInt32 pMethod = *((sal_uInt32*)pThis);
+ pMethod += 4 * nVtableIndex;
+ pMethod = *((sal_uInt32 *)pMethod);
+
+ typedef void (*FunctionCall )( sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32);
+ FunctionCall pFunc = (FunctionCall)pMethod;
+
+ // fill registers
+ __asm__ __volatile__ (
+ "ldr r0, [%0, #0]\n\t"
+ "ldr r1, [%0, #4]\n\t"
+ "ldr r2, [%0, #8]\n\t"
+ "ldr r3, [%0, #12]\n\t"
+ : : "r" (pGPR)
+ : "r0", "r1", "r2", "r3"
+ );
+
+ // tell gcc that r0 to r3 are not available to it
+ register sal_uInt32 r0 asm("r0");
+ register sal_uInt32 r1 asm("r1");
+ register sal_uInt32 r2 asm("r2");
+ register sal_uInt32 r3 asm("r3");
+
+ (*pFunc)(r0, r1, r2, r3);
+
+ // get return value
+ __asm__ __volatile__ (
+ "mov %0, r0\n\t"
+ "mov %1, r1\n\t"
+ : "=r" (r0), "=r" (r1) : );
+
+ MapReturn(r0, r1, eReturnType, pRegisterReturn);
+}
+}
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < arm::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#ifdef __ARM_EABI__
+#define INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow ) \
+ if ( (nr < arm::MAX_GPR_REGS) && (nr % 2) ) \
+ { \
+ ++nr; \
+ } \
+ if ( nr < arm::MAX_GPR_REGS ) \
+ { \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ pGPR[nr++] = *(reinterpret_cast<sal_uInt32 *>( pSV ) + 1); \
+ } \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ { \
+ if ( (pDS - pStart) % 2) \
+ { \
+ ++pDS; \
+ } \
+ *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[0]; \
+ *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[1]; \
+ }
+#else
+#define INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow ) \
+ INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow) \
+ INSERT_INT32( ((sal_uInt32*)pSV)+1, nr, pGPR, pDS, bOverflow)
+#endif
+
+#define INSERT_FLOAT( pSV, nr, pFPR, pDS, bOverflow ) \
+ INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow)
+
+#define INSERT_DOUBLE( pSV, nr, pFPR, pDS, pStart, bOverflow ) \
+ INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow )
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < arm::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < arm::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+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 ...
+ sal_uInt32 * pStack = (sal_uInt32 *)__builtin_alloca(
+ sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ sal_uInt32 * pStackStart = pStack;
+
+ sal_uInt32 pGPR[arm::MAX_GPR_REGS];
+ sal_uInt32 nGPR = 0;
+
+ // 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
+
+ bool bOverFlow = false;
+
+ 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 )
+ ? __builtin_alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+
+ INSERT_INT32( &pCppReturn, nGPR, pGPR, pStack, bOverFlow );
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ INSERT_INT32( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverFlow );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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] = pStack, pUnoArgs[nPos],
+ uno_copyAndConvertData( pCppArgs[nPos] = alloca(8), pUnoArgs[nPos],
+ pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "hyper is %lx\n", pCppArgs[nPos]);
+#endif
+ INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart, bOverFlow );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "long is %x\n", pCppArgs[nPos]);
+#endif
+ INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_FLOAT:
+ INSERT_FLOAT( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ INSERT_DOUBLE( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart, bOverFlow );
+ 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(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT32( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverFlow );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass,
+ pStackStart,
+ (pStack - pStackStart),
+ pGPR, nGPR);
+
+ // NO exception occured...
+ *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 );
+
+ 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 (...)
+ {
+// __asm__ __volatile__ ("sub sp, sp, #2048\n");
+
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+}
+
+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);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1;
+ cpp_call(
+ pThis, aVtableSlot, // get, then set method
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ 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->getBridge()->getUnoEnv()->getRegisteredInterface)(
+ pThis->getBridge()->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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_hppa/call.cxx b/bridges/source/cpp_uno/gcc3_linux_hppa/call.cxx
new file mode 100644
index 000000000000..cd30e224bef5
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_hppa/call.cxx
@@ -0,0 +1,145 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <malloc.h>
+#include <rtl/alloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.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 "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+void MapReturn(sal_uInt32 ret0, sal_uInt32 ret1, typelib_TypeDescription *pReturnTypeDescr, bool bRegisterReturn, sal_uInt32 *pRegisterReturn)
+{
+ register float fret asm("fr4");
+ register double dret asm("fr4");
+
+ switch (pReturnTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ pRegisterReturn[1] = ret1;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ pRegisterReturn[0] = ret0;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = fret;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = dret;
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ if (bRegisterReturn)
+ {
+ pRegisterReturn[0] = ret0;
+ pRegisterReturn[1] = ret1;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+//Moved callVirtual into this .cxx so that I can do this and get gcc to not
+//touch r28 without having to learn any more pa-risc assembly than is
+//strictly necessary
+register sal_uInt32 r28 __asm__("%r28");
+
+void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescription *pReturnTypeDescr, bool bRegisterReturn,
+ sal_uInt32 *pStack, sal_uInt32 nStack, sal_uInt32 *pGPR, double *pFPR) __attribute__((noinline));
+
+void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescription *pReturnTypeDescr, bool bRegisterReturn,
+ sal_uInt32 *pStack, sal_uInt32 nStack, sal_uInt32 *pGPR, double *pFPR)
+{
+ register sal_uInt32* sp __asm__("%r30");
+
+ sal_uInt32 pMethod = *((sal_uInt32*)pThis);
+ pMethod += 4 * nVtableIndex;
+ pMethod = *((sal_uInt32 *)pMethod);
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "this is %p\n", pGPR[0]);
+ for (int i = 0; i < hppa::MAX_GPR_REGS ; ++i)
+ fprintf(stderr, "normal reg %d is %d %x\n", i, pGPR[i], pGPR[i]);
+
+ for (int i = 0; i < hppa::MAX_SSE_REGS ; ++i)
+ fprintf(stderr, "float reg %d is %x\n", i, pFPR[i]);
+
+ for (int i = 0; i < nStack; ++i)
+ fprintf(stderr, "stack bytes are %x\n", pStack[i]);
+#endif
+
+ //Always reserve 4 slots, and align to 8 bytes
+ sal_uInt32 nStackBytes = ( ( nStack + 4 + 1 ) >> 1 ) * 8;
+ __builtin_alloca(nStackBytes);
+ sal_uInt32 *stack = sp-8;
+ int o = -5;
+ for (sal_uInt32 i = 0; i < nStack; ++i, --o)
+ stack[o] = pStack[i];
+
+ typedef int (* FunctionCall )( sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32 );
+ FunctionCall pFunc = (FunctionCall)pMethod;
+
+ asm volatile("fldd %0, %%fr4" : : "m"(pFPR[0]) : "fr4");
+ asm volatile("fldd %0, %%fr5" : : "m"(pFPR[1]) : "fr5");
+ asm volatile("fldd %0, %%fr6" : : "m"(pFPR[2]) : "fr6");
+ asm volatile("fldd %0, %%fr7" : : "m"(pFPR[3]) : "fr7");
+ asm volatile("ldw %0, %%r28" : : "m"(pRegisterReturn) : "r28");
+ (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3]);
+
+ register sal_uInt32 r29 __asm__("%r29");
+ MapReturn(r28, r29, pReturnTypeDescr, bRegisterReturn, (sal_uInt32*)pRegisterReturn);
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_hppa/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_hppa/cpp2uno.cxx
new file mode 100644
index 000000000000..a78d7694c798
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_hppa/cpp2uno.cxx
@@ -0,0 +1,728 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <malloc.h>
+#include <hash_map>
+
+#include <rtl/alloc.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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 <dlfcn.h>
+
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+ static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ long r8, void ** gpreg, double *fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+ {
+ void ** startovrflw;
+ int nregs = 0; //number of words passed in registers
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "cpp2uno_call\n");
+#endif
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+ void * pCppReturn = 0;
+
+ if (pReturnTypeDescr)
+ {
+ if (hppa::isRegisterReturn(pReturnTypeRef))
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "simple return\n");
+#endif
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex return via r8\n");
+#endif
+ pCppReturn = (void *)r8;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ gpreg++;
+ fpreg++;
+ nregs++;
+
+ // 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;
+ bool bOverFlowUsed = false;
+ 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 ))
+ {
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_DOUBLE:
+ if (nregs < hppa::MAX_WORDS_IN_REGS && (nregs & 1))
+ {
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ if (nregs < hppa::MAX_WORDS_IN_REGS-1)
+ {
+ fpreg++;
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg;
+ gpreg+=2;
+ fpreg+=2;
+ nregs+=2;
+ }
+ else
+ {
+ if ((startovrflw-ovrflw) & 4)
+ ovrflw--;
+ pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)ovrflw - 4);
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw-=2;
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (nregs < hppa::MAX_WORDS_IN_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg;
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw--;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (nregs < hppa::MAX_WORDS_IN_REGS && (nregs & 1))
+ {
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ if (nregs < hppa::MAX_WORDS_IN_REGS-1)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg;
+ gpreg+=2;
+ fpreg+=2;
+ nregs+=2;
+ }
+ else
+ {
+ if ((startovrflw-ovrflw) & 4)
+ ovrflw--;
+ pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)ovrflw - 4);
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw-=2;
+ break;
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+ if (nregs < hppa::MAX_WORDS_IN_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)gpreg + 3);
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)ovrflw+3);
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw--;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (nregs < hppa::MAX_WORDS_IN_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)gpreg+2);
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)ovrflw+2);
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw--;
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ default:
+ if (nregs < hppa::MAX_WORDS_IN_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg;
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw--;
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ void *pCppStack;
+
+ if (nregs < hppa::MAX_WORDS_IN_REGS)
+ {
+ pCppArgs[nPos] = pCppStack = *gpreg;
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pCppStack = *ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw--;
+
+ 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 ),
+ 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] = pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "before dispatch\n");
+#endif
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "after dispatch\n");
+#endif
+
+ // in case an exception occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet =
+ (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+ }
+
+
+ //=====================================================================
+ static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ void ** gpreg, double* fpreg,
+ long sp, long r8,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+
+ {
+ void ** ovrflw = (void**)(sp);
+#ifdef CMC_DEBUG
+ fprintf(stderr, "cpp_mediate with\n");
+ fprintf(stderr, "%x %x\n", nFunctionIndex, nVtableOffset);
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[0]), (long)(ovrflw[-1]));
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[-2]), (long)(ovrflw[-3]));
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[-4]), (long)(ovrflw[-5]));
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[-6]), (long)(ovrflw[-7]));
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[-8]), (long)(ovrflw[-9]));
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[-10]), (long)(ovrflw[-11]));
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[-12]), (long)(ovrflw[-13]));
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[-14]), (long)(ovrflw[-15]));
+#endif
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ void * pThis;
+ if (nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is gpreg[1]\n");
+#endif
+ }
+ else
+ {
+ pThis = gpreg[0];
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is gpreg[0]\n");
+#endif
+ }
+
+ 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::createFromAscii("illegal vtable index!"),
+ (XInterface *)pCppI );
+ }
+
+ // determine called method
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ sal_Int32 nMemberPos =
+ pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers,
+ "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] ==
+ nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ r8, gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ r8, gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET(&pTD,
+ reinterpret_cast<Type *>(gpreg[1])->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 * >( r8 ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = (void*)r8;
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ r8, gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ OUString::createFromAscii("no member description found!"),
+ (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+ }
+}
+
+//=======================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+
+sal_Int64 cpp_vtable_call( sal_uInt32 in0, sal_uInt32 in1, sal_uInt32 in2, sal_uInt32 in3, sal_uInt32 firstonstack )
+{
+ register sal_Int32 r21 asm("r21");
+ register sal_Int32 r22 asm("r22");
+ register sal_Int32 r28 asm("r28");
+ sal_Int32 functionIndex = r21;
+ sal_Int32 vtableOffset = r22;
+ sal_Int32 r8 = r28;
+
+ long sp = (long)&firstonstack;
+
+ sal_uInt32 gpreg[hppa::MAX_GPR_REGS];
+ gpreg[0] = in0;
+ gpreg[1] = in1;
+ gpreg[2] = in2;
+ gpreg[3] = in3;
+
+ float fpreg[hppa::MAX_SSE_REGS]; //todo
+ register float f0 asm("fr4"); fpreg[0] = f0;
+ register float f1 asm("fr5"); fpreg[1] = f1;
+ register float f2 asm("fr6"); fpreg[2] = f2;
+ register float f3 asm("fr7"); fpreg[3] = f3;
+
+ double dpreg[hppa::MAX_SSE_REGS]; //todo
+ register double d0 asm("fr4"); dpreg[0] = d0;
+ register double d1 asm("fr5"); dpreg[1] = d1;
+ register double d2 asm("fr6"); dpreg[2] = d2;
+ register double d3 asm("fr7"); dpreg[3] = d3;
+
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "got to cpp_vtable_call with %x %x\n", functionIndex, vtableOffset);
+ for (int i = 0; i < hppa::MAX_GPR_REGS; ++i)
+ fprintf(stderr, "reg %d is %d %x\n", i, gpreg[i], gpreg[i]);
+ for (int i = 0; i < hppa::MAX_SSE_REGS; ++i)
+ fprintf(stderr, "float reg %d is %f %x\n", i, fpreg[i], ((long*)fpreg)[i]);
+ for (int i = 0; i < 4; ++i)
+ fprintf(stderr, "double reg %d is %f %llx\n", i, dpreg[i], ((long long*)dpreg)[i]);
+#endif
+
+ sal_Int64 nRegReturn;
+
+ typelib_TypeClass aType =
+ cpp_mediate( functionIndex, vtableOffset, (void**)gpreg, dpreg, sp, r8, &nRegReturn);
+
+ switch( aType )
+ {
+ case typelib_TypeClass_FLOAT:
+ f0 = (*((float*)&nRegReturn));
+ break;
+ case typelib_TypeClass_DOUBLE:
+ d0 = (*((double*)&nRegReturn));
+ break;
+ default:
+ break;
+ }
+
+ return nRegReturn;
+}
+
+
+namespace
+{
+ const int codeSnippetSize = 44;
+
+# define unldil(v) (((v & 0x7c) << 14) | ((v & 0x180) << 7) | ((v & 0x3) << 12) | ((v & 0xffe00) >> 8) | ((v & 0x100000) >> 20))
+# define L21(v) unldil(((unsigned long)(v) >> 11) & 0x1fffff) //Left 21 bits
+# define R11(v) (((unsigned long)(v) & 0x7FF) << 1) //Right 11 bits
+
+ unsigned char *codeSnippet(unsigned char* code, sal_Int32 functionIndex,
+ sal_Int32 vtableOffset, bool bHasHiddenParam)
+ {
+ if (bHasHiddenParam)
+ functionIndex |= 0x80000000;
+
+ unsigned char * p = code;
+ *(unsigned long*)&p[0] = 0xeaa00000; // b,l 0x8,r21
+ *(unsigned long*)&p[4] = 0xd6a01c1e; // depwi 0,31,2,r21
+ *(unsigned long*)&p[8] = 0x4aa10040; // ldw 32(r21),r1
+
+ *(unsigned long*)&p[12] = 0x22A00000 | L21(functionIndex); // ldil L<functionIndex>,r21
+ *(unsigned long*)&p[16] = 0x36B50000 | R11(functionIndex); // ldo R<functionIndex>,r21
+
+ *(unsigned long*)&p[20] = 0x22C00000 | L21(vtableOffset); // ldil L<vtableOffset>,r22
+ *(unsigned long*)&p[24] = 0x36D60000 | R11(vtableOffset); // ldo R<vtableOffset>,r22
+
+ *(unsigned long*)&p[28] = 0x0c201094; // ldw 0(r1),r20
+ *(unsigned long*)&p[32] = 0xea80c000; // bv r0(r20)
+ *(unsigned long*)&p[36] = 0x0c281093; // ldw 4(r1),r19
+ *(unsigned long*)&p[40] = ((unsigned long)(cpp_vtable_call) & ~2);
+
+ 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, sal_PtrDiff writetoexecdiff,
+ 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 + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, false);
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, false);
+ }
+ break;
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, false);
+ break;
+ }
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *beg, unsigned char const *end)
+{
+ void *p = (void*)((size_t)beg & ~31);
+ size_t stride = 32;
+ while (p < end)
+ {
+ asm volatile("fdc (%0)\n\t"
+ "sync\n\t"
+ "fic,m %1(%%sr4, %0)\n\t"
+ "sync" : "+r"(p) : "r"(stride) : "memory");
+ }
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_hppa/except.cxx b/bridges/source/cpp_uno/gcc3_linux_hppa/except.cxx
new file mode 100644
index 000000000000..8242bacaedc6
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_hppa/except.cxx
@@ -0,0 +1,337 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#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;
+
+extern sal_Int32 * pHack;
+extern sal_Int32 nHack;
+
+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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+ public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI(typelib_CompoundTypeDescription *) SAL_THROW( () );
+ };
+ //____________________________________________________________________
+ RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+ {
+ }
+ //____________________________________________________________________
+ RTTI::~RTTI() SAL_THROW( () )
+ {
+ dlclose( m_hApp );
+ }
+
+ //____________________________________________________________________
+ 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( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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() +4;
+#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;
+ }
+
+ //------------------------------------------------------------------
+ static void 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 occured: %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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+ }
+
+ static void* getAdjustedPtr(__cxa_exception* header)
+ {
+ return header->adjustedPtr;
+ }
+
+ //===================================================================
+ void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+ {
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, 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 occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, getAdjustedPtr(header), pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+ }
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_hppa/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_hppa/makefile.mk
new file mode 100644
index 000000000000..fcdcea72454f
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_hppa/makefile.mk
@@ -0,0 +1,86 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.2 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+NO_BSYMBOLIC=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)" == "GCCLINUXH"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSCXX += -fno-omit-frame-pointer
+
+NOOPTFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/bridges/source/cpp_uno/gcc3_linux_hppa/share.hxx b/bridges/source/cpp_uno/gcc3_linux_hppa/share.hxx
new file mode 100644
index 000000000000..eedfdf75da8d
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_hppa/share.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+
+namespace hppa
+{
+ enum hppalimits { MAX_WORDS_IN_REGS = 4, MAX_GPR_REGS = 4, MAX_SSE_REGS = 4 };
+
+ bool isRegisterReturn( typelib_TypeDescriptionReference *pTypeRef );
+}
diff --git a/bridges/source/cpp_uno/gcc3_linux_hppa/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_hppa/uno2cpp.cxx
new file mode 100644
index 000000000000..a342568d5bf8
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_hppa/uno2cpp.cxx
@@ -0,0 +1,524 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <malloc.h>
+#include <rtl/alloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.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 "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescription *pReturnTypeDescr, bool bRegisterReturn,
+ sal_uInt32 *pStack, sal_uInt32 nStack, sal_uInt32 *pGPR, double *pFPR);
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS, bOverFlow )\
+ if (nr < hppa::MAX_WORDS_IN_REGS) \
+ { \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ } \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverFlow )\
+ if ( (nr < hppa::MAX_WORDS_IN_REGS) && (nr % 2) ) \
+ { \
+ ++nr; \
+ } \
+ if ( nr < hppa::MAX_WORDS_IN_REGS ) \
+ { \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ pGPR[nr++] = *(reinterpret_cast<sal_uInt32 *>( pSV ) + 1); \
+ } \
+ else \
+ bOverFlow = true; \
+ if ( bOverFlow ) \
+ { \
+ if ( (pDS - pStart) % 2) \
+ ++pDS; \
+ *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[1]; \
+ *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[0]; \
+ }
+
+#define INSERT_FLOAT( pSV, nr, pFPR, pDS, bOverFlow ) \
+ if (nr < hppa::MAX_WORDS_IN_REGS) \
+ { \
+ sal_uInt32 *pDouble = (sal_uInt32 *)&(pFPR[nr++]); \
+ pDouble[0] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ } \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_DOUBLE( pSV, nr, pFPR, pDS, pStart, bOverFlow ) \
+ if ( (nr < hppa::MAX_WORDS_IN_REGS) && (nr % 2) ) \
+ { \
+ ++nr; \
+ } \
+ if ( nr < hppa::MAX_WORDS_IN_REGS ) \
+ { \
+ sal_uInt32 *pDouble = (sal_uInt32 *)&(pFPR[nr+1]); \
+ pDouble[0] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ pDouble[1] = *(reinterpret_cast<sal_uInt32 *>( pSV ) + 1); \
+ nr+=2; \
+ } \
+ else \
+ bOverFlow = true; \
+ if ( bOverFlow ) \
+ { \
+ if ( (pDS - pStart) % 2) \
+ ++pDS; \
+ *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[1]; \
+ *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[0]; \
+ }
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS, bOverFlow ) \
+ if ( nr < hppa::MAX_WORDS_IN_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS, bOverFlow ) \
+ if ( nr < hppa::MAX_WORDS_IN_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+namespace hppa
+{
+ bool is_complex_struct(const typelib_TypeDescription * type)
+ {
+ const typelib_CompoundTypeDescription * p
+ = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
+ for (sal_Int32 i = 0; i < p->nMembers; ++i)
+ {
+ if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
+ p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
+ {
+ typelib_TypeDescription * t = 0;
+ TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
+ bool b = is_complex_struct(t);
+ TYPELIB_DANGER_RELEASE(t);
+ if (b) {
+ return true;
+ }
+ }
+ else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
+ return true;
+ }
+ if (p->pBaseTypeDescription != 0)
+ return is_complex_struct(&p->pBaseTypeDescription->aBase);
+ return false;
+ }
+
+ bool isRegisterReturn( typelib_TypeDescriptionReference *pTypeRef )
+ {
+ if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
+ return true;
+ else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+ /* If the struct is larger than 8 bytes, then there is a buffer at r8 to stick the return value into */
+ bool bRet = pTypeDescr->nSize <= 8 && !is_complex_struct(pTypeDescr);
+
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ return bRet;
+ }
+ return false;
+ }
+}
+
+
+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 ...
+ sal_uInt32 * pStack = (sal_uInt32 *)__builtin_alloca(
+ sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ sal_uInt32 * pStackStart = pStack;
+
+ sal_uInt32 pGPR[hppa::MAX_GPR_REGS];
+ double pFPR[hppa::MAX_SSE_REGS];
+ sal_uInt32 nRegs=0;
+
+ // 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
+ bool bOverFlow = false;
+ bool bRegisterReturn = true;
+
+ if (pReturnTypeDescr)
+ {
+
+ bRegisterReturn = hppa::isRegisterReturn(pReturnTypeRef);
+ if (bRegisterReturn)
+ pCppReturn = pUnoReturn; // direct way for simple types
+ else
+ {
+ // complex return via ptr
+ pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? __builtin_alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ INSERT_INT32( &pAdjustedThisPtr, nRegs, pGPR, pStack, bOverFlow );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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] = alloca(8), pUnoArgs[nPos],
+ pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "hyper is %llx\n", *((long long*)pCppArgs[nPos]));
+#endif
+ INSERT_INT64( pCppArgs[nPos], nRegs, pGPR, pStack, pStackStart, bOverFlow );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "long is %x\n", pCppArgs[nPos]);
+#endif
+ INSERT_INT32( pCppArgs[nPos], nRegs, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16( pCppArgs[nPos], nRegs, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8( pCppArgs[nPos], nRegs, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_FLOAT:
+ INSERT_FLOAT( pCppArgs[nPos], nRegs, pFPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ INSERT_DOUBLE( pCppArgs[nPos], nRegs, pFPR, pStack, pStackStart, bOverFlow );
+ 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(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT32( &(pCppArgs[nPos]), nRegs, pGPR, pStack, bOverFlow );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr, bRegisterReturn,
+ pStackStart,
+ (pStack - pStackStart), pGPR, pFPR);
+
+ // NO exception occured...
+ *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 );
+
+ 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( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+}
+
+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);
+#if OSL_DEBUG_LEVEL > 0
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+#endif
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+#endif
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1;
+ cpp_call(
+ pThis, aVtableSlot, // get, then set method
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+#endif
+
+ 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->getBridge()->getUnoEnv()->getRegisteredInterface)(
+ pThis->getBridge()->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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_ia64/call.s b/bridges/source/cpp_uno/gcc3_linux_ia64/call.s
new file mode 100644
index 000000000000..8073127da3e3
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_ia64/call.s
@@ -0,0 +1,20 @@
+/* ia64 support code for OpenOffice C++/UNO bridging
+ *
+ * Caolan McNamara <caolanm@redhat.com>
+ */
+ .text
+ .align 16
+ .global privateSnippetExecutor#
+ .proc privateSnippetExecutor#
+privateSnippetExecutor:
+ adds r15 = 8, gp /* r15 now points to real gp value*/
+ ;;
+ ld8 r14 = [gp] /* load nOffsetAndIndex into a handy register */
+ ld8 gp = [r15] /* load real gp value into gp */
+ ;;
+ /* store the address where large structs are "returned" into a handy register */
+ mov r15 = r8
+ ;;
+ br cpp_vtable_call# /* call cpp_vtable_call which'll suck out r14 */
+ ;;
+ .endp privateSnippetExecutor#
diff --git a/bridges/source/cpp_uno/gcc3_linux_ia64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_ia64/cpp2uno.cxx
new file mode 100644
index 000000000000..900560794513
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_ia64/cpp2uno.cxx
@@ -0,0 +1,687 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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 <stdio.h>
+
+extern "C" { extern void (*privateSnippetExecutor)(); }
+
+using namespace ::com::sun::star::uno;
+
+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, long r8,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "as far as cpp2uno_call\n");
+#endif
+
+ int ng = 0; //number of gpr registers used
+ int nf = 0; //number of fpr regsiters used
+
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // 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 ( ia64::return_in_hidden_param( pReturnTypeRef ) ) // complex return via ptr passed as hidden parameter reg (pCppReturn)
+ {
+ pCppReturn = *(void **)gpreg;
+ gpreg++;
+ ng++;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ else if ( ia64::return_via_r8_buffer( pReturnTypeRef ) ) // complex return via ptr passed in r8
+ {
+ pCppReturn = (void *)r8;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+
+ else
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ // pop this
+ gpreg++;
+ ng++;
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int64), "### 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;
+ bool bOverFlowUsed = false;
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "arg %d of %d\n", nPos, nParams);
+#endif
+
+ //I think it is impossible to get UNO to pass structs as parameters by copy
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "simple\n");
+#endif
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_FLOAT:
+ if (nf < ia64::MAX_SSE_REGS && ng < ia64::MAX_GPR_REGS)
+ {
+ float tmp = (float) (*((double *)fpreg));
+ (*((float *) fpreg)) = tmp;
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
+ nf++;
+ gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (nf < ia64::MAX_SSE_REGS && ng < ia64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
+ nf++;
+ gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ default:
+ if (ng < ia64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex, ng is %d\n", ng);
+#endif
+ void *pCppStack; //temporary stack pointer
+
+ if (ng < ia64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pCppStack = *gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pCppStack = *ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+
+ 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 ),
+ 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] = pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "end of params\n");
+#endif
+
+ // 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 occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = ia64::return_via_r8_buffer(pReturnTypeRef) ? typelib_TypeClass_VOID : (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_uInt64 nOffsetAndIndex,
+ void ** gpreg, void ** fpreg, long sp, long r8,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int64)==sizeof(void *), "### unexpected!" );
+
+ sal_Int32 nVtableOffset = (nOffsetAndIndex >> 32);
+ sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
+
+ void ** ovrflw = (void**)(sp);
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ void * pThis;
+ if (nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is gpreg[1]\n");
+#endif
+ }
+ else
+ {
+ pThis = gpreg[0];
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is gpreg[0]\n");
+#endif
+ }
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is %p\n", pThis);
+#endif
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is now %p\n", pThis);
+#endif
+
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "indexes are %d %d\n", nFunctionIndex, pTypeDescr->nMapFunctionIndexToMemberIndex);
+#endif
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "members are %d %d\n", nMemberPos, pTypeDescr->nAllMembers);
+#endif
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ r8, gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ r8, gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->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 * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ r8, gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "screwed\n");
+#endif
+
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "end of cpp_mediate\n");
+#endif
+ return eRet;
+}
+}
+
+extern "C" ia64::RegReturn cpp_vtable_call(
+ long in0, long in1, long in2, long in3, long in4, long in5, long in6, long in7,
+ long firstonstack
+ )
+{
+ register long r15 asm("r15");
+ long r8 = r15;
+
+ register long r14 asm("r14");
+ long nOffsetAndIndex = r14;
+
+ long sp = (long)&firstonstack;
+
+ sal_uInt64 gpreg[ia64::MAX_GPR_REGS];
+ gpreg[0] = in0;
+ gpreg[1] = in1;
+ gpreg[2] = in2;
+ gpreg[3] = in3;
+ gpreg[4] = in4;
+ gpreg[5] = in5;
+ gpreg[6] = in6;
+ gpreg[7] = in7;
+
+ double fpreg[ia64::MAX_SSE_REGS];
+ register double f8 asm("f8"); fpreg[0] = f8;
+ register double f9 asm("f9"); fpreg[1] = f9;
+ register double f10 asm("f10"); fpreg[2] = f10;
+ register double f11 asm("f11"); fpreg[3] = f11;
+ register double f12 asm("f12"); fpreg[4] = f12;
+ register double f13 asm("f13"); fpreg[5] = f13;
+ register double f14 asm("f14"); fpreg[6] = f14;
+ register double f15 asm("f15"); fpreg[7] = f15;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "cpp_vtable_call called with %lx\n", nOffsetAndIndex);
+ fprintf(stderr, "adump is %lx %lx %lx %lx %lx %lx %lx %lx\n", in0, in1, in2, in3, in4, in5, in6, in7);
+ fprintf(stderr, "bdump is %f %f %f %f %f %f %f %f\n", f8, f9, f10, f11, f12, f13, f14, f15);
+#endif
+
+ volatile long nRegReturn[4] = { 0 };
+
+ typelib_TypeClass aType =
+ cpp_mediate( nOffsetAndIndex, (void**)gpreg, (void**)fpreg, sp, r8, (sal_Int64*)&nRegReturn[0]);
+
+ ia64::RegReturn ret;
+ switch( aType )
+ {
+ case typelib_TypeClass_VOID:
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_HYPER:
+ ret.r8 = nRegReturn[0];
+ break;
+ case typelib_TypeClass_FLOAT:
+ asm volatile("ldfs f8=%0" : : "m"((*((float*)&nRegReturn))) : "f8");
+ break;
+ case typelib_TypeClass_DOUBLE:
+ asm volatile("ldfd f8=%0" : : "m"((*((double*)&nRegReturn))) : "f8");
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ ret.r8 = nRegReturn[0];
+ ret.r9 = nRegReturn[1];
+ ret.r10 = nRegReturn[2];
+ ret.r11 = nRegReturn[3];
+ break;
+ }
+ default:
+ break;
+ }
+ return ret;
+}
+
+namespace
+{
+const int codeSnippetSize = 40;
+
+bridges::cpp_uno::shared::VtableFactory::Slot codeSnippet( unsigned char * code, sal_PtrDiff writetoexecdiff, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ bool bHasHiddenParam )
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "size is %d\n", codeSnippetSize);
+ fprintf(stderr,"in codeSnippet functionIndex is %x\n", nFunctionIndex);
+ fprintf(stderr,"in codeSnippet vtableOffset is %x\n", nVtableOffset);
+#endif
+
+ sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
+
+ if ( bHasHiddenParam )
+ nOffsetAndIndex |= 0x80000000;
+
+ long *raw = (long *)code;
+
+ bridges::cpp_uno::shared::VtableFactory::Slot* destination = (bridges::cpp_uno::shared::VtableFactory::Slot*)cpp_vtable_call;
+
+ raw[0] = (long)&privateSnippetExecutor;
+ raw[1] = (long)&raw[2];
+ raw[2] = nOffsetAndIndex;
+ raw[3] = destination->gp_value;
+
+ return *(bridges::cpp_uno::shared::VtableFactory::Slot*)(code+writetoexecdiff);
+}
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *, unsigned char const *)
+{
+}
+
+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);
+ Slot foo = {0,0};
+ slots[-2] = foo;
+ slots[-1] = foo;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** in_slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*in_slots) -= functionCount;
+ Slot * slots = *in_slots;
+#ifdef CMC_DEBUG
+ fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
+ fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
+#endif
+
+ 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:
+ *slots++ = codeSnippet(
+ code, writetoexecdiff, functionOffset++, vtableOffset,
+ ia64::return_in_hidden_param(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+ code += codeSnippetSize;
+
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ *slots++ = codeSnippet(code, writetoexecdiff, functionOffset++, vtableOffset, false);
+ code += codeSnippetSize;
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ *slots++ = codeSnippet(
+ code, writetoexecdiff, functionOffset++, vtableOffset,
+ ia64::return_in_hidden_param(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ code += codeSnippetSize;
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_ia64/except.cxx b/bridges/source/cpp_uno/gcc3_linux_ia64/except.cxx
new file mode 100644
index 000000000000..3bbf940ec55f
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_ia64/except.cxx
@@ -0,0 +1,290 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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() +4;
+#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;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 )
+{
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ terminate();
+
+ 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)
+ terminate();
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
+{
+ OSL_ENSURE( header, "### no exception header!!!" );
+ if (! header)
+ terminate();
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
+ if (! pExcTypeDescr)
+ terminate();
+
+ // construct uno exception any
+ ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ ::typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_ia64/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_ia64/makefile.mk
new file mode 100644
index 000000000000..b8d9da98ff74
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_ia64/makefile.mk
@@ -0,0 +1,87 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.3 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCLINUXAgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer
+
+NOOPTFILES= \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/cpp2uno.obj
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+
+SHL1OBJS= $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+ $(CC) -c -o $(SLO)$/$(@:b).o $< -fpic ; touch $@
diff --git a/bridges/source/cpp_uno/gcc3_linux_ia64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_ia64/share.hxx
new file mode 100644
index 000000000000..4cd0c659b629
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_ia64/share.hxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+namespace ia64
+{
+ enum ia64limits { MAX_GPR_REGS = 8, MAX_SSE_REGS = 8, MAX_REG_SLOTS = 8 };
+
+ bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
+ bool return_via_r8_buffer( typelib_TypeDescriptionReference *pTypeRef );
+
+ struct RegReturn
+ {
+ long r8;
+ long r9;
+ long r10;
+ long r11;
+ };
+}
+
+namespace bridges
+{
+ namespace cpp_uno
+ {
+ namespace shared
+ {
+ /*
+ http://www.swag.uwaterloo.ca/asx/ABI.html
+ On Itanium, function pointers are pairs: the function address followed
+ by the global pointer value that should be used when calling the
+ function (code address, gp value)
+ */
+ struct VtableFactory::Slot
+ {
+ sal_uInt64 code_address;
+ sal_uInt64 gp_value;
+ };
+ }
+ }
+}
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_ia64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_ia64/uno2cpp.cxx
new file mode 100644
index 000000000000..d1d98f222738
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_ia64/uno2cpp.cxx
@@ -0,0 +1,693 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.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 "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+void MapReturn(const ia64::RegReturn &rRet, double dret, typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn, sal_uInt64 *pRegisterReturn)
+{
+ switch (pReturnTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *pRegisterReturn = rRet.r8;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *pRegisterReturn = (unsigned short)rRet.r8;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *pRegisterReturn = (unsigned char)rRet.r8;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *reinterpret_cast<float *>( pRegisterReturn ) = dret;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *reinterpret_cast<double *>( pRegisterReturn ) = dret;
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ sal_uInt32 nRetSize = pReturnTypeDescr->nSize;
+ if (bSimpleReturn && nRetSize <= 32 && nRetSize > 0)
+ memcpy(pRegisterReturn, (void*)&rRet, nRetSize);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+namespace ia64
+{
+ bool is_complex_struct(const typelib_TypeDescription * type)
+ {
+ const typelib_CompoundTypeDescription * p
+ = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
+ for (sal_Int32 i = 0; i < p->nMembers; ++i)
+ {
+ if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
+ p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
+ {
+ typelib_TypeDescription * t = 0;
+ TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
+ bool b = is_complex_struct(t);
+ TYPELIB_DANGER_RELEASE(t);
+ if (b) {
+ return true;
+ }
+ }
+ else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
+ return true;
+ }
+ if (p->pBaseTypeDescription != 0)
+ return is_complex_struct(&p->pBaseTypeDescription->aBase);
+ return false;
+ }
+
+ bool is_complex_struct( typelib_TypeDescriptionReference *pTypeRef )
+ {
+ if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+ bool bRet = is_complex_struct( pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+
+ return bRet;
+ }
+ return false;
+ }
+
+ bool return_via_r8_buffer( typelib_TypeDescriptionReference *pTypeRef )
+ {
+ if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
+ {
+ if (is_complex_struct( pTypeRef )) return false;
+
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+ /* If the struct is larger than 32 bytes, then there is a buffer at r8 to stick the return value into */
+ bool bRet = pTypeDescr->nSize > 32;
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ return bRet;
+ }
+ return false;
+ }
+
+ bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
+ {
+ if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
+ return false;
+ else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
+ return is_complex_struct( pTypeRef );
+ return true;
+ }
+
+
+}
+
+namespace
+{
+//==================================================================================================
+static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
+ sal_uInt64 *pStack, sal_uInt32 nStack,
+ sal_uInt64 *pGPR, sal_uInt32 nGPR,
+ double *pFPR, sal_uInt32 nFPR)
+{
+ // Stack, if used, must be 16-bytes aligned
+ if ( nStack )
+ nStack = ( nStack + 1 ) & ~1;
+
+ // Should not happen, but...
+ if ( nFPR > ia64::MAX_SSE_REGS )
+ nFPR = ia64::MAX_SSE_REGS;
+ if ( nGPR > ia64::MAX_GPR_REGS )
+ nGPR = ia64::MAX_GPR_REGS;
+
+#ifdef CMC_DEBUG
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
+ for ( unsigned int i = 0; i < nGPR; ++i )
+ fprintf( stderr, "0x%lx, ", pGPR[i] );
+ fprintf( stderr, "\nFPR's (%d): ", nFPR );
+ for ( unsigned int i = 0; i < nFPR; ++i )
+ fprintf( stderr, "0x%lx (%f), ", pFPR[i], pFPR[i] );
+ fprintf( stderr, "\nStack (%d): ", nStack );
+ for ( unsigned int i = 0; i < nStack; ++i )
+ fprintf( stderr, "0x%lx, ", pStack[i] );
+ fprintf( stderr, "\n" );
+ fprintf( stderr, "pRegisterReturn is %p\n", pRegisterReturn);
+ }
+#endif
+
+ // Load parameters to stack, if necessary
+ sal_uInt64 *stack = (sal_uInt64 *) __builtin_alloca( nStack * 8 );
+ memcpy( stack, pStack, nStack * 8 );
+
+ // To get pointer to method
+ // a) get the address of the vtable
+ sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
+ // b) get the address from the vtable entry at offset, each entry is 16bytes,
+ // 8 for function pointer, and 8 for global pointer
+ pMethod += 16 * nVtableIndex;
+
+ typedef void (* FunctionCall )( sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64 );
+ FunctionCall pFunc = (FunctionCall)pMethod;
+
+ switch (nFPR) //deliberate fall through
+ {
+ case 8:
+ asm volatile("ldfd f15=%0" : : "m"(pFPR[7]) : "f15");
+ case 7:
+ asm volatile("ldfd f14=%0" : : "m"(pFPR[6]) : "f14");
+ case 6:
+ asm volatile("ldfd f13=%0" : : "m"(pFPR[5]) : "f13");
+ case 5:
+ asm volatile("ldfd f12=%0" : : "m"(pFPR[4]) : "f12");
+ case 4:
+ asm volatile("ldfd f11=%0" : : "m"(pFPR[3]) : "f11");
+ case 3:
+ asm volatile("ldfd f10=%0" : : "m"(pFPR[2]) : "f10");
+ case 2:
+ asm volatile("ldfd f9=%0" : : "m"(pFPR[1]) : "f9");
+ case 1:
+ asm volatile("ldfd f8=%0" : : "m"(pFPR[0]) : "f8");
+ default:
+ break;
+ }
+
+ //stick the return area into r8 for big struct returning
+ asm volatile("ld8 r8=%0" : : "m"(pRegisterReturn) : "r8");
+
+ (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3], pGPR[4], pGPR[5], pGPR[6], pGPR[7]);
+
+ register double f8 asm("f8");
+ ia64::RegReturn ret;
+ {
+ register long r8 asm("r8"); ret.r8 = r8;
+ register long r9 asm("r9"); ret.r9 = r9;
+ register long r10 asm("r10"); ret.r10 = r10;
+ register long r11 asm("r11"); ret.r11 = r11;
+ }
+
+ MapReturn(ret, f8, pReturnTypeDescr, bSimpleReturn, (sal_uInt64*)pRegisterReturn);
+}
+
+// Macros for easier insertion of values to registers or stack
+// pSV - pointer to the source
+// nr - order of the value [will be increased if stored to register]
+// pFPR, pGPR - pointer to the registers
+// pDS - pointer to the stack [will be increased if stored here]
+
+// The value in %xmm register is already prepared to be retrieved as a float,
+// thus we treat float and double the same
+#define INSERT_FLOAT( pSV, nfr, pFPR, ngr, pGPR, pDS, bOverflow ) \
+ if ( nfr < ia64::MAX_SSE_REGS && ngr < ia64::MAX_GPR_REGS ) \
+ pFPR[nfr++] = *reinterpret_cast<float *>( pSV ); \
+ if ( ngr < ia64::MAX_GPR_REGS ) \
+ pGPR[ngr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
+
+#define INSERT_DOUBLE( pSV, nfr, pFPR, ngr, pGPR, pDS, bOverflow ) \
+ if ( nfr < ia64::MAX_SSE_REGS && ngr < ia64::MAX_GPR_REGS ) \
+ pFPR[nfr++] = *reinterpret_cast<double *>( pSV ); \
+ if ( ngr < ia64::MAX_GPR_REGS ) \
+ pGPR[ngr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
+
+#define INSERT_INT64( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ia64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ia64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ia64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ia64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+//==================================================================================================
+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 ...
+ sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+3) * sizeof(sal_Int64) );
+ sal_uInt64 * pStackStart = pStack;
+
+ sal_uInt64 pGPR[ia64::MAX_GPR_REGS];
+ sal_uInt32 nGPR = 0;
+
+ double pFPR[ia64::MAX_SSE_REGS];
+ sal_uInt32 nFPR = 0;
+
+ // 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
+
+ bool bOverFlow = false;
+
+ bool bSimpleReturn = true;
+ if (pReturnTypeDescr)
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "return type is %d\n", pReturnTypeDescr->eTypeClass);
+#endif
+ if ( ia64::return_in_hidden_param(pReturnTypeRef) || ia64::return_via_r8_buffer(pReturnTypeRef) )
+ bSimpleReturn = false;
+
+ if ( bSimpleReturn )
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+#ifdef CMC_DEBUG
+ fprintf(stderr, "simple return\n");
+#endif
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize ) : pUnoReturn);
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pCppReturn/pUnoReturn is %lx/%lx", pCppReturn, pUnoReturn);
+#endif
+ if (!ia64::return_via_r8_buffer(pReturnTypeRef))
+ INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack, bOverFlow );
+ }
+ }
+ // push "this" pointer
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "this pointer is %p\n", pAdjustedThisPtr);
+#endif
+ INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverFlow );
+
+ // Args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "n params is %d\n", nParams);
+#endif
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "param %d is %d %d %d\n", nPos, rParam.bOut, bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ),
+ pParamTypeDescr->eTypeClass);
+#endif
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+// uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
+ uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "hyper is %lx\n", *(unsigned long*)(pCppArgs[nPos]));
+#endif
+ INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "long is %lx\n", *(unsigned int*)(pCppArgs[nPos]));
+#endif
+ INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "short is %x\n", *(unsigned short*)(pCppArgs[nPos]));
+#endif
+ INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "byte is %x\n", *(unsigned char*)(pCppArgs[nPos]));
+#endif
+ INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_FLOAT:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "a float is %f\n", *(float*)(pCppArgs[nPos]));
+ fprintf(stderr, "b float is %f\n", *(double*)(pCppArgs[nPos]));
+#endif
+ INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR, nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_DOUBLE:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "double is %f\n", *(double*)(pCppArgs[nPos]));
+#endif
+ INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, nGPR, pGPR, pStack, bOverFlow );
+ break;
+ default:
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+
+ }
+ else // ptr to complex value | ref
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex type again %d\n", rParam.bIn);
+#endif
+ if (! rParam.bIn) // is pure out
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex size is %d\n", pParamTypeDescr->nSize );
+#endif
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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 ))
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "this one\n");
+#endif
+ uno_copyAndConvertData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "that one, passing %lx through\n", pUnoArgs[nPos]);
+#endif
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverFlow );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr, bSimpleReturn,
+ pStackStart, ( pStack - pStackStart ),
+ pGPR, nGPR,
+ pFPR, nFPR );
+ // NO exception occured...
+ *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 );
+
+ 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( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/call.s b/bridges/source/cpp_uno/gcc3_linux_intel/call.s
new file mode 100644
index 000000000000..f345e3a764ac
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/call.s
@@ -0,0 +1,268 @@
+ .text
+
+.globl privateSnippetExecutorGeneral
+ .type privateSnippetExecutorGeneral,@function
+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:
+ .size privateSnippetExecutorGeneral,.-privateSnippetExecutorGeneral
+
+.globl privateSnippetExecutorVoid
+ .type privateSnippetExecutorVoid,@function
+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:
+ .size privateSnippetExecutorVoid,.-privateSnippetExecutorVoid
+
+.globl privateSnippetExecutorHyper
+ .type privateSnippetExecutorHyper,@function
+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:
+ .size privateSnippetExecutorHyper,.-privateSnippetExecutorHyper
+
+.globl privateSnippetExecutorFloat
+ .type privateSnippetExecutorFloat,@function
+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:
+ .size privateSnippetExecutorFloat,.-privateSnippetExecutorFloat
+
+.globl privateSnippetExecutorDouble
+ .type privateSnippetExecutorDouble,@function
+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:
+ .size privateSnippetExecutorDouble,.-privateSnippetExecutorDouble
+
+.globl privateSnippetExecutorClass
+ .type privateSnippetExecutorClass,@function
+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:
+ .size privateSnippetExecutorClass,.-privateSnippetExecutorClass
+
+ .section .eh_frame,"a",@progbits
+.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:
+ .section .note.GNU-stack,"",@progbits
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..6e6c2009dde8
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx
@@ -0,0 +1,492 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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"
+
+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)
+ {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+
+ 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 occured...
+ 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 occured...
+ {
+ // 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 );
+ }
+ // 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(
+ rtl::OUString::createFromAscii("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(
+ rtl::OUString::createFromAscii("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_PtrDiff writetoexecdiff, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ typelib_TypeClass returnTypeClass)
+{
+ if (!bridges::cpp_uno::shared::isSimpleType(returnTypeClass)) {
+ functionIndex |= 0x80000000;
+ }
+ PrivateSnippetExecutor exec;
+ 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_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_INTERFACE:
+ exec = privateSnippetExecutorClass;
+ break;
+ default:
+ exec = privateSnippetExecutorGeneral;
+ break;
+ }
+ 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) - writetoexecdiff;
+ 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, sal_PtrDiff writetoexecdiff,
+ 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 + writetoexecdiff;
+ code = codeSnippet(
+ code, writetoexecdiff, functionOffset++, vtableOffset,
+ reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef->eTypeClass);
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, writetoexecdiff, functionOffset++, vtableOffset,
+ typelib_TypeClass_VOID);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, writetoexecdiff, functionOffset++, vtableOffset,
+ reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef->eTypeClass);
+ 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 *)
+{}
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx
new file mode 100644
index 000000000000..a804fd17addc
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx
@@ -0,0 +1,333 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.14.20.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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() +4;
+#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;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 occured: %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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, 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 occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk
new file mode 100644
index 000000000000..1bf0819311fb
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk
@@ -0,0 +1,88 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.11 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCLINUXIgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+#cmc: Ideally --noexecstack would be in operations, but with #i51385# pyuno
+#remote bridgeing breaks
+# $(CC) -Wa,--noexecstack -c -o $(SLO)$/$(@:b).o $<
+ $(CC) -c -o $(SLO)$/$(@:b).o $<
+ touch $@
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx b/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx
new file mode 100644
index 000000000000..7529230fde94
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..2a88705ce01c
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx
@@ -0,0 +1,447 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.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 "share.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+// 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):
+void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs ) __attribute__((noinline));
+
+void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ 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", "edx" );
+ switch( eReturnType )
+ {
+ 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;
+ default:
+ break;
+ }
+}
+
+//==================================================================================================
+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 =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ 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 = *(void **)pCppStack
+ = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ 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
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *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 );
+
+ 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( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/gcc3_linux_m68k/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_m68k/cpp2uno.cxx
new file mode 100644
index 000000000000..1d63ebde491f
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_m68k/cpp2uno.cxx
@@ -0,0 +1,539 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <malloc.h>
+#include <hash_map>
+
+#include <rtl/alloc.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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 <dlfcn.h>
+
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+ static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ long r8, void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+ {
+ // pCallStack: ret, [return ptr], this, params
+ char * pTopStack = (char *)(pCallStack + 0);
+ char * pCppStack = pTopStack;
+#ifdef CMC_DEBUG
+ fprintf(stderr, "cpp2uno_call\n");
+#endif
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+ void * pCppReturn = 0;
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "simple return\n");
+#endif
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex return\n");
+#endif
+ pCppReturn = (void *)r8;
+
+ 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 ))
+ {
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+ pCppArgs[nPos] = pCppStack + 3;
+ pUnoArgs[nPos] = pCppStack + 3;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ pCppArgs[nPos] = pCppStack + 2;
+ pUnoArgs[nPos] = pCppStack + 2;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ default:
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ 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;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "before dispatch\n");
+#endif
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "after dispatch\n");
+#endif
+
+ // in case an exception occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet =
+ (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+ }
+
+
+ //=====================================================================
+ static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ long sp, long r8,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+ {
+ void ** pCallStack = (void**)(sp);
+#ifdef CMC_DEBUG
+ fprintf(stderr, "cpp_mediate with\n");
+ fprintf(stderr, "%x %x\n", nFunctionIndex, nVtableOffset);
+ fprintf(stderr, "and %x %x\n", pCallStack, pRegisterReturn);
+ fprintf(stderr, "and %x %x\n", pCallStack[0], pCallStack[1]);
+#endif
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ void *pThis = pCallStack[0];
+
+ 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::createFromAscii("illegal vtable index!"),
+ (XInterface *)pCppI );
+ }
+
+ // determine called method
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ sal_Int32 nMemberPos =
+ pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers,
+ "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] ==
+ nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ r8, pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ r8, pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET(&pTD,
+ reinterpret_cast<Type *>(pCallStack[1])->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 * >( r8 ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = (void*)r8;
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ r8, pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ OUString::createFromAscii("no member description found!"),
+ (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+ }
+}
+
+//=======================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+
+extern "C" sal_Int64 cpp_vtable_call( long firstonstack )
+{
+ register long d0 asm("d0");
+ long functionIndex = d0;
+
+ register long a1 asm("a1");
+ long r8 = a1;
+
+ register long d1 asm("d1");
+ long vtableOffset = d1;
+
+ long sp = (long)&firstonstack;
+
+ sal_Int64 nRegReturn;
+ cpp_mediate( functionIndex, vtableOffset, sp, r8, &nRegReturn );
+ return nRegReturn;
+}
+
+namespace
+{
+ const int codeSnippetSize = 20;
+
+ //some m68k info : http://www2.biglobe.ne.jp/~inaba/trampolines.html
+
+ unsigned char *codeSnippet(unsigned char* code, sal_Int32 functionIndex,
+ sal_Int32 vtableOffset)
+ {
+ unsigned char * p = code;
+ *(short *)&p[0] = 0x203C; //movel functionIndex,d0
+ *(long *)&p[2] = functionIndex;
+ *(short *)&p[6] = 0x223C; //movel functionIndex,d1
+ *(long *)&p[8] = vtableOffset;
+ *(short *)&p[12] = 0x4EF9; //jmp cpp_vtable_call
+ *(long *)&p[14] = (long)&cpp_vtable_call;
+ *(short *)&p[18] = 0x4E71; //nop
+ 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, sal_PtrDiff writetoexecdiff,
+ 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 + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset);
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset);
+ }
+ break;
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ (s++)->fn = code + writetoexecdiff;
+
+ typelib_InterfaceMethodTypeDescription *pMethodTD =
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(member);
+
+ bool issimple = bridges::cpp_uno::shared::isSimpleType(
+ pMethodTD->pReturnTypeRef);
+
+ code = codeSnippet(code, functionOffset++, vtableOffset);
+ break;
+ }
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const * /*beg*/, unsigned char const * /*end*/)
+{
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_m68k/except.cxx b/bridges/source/cpp_uno/gcc3_linux_m68k/except.cxx
new file mode 100644
index 000000000000..8242bacaedc6
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_m68k/except.cxx
@@ -0,0 +1,337 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#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;
+
+extern sal_Int32 * pHack;
+extern sal_Int32 nHack;
+
+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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+ public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI(typelib_CompoundTypeDescription *) SAL_THROW( () );
+ };
+ //____________________________________________________________________
+ RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+ {
+ }
+ //____________________________________________________________________
+ RTTI::~RTTI() SAL_THROW( () )
+ {
+ dlclose( m_hApp );
+ }
+
+ //____________________________________________________________________
+ 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( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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() +4;
+#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;
+ }
+
+ //------------------------------------------------------------------
+ static void 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 occured: %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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+ }
+
+ static void* getAdjustedPtr(__cxa_exception* header)
+ {
+ return header->adjustedPtr;
+ }
+
+ //===================================================================
+ void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+ {
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, 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 occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, getAdjustedPtr(header), pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+ }
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_m68k/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_m68k/makefile.mk
new file mode 100644
index 000000000000..8371d653a25b
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_m68k/makefile.mk
@@ -0,0 +1,84 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.2 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+NO_BSYMBOLIC=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCLINUX6gcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSCXX += -fno-omit-frame-pointer
+
+NOOPTFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/uno2cpp.obj
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/bridges/source/cpp_uno/gcc3_linux_m68k/share.hxx b/bridges/source/cpp_uno/gcc3_linux_m68k/share.hxx
new file mode 100644
index 000000000000..10380f29e324
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_m68k/share.hxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
diff --git a/bridges/source/cpp_uno/gcc3_linux_m68k/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_m68k/uno2cpp.cxx
new file mode 100644
index 000000000000..067279965923
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_m68k/uno2cpp.cxx
@@ -0,0 +1,496 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <malloc.h>
+#include <rtl/alloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.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 "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+void MapReturn(long d0, long d1, typelib_TypeClass eReturnType, long *pRegisterReturn)
+{
+ register float fret asm("fp0");
+ register double dret asm("fp0");
+
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ pRegisterReturn[1] = d1;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ pRegisterReturn[0] = d0;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = fret;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = dret;
+ break;
+ default:
+ break;
+ }
+}
+
+namespace
+{
+//================================================================
+
+void callVirtualMethod(
+ void * pThis,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_uInt32 *pStack,
+ sal_uInt32 nStack) __attribute__((noinline));
+
+void callVirtualMethod(
+ void * pThis,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_uInt32 *pStack,
+ sal_uInt32 nStack)
+{
+ // never called
+ if (! pThis)
+ CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+ if ( nStack )
+ {
+ // m68k stack is either 2 or 4 bytes aligned, doesn't really matter as
+ // we deal in 4 byte units anyway
+ sal_uInt32 nStackBytes = nStack * sizeof(sal_uInt32);
+ sal_uInt32 *stack = (sal_uInt32 *) __builtin_alloca( nStackBytes );
+ memcpy( stack, pStack, nStackBytes );
+ }
+
+#ifdef CMC_DEBUG
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "\nStack (%d): ", nStack );
+ for ( unsigned int i = 0; i < nStack; ++i )
+ fprintf( stderr, "0x%lx, ", pStack[i] );
+ fprintf( stderr, "\n" );
+ fprintf( stderr, "pRegisterReturn is %p\n", pRegisterReturn);
+ }
+#endif
+
+ sal_uInt32 pMethod = *((sal_uInt32*)pThis);
+ pMethod += 4 * nVtableIndex;
+ pMethod = *((sal_uInt32 *)pMethod);
+
+ typedef long (*FunctionCall )();
+ FunctionCall pFunc = (FunctionCall)pMethod;
+
+ //stick the return area into r8 for big struct returning
+ asm volatile("movel %0,%%a1" : : "m"(pRegisterReturn) : );
+
+ long d0 = (*pFunc)();
+
+ register long d1 asm("d1");
+
+ MapReturn(d0, d1, eReturnType, (long*)pRegisterReturn);
+}
+}
+
+#define INSERT_INT32( pSV, pDS )\
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT64( pSV, pDS )\
+ INSERT_INT32( pSV, pDS ) \
+ INSERT_INT32( ((sal_uInt32*)pSV)+1, pDS )
+
+#define INSERT_FLOAT( pSV, pDS ) \
+ INSERT_INT32( pSV, pDS )
+
+#define INSERT_DOUBLE( pSV, pDS ) \
+ INSERT_INT64( pSV, pDS )
+
+#define INSERT_INT16( pSV, pDS ) \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, pDS ) \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+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 ...
+ sal_uInt32 * pStack = (sal_uInt32 *)__builtin_alloca(
+ sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ sal_uInt32 * pStackStart = pStack;
+
+ // 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 )
+ ? __builtin_alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+
+// INSERT_INT32( &pCppReturn, pStack );
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ INSERT_INT32( &pAdjustedThisPtr, pStack );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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] = pStack, pUnoArgs[nPos],
+ uno_copyAndConvertData( pCppArgs[nPos] = alloca(8), pUnoArgs[nPos],
+ pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "hyper is %lx\n", pCppArgs[nPos]);
+#endif
+ INSERT_INT64( pCppArgs[nPos], pStack );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "long is %x\n", pCppArgs[nPos]);
+#endif
+ INSERT_INT32( pCppArgs[nPos], pStack );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16( pCppArgs[nPos], pStack );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8( pCppArgs[nPos], pStack );
+ break;
+ case typelib_TypeClass_FLOAT:
+ INSERT_FLOAT( pCppArgs[nPos], pStack );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ INSERT_DOUBLE( pCppArgs[nPos], pStack );
+ 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(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT32( &(pCppArgs[nPos]), pStack );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass,
+ pStackStart,
+ (pStack - pStackStart));
+
+ // NO exception occured...
+ *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 );
+
+ 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( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+}
+
+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);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1;
+ cpp_call(
+ pThis, aVtableSlot, // get, then set method
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ 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->getBridge()->getUnoEnv()->getRegisteredInterface)(
+ pThis->getBridge()->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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_mips/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_mips/cpp2uno.cxx
new file mode 100644
index 000000000000..ec4055ca74c4
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_mips/cpp2uno.cxx
@@ -0,0 +1,806 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/data.h>
+#include <osl/endian.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 <stdio.h>
+#include <string.h>
+
+using namespace com::sun::star::uno;
+
+//#define BRDEBUG
+
+#ifdef BRDEBUG
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+#endif
+#include <sys/sysmips.h>
+
+#ifdef OSL_BIGENDIAN
+#define IS_BIG_ENDIAN 1
+#else
+#define IS_BIG_ENDIAN 0
+#endif
+
+using namespace ::com::sun::star::uno;
+
+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_Int64 * pRegisterReturn /* space for register return */ )
+ {
+ /* Most MIPS ABIs view the arguments as a struct, of which the
+ first N words go in registers and the rest go on the stack. If I < N, the
+ Ith word might go in Ith integer argument register or the Ith
+ floating-point one. For these ABIs, we only need to remember the number
+ of words passed so far. We are interested only in o32 ABI,so it is the
+ case.
+ */
+ int nw = 0; // number of words used by arguments
+
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call1\n");
+#endif
+
+ /* C++ has [ret *] or this as the first arguments, so no arguments will
+ * be passed in floating-point registers?
+ */
+ //int int_seen = 0; // have we seen integer arguments?
+
+ void ** pCppStack; //temporary stack pointer
+
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // 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 = pRegisterReturn; // direct way for simple types
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:simplereturn\n");
+#endif
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)gpreg;
+ gpreg++;
+ nw++;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:complexreturn\n");
+#endif
+ }
+ }
+
+ // pop this
+ gpreg++;
+ nw++;
+
+ // 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;
+
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:nParams=%d\n",nParams);
+#endif
+
+ 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
+ {
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_DOUBLE:
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:hyper=%d,%p\n",pParamTypeDescr->eTypeClass,gpreg[0]);
+#endif
+ if (nw < 3) {
+ if (nw & 1) {
+ nw++;
+ gpreg++;
+ }
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:gpreg=%p,%p\n",gpreg[0],gpreg[1]);
+#endif
+ pCppArgs[nPos] = gpreg;
+ pUnoArgs[nPos] = gpreg;
+ nw += 2;
+ gpreg += 2;
+ } else {
+ if (((long)ovrflw) & 4) ovrflw++;
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:overflw=%p,%p\n",ovrflw[0],ovrflw[1]);
+#endif
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 2;
+ }
+ break;
+
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:byte=%p,%p\n",gpreg[0],ovrflw[0]);
+#endif
+ if (nw < 4) {
+ pCppArgs[nPos] = ((char *)gpreg + 3*IS_BIG_ENDIAN);
+ pUnoArgs[nPos] = ((char *)gpreg + 3*IS_BIG_ENDIAN);
+ nw++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = ((char *)ovrflw + 3*IS_BIG_ENDIAN);
+ pUnoArgs[nPos] = ((char *)ovrflw + 3*IS_BIG_ENDIAN);
+ ovrflw++;
+ }
+ break;
+
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:char=%p,%p\n",gpreg[0],ovrflw[0]);
+#endif
+ if (nw < 4) {
+ pCppArgs[nPos] = ((char *)gpreg + 2*IS_BIG_ENDIAN);
+ pUnoArgs[nPos] = ((char *)gpreg + 2*IS_BIG_ENDIAN);
+ nw++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = ((char *)ovrflw + 2*IS_BIG_ENDIAN);
+ pUnoArgs[nPos] = ((char *)ovrflw + 2*IS_BIG_ENDIAN);
+ ovrflw++;
+ }
+ break;
+
+
+ default:
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:def=%p,%p\n",gpreg[0],ovrflw[0]);
+#endif
+ if (nw < 4) {
+ pCppArgs[nPos] = gpreg;
+ pUnoArgs[nPos] = gpreg;
+ nw++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw++;
+ }
+ break;
+
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:ptr|ref\n");
+#endif
+ if (nw < 4) {
+ pCppArgs[nPos] = *(void **)gpreg;
+ pCppStack = gpreg;
+ nw++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = *(void **)ovrflw;
+ pCppStack = ovrflw;
+ ovrflw++;
+ }
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:pCppStack=%p\n",pCppStack);
+#endif
+
+ 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;
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",*(void**)pCppStack,pParamTypeDescr->nSize,nPos,pUnoArgs[nPos]);
+#endif
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:direct,pUnoArgs[%d]=%p\n",nPos,pUnoArgs[nPos]);
+#endif
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call2,%p,unoargs=%p\n",pThis->getUnoI()->pDispatcher,pUnoArgs);
+#endif
+
+ // 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 );
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call2,after dispatch\n");
+#endif
+
+ // in case an exception occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+ }
+
+
+ //==================================================================================================
+ static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+ {
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate1 gp=%p,fp=%p,ov=%p\n",gpreg,fpreg,ovrflw);
+ fprintf(stderr,"gp=%x,%x,%x,%x\n",gpreg[0],gpreg[1],gpreg[2],gpreg[3]);
+#endif
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ void * pThis;
+ if (nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+ }
+ else
+ {
+ pThis = gpreg[0];
+ }
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate12,pThis=%p, nFunctionIndex=%d,nVtableOffset=%d\n",pThis,nFunctionIndex,nVtableOffset);
+#endif
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate13,pCppI=%p\n",pCppI);
+#endif
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate2\n");
+#endif
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("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] );
+
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate3\n");
+ OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
+#endif
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate4\n");
+#endif
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate5\n");
+#endif
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate51\n");
+#endif
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate52\n");
+#endif
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->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 * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate6\n");
+#endif
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+ }
+
+ //==================================================================================================
+ /**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+// static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** fpregptr, void** ovrflw)
+// static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** ovrflw)
+ static void cpp_vtable_call(void)
+ {
+ int nFunctionIndex;
+ int vTableOffset;
+ void** pCallStack;
+ void** ovrflw;
+
+ sal_Int32 gpreg[4];
+ double fpreg[2];
+
+ //memcpy( fpreg, fpregptr, 16);
+
+ volatile long nRegReturn[2];
+
+ __asm__( "sw $4, %0\n\t"
+ "sw $5, %1\n\t"
+ "sw $6, %2\n\t"
+ "sw $7, %3\n\t"
+ ::"m"(nFunctionIndex), "m"(vTableOffset), "m"(pCallStack), "m"(ovrflw) );
+
+ memcpy( gpreg, pCallStack, 16);
+
+#ifdef BRDEBUG
+ fprintf(stderr,"in cpp_vtable_call nFunctionIndex is %d\n",nFunctionIndex);
+ fprintf(stderr,"in cpp_vtable_call nVtableOffset is %d\n",vTableOffset);
+ fprintf(stderr,"gp=%x,%x,%x,%x\n",gpreg[0],gpreg[1],gpreg[2],gpreg[3]);
+#endif
+
+ //sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False;
+
+ typelib_TypeClass aType =
+ cpp_mediate( nFunctionIndex, vTableOffset, (void**)gpreg, (void**)fpreg, ovrflw, (sal_Int64*)nRegReturn );
+
+ switch( aType )
+ {
+
+ // move return value into register space
+ // (will be loaded by machine code snippet)
+
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ __asm__( "lbu $2,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ __asm__( "lhu $2,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+
+ case typelib_TypeClass_SHORT:
+ __asm__( "lh $2,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+
+
+ case typelib_TypeClass_FLOAT:
+ __asm__( "lwc1 $f0,%0\n\t" : :
+ "m" (*((float*)nRegReturn)) );
+ break;
+
+ case typelib_TypeClass_DOUBLE:
+ { register double dret asm("$f0");
+ dret = (*((double*)nRegReturn)); }
+ break;
+
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ __asm__( "lw $3,%0\n\t" : :
+ "m"(nRegReturn[1]) ); // fall through
+
+ default:
+ __asm__( "lw $2,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+ }
+ }
+
+
+ int const codeSnippetSize = 56;
+
+ unsigned char * codeSnippet( unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool simpleRetType)
+ {
+
+#ifdef BRDEBUG
+ fprintf(stderr,"in codeSnippet functionIndex is %d\n", functionIndex);
+ fprintf(stderr,"in codeSnippet vtableOffset is %d\n", vtableOffset);
+ fflush(stderr);
+#endif
+
+ if (! simpleRetType )
+ functionIndex |= 0x80000000;
+
+ unsigned long * p = (unsigned long *) code;
+
+ // OSL_ASSERT( sizeof (long) == 4 );
+ OSL_ASSERT((((unsigned long)code) & 0x3) == 0 ); //aligned to 4 otherwise a mistake
+
+ /* generate this code */
+ /*
+ #save regs into argument space required by mips abi
+ c: afa40000 sw a0,0(sp)
+ 10: afa50004 sw a1,4(sp)
+ 14: afa60008 sw a2,8(sp)
+ 18: afa7000c sw a3,12(sp)
+ #a0=index
+ 1c: 3c040000 lui a0,0x0
+ 20: 34840000 ori a0,a0,0x0
+ #a1=offset
+ 24: 3c050000 lui a1,0x0
+ 28: 34a50000 ori a1,a1,0x0
+ #a2=gpregptr
+ 2c: 27a60000 addiu a2,sp,0
+ #a3=ovrflw
+ 30: 27a70010 addiu a3,sp,16
+ #load cpp_vtable_call addr
+ 34: 3c190000 lui t9,0x0
+ 38: 37390000 ori t9,t9,0
+ #jmp to the function,note: we don't use jalr, that will destroy $ra
+ #but be sure to use t9! gp calculation depends on it
+ 3c: 03200008 jr t9
+ 40: 00000000 nop
+
+ be careful, we use the argument space reserved by the caller to
+ write down regs. This can avoid the need to make use of arbitary far away
+ stack space or to allocate a function frame for this code snippet itself.
+ Since only functions with variable arguments will overwrite the space,
+ cpp_vtable_call should be safe.
+ ??? gcc seems change this behavior! cpp_vtable_call overwrite the space!
+ */
+
+ * p++ = 0xafa40000;
+ * p++ = 0xafa50004;
+ * p++ = 0xafa60008;
+ * p++ = 0xafa7000c;
+ * p++ = 0x3c040000 | ((functionIndex>>16) & 0x0000ffff);
+ * p++ = 0x34840000 | (functionIndex & 0x0000ffff);
+ * p++ = 0x3c050000 | ((vtableOffset>>16) & 0x0000ffff);
+ * p++ = 0x34a50000 | (vtableOffset & 0x0000ffff);
+ * p++ = 0x27a60000;
+ * p++ = 0x27a70010;
+ * p++ = 0x3c190000 | ((((unsigned long)cpp_vtable_call) >> 16) & 0x0000ffff);
+ * p++ = 0x37390000 | (((unsigned long)cpp_vtable_call) & 0x0000FFFF);
+ * p++ = 0x03200008;
+ * p++ = 0x00000000;
+ return (code + codeSnippetSize);
+
+ }
+
+
+}
+
+
+#define MIN_LINE_SIZE 32
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * /*bptr*/, unsigned char const * /*eptr*/)
+{
+ sysmips(FLUSH_CACHE,0,0,0);
+}
+
+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; //null
+ slots[-1].fn = 0; //destructor
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+#ifdef BRDEBUG
+ fprintf(stderr, "in addLocalFunctions functionOffset is %d\n",functionOffset);
+ fprintf(stderr, "in addLocalFunctions vtableOffset is %d\n",vtableOffset);
+ fprintf(stderr, "nMembers=%d\n",type->nMembers);
+ fflush(stderr);
+#endif
+
+ 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 + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_mips/except.cxx b/bridges/source/cpp_uno/gcc3_linux_mips/except.cxx
new file mode 100644
index 000000000000..88dd91e4e47a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_mips/except.cxx
@@ -0,0 +1,328 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#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 defined BRIDGES_DEBUG
+ 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 defined BRIDGES_DEBUG
+ 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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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() +4;
+#if defined BRIDGES_DEBUG
+ 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;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 defined BRIDGES_DEBUG
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if defined _DEBUG
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if defined BRIDGES_DEBUG
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if defined _DEBUG
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_mips/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_mips/makefile.mk
new file mode 100644
index 000000000000..73bc2768869b
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_mips/makefile.mk
@@ -0,0 +1,85 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.3 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+NO_BSYMBOLIC=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)" == "GCCLINUXM"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer
+
+CFLAGSNOOPT=-O0
+
+NOOPTFILES = \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/cpp2uno.obj
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+
+SHL1TARGET=$(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+
+SHL1OBJS= $(SLOFILES)
+SHL1LIBS =$(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_mips/share.hxx b/bridges/source/cpp_uno/gcc3_linux_mips/share.hxx
new file mode 100644
index 000000000000..64224956fa40
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_mips/share.hxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
diff --git a/bridges/source/cpp_uno/gcc3_linux_mips/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_mips/uno2cpp.cxx
new file mode 100644
index 000000000000..19026bbdd01c
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_mips/uno2cpp.cxx
@@ -0,0 +1,600 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.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 "share.hxx"
+
+//#define BRDEBUG
+#ifdef BRDEBUG
+#include <stdio.h>
+#endif
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+
+ //==================================================================================================
+ static void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ char * pPT,
+ sal_Int32 * pStackLongs,
+ sal_Int32 /*nStackLongs*/)
+ {
+
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ unsigned long * 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 c; // character of parameter type being decoded
+ int iret, iret2; // temporary function return values
+
+ // never called
+ if (! pAdjustedThisPtr ) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+#ifdef BRDEBUG
+ fprintf(stderr,"in CallVirtualMethod\n");
+#endif
+
+ // 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 abosulte 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 paramters string is %s\n",pPT);
+ int k = nStackLongs;
+ long * q = (long *)pStackLongs;
+ while (k > 0) {
+ fprintf(stderr,"uno stack is: %x\n",(unsigned int)*q);
+ k--;
+ q++;
+ }
+#endif
+
+ /* parse the argument list up to the ending ) */
+ while (*pPT != 'X') {
+ c = *pPT;
+ 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;
+
+ case 'S':
+ if (nw < 4) {
+ gpr[nw++] = *((unsigned short*)pStackLongs);
+ } else {
+ *p++ = *((unsigned short *)pStackLongs);
+ }
+ pStackLongs += 1;
+ break;
+
+ case 'B':
+ if (nw < 4) {
+ gpr[nw++] = *((char *)pStackLongs);
+ } else {
+ *p++ = *((char *)pStackLongs);
+ }
+ pStackLongs += 1;
+ break;
+
+ default:
+ if (nw < 4) {
+ gpr[nw++] = *pStackLongs;
+ } else {
+ *p++ = *pStackLongs;
+ }
+ pStackLongs += 1;
+ break;
+ }
+ pPT++;
+ }
+
+ /* figure out the address of the function we need to invoke */
+ off = nVtableIndex;
+ off = off * 4; // 4 bytes per slot
+ mfunc = *((unsigned long **)pAdjustedThisPtr); // get the address of the vtable
+ mfunc = (unsigned long *)((char *)mfunc + off); // get the address from the vtable entry at offset
+ mfunc = *((unsigned long **)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 */
+
+ __asm__ __volatile__ (
+ "lw $4, 0(%0)\n\t"
+ "lw $5, 4(%0)\n\t"
+ "lw $6, 8(%0)\n\t"
+ "lw $7, 12(%0)\n\t"
+ : : "r" (gpr)
+ : "$4", "$5", "$6", "$7"
+ );
+
+ __asm__ __volatile__ ("addiu $29,$29,-528\r\n":::"$29");
+
+ (*ptr)();
+
+ __asm__ __volatile__ ("addiu $29,$29,528\r\n":::"$29");
+
+ __asm__ __volatile__ (
+ "sw $2,%0 \n\t"
+ "sw $3,%1 \n\t"
+ : "=m" (iret), "=m" (iret2) : );
+ register float fret asm("$f0");
+ register double dret asm("$f0");
+
+ 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:
+ *(unsigned short*)pRegisterReturn = (unsigned short)iret;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)iret;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = fret;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = dret;
+ break;
+ default:
+ break;
+ }
+ }
+
+
+ //==================================================================================================
+ 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 =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // need to know parameter types for callVirtualMethod so generate a signature string
+ char * pParamType = (char *) alloca(nParams+2);
+ char * pPT = pParamType;
+
+#ifdef BRDEBUG
+ fprintf(stderr,"in cpp_call\n");
+#endif
+
+ // 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 = *(void **)pCppStack =
+ (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize ): pUnoReturn); // direct way
+ *pPT++ = 'I'; //signify that a complex return type on stack
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ void* pAdjustedThisPtr = reinterpret_cast< void **>(pThis->getCppI()) + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+ *pPT++ = 'I';
+
+ // stack space
+ // OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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)
+ {
+
+ // 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 );
+ 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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 );
+ }
+ // 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;
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass, pParamType,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *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 );
+
+ 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( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+ }
+
+}
+
+
+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);
+ //typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+#ifdef BRDEBUG
+ fprintf(stderr,"in dispatch\n");
+#endif
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+}}}
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx
new file mode 100644
index 000000000000..1aca0f480b6a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx
@@ -0,0 +1,737 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <string.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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 <stdio.h>
+
+
+using namespace ::com::sun::star::uno;
+
+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_Int64 * pRegisterReturn /* space for register return */ )
+{
+ int ng = 0; //number of gpr registers used
+ int nf = 0; //number of fpr regsiters used
+ void ** pCppStack; //temporary stack pointer
+
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // 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 = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)gpreg;
+ gpreg++;
+ ng++;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ gpreg++;
+ ng++;
+
+ // 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
+ {
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+
+ case typelib_TypeClass_DOUBLE:
+ if (nf < 8) {
+ pCppArgs[nPos] = fpreg;
+ pUnoArgs[nPos] = fpreg;
+ nf++;
+ fpreg += 2;
+ } else {
+ if (((long)ovrflw) & 4) ovrflw++;
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 2;
+ }
+ break;
+
+ case typelib_TypeClass_FLOAT:
+ // fpreg are all double values so need to
+ // modify fpreg to be a single word float value
+ if (nf < 8) {
+ float tmp = (float) (*((double *)fpreg));
+ (*((float *) fpreg)) = tmp;
+ pCppArgs[nPos] = fpreg;
+ pUnoArgs[nPos] = fpreg;
+ nf++;
+ fpreg += 2;
+ } else {
+#if 0 /* abi is not being followed correctly */
+ if (((long)ovrflw) & 4) ovrflw++;
+ float tmp = (float) (*((double *)ovrflw));
+ (*((float *) ovrflw)) = tmp;
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 2;
+#else
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 1;
+#endif
+ }
+ break;
+
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (ng < 7) {
+ if (ng & 1) {
+ ng++;
+ gpreg++;
+ }
+ pCppArgs[nPos] = gpreg;
+ pUnoArgs[nPos] = gpreg;
+ ng += 2;
+ gpreg += 2;
+ } else {
+ if (((long)ovrflw) & 4) ovrflw++;
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 2;
+ }
+ break;
+
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+ if (ng < 8) {
+ pCppArgs[nPos] = (((char *)gpreg) + 3);
+ pUnoArgs[nPos] = (((char *)gpreg) + 3);
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = (((char *)ovrflw) + 3);
+ pUnoArgs[nPos] = (((char *)ovrflw) + 3);
+ ovrflw++;
+ }
+ break;
+
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (ng < 8) {
+ pCppArgs[nPos] = (((char *)gpreg)+ 2);
+ pUnoArgs[nPos] = (((char *)gpreg)+ 2);
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = (((char *)ovrflw) + 2);
+ pUnoArgs[nPos] = (((char *)ovrflw) + 2);
+ ovrflw++;
+ }
+ break;
+
+
+ default:
+ if (ng < 8) {
+ pCppArgs[nPos] = gpreg;
+ pUnoArgs[nPos] = gpreg;
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw++;
+ }
+ break;
+
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+
+ if (ng < 8) {
+ pCppArgs[nPos] = *(void **)gpreg;
+ pCppStack = gpreg;
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = *(void **)ovrflw;
+ pCppStack = ovrflw;
+ ovrflw++;
+ }
+
+ 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 );
+ }
+ }
+ }
+
+ // 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 occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ void * pThis;
+ if (nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+ }
+ else
+ {
+ pThis = gpreg[0];
+ }
+
+ 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(
+ rtl::OUString::createFromAscii("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] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->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 * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** fpregptr, void** ovrflw)
+{
+ sal_Int32 gpreg[8];
+ double fpreg[8];
+
+ memcpy( gpreg, gpregptr, 32);
+ memcpy( fpreg, fpregptr, 64);
+
+ volatile long nRegReturn[2];
+
+ // fprintf(stderr,"in cpp_vtable_call nFunctionIndex is %x\n",nFunctionIndex);
+ // fprintf(stderr,"in cpp_vtable_call nVtableOffset is %x\n",nVtableOffset);
+ // fflush(stderr);
+
+ sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False;
+
+ typelib_TypeClass aType =
+ cpp_mediate( nFunctionIndex, nVtableOffset, (void**)gpreg, (void**)fpreg, ovrflw, (sal_Int64*)nRegReturn );
+
+ switch( aType )
+ {
+
+ // move return value into register space
+ // (will be loaded by machine code snippet)
+
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ __asm__( "lbz 3,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ __asm__( "lhz 3,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+
+ case typelib_TypeClass_FLOAT:
+ __asm__( "lfs 1,%0\n\t" : :
+ "m" (*((float*)nRegReturn)) );
+ break;
+
+ case typelib_TypeClass_DOUBLE:
+ __asm__( "lfd 1,%0\n\t" : :
+ "m" (*((double*)nRegReturn)) );
+ break;
+
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ __asm__( "lwz 4,%0\n\t" : :
+ "m"(nRegReturn[1]) ); // fall through
+
+ default:
+ __asm__( "lwz 3,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+ }
+}
+
+
+int const codeSnippetSize = 108;
+
+unsigned char * codeSnippet( unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool simpleRetType)
+{
+
+ // fprintf(stderr,"in codeSnippet functionIndex is %x\n", functionIndex);
+ // fprintf(stderr,"in codeSnippet vtableOffset is %x\n", vtableOffset);
+ // fflush(stderr);
+
+ if (! simpleRetType )
+ functionIndex |= 0x80000000;
+
+ unsigned long * p = (unsigned long *) code;
+
+ // OSL_ASSERT( sizeof (long) == 4 );
+ OSL_ASSERT((((unsigned long)code) & 0x3) == 0 ); //aligned to 4 otherwise a mistake
+
+ /* generate this code */
+ // # so first save gpr 3 to gpr 10 (aligned to 4)
+ // stw r3,-2048(r1)
+ // stw r4,-2044(r1)
+ // stw r5,-2040(r1)
+ // stw r6,-2036(r1)
+ // stw r7,-2032(r1)
+ // stw r8,-2028(r1)
+ // stw r9,-2024(r1)
+ // stw r10,-2020(r1)
+
+
+ // # next save fpr 1 to fpr 8 (aligned to 8)
+ // stfd f1,-2016(r1)
+ // stfd f2,-2008(r1)
+ // stfd f3,-2000(r1)
+ // stfd f4,-1992(r1)
+ // stfd f5,-1984(r1)
+ // stfd f6,-1976(r1)
+ // stfd f7,-1968(r1)
+ // stfd f8,-1960(r1)
+
+ // # now here is where cpp_vtable_call must go
+ // lis r3,-8531
+ // ori r3,r3,48879
+ // mtctr r3
+
+ // # now load up the functionIndex
+ // lis r3,-8531
+ // ori r3,r3,48879
+
+ // # now load up the vtableOffset
+ // lis r4,-8531
+ // ori r4,r4,48879
+
+ // #now load up the pointer to the saved gpr registers
+ // addi r5,r1,-2048
+
+ // #now load up the pointer to the saved fpr registers
+ // addi r6,r1,-2016
+
+ // #now load up the pointer to the overflow call stack
+ // addi r7,r1,8
+ // bctr
+
+ * p++ = 0x9061f800;
+ * p++ = 0x9081f804;
+ * p++ = 0x90a1f808;
+ * p++ = 0x90c1f80c;
+ * p++ = 0x90e1f810;
+ * p++ = 0x9101f814;
+ * p++ = 0x9121f818;
+ * p++ = 0x9141f81c;
+ * p++ = 0xd821f820;
+ * p++ = 0xd841f828;
+ * p++ = 0xd861f830;
+ * p++ = 0xd881f838;
+ * p++ = 0xd8a1f840;
+ * p++ = 0xd8c1f848;
+ * p++ = 0xd8e1f850;
+ * p++ = 0xd901f858;
+ * p++ = 0x3c600000 | (((unsigned long)cpp_vtable_call) >> 16);
+ * p++ = 0x60630000 | (((unsigned long)cpp_vtable_call) & 0x0000FFFF);
+ * p++ = 0x7c6903a6;
+ * p++ = 0x3c600000 | (((unsigned long)functionIndex) >> 16);
+ * p++ = 0x60630000 | (((unsigned long)functionIndex) & 0x0000FFFF);
+ * p++ = 0x3c800000 | (((unsigned long)vtableOffset) >> 16);
+ * p++ = 0x60840000 | (((unsigned long)vtableOffset) & 0x0000FFFF);
+ * p++ = 0x38a1f800;
+ * p++ = 0x38c1f820;
+ * p++ = 0x38e10008;
+ * p++ = 0x4e800420;
+ return (code + codeSnippetSize);
+
+}
+
+
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * bptr, unsigned char const * eptr)
+{
+ int const lineSize = 32;
+ for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
+ __asm__ volatile ("dcbst 0, %0" : : "r"(p) : "memory");
+ }
+ __asm__ volatile ("sync" : : : "memory");
+ for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
+ __asm__ volatile ("icbi 0, %0" : : "r"(p) : "memory");
+ }
+ __asm__ volatile ("isync" : : : "memory");
+}
+
+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, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ // fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
+ // fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
+ // fflush(stderr);
+
+ 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 + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc/except.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc/except.cxx
new file mode 100644
index 000000000000..28ad7dc83ed7
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc/except.cxx
@@ -0,0 +1,290 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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 iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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() +4;
+#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 = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 )
+{
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ terminate();
+
+ 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)
+ terminate();
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
+{
+ OSL_ENSURE( header, "### no exception header!!!" );
+ if (! header)
+ terminate();
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
+ if (! pExcTypeDescr)
+ terminate();
+
+ // construct uno exception any
+ ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ ::typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_powerpc/makefile.mk
new file mode 100644
index 000000000000..d6cc303b88bd
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc/makefile.mk
@@ -0,0 +1,84 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.10 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)$(CPUNAME)" == "GCCLINUXPgcc3POWERPC"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer
+
+NOOPTFILES= \
+ $(SLO)$/uno2cpp.obj
+
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS= $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc/share.hxx b/bridges/source/cpp_uno/gcc3_linux_powerpc/share.hxx
new file mode 100644
index 000000000000..3b1956075514
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc/share.hxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc/uno2cpp.cxx
new file mode 100644
index 000000000000..2a8626733f24
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc/uno2cpp.cxx
@@ -0,0 +1,637 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.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 "share.hxx"
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+
+//==================================================================================================
+static void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ char * pPT,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs)
+{
+
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ // the basic idea here is to use gpr[8] as a storage area for
+ // the future values of registers r3 to r10 needed for the call,
+ // and similarly fpr[8] as a storage area for the future values
+ // of floating point registers f1 to f8
+
+ unsigned long * mfunc; // actual function to be invoked
+ void (*ptr)();
+ int gpr[8]; // storage for gpregisters, map to r3-r10
+ int off; // offset used to find function
+ double fpr[8]; // storage for fpregisters, map to f1-f8
+ int n; // number of gprs mapped so far
+ int f; // number of fprs mapped so far
+ long *p; // pointer to parameter overflow area
+ int c; // character of parameter type being decoded
+ double dret; // temporary function return values
+ int iret, iret2;
+
+ // Because of the Power PC 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.
+
+ // Note: This keeps us from having to decode the signature twice and
+ // prevents problems with later local variables.
+
+ // Note: could require up to 2*nStackLongs words of parameter stack area
+ // if the call has many float parameters (i.e. floats take up only 1
+ // word on the stack but take 2 words in parameter area in the
+ // stack frame .
+
+ // Update! floats on the outgoing parameter stack only take up 1 word
+ // (stfs is used) which is not correct according to the ABI but we
+ // will match what the compiler does until this is figured out
+
+ // this grows the current stack to the appropriate size
+ // and sets the outgoing stack pointer p to the right place
+ __asm__ __volatile__ (
+ "rlwinm %0,%0,3,3,28\n\t"
+ "addi %0,%0,22\n\t"
+ "rlwinm %0,%0,0,4,28\n\t"
+ "lwz 0,0(1)\n\t"
+ "subf 1,%0,1\n\t"
+ "stw 0,0(1)\n\t"
+ : : "r" (nStackLongs) : "0" );
+
+ __asm__ __volatile__ ( "addi %0,1,8" : "=r" (p) : );
+
+ // never called
+ // if (! pAdjustedThisPtr ) dummy_can_throw_anything("xxx"); // address something
+
+
+ // now begin to load the C++ function arguments into storage
+ n = 0;
+ f = 0;
+
+ // now we need to parse the entire signature string */
+ // until we get the END indicator */
+
+ // treat complex return pointer like any other parameter //
+
+#if 0
+ /* Let's figure out what is really going on here*/
+ fprintf(stderr,"callVirtualMethod paramters string is %s\n",pPT);
+ int k = nStackLongs;
+ long * q = (long *)pStackLongs;
+ while (k > 0) {
+ fprintf(stderr,"uno stack is: %x\n",*q);
+ k--;
+ q++;
+ }
+#endif
+
+ /* parse the argument list up to the ending ) */
+ while (*pPT != 'X') {
+ c = *pPT;
+ switch (c) {
+ case 'D': /* type is double */
+ if (f < 8) {
+ fpr[f++] = *((double *)pStackLongs); /* store in register */
+ } else {
+ if (((long) p) & 4)
+ p++;
+ *p++ = *pStackLongs; /* or on the parameter stack */
+ *p++ = *(pStackLongs + 1);
+ }
+ pStackLongs += 2;
+ break;
+
+ case 'F': /* type is float */
+ /* this assumes that floats are stored as 1 32 bit word on param
+ stack and that if passed in parameter stack to C, should be
+ as double word.
+
+ Whoops: the abi is not actually followed by gcc, need to
+ store floats as a *single* word on outgoing parameter stack
+ to match what gcc actually does
+ */
+ if (f < 8) {
+ fpr[f++] = *((float *)pStackLongs);
+ } else {
+#if 0 /* if abi were followed */
+ if (((long) p) & 4)
+ p++;
+ *((double *)p) = *((float *)pStackLongs);
+ p += 2;
+#else
+ *((float *)p) = *((float *)pStackLongs);
+ p += 1;
+#endif
+ }
+ pStackLongs += 1;
+ break;
+
+ case 'H': /* type is long long */
+ if (n & 1) n++; /* note even elements gpr[] will map to
+ odd registers*/
+ if (n <= 6) {
+ gpr[n++] = *pStackLongs;
+ gpr[n++] = *(pStackLongs+1);
+ } else {
+ if (((long) p) & 4)
+ p++;
+ *p++ = *pStackLongs;
+ *p++ = *(pStackLongs+1);
+ }
+ pStackLongs += 2;
+ break;
+
+ case 'S':
+ if (n < 8) {
+ gpr[n++] = *((unsigned short*)pStackLongs);
+ } else {
+ *p++ = *((unsigned short *)pStackLongs);
+ }
+ pStackLongs += 1;
+ break;
+
+ case 'B':
+ if (n < 8) {
+ gpr[n++] = *((char *)pStackLongs);
+ } else {
+ *p++ = *((char *)pStackLongs);
+ }
+ pStackLongs += 1;
+ break;
+
+ default:
+ if (n < 8) {
+ gpr[n++] = *pStackLongs;
+ } else {
+ *p++ = *pStackLongs;
+ }
+ pStackLongs += 1;
+ break;
+ }
+ pPT++;
+ }
+
+ /* figure out the address of the function we need to invoke */
+ off = nVtableIndex;
+ off = off * 4; // 4 bytes per slot
+ mfunc = *((unsigned long **)pAdjustedThisPtr); // get the address of the vtable
+ mfunc = (unsigned long *)((char *)mfunc + off); // get the address from the vtable entry at offset
+ mfunc = *((unsigned long **)mfunc); // the function is stored at the address
+ ptr = (void (*)())mfunc;
+
+ /* Set up the machine registers and invoke the function */
+
+ __asm__ __volatile__ (
+ "lwz 3, 0(%0)\n\t"
+ "lwz 4, 4(%0)\n\t"
+ "lwz 5, 8(%0)\n\t"
+ "lwz 6, 12(%0)\n\t"
+ "lwz 7, 16(%0)\n\t"
+ "lwz 8, 20(%0)\n\t"
+ "lwz 9, 24(%0)\n\t"
+ "lwz 10, 28(%0)\n\t"
+ "lfd 1, 0(%1)\n\t"
+ "lfd 2, 8(%1)\n\t"
+ "lfd 3, 16(%1)\n\t"
+ "lfd 4, 24(%1)\n\t"
+ "lfd 5, 32(%1)\n\t"
+ "lfd 6, 40(%1)\n\t"
+ "lfd 7, 48(%1)\n\t"
+ "lfd 8, 56(%1)\n\t"
+ : : "r" (gpr), "r" (fpr)
+ : "0", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"
+ );
+
+ (*ptr)();
+
+ __asm__ __volatile__ (
+ "mr %1, 3\n\t"
+ "mr %2, 4\n\t"
+ "fmr %0, 1\n\t"
+ : "=f" (dret), "=r" (iret), "=r" (iret2) : );
+
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[0] = iret;
+ ((long*)pRegisterReturn)[1] = iret2;
+ 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:
+ *(unsigned short*)pRegisterReturn = (unsigned short)iret;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)iret;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = (float)dret;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = dret;
+ break;
+ }
+}
+
+
+//==================================================================================================
+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 =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // need to know parameter types for callVirtualMethod so generate a signature string
+ char * pParamType = (char *) alloca(nParams+2);
+ char * pPT = pParamType;
+
+ // 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 = *(void **)pCppStack =
+ (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize ): pUnoReturn); // direct way
+ *pPT++ = 'I'; //signify that a complex return type on stack
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ void* pAdjustedThisPtr = reinterpret_cast< void **>(pThis->getCppI()) + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+ *pPT++ = 'I';
+
+ // stack space
+ // OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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)
+ {
+
+ // 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
+ }
+
+ // 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 );
+ 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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 );
+ }
+ // 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;
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass, pParamType,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *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 );
+
+ 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( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+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);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
new file mode 100644
index 000000000000..e514914db3b7
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
@@ -0,0 +1,725 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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 <stdio.h>
+#include <string.h>
+
+
+using namespace ::com::sun::star::uno;
+
+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_Int64 * pRegisterReturn /* space for register return */ )
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "as far as cpp2uno_call\n");
+#endif
+
+ int ng = 0; //number of gpr registers used
+ int nf = 0; //number of fpr regsiters used
+
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // 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 = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)gpreg;
+ gpreg++;
+ ng++;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ gpreg++;
+ ng++;
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int64), "### 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;
+ bool bOverFlowUsed = false;
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "arg %d of %d\n", nPos, nParams);
+#endif
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "simple\n");
+#endif
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_DOUBLE:
+ if (nf < ppc64::MAX_SSE_REGS)
+ {
+ if (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT)
+ {
+ float tmp = (float) (*((double *)fpreg));
+ (*((float *) fpreg)) = tmp;
+ }
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
+ nf++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+ if (ng < ppc64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-1));
+ ng++;
+ gpreg++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-1));
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (ng < ppc64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-2));
+ ng++;
+ gpreg++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-2));
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (ng < ppc64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-4));
+ ng++;
+ gpreg++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-4));
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ default:
+ if (ng < ppc64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex, ng is %d\n", ng);
+#endif
+ void *pCppStack; //temporary stack pointer
+
+ if (ng < ppc64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pCppStack = *gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pCppStack = *ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+
+ 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 ),
+ 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] = pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "end of params\n");
+#endif
+
+ // 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 occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_uInt64 nOffsetAndIndex,
+ void ** gpreg, void ** fpreg, long sp,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int64)==sizeof(void *), "### unexpected!" );
+
+ sal_Int32 nVtableOffset = (nOffsetAndIndex >> 32);
+ sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
+
+ long sf = *(long*)sp;
+ void ** ovrflw = (void**)(sf + 112);
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ void * pThis;
+ if (nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is gpreg[1]\n");
+#endif
+ }
+ else
+ {
+ pThis = gpreg[0];
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is gpreg[0]\n");
+#endif
+ }
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is %lx\n", pThis);
+#endif
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is now %lx\n", pThis);
+#endif
+
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "indexes are %d %d\n", nFunctionIndex, pTypeDescr->nMapFunctionIndexToMemberIndex);
+#endif
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "members are %d %d\n", nMemberPos, pTypeDescr->nAllMembers);
+#endif
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->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 * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "screwed\n");
+#endif
+
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "end of cpp_mediate\n");
+#endif
+ return eRet;
+}
+
+extern "C" void privateSnippetExecutor( ... )
+{
+ volatile long nOffsetAndIndex;
+
+ //mr %r3, %r11 # move into arg1 the 64bit value passed from OOo
+ __asm__ __volatile__ (
+ "mr %0, 11\n\t"
+ : "=r" (nOffsetAndIndex) : );
+
+ sal_uInt64 gpreg[ppc64::MAX_GPR_REGS];
+ double fpreg[ppc64::MAX_SSE_REGS];
+
+ __asm__ __volatile__ (
+ "std 3, 0(%0)\t\n"
+ "std 4, 8(%0)\t\n"
+ "std 5, 16(%0)\t\n"
+ "std 6, 24(%0)\t\n"
+ "std 7, 32(%0)\t\n"
+ "std 8, 40(%0)\t\n"
+ "std 9, 48(%0)\t\n"
+ "std 10, 56(%0)\t\n"
+ "stfd 1, 0(%1)\t\n"
+ "stfd 2, 8(%1)\t\n"
+ "stfd 3, 16(%1)\t\n"
+ "stfd 4, 24(%1)\t\n"
+ "stfd 5, 32(%1)\t\n"
+ "stfd 6, 40(%1)\t\n"
+ "stfd 7, 48(%1)\t\n"
+ "stfd 8, 56(%1)\t\n"
+ "stfd 9, 64(%1)\t\n"
+ "stfd 10, 72(%1)\t\n"
+ "stfd 11, 80(%1)\t\n"
+ "stfd 12, 88(%1)\t\n"
+ "stfd 13, 96(%1)\t\n"
+ : : "r" (gpreg), "r" (fpreg)
+ : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
+ "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", "fr8", "fr9",
+ "fr10", "fr11", "fr12", "fr13"
+ );
+
+ volatile long sp;
+
+ //stack pointer
+ __asm__ __volatile__ (
+ "mr %0, 1\n\t"
+ : "=r" (sp) : );
+
+ volatile long nRegReturn[0];
+
+ typelib_TypeClass aType =
+ cpp_mediate( nOffsetAndIndex, (void**)gpreg, (void**)fpreg, sp, (sal_Int64*)nRegReturn);
+
+ switch( aType )
+ {
+ case typelib_TypeClass_VOID:
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ __asm__( "lbz 3,%0\n\t"
+ : : "m" (nRegReturn[0]) );
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ __asm__( "lhz 3,%0\n\t"
+ : : "m" (nRegReturn[0]) );
+ break;
+ case typelib_TypeClass_SHORT:
+ __asm__( "lha 3,%0\n\t"
+ : : "m" (nRegReturn[0]) );
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ __asm__( "lwz 3,%0\n\t"
+ : : "m"(nRegReturn[0]) );
+ break;
+ case typelib_TypeClass_LONG:
+ __asm__( "lwa 3,%0\n\t"
+ : : "m"(nRegReturn[0]) );
+ break;
+ case typelib_TypeClass_FLOAT:
+ __asm__( "lfs 1,%0\n\t"
+ : : "m" (*((float*)nRegReturn)) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ __asm__( "lfd 1,%0\n\t"
+ : : "m" (*((double*)nRegReturn)) );
+ break;
+ default:
+ __asm__( "ld 3,%0\n\t"
+ : : "m" (nRegReturn[0]) );
+ break;
+ }
+}
+
+const int codeSnippetSize = 24;
+
+unsigned char * codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ bool simpleRetType)
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr,"in codeSnippet functionIndex is %x\n", nFunctionIndex);
+ fprintf(stderr,"in codeSnippet vtableOffset is %x\n", nVtableOffset);
+#endif
+
+ sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
+
+ if ( !simpleRetType )
+ nOffsetAndIndex |= 0x80000000;
+
+ void ** raw = (void **)&code[0];
+ memcpy(raw, (char*) privateSnippetExecutor, 16);
+ raw[2] = (void*) nOffsetAndIndex;
+#ifdef CMC_DEBUG
+ fprintf(stderr, "in: offset/index is %x %x %d, %lx\n",
+ nFunctionIndex, nVtableOffset, !simpleRetType, raw[2]);
+#endif
+ return (code + codeSnippetSize);
+}
+
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * bptr, unsigned char const * eptr)
+{
+ int const lineSize = 32;
+ for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
+ __asm__ volatile ("dcbst 0, %0" : : "r"(p) : "memory");
+ }
+ __asm__ volatile ("sync" : : : "memory");
+ for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
+ __asm__ volatile ("icbi 0, %0" : : "r"(p) : "memory");
+ }
+ __asm__ volatile ("isync" : : : "memory");
+}
+
+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, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+#ifdef CMC_DEBUG
+ fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
+ fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
+#endif
+
+ 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 + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/except.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/except.cxx
new file mode 100644
index 000000000000..9badda7c137a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/except.cxx
@@ -0,0 +1,290 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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() +4;
+#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;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 )
+{
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ terminate();
+
+ 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)
+ terminate();
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
+{
+ OSL_ENSURE( header, "### no exception header!!!" );
+ if (! header)
+ terminate();
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
+ if (! pExcTypeDescr)
+ terminate();
+
+ // construct uno exception any
+ ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ ::typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_powerpc64/makefile.mk
new file mode 100644
index 000000000000..405e8bc6d2dc
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/makefile.mk
@@ -0,0 +1,83 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.3 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)$(CPUNAME)" == "GCCLINUXPgcc3POWERPC64"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer
+
+NOOPTFILES= \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/cpp2uno.obj
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+
+SHL1OBJS= $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
new file mode 100644
index 000000000000..fdbc7a8f6b1c
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+namespace ppc64
+{
+ enum ppclimits { MAX_GPR_REGS = 8, MAX_SSE_REGS = 13 };
+}
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
new file mode 100644
index 000000000000..628c26f4cea4
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
@@ -0,0 +1,603 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.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 "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+void MapReturn(long r3, double dret, typelib_TypeClass eTypeClass, void *pRegisterReturn)
+{
+ switch (eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = r3;
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = r3;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = (unsigned short)r3;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = (unsigned char)r3;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *reinterpret_cast<float *>( pRegisterReturn ) = dret;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *reinterpret_cast<double *>( pRegisterReturn ) = dret;
+ break;
+ default:
+ break;
+ }
+}
+
+namespace
+{
+//==================================================================================================
+static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr,
+ sal_uInt64 *pStack, sal_uInt32 nStack,
+ sal_uInt64 *pGPR, sal_uInt32 nGPR,
+ double *pFPR, sal_uInt32 nFPR)
+{
+ // Stack, if used, must be 16-bytes aligned
+ if ( nStack )
+ nStack = ( nStack + 1 ) & ~1;
+
+ // Should not happen, but...
+ if ( nFPR > ppc64::MAX_SSE_REGS )
+ nFPR = ppc64::MAX_SSE_REGS;
+ if ( nGPR > ppc64::MAX_GPR_REGS )
+ nGPR = ppc64::MAX_GPR_REGS;
+
+#ifdef CMC_DEBUG
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
+ for ( int i = 0; i < nGPR; ++i )
+ fprintf( stderr, "0x%lx, ", pGPR[i] );
+ fprintf( stderr, "\nFPR's (%d): ", nFPR );
+ for ( int i = 0; i < nFPR; ++i )
+ fprintf( stderr, "0x%lx (%f), ", pFPR[i], pFPR[i] );
+ fprintf( stderr, "\nStack (%d): ", nStack );
+ for ( int i = 0; i < nStack; ++i )
+ fprintf( stderr, "0x%lx, ", pStack[i] );
+ fprintf( stderr, "\n" );
+ }
+#endif
+
+ // Load parameters to stack, if necessary
+ sal_uInt64 *stack = (sal_uInt64 *) __builtin_alloca( nStack * 8 );
+ memcpy( stack, pStack, nStack * 8 );
+
+ // Get pointer to method
+ sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
+ pMethod += 8 * nVtableIndex;
+ pMethod = *((sal_uInt64 *)pMethod);
+
+ typedef void (* FunctionCall )( sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64 );
+ FunctionCall pFunc = (FunctionCall)pMethod;
+
+ volatile double dret;
+
+ // fill registers
+ __asm__ __volatile__ (
+ "ld 3, 0(%0)\n\t"
+ "ld 4, 8(%0)\n\t"
+ "ld 5, 16(%0)\n\t"
+ "ld 6, 24(%0)\n\t"
+ "ld 7, 32(%0)\n\t"
+ "ld 8, 40(%0)\n\t"
+ "ld 9, 48(%0)\n\t"
+ "ld 10, 56(%0)\n\t"
+ "lfd 1, 0(%1)\n\t"
+ "lfd 2, 8(%1)\n\t"
+ "lfd 3, 16(%1)\n\t"
+ "lfd 4, 24(%1)\n\t"
+ "lfd 5, 32(%1)\n\t"
+ "lfd 6, 40(%1)\n\t"
+ "lfd 7, 48(%1)\n\t"
+ "lfd 8, 56(%1)\n\t"
+ "lfd 9, 64(%1)\n\t"
+ "lfd 10, 72(%1)\n\t"
+ "lfd 11, 80(%1)\n\t"
+ "lfd 12, 88(%1)\n\t"
+ "lfd 13, 96(%1)\n\t"
+ : : "r" (pGPR), "r" (pFPR)
+ : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
+ "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", "fr8", "fr9",
+ "fr10", "fr11", "fr12", "fr13"
+ );
+
+ // tell gcc that r3 to r11 are not available to it for doing the TOC and exception munge on the func call
+ register sal_uInt64 r3 asm("r3");
+ register sal_uInt64 r4 asm("r4");
+ register sal_uInt64 r5 asm("r5");
+ register sal_uInt64 r6 asm("r6");
+ register sal_uInt64 r7 asm("r7");
+ register sal_uInt64 r8 asm("r8");
+ register sal_uInt64 r9 asm("r9");
+ register sal_uInt64 r10 asm("r10");
+ register sal_uInt64 r11 asm("r11");
+
+ (*pFunc)(r3, r4, r5, r6, r7, r8, r9, r10);
+
+ // get return value
+ __asm__ __volatile__ (
+ "mr %1, 3\n\t"
+ "mr %2, 4\n\t"
+ "fmr %0, 1\n\t"
+ : "=f" (dret), "=r" (r3), "=r" (r4) : );
+
+ MapReturn(r3, dret, pReturnTypeDescr->eTypeClass, pRegisterReturn);
+}
+
+// Macros for easier insertion of values to registers or stack
+// pSV - pointer to the source
+// nr - order of the value [will be increased if stored to register]
+// pFPR, pGPR - pointer to the registers
+// pDS - pointer to the stack [will be increased if stored here]
+
+// The value in %xmm register is already prepared to be retrieved as a float,
+// thus we treat float and double the same
+#define INSERT_FLOAT( pSV, nr, pFPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_SSE_REGS ) \
+ pFPR[nr++] = *reinterpret_cast<float *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
+
+#define INSERT_DOUBLE( pSV, nr, pFPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_SSE_REGS ) \
+ pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
+
+#define INSERT_INT64( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+//==================================================================================================
+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 ...
+ sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+3) * sizeof(sal_Int64) );
+ sal_uInt64 * pStackStart = pStack;
+
+ sal_uInt64 pGPR[ppc64::MAX_GPR_REGS];
+ sal_uInt32 nGPR = 0;
+
+ double pFPR[ppc64::MAX_SSE_REGS];
+ sal_uInt32 nFPR = 0;
+
+ // 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
+
+ bool bOverFlow = false;
+
+ if (pReturnTypeDescr)
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "return type is %d\n", pReturnTypeDescr->eTypeClass);
+#endif
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+#ifdef CMC_DEBUG
+ fprintf(stderr, "simple return\n");
+#endif
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize ) : pUnoReturn);
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pCppReturn/pUnoReturn is %lx/%lx", pCppReturn, pUnoReturn);
+#endif
+ INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack, bOverFlow );
+ }
+ }
+ // push "this" pointer
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
+#ifdef CMC_DEBUG
+ fprintf(stderr, "this pointer is %p\n", pAdjustedThisPtr);
+#endif
+ INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverFlow );
+
+ // Args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "n params is %d\n", nParams);
+#endif
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "param %d is %d %d %d\n", nPos, rParam.bOut, bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ),
+ pParamTypeDescr->eTypeClass);
+#endif
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+// uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
+ uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "hyper is %lx\n", pCppArgs[nPos]);
+#endif
+ INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "long is %x\n", pCppArgs[nPos]);
+#endif
+ INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_FLOAT:
+ INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack, bOverFlow );
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+
+ }
+ else // ptr to complex value | ref
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex type again %d\n", rParam.bIn);
+#endif
+ if (! rParam.bIn) // is pure out
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex size is %d\n", pParamTypeDescr->nSize );
+#endif
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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 ))
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "this one\n");
+#endif
+ uno_copyAndConvertData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "that one, passing %lx through\n", pUnoArgs[nPos]);
+#endif
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverFlow );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr,
+ pStackStart, ( pStack - pStackStart ),
+ pGPR, nGPR,
+ pFPR, nFPR );
+ // NO exception occured...
+ *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 );
+
+ 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( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+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);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx
new file mode 100644
index 000000000000..3ebc8a589df0
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx
@@ -0,0 +1,698 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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 <stdio.h>
+#include <string.h>
+
+using namespace ::com::sun::star::uno;
+
+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_Int64 * pRegisterReturn /* space for register return */ )
+{
+ int ng = 0; //number of gpr registers used
+ int nf = 0; //number of fpr regsiters used
+ void ** pCppStack; //temporary stack pointer
+
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // 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 = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)gpreg;
+ gpreg++;
+ ng++;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ gpreg++;
+ ng++;
+
+ // 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
+ {
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+
+ case typelib_TypeClass_DOUBLE:
+ if (nf < 2) {
+ pCppArgs[nPos] = fpreg;
+ pUnoArgs[nPos] = fpreg;
+ nf++;
+ fpreg += 2;
+ } else {
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 2;
+ }
+ break;
+
+ case typelib_TypeClass_FLOAT:
+ // fpreg are all double values so need to
+ // modify fpreg to be a single word float value
+ if (nf < 2) {
+// float tmp = (float) (*((double *)fpreg));
+// (*((float *) fpreg)) = tmp;
+ pCppArgs[nPos] = fpreg;
+ pUnoArgs[nPos] = fpreg;
+ nf++;
+ fpreg += 2;
+ } else {
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 1;
+ }
+ break;
+
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (ng < 4) {
+ pCppArgs[nPos] = gpreg;
+ pUnoArgs[nPos] = gpreg;
+ ng += 2;
+ gpreg += 2;
+ } else {
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 2;
+ }
+ break;
+
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+ if (ng < 5) {
+ pCppArgs[nPos] = (((char *)gpreg) + 3);
+ pUnoArgs[nPos] = (((char *)gpreg) + 3);
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = (((char *)ovrflw) + 3);
+ pUnoArgs[nPos] = (((char *)ovrflw) + 3);
+ ovrflw++;
+ }
+ break;
+
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (ng < 5) {
+ pCppArgs[nPos] = (((char *)gpreg)+ 2);
+ pUnoArgs[nPos] = (((char *)gpreg)+ 2);
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = (((char *)ovrflw) + 2);
+ pUnoArgs[nPos] = (((char *)ovrflw) + 2);
+ ovrflw++;
+ }
+ break;
+
+
+ default:
+ if (ng < 5) {
+ pCppArgs[nPos] = gpreg;
+ pUnoArgs[nPos] = gpreg;
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw++;
+ }
+ break;
+
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+
+ if (ng < 5) {
+ pCppArgs[nPos] = *(void **)gpreg;
+ pCppStack = gpreg;
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = *(void **)ovrflw;
+ pCppStack = ovrflw;
+ ovrflw++;
+ }
+
+ 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 );
+ }
+ }
+ }
+
+ // 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 occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//============================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_uInt32 nOffsetAndIndex,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ sal_Int16 nVtableOffset = (nOffsetAndIndex >> 16);
+ sal_Int16 nFunctionIndex = (nOffsetAndIndex & 0xFFFF);
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // _this_ ptr is patched cppu_XInterfaceProxy object
+ void * pThis;
+ if( nFunctionIndex & 0x8000 )
+ {
+ nFunctionIndex &= 0x7fff;
+ pThis = gpreg[1];
+ }
+ else
+ {
+ pThis = gpreg[0];
+ }
+
+ 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(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pCppI );
+ }
+
+ // determine called method
+ OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->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 * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static void privateSnippetExecutor( sal_uInt32 nOffsetAndIndex, void** gpregptr, void** fpregptr, void** ovrflw)
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "privateSnippetExecutor\n");
+#endif
+
+
+ sal_Int32 gpreg[8];
+ double fpreg[8];
+
+ memcpy( gpreg, gpregptr, 32);
+ memcpy( fpreg, fpregptr, 64);
+
+ volatile long nRegReturn[2];
+
+ typelib_TypeClass aType =
+ cpp_mediate( nOffsetAndIndex, (void**)gpreg, (void**)fpreg, ovrflw,
+ (sal_Int64*)nRegReturn );
+
+ switch( aType )
+ {
+
+ // move return value into register space
+ // (will be loaded by machine code snippet)
+
+ case typelib_TypeClass_BOOLEAN:
+ {
+ unsigned long tmp = (unsigned long)(*(unsigned char *)nRegReturn);
+ __asm__ volatile ( "l 2,%0\n\t" : :
+ "m"(tmp) : "2" );
+ break;
+ }
+ case typelib_TypeClass_BYTE:
+ {
+ long tmp = (long)(*(signed char *)nRegReturn);
+ __asm__ volatile ( "l 2,%0\n\t" : :
+ "m"(tmp) : "2" );
+ break;
+ }
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ {
+ unsigned long tmp = (unsigned long)(*(unsigned short *)nRegReturn);
+ __asm__ volatile ( "l 2,%0\n\t" : :
+ "m"(tmp) : "2" );
+ break;
+ }
+ case typelib_TypeClass_SHORT:
+ {
+ long tmp = (long)(*(short *)nRegReturn);
+ __asm__ volatile ( "l 2,%0\n\t" : :
+ "m"(tmp) : "2" );
+ break;
+ }
+ case typelib_TypeClass_FLOAT:
+ __asm__ volatile ( "le 0,%0\n\t" : :
+ "m" (*((float*)nRegReturn)) : "16" );
+ break;
+
+ case typelib_TypeClass_DOUBLE:
+ __asm__ volatile ( "ld 0,%0\n\t" : :
+ "m" (*((double*)nRegReturn)) : "16" );
+ break;
+
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ __asm__ volatile ( "lm 2,3,%0\n\t" : :
+ "m"(nRegReturn[0]) : "2", "3" );
+ break;
+
+ default:
+ __asm__ volatile ( "l 2,%0\n\t" : :
+ "m"(nRegReturn[0]) : "2" );
+ break;
+ }
+}
+
+const int codeSnippetSize = 50;
+
+unsigned char* codeSnippet( unsigned char * code, sal_Int16 nFunctionIndex, sal_Int16 nVtableOffset, bool simple_ret_type )
+{
+ sal_uInt32 nOffsetAndIndex = ( ( nVtableOffset ) << 16 ) | ( nFunctionIndex );
+
+ if (! simple_ret_type)
+ nOffsetAndIndex |= 0x8000;
+
+ OSL_ASSERT( sizeof (long) == 4 );
+
+ /* generate this code */
+ // lr %r0,%r13
+ // bras %r13,0x6
+ // .long privateSnippetExecutor
+ // .long nOffsetAndIndex
+ // stm %r2,%r6,8(%r15)
+ // std %f0,64(%r15)
+ // std %f2,72(%r15)
+
+ // l %r2,4(%r13)
+ // la %r3,8(%r15)
+ // la %r4,64(%r15)
+ // la %r5,96(%r15)
+ // l %r1,0(%r13)
+ // lr %r13,%r0
+ // br %r1
+
+ unsigned char * p = code;
+ *reinterpret_cast< sal_Int16 * >(p) = 0x180d;
+ p += sizeof(sal_Int16);
+ *reinterpret_cast< sal_Int32 * >(p) = 0xa7d50006;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) =
+ reinterpret_cast< sal_Int32 >(privateSnippetExecutor);
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = nOffsetAndIndex;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x9026f008;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x6000f040;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x6020f048;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x5820d004;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x4130f008;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x4140f040;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x4150f060;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x5810d000;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int16 * >(p) = 0x18d0;
+ p += sizeof(sal_Int16);
+ *reinterpret_cast< sal_Int16 * >(p) = 0x07f1;
+ p += sizeof(sal_Int16);
+
+ return (code + codeSnippetSize);
+}
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *, unsigned char const *)
+{
+}
+
+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, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+#ifdef CMC_DEBUG
+ fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
+ fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
+#endif
+
+ 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 + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390/except.cxx b/bridges/source/cpp_uno/gcc3_linux_s390/except.cxx
new file mode 100644
index 000000000000..0d49d0b95a74
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390/except.cxx
@@ -0,0 +1,290 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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 iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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() +4;
+#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 = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 )
+{
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ terminate();
+
+ 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)
+ terminate();
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
+{
+ OSL_ENSURE( header, "### no exception header!!!" );
+ if (! header)
+ terminate();
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
+ if (! pExcTypeDescr)
+ terminate();
+
+ // construct uno exception any
+ ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ ::typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_s390/makefile.mk
new file mode 100644
index 000000000000..9b27f0f5ad97
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390/makefile.mk
@@ -0,0 +1,81 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.8 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)$(CPUNAME)" == "GCCLINUX3gcc3S390"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390/share.hxx b/bridges/source/cpp_uno/gcc3_linux_s390/share.hxx
new file mode 100644
index 000000000000..ab8565341ece
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390/share.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_s390/uno2cpp.cxx
new file mode 100644
index 000000000000..364464a28565
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390/uno2cpp.cxx
@@ -0,0 +1,638 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.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 "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+static sal_Int32
+invoke_count_words(char * pPT)
+{
+ sal_Int32 overflow = 0, gpr = 0, fpr = 0;
+ int c; // character of parameter type being decoded
+
+ while (*pPT != 'X') {
+ c = *pPT;
+ switch (c) {
+ case 'D': /* type is double */
+ if (fpr < 2) fpr++; else overflow+=2;
+ break;
+
+ case 'F': /* type is float */
+ if (fpr < 2) fpr++; else overflow++;
+ break;
+
+ case 'H': /* type is long long */
+ if (gpr < 4) gpr+=2; else gpr=5, overflow+=2;
+ break;
+
+ case 'S':
+ case 'T':
+ case 'B':
+ case 'C':
+ if (gpr < 5) gpr++; else overflow++;
+ break;
+
+ default:
+ if (gpr < 5) gpr++; else overflow++;
+ break;
+ }
+ pPT++;
+ }
+ /* Round up number of overflow words to ensure stack
+ stays aligned to 8 bytes. */
+ return (overflow + 1) & ~1;
+}
+
+static void
+//invoke_copy_to_stack(sal_Int32 paramCount, sal_Int32 * pStackLongs, char * pPT, sal_Int32* d_ov, sal_Int32 overflow)
+invoke_copy_to_stack(sal_Int32 * pStackLongs, char * pPT, sal_Int32* d_ov, sal_Int32 overflow)
+{
+ sal_Int32 *d_gpr = d_ov + overflow;
+ sal_Int64 *d_fpr = (sal_Int64 *)(d_gpr + 5);
+ sal_Int32 gpr = 0, fpr = 0;
+ char c;
+
+ while (*pPT != 'X') {
+ c = *pPT;
+ switch (c) {
+ case 'D': /* type is double */
+ if (fpr < 2)
+ *((double*) d_fpr) = *((double *)pStackLongs), d_fpr++, fpr++;
+ else
+ *((double*) d_ov ) = *((double *)pStackLongs), d_ov+=2;
+
+ pStackLongs += 2;
+ break;
+
+ case 'F': /* type is float */
+ if (fpr < 2) {
+ *((sal_Int64*) d_fpr) = 0;
+ *((float*) d_fpr) = *((float *)pStackLongs), d_fpr++, fpr++;
+ }
+ else {
+ *((sal_Int64*) d_ov) = 0;
+ *((float*) d_ov ) = *((float *)pStackLongs), d_ov++;
+ }
+
+ pStackLongs += 1;
+ break;
+
+ case 'H': /* type is long long */
+ if (gpr < 4) {
+ *((sal_Int64*) d_gpr) = *((sal_Int64*) pStackLongs), d_gpr+=2, gpr+=2;
+ }
+ else {
+ *((sal_Int64*) d_ov ) = *((sal_Int64*) pStackLongs), d_ov+=2, gpr=5;
+ }
+ pStackLongs += 2;
+ break;
+
+ case 'S':
+ if (gpr < 5)
+ *((sal_uInt32*)d_gpr) = *((unsigned short*)pStackLongs), d_gpr++, gpr++;
+ else
+ *((sal_uInt32*)d_ov ) = *((unsigned short*)pStackLongs), d_ov++;
+ pStackLongs += 1;
+ break;
+
+ case 'T':
+ if (gpr < 5)
+ *((sal_Int32*)d_gpr) = *((signed short*)pStackLongs), d_gpr++, gpr++;
+ else
+ *((sal_Int32*)d_ov ) = *((signed short*)pStackLongs), d_ov++;
+ pStackLongs += 1;
+ break;
+
+ case 'B':
+ if (gpr < 5)
+ *((sal_uInt32*)d_gpr) = *((unsigned char*)pStackLongs), d_gpr++, gpr++;
+ else
+ *((sal_uInt32*)d_ov ) = *((unsigned char*)pStackLongs), d_ov++;
+ pStackLongs += 1;
+ break;
+
+ case 'C':
+ if (gpr < 5)
+ *((sal_Int32*)d_gpr) = *((signed char*)pStackLongs), d_gpr++, gpr++;
+ else
+ *((sal_Int32*)d_ov ) = *((signed char*)pStackLongs), d_ov++;
+ pStackLongs += 1;
+ break;
+
+ default:
+ if (gpr < 5)
+ *((sal_Int32*)d_gpr) = *pStackLongs, d_gpr++, gpr++;
+ else
+ *((sal_Int32*)d_ov ) = *pStackLongs, d_ov++;
+ pStackLongs += 1;
+ break;
+ }
+ pPT++;
+ }
+}
+
+//==================================================================================================
+static void callVirtualMethod(
+ void * pThis,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ char * pPT,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs)
+{
+
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ // the basic idea here is to use gpr[5] as a storage area for
+ // the future values of registers r2 to r6 needed for the call,
+ // and similarly fpr[2] as a storage area for the future values
+ // of floating point registers f0 to f2
+
+ sal_Int32 *vtable = *(sal_Int32 **)pThis;
+// sal_Int32 method = vtable[nVtableIndex + 2];
+ sal_Int32 method = vtable[nVtableIndex];
+ sal_Int32 overflow = invoke_count_words (pPT);
+ sal_Int32 result;
+ volatile double dret; // temporary function return values
+ volatile float fret;
+ volatile int iret, iret2;
+
+ void * dummy = alloca(32); // dummy alloca to force r11 usage for exception handling
+
+ __asm__ __volatile__
+ (
+ "lr 7,15\n\t"
+ "ahi 7,-48\n\t"
+
+ "lr 3,%2\n\t"
+ "sll 3,2\n\t"
+ "lcr 3,3\n\t"
+ "l 2,0(15)\n\t"
+ "la 15,0(3,7)\n\t"
+ "st 2,0(15)\n\t"
+
+ "lr 2,%0\n\t"
+ "lr 3,%1\n\t"
+ "la 4,96(15)\n\t"
+ "lr 5,%2\n\t"
+ "basr 14,%3\n\t"
+
+ "ld 0,116(7)\n\t"
+ "ld 2,124(7)\n\t"
+ "lm 2,6,96(7)\n\t"
+ :
+ : "r" (pStackLongs),
+ "r" (pPT),
+ "r" (overflow),
+ "a" (invoke_copy_to_stack),
+ "a" (method),
+ "X" (dummy)
+ : "2", "3", "4", "5", "6", "7", "memory"
+ );
+// "basr 14,%8\n\t"
+
+ (*(void (*)())method)();
+
+ __asm__ __volatile__
+ (
+ "la 15,48(7)\n\t"
+
+ "lr %2,2\n\t"
+ "lr %3,3\n\t"
+ "ler %0,0\n\t"
+ "ldr %1,0\n\t"
+
+ : "=f" (fret), "=f" (dret), "=r" (iret), "=r" (iret2)
+ );
+
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+// ((long*)pRegisterReturn)[0] = iret;
+ ((long*)pRegisterReturn)[1] = iret2;
+ 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:
+ *(unsigned short*)pRegisterReturn = (unsigned short)iret;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)iret;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = fret;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = dret;
+ break;
+ }
+}
+
+
+//============================================================================
+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 =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // need to know parameter types for callVirtualMethod so generate a signature string
+ char * pParamType = (char *) alloca(nParams+2);
+ char * pPT = pParamType;
+
+ // 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 = *(void **)pCppStack = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ *pPT++ = 'I'; //signify that a complex return type on stack
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push "this" pointer
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+ *pPT++ = 'I';
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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)
+ {
+
+ // 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:
+ *pPT++ = 'T';
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *pPT++ = 'S';
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ *pPT++ = 'B';
+ break;
+ case typelib_TypeClass_BYTE:
+ *pPT++ = 'C';
+ 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
+ }
+
+ // 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 );
+ 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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 );
+ }
+ // 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;
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass, pParamType,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *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 );
+
+ 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( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "unoInterfaceProxyDispatch\n");
+#endif
+
+
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy *> (pUnoI);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390x/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_s390x/cpp2uno.cxx
new file mode 100644
index 000000000000..e866e05f32c5
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390x/cpp2uno.cxx
@@ -0,0 +1,655 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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 <stdio.h>
+
+using namespace ::com::sun::star::uno;
+
+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_Int64 * pRegisterReturn /* space for register return */ )
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "as far as cpp2uno_call\n");
+#endif
+ int ng = 0; //number of gpr registers used
+ int nf = 0; //number of fpr regsiters used
+
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // 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 = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)gpreg;
+ gpreg++;
+ ng++;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ gpreg++;
+ ng++;
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int64), "### 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 );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "arg %d of %d\n", nPos, nParams);
+#endif
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "simple\n");
+#endif
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_DOUBLE:
+ if (nf < s390x::MAX_SSE_REGS)
+ {
+ if (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT)
+ {
+ float tmp = (float) (*((double *)fpreg));
+ (*((float *) fpreg)) = tmp;
+ }
+
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
+ nf++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ ovrflw++;
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+ if (ng < s390x::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-1));
+ ng++;
+ gpreg++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-1));
+ ovrflw++;
+ }
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (ng < s390x::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-2));
+ ng++;
+ gpreg++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-2));
+ ovrflw++;
+ }
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (ng < s390x::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-4));
+ ng++;
+ gpreg++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-4));
+ ovrflw++;
+ }
+ break;
+ default:
+ if (ng < s390x::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ ovrflw++;
+ }
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex, ng is %d\n", ng);
+#endif
+
+ void *pCppStack; //temporary stack pointer
+
+ if (ng < s390x::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pCppStack = *gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pCppStack = *ovrflw;
+ ovrflw++;
+ }
+
+ 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 ),
+ 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] = pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "end of params\n");
+#endif
+
+ // 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 occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//============================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_uInt64 nOffsetAndIndex,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int64)==sizeof(void *), "### unexpected!" );
+
+ sal_Int32 nVtableOffset = (nOffsetAndIndex >> 32);
+ sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "nVTableOffset, nFunctionIndex are %x %x\n", nVtableOffset, nFunctionIndex);
+#endif
+
+#ifdef CMC_DEBUG
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "= cpp_mediate () =\nGPR's (%d): ", 5 );
+ for ( unsigned int i = 0; i < 5; ++i )
+ fprintf( stderr, "0x%lx, ", gpreg[i] );
+ fprintf( stderr, "\n");
+ fprintf( stderr, "\nFPR's (%d): ", 4 );
+ for ( unsigned int i = 0; i < 4; ++i )
+ fprintf( stderr, "0x%lx (%f), ", fpreg[i], fpreg[i] );
+ fprintf( stderr, "\n");
+ }
+#endif
+
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // _this_ ptr is patched cppu_XInterfaceProxy object
+ void * pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+ }
+ else
+ {
+ pThis = gpreg[0];
+ }
+
+ 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(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pCppI );
+ }
+
+ // determine called method
+ OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->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 * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+long privateSnippetExecutor(long r2, long r3, long r4, long r5, long r6, long firstonstack)
+{
+ register long r0 asm("r0");
+ sal_uInt32 nOffsetAndIndex = r0;
+
+ long sp = (long)&firstonstack;
+
+ sal_uInt64 gpreg[s390x::MAX_GPR_REGS];
+ gpreg[0] = r2;
+ gpreg[1] = r3;
+ gpreg[2] = r4;
+ gpreg[3] = r5;
+ gpreg[4] = r6;
+
+ double fpreg[s390x::MAX_SSE_REGS];
+ register double f0 asm("f0"); fpreg[0] = f0;
+ register double f2 asm("f2"); fpreg[1] = f2;
+ register double f4 asm("f4"); fpreg[2] = f4;
+ register double f6 asm("f6"); fpreg[3] = f6;
+
+ volatile long nRegReturn[1];
+#ifdef CMC_DEBUG
+ fprintf(stderr, "before mediate with %lx\n",nOffsetAndIndex);
+ fprintf(stderr, "doubles are %f %f %f %f\n", fpreg[0], fpreg[1], fpreg[2], fpreg[3]);
+#endif
+ typelib_TypeClass aType =
+ cpp_mediate( nOffsetAndIndex, (void**)gpreg, (void**)fpreg, (void**)sp,
+ (sal_Int64*)nRegReturn );
+#ifdef CMC_DEBUG
+ fprintf(stderr, "after mediate ret is %lx %ld\n", nRegReturn[0], nRegReturn[0]);
+#endif
+
+ switch( aType )
+ {
+ case typelib_TypeClass_VOID:
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_LONG:
+ default:
+ break;
+ case typelib_TypeClass_FLOAT:
+ {
+ double tmp = (double) (*((float *)nRegReturn));
+ (*((double *) nRegReturn)) = tmp;
+ }
+ //deliberate fall through
+ case typelib_TypeClass_DOUBLE:
+ __asm__ ( "ld 0,%0\n\t"
+ : : "m" (*((double*)nRegReturn)) );
+ break;
+ }
+ return nRegReturn[0];
+}
+
+const int codeSnippetSize = 32;
+
+unsigned char *codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, bool simple_ret_type )
+{
+ sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_Int64) nFunctionIndex );
+
+ if (! simple_ret_type)
+ nOffsetAndIndex |= 0x80000000;
+
+ unsigned char * p = code;
+ *(short *)&p[0] = 0x0d10; /* basr %r1,0 */
+ *(short *)&p[2] = 0xeb01; /* lmg %r0,%r1,14(%r1) */
+ *(short *)&p[4] = 0x100e;
+ *(short *)&p[6] = 0x0004;
+ *(short *)&p[8] = 0x07f1; /* br %r1 */
+ *(long *)&p[16] = (long)nOffsetAndIndex;
+ *(long *)&p[24] = (long)&privateSnippetExecutor;
+ return (code + codeSnippetSize);
+}
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *, unsigned char const *)
+{
+}
+
+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, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+#ifdef CMC_DEBUG
+ fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
+ fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
+#endif
+
+ 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 + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390x/except.cxx b/bridges/source/cpp_uno/gcc3_linux_s390x/except.cxx
new file mode 100644
index 000000000000..e474dce7268c
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390x/except.cxx
@@ -0,0 +1,291 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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 iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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() +4;
+#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 = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 )
+{
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ terminate();
+
+ 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)
+ terminate();
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
+{
+ OSL_ENSURE( header, "### no exception header!!!" );
+ if (! header)
+ terminate();
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
+ if (! pExcTypeDescr)
+ terminate();
+
+ // construct uno exception any
+ ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ ::typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390x/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_s390x/makefile.mk
new file mode 100644
index 000000000000..b85bcb187d83
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390x/makefile.mk
@@ -0,0 +1,81 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.3 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)$(CPUNAME)" == "GCCLINUX3gcc3S390X"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390x/share.hxx b/bridges/source/cpp_uno/gcc3_linux_s390x/share.hxx
new file mode 100644
index 000000000000..8e56e324e315
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390x/share.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+namespace s390x
+{
+ enum s390xlimits { MAX_GPR_REGS = 5, MAX_SSE_REGS = 4 };
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390x/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_s390x/uno2cpp.cxx
new file mode 100644
index 000000000000..5940f566f9ca
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390x/uno2cpp.cxx
@@ -0,0 +1,541 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.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 "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+void MapReturn(long r2, double f0, typelib_TypeClass eTypeClass, sal_uInt64* pRegisterReturn)
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr,"Mapping Return with %lx %ld %f\n", r2, r2, f0);
+#endif
+ switch (eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *pRegisterReturn = r2;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *pRegisterReturn = (unsigned short)r2;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *pRegisterReturn = (unsigned char)r2;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *reinterpret_cast<float *>( pRegisterReturn ) = f0;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *reinterpret_cast<double *>( pRegisterReturn ) = f0;
+ break;
+ default:
+ break;
+ }
+#ifdef CMC_DEBUG
+ fprintf(stderr, "end of MapReturn with %x\n", pRegisterReturn ? *pRegisterReturn : 0);
+#endif
+}
+
+#define INSERT_FLOAT( pSV, nr, pFPR, pDS ) \
+ { \
+ float tmp = *reinterpret_cast<float *>( pSV ); \
+ if ( nr < s390x::MAX_SSE_REGS ) \
+ { \
+ pFPR[nr++] = *reinterpret_cast<float *>( pSV ); \
+ } \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ }
+
+#define INSERT_DOUBLE( pSV, nr, pFPR, pDS ) \
+ if ( nr < s390x::MAX_SSE_REGS ) \
+ pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
+
+#define INSERT_INT64( pSV, nr, pGPR, pDS ) \
+ if ( nr < s390x::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
+ if ( nr < s390x::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
+ if ( nr < s390x::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS ) \
+ if ( nr < s390x::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+namespace
+{
+//==================================================================================================
+void callVirtualMethod(
+ void * pThis, sal_Int32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr,
+ sal_uInt64 *pStack, sal_uInt32 nStack,
+ sal_uInt64 *pGPR, sal_uInt32 nGPR,
+ double *pFPR, sal_uInt32 nFPR)
+{
+ // Should not happen, but...
+ if ( nFPR > s390x::MAX_SSE_REGS )
+ nFPR = s390x::MAX_SSE_REGS;
+ if ( nGPR > s390x::MAX_GPR_REGS )
+ nGPR = s390x::MAX_GPR_REGS;
+
+#ifdef CMC_DEBUG
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "= nStack is %d\n", nStack );
+ fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
+ for ( unsigned int i = 0; i < nGPR; ++i )
+ fprintf( stderr, "0x%lx, ", pGPR[i] );
+ fprintf( stderr, "\nFPR's (%d): ", nFPR );
+ for ( unsigned int i = 0; i < nFPR; ++i )
+ fprintf( stderr, "0x%lx (%f), ", pFPR[i], pFPR[i] );
+ fprintf( stderr, "\nStack (%d): ", nStack );
+ for ( unsigned int i = 0; i < nStack; ++i )
+ fprintf( stderr, "0x%lx, ", pStack[i] );
+ fprintf( stderr, "\n" );
+ fprintf( stderr, "pRegisterReturn is %p\n", pRegisterReturn);
+ }
+#endif
+
+ // Load parameters to stack, if necessary
+ // Stack, if used, must be 8-bytes aligned
+ sal_uInt64 *stack = (sal_uInt64 *) __builtin_alloca( nStack * 8 );
+ memcpy( stack, pStack, nStack * 8 );
+
+ // To get pointer to method
+ // a) get the address of the vtable
+ sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
+ // b) get the address from the vtable entry at offset
+ pMethod += 8 * nVtableIndex;
+ pMethod = *((sal_uInt64 *)pMethod);
+
+ typedef void (* FunctionCall )( sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64 );
+ FunctionCall pFunc = (FunctionCall)pMethod;
+
+ switch (nFPR) //deliberate fall through
+ {
+ case 4:
+ asm volatile("ld 6,%0" :: "m"(pFPR[3]) : "16");
+ case 3:
+ asm volatile("ld 4,%0" :: "m"(pFPR[2]) : "16");
+ case 2:
+ asm volatile("ld 2,%0" :: "m"(pFPR[1]) : "16");
+ case 1:
+ asm volatile("ld 0,%0" :: "m"(pFPR[0]) : "16");
+ default:
+ break;
+ }
+
+ volatile long r2;
+ volatile double f0;
+
+ (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3], pGPR[4]);
+
+ __asm__ __volatile__ (
+ "lgr %0,2\n\t"
+ "ldr %1,0\n\t"
+ : "=r" (r2), "=f" (f0)
+ : :
+ );
+
+ MapReturn(r2, f0, pReturnTypeDescr->eTypeClass, (sal_uInt64*)pRegisterReturn);
+}
+
+
+//============================================================================
+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 ...
+ sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+3) * sizeof(sal_Int64) );
+ sal_uInt64 * pStackStart = pStack;
+
+ sal_uInt64 pGPR[s390x::MAX_GPR_REGS];
+ sal_uInt32 nGPR = 0;
+
+ double pFPR[s390x::MAX_SSE_REGS];
+ sal_uInt32 nFPR = 0;
+
+ // 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 )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack );
+ }
+ }
+ // push "this" pointer
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
+
+ INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int64), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_FLOAT:
+ INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR, pStack );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack );
+ 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(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr,
+ pStackStart, (pStack - pStackStart),
+ pGPR, nGPR,
+ pFPR, nFPR );
+ // NO exception occured...
+ *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 );
+
+ 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( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "unoInterfaceProxyDispatch\n");
+#endif
+
+
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy *> (pUnoI);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_sparc/call.s b/bridges/source/cpp_uno/gcc3_linux_sparc/call.s
new file mode 100644
index 000000000000..09c611237968
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_sparc/call.s
@@ -0,0 +1,10 @@
+.global doFlushCode
+doFlushCode:
+.L: flush %o0
+ deccc %o1
+ bne .L
+ add %o0, 8, %o0
+ retl
+ nop
+.size doFlushCode,(.-doFlushCode)
+.align 8
diff --git a/bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx
new file mode 100644
index 000000000000..4e07c2c879d7
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx
@@ -0,0 +1,578 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/data.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"
+
+using namespace com::sun::star::uno;
+
+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 ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // pCallStack: [ret ptr], this, params
+ char * pCppStack = (char *)pCallStack;
+
+ // 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 = pRegisterReturn; // direct way for simple types
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void**)pCppStack;
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ pCppStack += sizeof( void* );
+ }
+ }
+ // 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] = pUnoArgs[nPos] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack, pParamTypeDescr);
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ {
+ if ((reinterpret_cast< long >(pCppStack) & 7) != 0)
+ {
+ OSL_ASSERT( sizeof (double) == sizeof (sal_Int64) );
+ void * pDest = alloca( sizeof (sal_Int64) );
+ *reinterpret_cast< sal_Int32 * >(pDest) =
+ *reinterpret_cast< sal_Int32 const * >(pCppStack);
+ *(reinterpret_cast< sal_Int32 * >(pDest) + 1) =
+ *(reinterpret_cast< sal_Int32 const * >(pCppStack) + 1);
+ pCppArgs[nPos] = pUnoArgs[nPos] = pDest;
+ }
+ 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 occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: this, params
+ // eventual [ret*] lies at pCallStack -1
+ // so count down pCallStack by one to keep it simple
+ // pCallStack: this, params
+ // eventual [ret*] lies at pCallStack -1
+ // so count down pCallStack by one to keep it simple
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ static_cast< char * >(*pCallStack) - nVtableOffset);
+ if ((nFunctionIndex & 0x80000000) != 0) {
+ nFunctionIndex &= 0x7FFFFFFF;
+ --pCallStack;
+ }
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException( rtl::OUString::createFromAscii("illegal vtable index!"), (XInterface *)pCppI );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+#if defined BRIDGES_DEBUG
+ OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
+#endif
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[2] )->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[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = pCallStack[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(rtl::OUString::createFromAscii("no member description found!"), (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+ return eRet;
+}
+
+
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static void cpp_vtable_call()
+{
+ sal_Int64 nRegReturn;
+ int nFunctionIndex;
+ void** pCallStack;
+ int vTableOffset;
+
+void * pRegReturn = &nRegReturn;
+
+ __asm__( "st %%i0, %0\n\t"
+ "st %%i1, %1\n\t"
+ "st %%i2, %2\n\t"
+ : : "m"(nFunctionIndex), "m"(pCallStack), "m"(vTableOffset) );
+
+// fprintf(stderr,"cpp_mediate nFunctionIndex=%x\n",nFunctionIndex);
+// fflush(stderr);
+
+ sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False;
+ typelib_TypeClass aType =
+ cpp_mediate( nFunctionIndex, vTableOffset, pCallStack+17, (sal_Int64*)&nRegReturn );
+
+ switch( aType )
+ {
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ __asm__( "ld %0, %%l0\n\t"
+ "ldsb [%%l0], %%i0\n"
+ : : "m"(pRegReturn) );
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ __asm__( "ld %0, %%l0\n\t"
+ "ldsh [%%l0], %%i0\n"
+ : : "m"(pRegReturn) );
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ __asm__( "ld %0, %%l0\n\t"
+ "ld [%%l0], %%i0\n\t"
+ "add %%l0, 4, %%l0\n\t"
+ "ld [%%l0], %%i1\n\t"
+ : : "m"(pRegReturn) );
+
+ break;
+ case typelib_TypeClass_FLOAT:
+ __asm__( "ld %0, %%l0\n\t"
+ "ld [%%l0], %%f0\n"
+ : : "m"(pRegReturn) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ __asm__( "ld %0, %%l0\n\t"
+ "ldd [%%l0], %%f0\n"
+ : : "m"(pRegReturn) );
+ break;
+ case typelib_TypeClass_VOID:
+ break;
+ default:
+ __asm__( "ld %0, %%l0\n\t"
+ "ld [%%l0], %%i0\n"
+ : : "m"(pRegReturn) );
+ break;
+ }
+
+ if( bComplex )
+ {
+ __asm__( "add %i7, 4, %i7\n\t" );
+ // after call to complex return valued funcion there is an unimp instruction
+ }
+
+}
+//__________________________________________________________________________________________________
+
+int const codeSnippetSize = 56;
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool simpleRetType)
+{
+ sal_uInt32 index = functionIndex;
+ if (!simpleRetType) {
+ index |= 0x80000000;
+ }
+ unsigned int * p = reinterpret_cast< unsigned int * >(code);
+ OSL_ASSERT(sizeof (unsigned int) == 4);
+ // st %o0, [%sp+68]:
+ *p++ = 0xD023A044;
+ // st %o1, [%sp+72]:
+ *p++ = 0xD223A048;
+ // st %o2, [%sp+76]:
+ *p++ = 0xD423A04C;
+ // st %o3, [%sp+80]:
+ *p++ = 0xD623A050;
+ // st %o4, [%sp+84]:
+ *p++ = 0xD823A054;
+ // st %o5, [%sp+88]:
+ *p++ = 0xDA23A058;
+ // sethi %hi(index), %o0:
+ *p++ = 0x11000000 | (index >> 10);
+ // or %o0, %lo(index), %o0:
+ *p++ = 0x90122000 | (index & 0x3FF);
+ // sethi %hi(vtableOffset), %o2:
+ *p++ = 0x15000000 | (vtableOffset >> 10);
+ // or %o2, %lo(vtableOffset), %o2:
+ *p++ = 0x9412A000 | (vtableOffset & 0x3FF);
+ // sethi %hi(cpp_vtable_call), %o3:
+ *p++ = 0x17000000 | (reinterpret_cast< unsigned int >(cpp_vtable_call) >> 10);
+ // or %o3, %lo(cpp_vtable_call), %o3:
+ *p++ = 0x9612E000 | (reinterpret_cast< unsigned int >(cpp_vtable_call) & 0x3FF);
+ // jmpl %o3, %g0:
+ *p++ = 0x81C2C000;
+ // mov %sp, %o1:
+ *p++ = 0x9210000E;
+ OSL_ASSERT(
+ reinterpret_cast< unsigned char * >(p) - code <= codeSnippetSize);
+ return code + codeSnippetSize;
+}
+
+} //end of namespace
+
+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; //null
+ slots[-1].fn = 0; //destructor
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ 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 + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vTableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vTableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vTableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+// use flush code from cc50_solaris_sparc
+
+extern "C" void doFlushCode(unsigned long address, unsigned long count);
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const * begin, unsigned char const * end)
+{
+ unsigned long n = end - begin;
+ if (n != 0) {
+ unsigned long adr = reinterpret_cast< unsigned long >(begin);
+ unsigned long off = adr & 7;
+ doFlushCode(adr - off, (n + off + 7) >> 3);
+ }
+}
diff --git a/bridges/source/cpp_uno/gcc3_linux_sparc/except.cxx b/bridges/source/cpp_uno/gcc3_linux_sparc/except.cxx
new file mode 100644
index 000000000000..1024b7009478
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_sparc/except.cxx
@@ -0,0 +1,331 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#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 defined BRIDGES_DEBUG
+ 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 defined BRIDGES_DEBUG
+ 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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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 iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iiFind( m_generatedRttis.find( unoName ) );
+ if (iiFind == 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() +4;
+#if defined BRIDGES_DEBUG
+ 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 = iiFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 defined BRIDGES_DEBUG
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if defined _DEBUG
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if defined BRIDGES_DEBUG
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if defined _DEBUG
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_sparc/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_sparc/makefile.mk
new file mode 100644
index 000000000000..2bf38b311f1d
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_sparc/makefile.mk
@@ -0,0 +1,85 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.8 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)" == "GCCLINUXS"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSNOOPT=-O0
+
+NOOPTFILES = \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/call.obj
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+
+SHL1TARGET=$(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS= $(SLOFILES)
+SHL1LIBS =$(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+ $(ASM) $(AFLAGS) -o $(SLO)$/$(@:b).o $< && touch $@
diff --git a/bridges/source/cpp_uno/gcc3_linux_sparc/share.hxx b/bridges/source/cpp_uno/gcc3_linux_sparc/share.hxx
new file mode 100644
index 000000000000..4316ec314ad7
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_sparc/share.hxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "uno/mapping.h"
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+
+inline char* adjustPointer( char* pIn, typelib_TypeDescription* pType )
+{
+ switch( pType->nSize )
+ {
+ case 1: return pIn + 3;
+ case 2: return pIn + 2;
+ case 3: return pIn + 1;
+ // Huh ? perhaps a char[3] ? Though that would be a pointer
+ // well, we have it anyway for symmetry
+ }
+ return pIn;
+}
+
+}
diff --git a/bridges/source/cpp_uno/gcc3_linux_sparc/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_sparc/uno2cpp.cxx
new file mode 100644
index 000000000000..8384bdc9a76e
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_sparc/uno2cpp.cxx
@@ -0,0 +1,603 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <malloc.h>
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.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 "share.hxx"
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+namespace
+{
+//==================================================================================================
+// 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):
+
+void callVirtualMethod( void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs ) __attribute__((noinline));
+
+void callVirtualMethod( void * pAdjustedThisPtr,
+ sal_Int32 /* nVtableIndex */,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+#if OSL_DEBUG_LEVEL > 0
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs)
+#else
+ sal_Int32 * /*pStackLongs*/,
+ sal_Int32 /*nStackLongs*/)
+#endif
+{
+ // 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 o0 = 0, o1 = 0; // for register returns
+ volatile double f0d = 0;
+ volatile float f0f = 0;
+ volatile long long saveReg[7];
+
+ __asm__ (
+ // save registers
+ "std %%l0, [%4]\n\t"
+ "mov %4, %%l0\n\t"
+ "mov %%l0, %%l1\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%l2, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%l4, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%o0, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%o2, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%o4, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%l6, [%%l0]\n\t"
+ "mov %%l1, %%l7\n\t"
+
+ // increase our own stackframe if necessary
+ "mov %%sp, %%l3\n\t" // save stack ptr for readjustment
+
+ "subcc %%i5, 7, %%l0\n\t"
+ "ble .LmoveOn\n\t"
+ "nop\n\t"
+
+ "sll %%l0, 2, %%l0\n\t"
+ "add %%l0, 96, %%l0\n\t"
+ "mov %%sp, %%l1\n\t" // old stack ptr
+ "sub %%sp, %%l0, %%l0\n\t" // future stack ptr
+ "andcc %%l0, 7, %%g0\n\t" // align stack to 8
+ "be .LisAligned\n\t"
+ "nop\n\t"
+ "sub %%l0, 4, %%l0\n"
+ ".LisAligned:\n\t"
+ "mov %%l0, %%o5\n\t" // save newly computed stack ptr
+ "add %%g0, 16, %%o4\n"
+
+ // now copy longs down to save register window
+ // and local variables
+ ".LcopyDown:\n\t"
+ "ld [%%l1], %%l2\n\t"
+ "st %%l2,[%%l0]\n\t"
+ "add %%l0, 4, %%l0\n\t"
+ "add %%l1, 4, %%l1\n\t"
+ "subcc %%o4, 1, %%o4\n\t"
+ "bne .LcopyDown\n\t"
+
+ "mov %%o5, %%sp\n\t" // move new stack ptr (hopefully) atomically
+ // while register window is valid in both spaces
+ // (scheduling might hit in copyDown loop)
+
+ "sub %%i5, 7, %%l0\n\t" // copy parameters past the sixth to stack
+ "add %%i4, 28, %%l1\n\t"
+ "add %%sp, 92, %%l2\n"
+ ".LcopyLong:\n\t"
+ "ld [%%l1], %%o0\n\t"
+ "st %%o0, [%%l2]\n\t"
+ "add %%l1, 4, %%l1\n\t"
+ "add %%l2, 4, %%l2\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "bne .LcopyLong\n\t"
+ "nop\n"
+
+ ".LmoveOn:\n\t"
+ "mov %%i5, %%l0\n\t" // prepare out registers
+ "mov %%i4, %%l1\n\t"
+
+ "ld [%%l1], %%o0\n\t" // prepare complex return ptr
+ "st %%o0, [%%sp+64]\n\t"
+ "sub %%l0, 1, %%l0\n\t"
+ "add %%l1, 4, %%l1\n\t"
+
+ "ld [%%l1], %%o0\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o1\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o2\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o3\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o4\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o5\n"
+
+ ".LdoCall:\n\t"
+ "ld [%%i0], %%l0\n\t" // get vtable ptr
+
+"sll %%i1, 2, %%l6\n\t"
+// "add %%l6, 8, %%l6\n\t"
+ "add %%l6, %%l0, %%l0\n\t"
+// // vtable has 8byte wide entries,
+// // upper half contains 2 half words, of which the first
+// // is the this ptr patch !
+// // first entry is (or __tf)
+
+// "ldsh [%%l0], %%l6\n\t" // load this ptr patch
+// "add %%l6, %%o0, %%o0\n\t" // patch this ptr
+
+// "add %%l0, 4, %%l0\n\t" // get virtual function ptr
+ "ld [%%l0], %%l0\n\t"
+
+ "ld [%%i4], %%l2\n\t"
+ "subcc %%l2, %%g0, %%l2\n\t"
+ "bne .LcomplexCall\n\t"
+ "nop\n\t"
+ "call %%l0\n\t"
+ "nop\n\t"
+ "ba .LcallReturned\n\t"
+ "nop\n"
+ ".LcomplexCall:\n\t"
+ "call %%l0\n\t"
+ "nop\n\t"
+ "unimp\n"
+
+ ".LcallReturned:\n\t"
+ "mov %%l3, %%sp\n\t" // readjust stack so that our locals are where they belong
+ "st %%o0, %0\n\t" // save possible return registers into our locals
+ "st %%o1, %1\n\t"
+ "std %%f0, %2\n\t"
+ "st %%f0, %3\n\t"
+
+ // restore registers
+ "ldd [%%l7], %%l0\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%l2\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%l4\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%o0\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%o2\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%o4\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%l6\n\t"
+ : :
+ "m"(o0),
+ "m"(o1),
+ "m"(f0d),
+ "m"(f0f),
+ "r"(&saveReg[0])
+ );
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = o1;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = o0;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = (unsigned short)o0;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)o0;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = f0f;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = f0d;
+ break;
+ default:
+ break;
+ }
+}
+
+//=================================================================================================
+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, this, values|ptr ...
+ char * pCppStack =
+ (char *)alloca( (nParams+2) * sizeof(sal_Int64) );
+ 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
+ *(void**)pCppStack = NULL;
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack = (bridges::cpp_uno::shared::relatesToInterfaceType(pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ }
+ 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
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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 ))
+ {
+ pCppArgs[ nPos ] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack, pParamTypeDescr );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ OSL_ASSERT( sizeof (double) == sizeof (sal_Int64) );
+ *reinterpret_cast< sal_Int32 * >(pCppStack) =
+ *reinterpret_cast< sal_Int32 const * >(pUnoArgs[ nPos ]);
+ pCppStack += sizeof (sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(pCppStack) =
+ *(reinterpret_cast< sal_Int32 const * >(pUnoArgs[ nPos ] ) + 1);
+ break;
+ default:
+ uno_copyAndConvertData(
+ pCppArgs[nPos], pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ 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 );
+ 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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
+ {
+ int nStackLongs = (pCppStack - pCppStackStart)/sizeof(sal_Int32);
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic" );
+
+ if( nStackLongs & 1 )
+ // stack has to be 8 byte aligned
+ nStackLongs++;
+ callVirtualMethod(
+ pAdjustedThisPtr,
+ aVtableSlot.index,
+ pCppReturn,
+ pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart,
+ nStackLongs);
+ // NO exception occured...
+ *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 );
+
+ 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( ... )
+ {
+ // get exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+#if defined BRIDGES_DEBUG
+ OString cstr( OUStringToOString( pMemberDescr->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "received dispatch( %s )\n", cstr.getStr() );
+#endif
+
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+// typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx
new file mode 100644
index 000000000000..ad0faa1a01aa
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx
@@ -0,0 +1,806 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: abi.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+// This is an implementation of the x86-64 ABI as described in 'System V
+// Application Binary Interface, AMD64 Architecture Processor Supplement'
+// (http://www.x86-64.org/documentation/abi-0.95.pdf)
+//
+// The code in this file is a modification of src/x86/ffi64.c from libffi
+// (http://sources.redhat.com/libffi/) which is under the following license:
+
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 2002 Bo Thorsen <bo@suse.de>
+
+ x86-64 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <abi.hxx>
+
+#include <rtl/ustring.hxx>
+
+using namespace x86_64;
+
+typedef struct
+{
+ /* Registers for argument passing. */
+ long gpr[MAX_GPR_REGS];
+ __int128_t sse[MAX_SSE_REGS];
+
+ /* Stack space for arguments. */
+ char argspace[0];
+} stackLayout;
+
+/* Register class used for passing given 64bit part of the argument.
+ These represent classes as documented by the PS ABI, with the exception
+ of SSESF, SSEDF classes, that are basically SSE class, just gcc will
+ use SF or DFmode move instead of DImode to avoid reformating penalties.
+
+ Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
+ whenever possible (upper half does contain padding).
+ */
+enum x86_64_reg_class
+{
+ X86_64_NO_CLASS,
+ X86_64_INTEGER_CLASS,
+ X86_64_INTEGERSI_CLASS,
+ X86_64_SSE_CLASS,
+ X86_64_SSESF_CLASS,
+ X86_64_SSEDF_CLASS,
+ X86_64_SSEUP_CLASS,
+ X86_64_X87_CLASS,
+ X86_64_X87UP_CLASS,
+ X86_64_MEMORY_CLASS
+};
+
+#define MAX_CLASSES 4
+
+#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
+
+/* x86-64 register passing implementation. See x86-64 ABI for details. Goal
+ of this code is to classify each 8bytes of incoming argument by the register
+ class and assign registers accordingly. */
+
+/* Return the union class of CLASS1 and CLASS2.
+ See the x86-64 PS ABI for details. */
+
+static enum x86_64_reg_class
+merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
+{
+ /* Rule #1: If both classes are equal, this is the resulting class. */
+ if (class1 == class2)
+ return class1;
+
+ /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
+ the other class. */
+ if (class1 == X86_64_NO_CLASS)
+ return class2;
+ if (class2 == X86_64_NO_CLASS)
+ return class1;
+
+ /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
+ if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
+ return X86_64_MEMORY_CLASS;
+
+ /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
+ if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
+ || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
+ return X86_64_INTEGERSI_CLASS;
+ if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
+ || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
+ return X86_64_INTEGER_CLASS;
+
+ /* Rule #5: If one of the classes is X87 or X87UP class, MEMORY is used. */
+ if (class1 == X86_64_X87_CLASS || class1 == X86_64_X87UP_CLASS
+ || class2 == X86_64_X87_CLASS || class2 == X86_64_X87UP_CLASS)
+ return X86_64_MEMORY_CLASS;
+
+ /* Rule #6: Otherwise class SSE is used. */
+ return X86_64_SSE_CLASS;
+}
+
+/* Classify the argument of type TYPE and mode MODE.
+ CLASSES will be filled by the register class used to pass each word
+ of the operand. The number of words is returned. In case the parameter
+ should be passed in memory, 0 is returned. As a special case for zero
+ sized containers, classes[0] will be NO_CLASS and 1 is returned.
+
+ See the x86-64 PS ABI for details.
+*/
+static int
+classify_argument( typelib_TypeDescriptionReference *pTypeRef, enum x86_64_reg_class classes[], int &rByteOffset )
+{
+ /* First, align to the right place. */
+ rByteOffset = ALIGN( rByteOffset, pTypeRef->pType->nAlignment );
+
+ switch ( pTypeRef->eTypeClass )
+ {
+ case typelib_TypeClass_VOID:
+ classes[0] = X86_64_NO_CLASS;
+ return 1;
+ 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:
+ if ( ( rByteOffset % 8 + pTypeRef->pType->nSize ) <= 4 )
+ classes[0] = X86_64_INTEGERSI_CLASS;
+ else
+ classes[0] = X86_64_INTEGER_CLASS;
+ return 1;
+ case typelib_TypeClass_FLOAT:
+ if ( ( rByteOffset % 8 ) == 0 )
+ classes[0] = X86_64_SSESF_CLASS;
+ else
+ classes[0] = X86_64_SSE_CLASS;
+ return 1;
+ case typelib_TypeClass_DOUBLE:
+ classes[0] = X86_64_SSEDF_CLASS;
+ return 1;
+ /*case LONGDOUBLE:
+ classes[0] = X86_64_X87_CLASS;
+ classes[1] = X86_64_X87UP_CLASS;
+ return 2;*/
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_TYPEDEF:
+ case typelib_TypeClass_UNION:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_ARRAY:
+ case typelib_TypeClass_INTERFACE:
+ return 0;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+ const int UNITS_PER_WORD = 8;
+ int words = ( pTypeDescr->nSize + UNITS_PER_WORD - 1 ) / UNITS_PER_WORD;
+ enum x86_64_reg_class subclasses[MAX_CLASSES];
+
+ /* If the struct is larger than 16 bytes, pass it on the stack. */
+ if ( pTypeDescr->nSize > 16 )
+ {
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ return 0;
+ }
+
+ for ( int i = 0; i < words; i++ )
+ classes[i] = X86_64_NO_CLASS;
+
+ const typelib_CompoundTypeDescription *pStruct = reinterpret_cast<const typelib_CompoundTypeDescription*>( pTypeDescr );
+
+ /* Merge the fields of structure. */
+ for ( sal_Int32 nMember = 0; nMember < pStruct->nMembers; ++nMember )
+ {
+ typelib_TypeDescriptionReference *pTypeInStruct = pStruct->ppTypeRefs[ nMember ];
+ rByteOffset = pStruct->pMemberOffsets[ nMember ];
+
+ int num = classify_argument( pTypeInStruct, subclasses, rByteOffset );
+
+ if ( num == 0 )
+ {
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ return 0;
+ }
+
+ for ( int i = 0; i < num; i++ )
+ {
+ int pos = rByteOffset / 8;
+ classes[i + pos] = merge_classes( subclasses[i], classes[i + pos] );
+ }
+ }
+
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+
+ /* Final merger cleanup. */
+ for ( int i = 0; i < words; i++ )
+ {
+ /* If one class is MEMORY, everything should be passed in
+ memory. */
+ if ( classes[i] == X86_64_MEMORY_CLASS )
+ return 0;
+
+ /* The X86_64_SSEUP_CLASS should be always preceded by
+ X86_64_SSE_CLASS. */
+ if ( classes[i] == X86_64_SSEUP_CLASS
+ && ( i == 0 || classes[i - 1] != X86_64_SSE_CLASS ) )
+ classes[i] = X86_64_SSE_CLASS;
+
+ /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */
+ if ( classes[i] == X86_64_X87UP_CLASS
+ && ( i == 0 || classes[i - 1] != X86_64_X87_CLASS ) )
+ classes[i] = X86_64_SSE_CLASS;
+ }
+ return words;
+ }
+
+ default:
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "Unhandled case: pType->eTypeClass == %d\n", pTypeRef->eTypeClass );
+#endif
+ OSL_ASSERT(0);
+ }
+ return 0; /* Never reached. */
+}
+
+/* Examine the argument and return set number of register required in each
+ class. Return 0 iff parameter should be passed in memory. */
+bool x86_64::examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedSSE )
+{
+ enum x86_64_reg_class classes[MAX_CLASSES];
+ int offset = 0;
+ int n;
+
+ n = classify_argument( pTypeRef, classes, offset );
+
+ if ( n == 0 )
+ return false;
+
+ nUsedGPR = 0;
+ nUsedSSE = 0;
+ for ( n--; n >= 0; n-- )
+ switch ( classes[n] )
+ {
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ nUsedGPR++;
+ break;
+ case X86_64_SSE_CLASS:
+ case X86_64_SSESF_CLASS:
+ case X86_64_SSEDF_CLASS:
+ nUsedSSE++;
+ break;
+ case X86_64_NO_CLASS:
+ case X86_64_SSEUP_CLASS:
+ break;
+ case X86_64_X87_CLASS:
+ case X86_64_X87UP_CLASS:
+ if ( !bInReturn )
+ return false;
+ break;
+ default:
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "Unhandled case: classes[n] == %d\n", classes[n] );
+#endif
+ OSL_ASSERT(0);
+ }
+ return true;
+}
+
+bool x86_64::return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
+{
+ int g, s;
+
+ return examine_argument( pTypeRef, true, g, s ) == 0;
+}
+
+void x86_64::fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64 *pGPR, const double *pSSE, void *pStruct )
+{
+ enum x86_64_reg_class classes[MAX_CLASSES];
+ int offset = 0;
+ int n;
+
+ n = classify_argument( pTypeRef, classes, offset );
+
+ sal_uInt64 *pStructAlign = reinterpret_cast<sal_uInt64 *>( pStruct );
+ for ( n--; n >= 0; n-- )
+ switch ( classes[n] )
+ {
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ *pStructAlign++ = *pGPR++;
+ break;
+ case X86_64_SSE_CLASS:
+ case X86_64_SSESF_CLASS:
+ case X86_64_SSEDF_CLASS:
+ *pStructAlign++ = *reinterpret_cast<const sal_uInt64 *>( pSSE++ );
+ break;
+ default:
+ break;
+ }
+}
+
+#if 0
+
+/* Functions to load floats and double to an SSE register placeholder. */
+extern void float2sse (float, __int128_t *);
+extern void double2sse (double, __int128_t *);
+extern void floatfloat2sse (void *, __int128_t *);
+
+/* Functions to put the floats and doubles back. */
+extern float sse2float (__int128_t *);
+extern double sse2double (__int128_t *);
+extern void sse2floatfloat(__int128_t *, void *);
+
+/*@-exportheader@*/
+void
+ffi_prep_args (stackLayout *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+ int gprcount, ssecount, i, g, s;
+ void **p_argv;
+ void *argp = &stack->argspace;
+ ffi_type **p_arg;
+
+ /* First check if the return value should be passed in memory. If so,
+ pass the pointer as the first argument. */
+ gprcount = ssecount = 0;
+ if (ecif->cif->rtype->type != FFI_TYPE_VOID
+ && examine_argument (ecif->cif->rtype, 1, &g, &s) == 0)
+ (void *)stack->gpr[gprcount++] = ecif->rvalue;
+
+ for (i=ecif->cif->nargs, p_arg=ecif->cif->arg_types, p_argv = ecif->avalue;
+ i!=0; i--, p_arg++, p_argv++)
+ {
+ int in_register = 0;
+
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_POINTER:
+ if (gprcount < MAX_GPR_REGS)
+ {
+ stack->gpr[gprcount] = 0;
+ stack->gpr[gprcount++] = *(long long *)(*p_argv);
+ in_register = 1;
+ }
+ break;
+
+ case FFI_TYPE_FLOAT:
+ if (ssecount < MAX_SSE_REGS)
+ {
+ float2sse (*(float *)(*p_argv), &stack->sse[ssecount++]);
+ in_register = 1;
+ }
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ if (ssecount < MAX_SSE_REGS)
+ {
+ double2sse (*(double *)(*p_argv), &stack->sse[ssecount++]);
+ in_register = 1;
+ }
+ break;
+ }
+
+ if (in_register)
+ continue;
+
+ /* Either all places in registers where filled, or this is a
+ type that potentially goes into a memory slot. */
+ if (examine_argument (*p_arg, 0, &g, &s) == 0
+ || gprcount + g > MAX_GPR_REGS || ssecount + s > MAX_SSE_REGS)
+ {
+ /* Pass this argument in memory. */
+ argp = (void *)ALIGN(argp, (*p_arg)->alignment);
+ memcpy (argp, *p_argv, (*p_arg)->size);
+ argp += (*p_arg)->size;
+ }
+ else
+ {
+ /* All easy cases are eliminated. Now fire the big guns. */
+
+ enum x86_64_reg_class classes[MAX_CLASSES];
+ int offset = 0, j, num;
+ void *a;
+
+ num = classify_argument (*p_arg, classes, &offset);
+ for (j=0, a=*p_argv; j<num; j++, a+=8)
+ {
+ switch (classes[j])
+ {
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ stack->gpr[gprcount++] = *(long long *)a;
+ break;
+ case X86_64_SSE_CLASS:
+ floatfloat2sse (a, &stack->sse[ssecount++]);
+ break;
+ case X86_64_SSESF_CLASS:
+ float2sse (*(float *)a, &stack->sse[ssecount++]);
+ break;
+ case X86_64_SSEDF_CLASS:
+ double2sse (*(double *)a, &stack->sse[ssecount++]);
+ break;
+ default:
+ abort();
+ }
+ }
+ }
+ }
+}
+
+/* Perform machine dependent cif processing. */
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+ int gprcount, ssecount, i, g, s;
+
+ gprcount = ssecount = 0;
+
+ /* Reset the byte count. We handle this size estimation here. */
+ cif->bytes = 0;
+
+ /* If the return value should be passed in memory, pass the pointer
+ as the first argument. The actual memory isn't allocated here. */
+ if (cif->rtype->type != FFI_TYPE_VOID
+ && examine_argument (cif->rtype, 1, &g, &s) == 0)
+ gprcount = 1;
+
+ /* Go over all arguments and determine the way they should be passed.
+ If it's in a register and there is space for it, let that be so. If
+ not, add it's size to the stack byte count. */
+ for (i=0; i<cif->nargs; i++)
+ {
+ if (examine_argument (cif->arg_types[i], 0, &g, &s) == 0
+ || gprcount + g > MAX_GPR_REGS || ssecount + s > MAX_SSE_REGS)
+ {
+ /* This is passed in memory. First align to the basic type. */
+ cif->bytes = ALIGN(cif->bytes, cif->arg_types[i]->alignment);
+
+ /* Stack arguments are *always* at least 8 byte aligned. */
+ cif->bytes = ALIGN(cif->bytes, 8);
+
+ /* Now add the size of this argument. */
+ cif->bytes += cif->arg_types[i]->size;
+ }
+ else
+ {
+ gprcount += g;
+ ssecount += s;
+ }
+ }
+
+ /* Set the flag for the closures return. */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_STRUCT:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ case FFI_TYPE_LONGDOUBLE:
+ cif->flags = (unsigned) cif->rtype->type;
+ break;
+
+ case FFI_TYPE_UINT64:
+ cif->flags = FFI_TYPE_SINT64;
+ break;
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+typedef struct
+{
+ long gpr[2];
+ __int128_t sse[2];
+ long double st0;
+} return_value;
+
+//#endif
+
+void
+ffi_fill_return_value (return_value *rv, extended_cif *ecif)
+{
+ enum x86_64_reg_class classes[MAX_CLASSES];
+ int i = 0, num;
+ long *gpr = rv->gpr;
+ __int128_t *sse = rv->sse;
+ signed char sc;
+ signed short ss;
+
+ /* This is needed because of the way x86-64 handles signed short
+ integers. */
+ switch (ecif->cif->rtype->type)
+ {
+ case FFI_TYPE_SINT8:
+ sc = *(signed char *)gpr;
+ *(long long *)ecif->rvalue = (long long)sc;
+ return;
+ case FFI_TYPE_SINT16:
+ ss = *(signed short *)gpr;
+ *(long long *)ecif->rvalue = (long long)ss;
+ return;
+ default:
+ /* Just continue. */
+ ;
+ }
+
+ num = classify_argument (ecif->cif->rtype, classes, &i);
+
+ if (num == 0)
+ /* Return in memory. */
+ ecif->rvalue = (void *) rv->gpr[0];
+ else if (num == 2 && classes[0] == X86_64_X87_CLASS &&
+ classes[1] == X86_64_X87UP_CLASS)
+ /* This is a long double (this is easiest to handle this way instead
+ of an eightbyte at a time as in the loop below. */
+ *((long double *)ecif->rvalue) = rv->st0;
+ else
+ {
+ void *a;
+
+ for (i=0, a=ecif->rvalue; i<num; i++, a+=8)
+ {
+ switch (classes[i])
+ {
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ *(long long *)a = *gpr;
+ gpr++;
+ break;
+ case X86_64_SSE_CLASS:
+ sse2floatfloat (sse++, a);
+ break;
+ case X86_64_SSESF_CLASS:
+ *(float *)a = sse2float (sse++);
+ break;
+ case X86_64_SSEDF_CLASS:
+ *(double *)a = sse2double (sse++);
+ break;
+ default:
+ abort();
+ }
+ }
+ }
+}
+
+//#if 0
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_UNIX64(void (*)(stackLayout *, extended_cif *),
+ void (*) (return_value *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, /*@out@*/ unsigned *, void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+ int dummy;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) &&
+ (examine_argument (cif->rtype, 1, &dummy, &dummy) == 0))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+ /* Stack must always be 16byte aligned. Make it so. */
+ cif->bytes = ALIGN(cif->bytes, 16);
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /* Calling 32bit code from 64bit is not possible */
+ FFI_ASSERT(0);
+ break;
+
+ case FFI_UNIX64:
+ /*@-usedef@*/
+ ffi_call_UNIX64 (ffi_prep_args, ffi_fill_return_value, &ecif,
+ cif->bytes, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+extern void ffi_closure_UNIX64(void);
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*, void*, void**, void*),
+ void *user_data)
+{
+ volatile unsigned short *tramp;
+
+ /* FFI_ASSERT (cif->abi == FFI_OSF); */
+
+ tramp = (volatile unsigned short *) &closure->tramp[0];
+ tramp[0] = 0xbb49; /* mov <code>, %r11 */
+ tramp[5] = 0xba49; /* mov <data>, %r10 */
+ tramp[10] = 0xff49; /* jmp *%r11 */
+ tramp[11] = 0x00e3;
+ *(void * volatile *) &tramp[1] = ffi_closure_UNIX64;
+ *(void * volatile *) &tramp[6] = closure;
+
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
+
+ return FFI_OK;
+}
+
+int
+ffi_closure_UNIX64_inner(ffi_closure *closure, va_list l, void *rp)
+{
+ ffi_cif *cif;
+ void **avalue;
+ ffi_type **arg_types;
+ long i, avn, argn;
+
+ cif = closure->cif;
+ avalue = alloca(cif->nargs * sizeof(void *));
+
+ argn = 0;
+
+ i = 0;
+ avn = cif->nargs;
+ arg_types = cif->arg_types;
+
+ /* Grab the addresses of the arguments from the stack frame. */
+ while (i < avn)
+ {
+ switch (arg_types[i]->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_POINTER:
+ {
+ if (l->gp_offset > 48-8)
+ {
+ avalue[i] = l->overflow_arg_area;
+ l->overflow_arg_area = (char *)l->overflow_arg_area + 8;
+ }
+ else
+ {
+ avalue[i] = (char *)l->reg_save_area + l->gp_offset;
+ l->gp_offset += 8;
+ }
+ }
+ break;
+
+ case FFI_TYPE_STRUCT:
+ /* FIXME */
+ FFI_ASSERT(0);
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ {
+ if (l->fp_offset > 176-16)
+ {
+ avalue[i] = l->overflow_arg_area;
+ l->overflow_arg_area = (char *)l->overflow_arg_area + 8;
+ }
+ else
+ {
+ avalue[i] = (char *)l->reg_save_area + l->fp_offset;
+ l->fp_offset += 16;
+ }
+ }
+#if DEBUG_FFI
+ fprintf (stderr, "double arg %d = %g\n", i, *(double *)avalue[i]);
+#endif
+ break;
+
+ case FFI_TYPE_FLOAT:
+ {
+ if (l->fp_offset > 176-16)
+ {
+ avalue[i] = l->overflow_arg_area;
+ l->overflow_arg_area = (char *)l->overflow_arg_area + 8;
+ }
+ else
+ {
+ avalue[i] = (char *)l->reg_save_area + l->fp_offset;
+ l->fp_offset += 16;
+ }
+ }
+#if DEBUG_FFI
+ fprintf (stderr, "float arg %d = %g\n", i, *(float *)avalue[i]);
+#endif
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+
+ argn += ALIGN(arg_types[i]->size, SIZEOF_ARG) / SIZEOF_ARG;
+ i++;
+ }
+
+ /* Invoke the closure. */
+ (closure->fun) (cif, rp, avalue, closure->user_data);
+
+ /* FIXME: Structs not supported. */
+ FFI_ASSERT(cif->rtype->type != FFI_TYPE_STRUCT);
+
+ /* Tell ffi_closure_UNIX64 how to perform return type promotions. */
+
+ return cif->rtype->type;
+}
+
+#endif
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx
new file mode 100644
index 000000000000..c5b7d94d2e01
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: abi.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
+#define _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
+
+// This is an implementation of the x86-64 ABI as described in 'System V
+// Application Binary Interface, AMD64 Architecture Processor Supplement'
+// (http://www.x86-64.org/documentation/abi-0.95.pdf)
+
+#include <typelib/typedescription.hxx>
+
+namespace x86_64
+{
+
+/* 6 general purpose registers are used for parameter passing */
+const sal_uInt32 MAX_GPR_REGS = 6;
+
+/* 8 SSE registers are used for parameter passing */
+const sal_uInt32 MAX_SSE_REGS = 8;
+
+/* Count number of required registers.
+
+ Examine the argument and return set number of register required in each
+ class.
+
+ Return false iff parameter should be passed in memory.
+*/
+bool examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedSSE );
+
+/** Does function that returns this type use a hidden parameter, or registers?
+
+ The value can be returned either in a hidden 1st parameter (which is a
+ pointer to a structure allocated by the caller), or in registers (rax, rdx
+ for the integers, xmm0, xmm1 for the floating point numbers).
+*/
+bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
+
+void fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64* pGPR, const double* pSSE, void *pStruct );
+
+} // namespace x86_64
+
+#endif // _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/call.s b/bridges/source/cpp_uno/gcc3_linux_x86-64/call.s
new file mode 100644
index 000000000000..a0572ef61641
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/call.s
@@ -0,0 +1,96 @@
+ .text
+ .align 2
+.globl privateSnippetExecutor
+ .type privateSnippetExecutor, @function
+privateSnippetExecutor:
+.LFB3:
+ pushq %rbp
+.LCFI0:
+ movq %rsp, %rbp
+.LCFI1:
+ subq $160, %rsp
+.LCFI2:
+ movq %r10, -152(%rbp) # Save (nVtableOffset << 32) + nFunctionIndex
+
+ movq %rdi, -112(%rbp) # Save GP registers
+ movq %rsi, -104(%rbp)
+ movq %rdx, -96(%rbp)
+ movq %rcx, -88(%rbp)
+ movq %r8 , -80(%rbp)
+ movq %r9 , -72(%rbp)
+
+ movsd %xmm0, -64(%rbp) # Save FP registers
+ movsd %xmm1, -56(%rbp)
+ movsd %xmm2, -48(%rbp)
+ movsd %xmm3, -40(%rbp)
+ movsd %xmm4, -32(%rbp)
+ movsd %xmm5, -24(%rbp)
+ movsd %xmm6, -16(%rbp)
+ movsd %xmm7, -8(%rbp)
+
+ leaq -144(%rbp), %r9 # 6th param: sal_uInt64 * pRegisterReturn
+ leaq 16(%rbp), %r8 # 5rd param: void ** ovrflw
+ leaq -64(%rbp), %rcx # 4th param: void ** fpreg
+ leaq -112(%rbp), %rdx # 3rd param: void ** gpreg
+ movl -148(%rbp), %esi # 2nd param: sal_int32 nVtableOffset
+ movl -152(%rbp), %edi # 1st param: sal_int32 nFunctionIndex
+
+ call cpp_vtable_call
+
+ cmp $10, %rax # typelib_TypeClass_FLOAT
+ je .Lfloat
+ cmp $11, %rax # typelib_TypeClass_DOUBLE
+ je .Lfloat
+
+ movq -144(%rbp), %rax # Return value (int case)
+ movq -136(%rbp), %rdx # Return value (int case)
+ movq -144(%rbp), %xmm0 # Return value (int case)
+ movq -136(%rbp), %xmm1 # Return value (int case)
+ jmp .Lfinish
+.Lfloat:
+ movlpd -144(%rbp), %xmm0 # Return value (float/double case)
+
+.Lfinish:
+ leave
+ ret
+.LFE3:
+ .size privateSnippetExecutor, .-privateSnippetExecutor
+ .section .eh_frame,"a",@progbits
+.Lframe1:
+ .long .LECIE1-.LSCIE1
+.LSCIE1:
+ .long 0x0
+ .byte 0x1
+ .string "zR"
+ .uleb128 0x1
+ .sleb128 -8
+ .byte 0x10
+ .uleb128 0x1
+ .byte 0x1b
+ .byte 0xc
+ .uleb128 0x7
+ .uleb128 0x8
+ .byte 0x90
+ .uleb128 0x1
+ .align 8
+.LECIE1:
+.LSFDE1:
+ .long .LEFDE1-.LASFDE1
+.LASFDE1:
+ .long .LASFDE1-.Lframe1
+ .long .LFB3-.
+ .long .LFE3-.LFB3
+ .uleb128 0x0
+ .byte 0x4
+ .long .LCFI0-.LFB3
+ .byte 0xe
+ .uleb128 0x10
+ .byte 0x86
+ .uleb128 0x2
+ .byte 0x4
+ .long .LCFI1-.LCFI0
+ .byte 0xd
+ .uleb128 0x6
+ .align 8
+.LEFDE1:
+ .section .note.GNU-stack,"",@progbits
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx
new file mode 100644
index 000000000000..c1e938446e77
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx
@@ -0,0 +1,525 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <hash_map>
+
+#include <rtl/alloc.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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 "abi.hxx"
+#include "share.hxx"
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+//==================================================================================================
+
+// Perform the UNO call
+//
+// We must convert the paramaters stored in gpreg, fpreg and ovrflw to UNO
+// arguments and call pThis->getUnoI()->pDispatcher.
+//
+// gpreg: [ret *], this, [gpr params]
+// fpreg: [fpr params]
+// ovrflw: [gpr or fpr params (properly aligned)]
+//
+// [ret *] is present when we are returning a structure bigger than 16 bytes
+// Simple types are returned in rax, rdx (int), or xmm0, xmm1 (fp).
+// Similarly structures <= 16 bytes are in rax, rdx, xmm0, xmm1 as necessary.
+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 */ )
+{
+ unsigned int nr_gpr = 0; //number of gpr registers used
+ unsigned int nr_fpr = 0; //number of fpr registers used
+
+ // 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 ( x86_64::return_in_hidden_param( pReturnTypeRef ) )
+ {
+ pCppReturn = *gpreg++;
+ nr_gpr++;
+
+ pUnoReturn = ( bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn ); // direct way
+ }
+ else
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+
+ // pop this
+ gpreg++;
+ nr_gpr++;
+
+ // stack space
+ // 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 );
+
+ int nUsedGPR = 0;
+ int nUsedSSE = 0;
+#if OSL_DEBUG_LEVEL > 1
+ bool bFitsRegisters =
+#endif
+ x86_64::examine_argument( rParam.pTypeRef, false, nUsedGPR, nUsedSSE );
+ if ( !rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ) ) // value
+ {
+ // Simple types must fit exactly one register on x86_64
+ OSL_ASSERT( bFitsRegisters && ( ( nUsedSSE == 1 && nUsedGPR == 0 ) || ( nUsedSSE == 0 && nUsedGPR == 1 ) ) );
+
+ if ( nUsedSSE == 1 )
+ {
+ if ( nr_fpr < x86_64::MAX_SSE_REGS )
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
+ nr_fpr++;
+ }
+ else
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
+ }
+ else if ( nUsedGPR == 1 )
+ {
+ if ( nr_gpr < x86_64::MAX_GPR_REGS )
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
+ nr_gpr++;
+ }
+ else
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // struct <= 16 bytes || ptr to complex value || ref
+ {
+ void *pCppStack;
+ if ( nr_gpr < x86_64::MAX_GPR_REGS )
+ {
+ pCppArgs[nPos] = pCppStack = *gpreg++;
+ nr_gpr++;
+ }
+ else
+ pCppArgs[nPos] = pCppStack = *ovrflw++;
+
+ 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;
+ }
+ else if ( bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ) ) // is in/inout
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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] = pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+ // 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 occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if ( pReturnTypeDescr )
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+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 */ )
+{
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+ void * pThis;
+ if ( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+ }
+ else
+ {
+ pThis = gpreg[0];
+ }
+ 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!\n" );
+ if ( nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex )
+ {
+ throw RuntimeException( OUString::createFromAscii("illegal vtable index!"),
+ reinterpret_cast<XInterface *>( pCppI ) );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!\n" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch ( aMemberDescr.get()->eTypeClass )
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ typelib_TypeDescriptionReference *pAttrTypeRef =
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( aMemberDescr.get() )->pAttributeTypeRef;
+
+ if ( pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex )
+ {
+ // is GET method
+ eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef = pAttrTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch ( nFunctionIndex )
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast<Type *>( gpreg[2] )->getTypeLibType() );
+ if ( pTD )
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
+ ( pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface,
+ pCppI->getOid().pData,
+ reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
+
+ if ( pInterface )
+ {
+ ::uno_any_construct( reinterpret_cast<uno_Any *>( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+
+ reinterpret_cast<void **>( pRegisterReturn )[0] = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ {
+ typelib_InterfaceMethodTypeDescription *pMethodTD =
+ reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( aMemberDescr.get() );
+
+ eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
+ pMethodTD->pReturnTypeRef,
+ pMethodTD->nParams,
+ pMethodTD->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException( OUString::createFromAscii("no member description found!"),
+ reinterpret_cast<XInterface *>( pCppI ) );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+extern "C" void privateSnippetExecutor( ... );
+
+const int codeSnippetSize = 24;
+
+// Generate a trampoline that redirects method calls to
+// privateSnippetExecutor().
+//
+// privateSnippetExecutor() saves all the registers that are used for
+// parameter passing on x86_64, and calls the cpp_vtable_call().
+// When it returns, privateSnippetExecutor() sets the return value.
+//
+// Note: The code snippet we build here must not create a stack frame,
+// otherwise the UNO exceptions stop working thanks to non-existing
+// unwinding info.
+unsigned char * codeSnippet( unsigned char * code,
+ sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ bool bHasHiddenParam ) SAL_THROW( () )
+{
+ sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
+
+ if ( bHasHiddenParam )
+ nOffsetAndIndex |= 0x80000000;
+
+ // movq $<nOffsetAndIndex>, %r10
+ *reinterpret_cast<sal_uInt16 *>( code ) = 0xba49;
+ *reinterpret_cast<sal_uInt64 *>( code + 2 ) = nOffsetAndIndex;
+
+ // movq $<address of the privateSnippetExecutor>, %r11
+ *reinterpret_cast<sal_uInt16 *>( code + 10 ) = 0xbb49;
+ *reinterpret_cast<sal_uInt64 *>( code + 12 ) = reinterpret_cast<sal_uInt64>( privateSnippetExecutor );
+
+ // jmpq *%r11
+ *reinterpret_cast<sal_uInt32 *>( code + 20 ) = 0x00e3ff49;
+
+ 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, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 nFunctionOffset,
+ sal_Int32 functionCount, sal_Int32 nVtableOffset )
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for ( sal_Int32 nPos = 0; nPos < type->nMembers; ++nPos )
+ {
+ typelib_TypeDescription * pTD = 0;
+
+ TYPELIB_DANGER_GET( &pTD, type->ppMembers[ nPos ] );
+ OSL_ASSERT( pTD );
+
+ if ( typelib_TypeClass_INTERFACE_ATTRIBUTE == pTD->eTypeClass )
+ {
+ typelib_InterfaceAttributeTypeDescription *pAttrTD =
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
+
+ // get method
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
+ x86_64::return_in_hidden_param( pAttrTD->pAttributeTypeRef ) );
+
+ if ( ! pAttrTD->bReadOnly )
+ {
+ // set method
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet( code, nFunctionOffset++, nVtableOffset, false );
+ }
+ }
+ else if ( typelib_TypeClass_INTERFACE_METHOD == pTD->eTypeClass )
+ {
+ typelib_InterfaceMethodTypeDescription *pMethodTD =
+ reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD );
+
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
+ x86_64::return_in_hidden_param( pMethodTD->pReturnTypeRef ) );
+ }
+ else
+ OSL_ASSERT( false );
+
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ return code;
+}
+
+//==================================================================================================
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *, unsigned char const * )
+{
+}
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx
new file mode 100644
index 000000000000..e4862e8bc83a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx
@@ -0,0 +1,333 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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 iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind2( m_generatedRttis.find( unoName ) );
+ if (iFind2 == 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() +4;
+#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 = iFind2->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 occured: %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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, 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 occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_x86-64/makefile.mk
new file mode 100644
index 000000000000..9b16f4ab5944
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/makefile.mk
@@ -0,0 +1,84 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.9 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCLINUXXgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer
+
+SLOFILES= \
+ $(SLO)$/abi.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+ $(CC) -c -o $(SLO)$/$(@:b).o $<
+ touch $@
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx
new file mode 100644
index 000000000000..1a171ffe08a2
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx
new file mode 100644
index 000000000000..23c40121afb7
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx
@@ -0,0 +1,574 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rtl/alloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.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 "abi.hxx"
+#include "share.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+//==================================================================================================
+static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
+ sal_uInt64 *pStack, sal_uInt32 nStack,
+ sal_uInt64 *pGPR, sal_uInt32 nGPR,
+ double *pFPR, sal_uInt32 nFPR) __attribute__((noinline));
+
+static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
+ sal_uInt64 *pStack, sal_uInt32 nStack,
+ sal_uInt64 *pGPR, sal_uInt32 nGPR,
+ double *pFPR, sal_uInt32 nFPR)
+{
+#if OSL_DEBUG_LEVEL > 1
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
+ for ( unsigned int i = 0; i < nGPR; ++i )
+ fprintf( stderr, "0x%lx, ", pGPR[i] );
+ fprintf( stderr, "\nFPR's (%d): ", nFPR );
+ for ( unsigned int i = 0; i < nFPR; ++i )
+ fprintf( stderr, "%f, ", pFPR[i] );
+ fprintf( stderr, "\nStack (%d): ", nStack );
+ for ( unsigned int i = 0; i < nStack; ++i )
+ fprintf( stderr, "0x%lx, ", pStack[i] );
+ fprintf( stderr, "\n" );
+ }
+#endif
+
+ // 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):
+ if ( !pThis )
+ CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything( "xxx" ); // address something
+
+ // Should not happen, but...
+ if ( nFPR > x86_64::MAX_SSE_REGS )
+ nFPR = x86_64::MAX_SSE_REGS;
+ if ( nGPR > x86_64::MAX_GPR_REGS )
+ nGPR = x86_64::MAX_GPR_REGS;
+
+ // Get pointer to method
+ sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
+ pMethod += 8 * nVtableIndex;
+ pMethod = *((sal_uInt64 *)pMethod);
+
+ // Load parameters to stack, if necessary
+ if ( nStack )
+ {
+ // 16-bytes aligned
+ sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 16;
+ sal_uInt64 *pCallStack = (sal_uInt64 *) __builtin_alloca( nStackBytes );
+ memcpy( pCallStack, pStack, nStackBytes );
+ }
+
+ // Return values
+ sal_uInt64 rax;
+ sal_uInt64 rdx;
+ double xmm0;
+ double xmm1;
+
+ asm volatile (
+
+ // Fill the xmm registers
+ "movq %2, %%rax\n\t"
+
+ "movsd (%%rax), %%xmm0\n\t"
+ "movsd 8(%%rax), %%xmm1\n\t"
+ "movsd 16(%%rax), %%xmm2\n\t"
+ "movsd 24(%%rax), %%xmm3\n\t"
+ "movsd 32(%%rax), %%xmm4\n\t"
+ "movsd 40(%%rax), %%xmm5\n\t"
+ "movsd 48(%%rax), %%xmm6\n\t"
+ "movsd 56(%%rax), %%xmm7\n\t"
+
+ // Fill the general purpose registers
+ "movq %1, %%rax\n\t"
+
+ "movq (%%rax), %%rdi\n\t"
+ "movq 8(%%rax), %%rsi\n\t"
+ "movq 16(%%rax), %%rdx\n\t"
+ "movq 24(%%rax), %%rcx\n\t"
+ "movq 32(%%rax), %%r8\n\t"
+ "movq 40(%%rax), %%r9\n\t"
+
+ // Perform the call
+ "movq %0, %%r11\n\t"
+ "movq %3, %%rax\n\t"
+ "call *%%r11\n\t"
+
+ // Fill the return values
+ "movq %%rax, %4\n\t"
+ "movq %%rdx, %5\n\t"
+ "movsd %%xmm0, %6\n\t"
+ "movsd %%xmm1, %7\n\t"
+ :
+ : "m" ( pMethod ), "m" ( pGPR ), "m" ( pFPR ), "m" ( nFPR ),
+ "m" ( rax ), "m" ( rdx ), "m" ( xmm0 ), "m" ( xmm1 )
+ : "rax", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11"
+ );
+
+ switch (pReturnTypeRef->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = rax;
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt32*>( &rax );
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt16*>( &rax );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt8*>( &rax );
+ break;
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_DOUBLE:
+ *reinterpret_cast<double *>( pRegisterReturn ) = xmm0;
+ break;
+ default:
+ {
+ sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize;
+ if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0)
+ {
+ sal_uInt64 longs[2];
+ longs[0] = rax;
+ longs[1] = rdx;
+
+ double doubles[2];
+ doubles[0] = xmm0;
+ doubles[1] = xmm1;
+ x86_64::fill_struct( pReturnTypeRef, &longs[0], &doubles[0], pRegisterReturn);
+ }
+ break;
+ }
+ }
+}
+
+//==================================================================================================
+
+// Macros for easier insertion of values to registers or stack
+// pSV - pointer to the source
+// nr - order of the value [will be increased if stored to register]
+// pFPR, pGPR - pointer to the registers
+// pDS - pointer to the stack [will be increased if stored here]
+
+// The value in %xmm register is already prepared to be retrieved as a float,
+// thus we treat float and double the same
+#define INSERT_FLOAT_DOUBLE( pSV, nr, pFPR, pDS ) \
+ if ( nr < x86_64::MAX_SSE_REGS ) \
+ pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
+
+#define INSERT_INT64( pSV, nr, pGPR, pDS ) \
+ if ( nr < x86_64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
+ if ( nr < x86_64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
+ if ( nr < x86_64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS ) \
+ if ( nr < x86_64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+//==================================================================================================
+
+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 )
+{
+ // Maxium space for [complex ret ptr], values | ptr ...
+ // (but will be used less - some of the values will be in pGPR and pFPR)
+ sal_uInt64 *pStack = (sal_uInt64 *)__builtin_alloca( (nParams + 3) * sizeof(sal_uInt64) );
+ sal_uInt64 *pStackStart = pStack;
+
+ sal_uInt64 pGPR[x86_64::MAX_GPR_REGS];
+ sal_uInt32 nGPR = 0;
+
+ double pFPR[x86_64::MAX_SSE_REGS];
+ sal_uInt32 nFPR = 0;
+
+ // 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 (see below)
+
+ bool bSimpleReturn = true;
+ if ( pReturnTypeDescr )
+ {
+ if ( x86_64::return_in_hidden_param( pReturnTypeRef ) )
+ bSimpleReturn = false;
+
+ if ( bSimpleReturn )
+ pCppReturn = pUnoReturn; // direct way for simple types
+ else
+ {
+ // complex return via ptr
+ pCppReturn = bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )?
+ __builtin_alloca( pReturnTypeDescr->nSize ) : pUnoReturn;
+ INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack );
+ }
+ }
+
+ // Push "this" pointer
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
+ INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack );
+
+ // Args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_DOUBLE:
+ INSERT_FLOAT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack );
+ 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(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeRef, bSimpleReturn,
+ pStackStart, ( pStack - pStackStart ),
+ pGPR, nGPR,
+ pFPR, nFPR );
+ // NO exception occured...
+ *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 );
+
+ 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( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+//==================================================================================================
+
+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);
+#if OSL_DEBUG_LEVEL > 0
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+#endif
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+#endif
+ 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( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; // get, then set method
+ cpp_call(
+ pThis, aVtableSlot, // get, then set method
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+#endif
+ 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->getBridge()->getUnoEnv()->getRegisteredInterface)(
+ pThis->getBridge()->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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/gcc3_macosx_intel/call.s b/bridges/source/cpp_uno/gcc3_macosx_intel/call.s
new file mode 100644
index 000000000000..fc8860ab4ce1
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_intel/call.s
@@ -0,0 +1,331 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: call.s,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+ .text
+
+.align 1, 0x90
+.globl _privateSnippetExecutorGeneral
+_privateSnippetExecutorGeneral:
+LFBg:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+LCFIg0:
+ movl %esp,%ebp
+LCFIg1:
+ subl $0x8,%esp # padding + 32bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call L_cpp_vtable_call$stub
+ movl 16(%esp),%eax # 32bit returnValue
+ leave
+ ret
+LFEg:
+ .long .-_privateSnippetExecutorGeneral
+
+.align 1, 0x90
+.globl _privateSnippetExecutorVoid
+_privateSnippetExecutorVoid:
+LFBv:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+LCFIv0:
+ movl %esp,%ebp
+LCFIv1:
+ sub $8,%esp # padding
+ pushl $0 # 32bit null pointer (returnValue not used)
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call L_cpp_vtable_call$stub
+ leave
+ ret
+LFEv:
+ .long .-_privateSnippetExecutorVoid
+
+.align 1, 0x90
+.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 L_cpp_vtable_call$stub
+ movl 16(%esp),%eax # 64bit returnValue, lower half
+ movl 20(%esp),%edx # 64bit returnValue, upper half
+ leave
+ ret
+LFEh:
+ .long .-_privateSnippetExecutorHyper
+
+.align 1, 0x90
+.globl _privateSnippetExecutorFloat
+_privateSnippetExecutorFloat:
+LFBf:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+LCFIf0:
+ movl %esp,%ebp
+LCFIf1:
+ subl $0x8,%esp # padding + 32bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call L_cpp_vtable_call$stub
+ flds 16(%esp) # 32bit returnValue
+ leave
+ ret
+LFEf:
+ .long .-_privateSnippetExecutorFloat
+
+.align 1, 0x90
+.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 L_cpp_vtable_call$stub
+ fldl 16(%esp) # 64bit returnValue
+ leave
+ ret
+LFEd:
+ .long .-_privateSnippetExecutorDouble
+
+.align 1, 0x90
+.globl _privateSnippetExecutorClass
+_privateSnippetExecutorClass:
+LFBc:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+LCFIc0:
+ movl %esp,%ebp
+LCFIc1:
+ subl $0x8,%esp # padding + 32bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call L_cpp_vtable_call$stub
+ movl 16(%esp),%eax # 32bit returnValue
+ leave
+ ret $4
+LFEc:
+ .long .-_privateSnippetExecutorClass
+
+ .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
+EH_frame1:
+ .set L$set$frame1,LECIE1-LSCIE1
+ .long L$set$frame1 # length
+LSCIE1:
+ .long 0 # CIE_ID
+ .byte 1 # version
+ .ascii "zPR\0" # augmentation
+ .byte 1 # code_alignment_factor (.uleb128 1)
+ .byte 0x7c # data_alignment_factor (.sleb128 -4)
+ .byte 8 # return_address_register
+ .byte 0x6 # augmentation size 7:
+ .byte 0x9b # ???
+ .long L___gxx_personality_v0$non_lazy_ptr-.
+ .byte 0x10
+ # initial_instructions:
+ .byte 0x0C # DW_CFA_def_cfa %esp, 4
+ .byte 5
+ .byte 4
+ .byte 0x88 # DW_CFA_offset ret, 1
+ .byte 1
+ .align 2
+LECIE1:
+ .globl _privateSnippetExecutorGeneral.eh
+_privateSnippetExecutorGeneral.eh:
+LSFDEg:
+ .set L$set$g1,LEFDEg-LASFDEg
+ .long L$set$g1 # length
+LASFDEg:
+ .long LASFDEg-EH_frame1 # CIE_pointer
+ .long LFBg-. # initial_location
+ .long LFEg-LFBg # address_range
+ .byte 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIg0-LFBg
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .byte 8
+ .byte 0x84 # DW_CFA_offset %ebp, 2
+ .byte 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIg1-LCFIg0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .byte 4
+ .align 2
+LEFDEg:
+ .globl _privateSnippetExecutorVoid.eh
+_privateSnippetExecutorVoid.eh:
+LSFDEv:
+ .set L$set$v1,LEFDEv-LASFDEv
+ .long L$set$v1 # length
+LASFDEv:
+ .long LASFDEv-EH_frame1 # CIE_pointer
+ .long LFBv-. # initial_location
+ .long LFEv-LFBv # address_range
+ .byte 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIv0-LFBv
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .byte 8
+ .byte 0x84 # DW_CFA_offset %ebp, 2
+ .byte 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIv1-LCFIv0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .byte 4
+ .align 2
+LEFDEv:
+ .globl _privateSnippetExecutorHyper.eh
+_privateSnippetExecutorHyper.eh:
+LSFDEh:
+ .set L$set$h1,LEFDEh-LASFDEh
+ .long L$set$h1 # length
+LASFDEh:
+ .long LASFDEh-EH_frame1 # CIE_pointer
+ .long LFBh-. # initial_location
+ .long LFEh-LFBh # address_range
+ .byte 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIh0-LFBh
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .byte 8
+ .byte 0x84 # DW_CFA_offset %ebp, 2
+ .byte 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIh1-LCFIh0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .byte 4
+ .align 2
+LEFDEh:
+ .globl _privateSnippetExecutorFloat.eh
+_privateSnippetExecutorFloat.eh:
+LSFDEf:
+ .set L$set$f1,LEFDEf-LASFDEf
+ .long L$set$f1 # length
+LASFDEf:
+ .long LASFDEf-EH_frame1 # CIE_pointer
+ .long LFBf-. # initial_location
+ .long LFEf-LFBf # address_range
+ .byte 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIf0-LFBf
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .byte 8
+ .byte 0x84 # DW_CFA_offset %ebp, 2
+ .byte 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIf1-LCFIf0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .byte 4
+ .align 2
+LEFDEf:
+ .globl _privateSnippetExecutorDouble.eh
+_privateSnippetExecutorDouble.eh:
+LSFDEd:
+ .set L$set$d1,LEFDEd-LASFDEd
+ .long L$set$d1 # length
+LASFDEd:
+ .long LASFDEd-EH_frame1 # CIE_pointer
+ .long LFBd-. # initial_location
+ .long LFEd-LFBd # address_range
+ .byte 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFId0-LFBd
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .byte 8
+ .byte 0x84 # DW_CFA_offset %ebp, 2
+ .byte 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFId1-LCFId0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .byte 4
+ .align 2
+LEFDEd:
+ .globl _privateSnippetExecutorClass.eh
+_privateSnippetExecutorClass.eh:
+LSFDEc:
+ .set L$set$c1,LEFDEc-LASFDEc
+ .long L$set$c1 # length
+LASFDEc:
+ .long LASFDEc-EH_frame1 # CIE_pointer
+ .long LFBc-. # initial_location
+ .long LFEc-LFBc # address_range
+ .byte 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIc0-LFBc
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .byte 8
+ .byte 0x84 # DW_CFA_offset %ebp, 2
+ .byte 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIc1-LCFIc0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .byte 4
+ .align 2
+LEFDEc:
+ .section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
+L_cpp_vtable_call$stub:
+ .indirect_symbol _cpp_vtable_call
+ hlt ; hlt ; hlt ; hlt ; hlt
+ .section __IMPORT,__pointers,non_lazy_symbol_pointers
+L___gxx_personality_v0$non_lazy_ptr:
+ .indirect_symbol ___gxx_personality_v0
+ .long 0
+ .constructor
+ .destructor
+ .align 1
+ .subsections_via_symbols
diff --git a/bridges/source/cpp_uno/gcc3_macosx_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_macosx_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..8eaff1ad49ef
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_intel/cpp2uno.cxx
@@ -0,0 +1,522 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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 "boost/static_assert.hpp"
+#include <stdio.h>
+
+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)
+ {
+ // xxx todo: test PolyStructy<STRUCT<long>> foo()
+ if (CPPU_CURRENT_NAMESPACE::isSimpleReturnType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pReturnValue; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+ 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
+ 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 occured...
+ 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 occured...
+ {
+ // 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 if return value
+ // is not transferred via eax[/edx]:
+ *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);
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "%p %p %p pThis=%p, pCppI=%p, function index=%d, vtable offset=%d\n", pCallStack[0], pCallStack[1], pCallStack[2], pThis, pCppI, nFunctionIndex, nVtableOffset );
+#endif
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "name=%s\n", rtl::OUStringToOString(pTypeDescr->aBase.pTypeName, RTL_TEXTENCODING_UTF8).getStr() );
+#endif
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("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] );
+#if OSL_DEBUG_LEVEL > 1
+ fprintf(stderr, "calling %s\n", rtl::OUStringToOString(aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_UTF8).getStr());
+#endif
+ 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(
+ rtl::OUString::createFromAscii("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 * pReturnTypeRef)
+{
+ PrivateSnippetExecutor exec;
+ if (pReturnTypeRef == 0) {
+ exec = privateSnippetExecutorVoid;
+ }
+ else {
+ switch (pReturnTypeRef->eTypeClass) {
+ 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:
+ case typelib_TypeClass_EXCEPTION: {
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ bool const bSimpleReturnStruct =
+ CPPU_CURRENT_NAMESPACE::isSimpleReturnType(pReturnTypeDescr);
+ sal_Int32 const nRetSize = pReturnTypeDescr->nSize;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ if (bSimpleReturnStruct && nRetSize <= 8) {
+ exec = privateSnippetExecutorGeneral; // fills eax
+ if (nRetSize > 4)
+ exec = privateSnippetExecutorHyper; // fills eax/edx
+ break;
+ }
+ }
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ case typelib_TypeClass_ANY:
+ functionIndex |= 0x80000000;
+ exec = privateSnippetExecutorClass;
+ break;
+ default:
+ exec = privateSnippetExecutorGeneral;
+ break;
+ }
+ }
+ 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,
+ 0 /* indicates VOID */);
+ }
+ 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 *)
+{}
diff --git a/bridges/source/cpp_uno/gcc3_macosx_intel/except.cxx b/bridges/source/cpp_uno/gcc3_macosx_intel/except.cxx
new file mode 100644
index 000000000000..c2147dfed527
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_intel/except.cxx
@@ -0,0 +1,332 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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 iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind2( m_generatedRttis.find( unoName ) );
+ if (iFind2 == 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() +4;
+#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 = iFind2->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 occured: %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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, 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 occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_macosx_intel/makefile.mk b/bridges/source/cpp_uno/gcc3_macosx_intel/makefile.mk
new file mode 100644
index 000000000000..41f79c3d1f8f
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_intel/makefile.mk
@@ -0,0 +1,83 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.5 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCMACOSXIgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+SHL1RPATH = URELIB
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+#cmc: Ideally --noexecstack would be in operations, but with #i51385# pyuno
+#remote bridgeing breaks
+# $(CC) -Wa,--noexecstack -c -o $(SLO)$/$(@:b).o $<
+ $(CC) -c -o $(SLO)$/$(@:b).o $<
+ touch $@
diff --git a/bridges/source/cpp_uno/gcc3_macosx_intel/share.hxx b/bridges/source/cpp_uno/gcc3_macosx_intel/share.hxx
new file mode 100644
index 000000000000..cbd6e2afa40d
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_intel/share.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+bool isSimpleReturnType(typelib_TypeDescription * pTD, bool recursive = false);
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
diff --git a/bridges/source/cpp_uno/gcc3_macosx_intel/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_macosx_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..3fd38cc9af41
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_intel/uno2cpp.cxx
@@ -0,0 +1,498 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+
+// #include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.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 "share.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+// 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):
+void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs ) __attribute__((noinline));
+
+void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
+ 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"
+ "mov %0, %%eax\n\t"
+ "mov %%eax, %%edx\n\t"
+ // stack padding to keep stack aligned:
+ "shl $2, %%eax\n\t"
+ "neg %%eax\n\t"
+ "add %%esp, %%eax\n\t"
+ "and $0xf, %%eax\n\t"
+ "sub %%eax, %%esp\n\t"
+ // copy:
+ "mov %%edx, %%eax\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", "edx" );
+ switch( pReturnTypeDescr->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;
+ default: {
+ sal_Int32 const nRetSize = pReturnTypeDescr->nSize;
+ if (bSimpleReturn && nRetSize <= 8 && nRetSize > 0) {
+ if (nRetSize > 4)
+ static_cast<long *>(pRegisterReturn)[1] = edx;
+ static_cast<long *>(pRegisterReturn)[0] = eax;
+ }
+ break;
+ }
+ }
+}
+
+//==================================================================================================
+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 =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ 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
+ bool bSimpleReturn = true;
+
+ if (pReturnTypeDescr)
+ {
+ bSimpleReturn = CPPU_CURRENT_NAMESPACE::isSimpleReturnType(
+ pReturnTypeDescr);
+ if (bSimpleReturn)
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ // complex return via ptr
+ *(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
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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
+ 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 );
+ 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr, bSimpleReturn,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *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 );
+
+ 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 (...)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "caught C++ exception\n" );
+#endif
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace CPPU_CURRENT_NAMESPACE {
+bool isSimpleReturnType(typelib_TypeDescription * pTD, bool recursive)
+{
+ if (bridges::cpp_uno::shared::isSimpleType( pTD ))
+ return true;
+ // Only structs of exactly 1, 2, 4, or 8 bytes are returned through
+ // registers, see <http://developer.apple.com/documentation/DeveloperTools/
+ // Conceptual/LowLevelABI/Articles/IA32.html>:
+ if (pTD->eTypeClass == typelib_TypeClass_STRUCT &&
+ (recursive || pTD->nSize <= 2 || pTD->nSize == 4 || pTD->nSize == 8))
+ {
+ typelib_CompoundTypeDescription *const pCompTD =
+ (typelib_CompoundTypeDescription *) pTD;
+ for ( sal_Int32 pos = pCompTD->nMembers; pos--; ) {
+ typelib_TypeDescription * pMemberTD = 0;
+ TYPELIB_DANGER_GET( &pMemberTD, pCompTD->ppTypeRefs[pos] );
+ bool const b = isSimpleReturnType(pMemberTD, true);
+ TYPELIB_DANGER_RELEASE( pMemberTD );
+ if (! b)
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+}
+
+//==================================================================================================
+
+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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/gcc3_macosx_powerpc/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_macosx_powerpc/cpp2uno.cxx
new file mode 100644
index 000000000000..fa5aa958f979
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_powerpc/cpp2uno.cxx
@@ -0,0 +1,733 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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"
+
+using namespace ::com::sun::star::uno;
+
+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_Int64 * pRegisterReturn /* space for register return */ )
+{
+
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (space for entire parameter list in structure format properly aligned)]
+
+ // 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
+
+ sal_Int32 ngpreg = 0;
+ sal_Int32 nfpreg = 0;
+
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *gpreg;
+ ngpreg++;
+ ++ovrflw;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ ngpreg++;
+ ++ovrflw;
+
+ // after handling optional return pointer and "this"
+ // make use of the space that is allocated to store all parameters in the callers stack
+ // by comying the proper registers filled with parameters to that space
+ char * pCppStack = (char *)ovrflw;
+
+
+ sal_Int32 nPos;
+
+ for ( nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ if (rParam.bOut)
+ {
+ if (ngpreg < 8)
+ {
+ *(sal_Int32 *)pCppStack = ((sal_Int32 *)gpreg)[ngpreg++];
+ }
+ pCppStack += sizeof (sal_Int32);
+ }
+ else
+ {
+ switch (rParam.pTypeRef->eTypeClass)
+ {
+ case typelib_TypeClass_FLOAT:
+ if (nfpreg < 13)
+ {
+ *(float *)pCppStack = ((double *)fpreg)[nfpreg++];
+ }
+ pCppStack += sizeof (float);
+ ngpreg += 1;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (nfpreg < 13)
+ {
+ *(double *)pCppStack = ((double *)fpreg)[nfpreg++];
+ }
+ pCppStack += sizeof (double);
+ ngpreg += 2;
+ break;
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_HYPER:
+ if (ngpreg < 8)
+ {
+ *(sal_Int32 *)pCppStack = ((sal_Int32 *)gpreg)[ngpreg++];
+ }
+ pCppStack += sizeof (sal_Int32);
+ // fall through on purpose
+ default:
+ if (ngpreg < 8)
+ {
+ *(sal_Int32 *)pCppStack = ((sal_Int32 *)gpreg)[ngpreg++];
+ }
+ pCppStack += sizeof (sal_Int32);
+ }
+ }
+ }
+
+ // now the stack has all of the paramters stored in it ready to be processed
+ // so we are ready to build the uno call stack
+ pCppStack = (char *)ovrflw;
+
+ // 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 ( 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
+ {
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ pCppArgs[nPos] = pCppStack +3;
+ pUnoArgs[nPos] = pCppStack +3;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ pCppArgs[nPos] = pCppStack +2;
+ pUnoArgs[nPos] = pCppStack +2;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ pCppStack += sizeof(sal_Int32); // extra long (two regs)
+ break;
+ default:
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ }
+ // 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 occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (in space allocated for all params properly aligned)]
+
+ void * pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+ }
+ else
+ {
+ pThis = gpreg[0];
+ }
+
+ 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(
+ rtl::OUString::createFromAscii("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] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->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 * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** fpregptr, void** ovrflw)
+{
+ sal_Int32 gpreg[8];
+ double fpreg[13];
+
+ // FIXME: why are we restoring the volatile ctr register here
+ sal_Int32 ctrsave = ((sal_Int32*)gpregptr)[-1];
+
+ memcpy( gpreg, gpregptr, 32);
+ memcpy( fpreg, fpregptr, 104);
+
+ volatile long nRegReturn[2];
+
+ // sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False;
+
+ typelib_TypeClass aType =
+ cpp_mediate( nFunctionIndex, nVtableOffset, (void**)gpreg, (void**)fpreg, ovrflw, (sal_Int64*)nRegReturn );
+
+ // FIXME: why are we restoring the volatile ctr register here
+ // FIXME: and why are we putting back the values for r4, r5, and r6 as well
+ // FIXME: this makes no sense to me, all of these registers are volatile!
+ __asm__( "lwz r4, %0\n\t"
+ "mtctr r4\n\t"
+ "lwz r4, %1\n\t"
+ "lwz r5, %2\n\t"
+ "lwz r6, %3\n\t"
+ : : "m"(ctrsave), "m"(gpreg[1]), "m"(gpreg[2]), "m"(gpreg[3]) );
+
+ switch( aType )
+ {
+
+ // move return value into register space
+ // (will be loaded by machine code snippet)
+
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ __asm__( "lbz r3,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ __asm__( "lhz r3,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+
+ case typelib_TypeClass_FLOAT:
+ __asm__( "lfs f1,%0\n\t" : :
+ "m" (*((float*)nRegReturn)) );
+ break;
+
+ case typelib_TypeClass_DOUBLE:
+ __asm__( "lfd f1,%0\n\t" : :
+ "m" (*((double*)nRegReturn)) );
+ break;
+
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ __asm__( "lwz r4,%0\n\t" : :
+ "m"(nRegReturn[1]) ); // fall through
+
+ default:
+ __asm__( "lwz r3,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+ }
+}
+
+
+int const codeSnippetSize = 136;
+
+unsigned char * codeSnippet( unsigned char * code, sal_Int32 functionIndex,
+ sal_Int32 vtableOffset, bool simpleRetType )
+{
+ if (! simpleRetType )
+ functionIndex |= 0x80000000;
+
+ // OSL_ASSERT( sizeof (long) == 4 );
+
+ // FIXME: why are we leaving an 8k gap in the stack here
+ // FIXME: is this to allow room for signal handling frames?
+ // FIXME: seems like overkill here but this is what was done for Mac OSX for gcc2
+ // FIXME: also why no saving of the non-volatile CR pieces here, to be safe
+ // FIXME: we probably should
+
+ /* generate this code */
+
+ // # so first save gpr 3 to gpr 10 (aligned to 4)
+ // stw r3, -8000(r1)
+ // stw r4, -7996(r1)
+ // stw r5, -7992(r1)
+ // stw r6, -7988(r1)
+ // stw r7, -7984(r1)
+ // stw r8, -7980(r1)
+ // stw r9, -7976(r1)
+ // stw r10,-7972(r1)
+
+ // # next save fpr 1 to fpr 13 (aligned to 8)
+ // stfd f1, -7968(r1)
+ // stfd f2, -7960(r1)
+ // stfd f3, -7952(r1)
+ // stfd f4, -7944(r1)
+ // stfd f5, -7936(r1)
+ // stfd f6, -7928(r1)
+ // stfd f7, -7920(r1)
+ // stfd f8, -7912(r1)
+ // stfd f9, -7904(r1)
+ // stfd f10,-7896(r1)
+ // stfd f11,-7888(r1)
+ // stfd f12,-7880(r1)
+ // stfd f13,-7872(r1)
+
+ // FIXME: ctr is volatile, while are we saving it and not CR?
+ // mfctr r3
+ // stw r3, -8004(r1)
+
+ // # now here is where cpp_vtable_call must go
+ // lis r3,0xdead
+ // ori r3,r3,0xbeef
+ // mtctr r3
+
+ // # now load up the functionIndex number
+ // lis r3, 0xdead
+ // ori r3,r3,0xbeef
+
+ // # now load up the vtableOffset
+ // lis r4, 0xdead
+ // ori r4,r4,0xbeef
+
+ // #now load up the pointer to the saved gpr registers
+ // addi r5,r1,-8000
+
+ // #now load up the pointer to the saved fpr registers
+ // addi r6,r1,-7968
+
+ // #now load up the pointer to the overflow call stack
+ // addi r7,r1,24 # frame pointer plus 24
+
+ // bctr
+
+ unsigned long * p = (unsigned long *) code;
+
+ * p++ = 0x9061e0c0;
+ * p++ = 0x9081e0c4;
+ * p++ = 0x90a1e0c8;
+ * p++ = 0x90c1e0cc;
+ * p++ = 0x90e1e0d0;
+ * p++ = 0x9101e0d4;
+ * p++ = 0x9121e0d8;
+ * p++ = 0x9141e0dc;
+ * p++ = 0xd821e0e0;
+ * p++ = 0xd841e0e8;
+ * p++ = 0xd861e0f0;
+ * p++ = 0xd881e0f8;
+ * p++ = 0xd8a1e100;
+ * p++ = 0xd8c1e108;
+ * p++ = 0xd8e1e110;
+ * p++ = 0xd901e118;
+ * p++ = 0xd921e120;
+ * p++ = 0xd941e128;
+ * p++ = 0xd961e130;
+ * p++ = 0xd981e138;
+ * p++ = 0xd9a1e140;
+ * p++ = 0x7c6902a6;
+ * p++ = 0x9061e0bc;
+ * p++ = 0x3c600000 | (((unsigned long)cpp_vtable_call) >> 16);
+ * p++ = 0x60630000 | (((unsigned long)cpp_vtable_call) & 0x0000FFFF);
+ * p++ = 0x7c6903a6;
+ * p++ = 0x3c600000 | (((unsigned long)functionIndex) >> 16);
+ * p++ = 0x60630000 | (((unsigned long)functionIndex) & 0x0000FFFF);
+ * p++ = 0x3c800000 | (((unsigned long)vtableOffset) >> 16);
+ * p++ = 0x60840000 | (((unsigned long)vtableOffset) & 0x0000FFFF);
+ * p++ = 0x38a1e0c0;
+ * p++ = 0x38c1e0e0;
+ * p++ = 0x38e10018;
+ * p++ = 0x4e800420;
+
+ return (code + codeSnippetSize);
+
+}
+
+
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * bptr, unsigned char const * eptr)
+{
+ int const lineSize = 32;
+ for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
+ __asm__ volatile ("dcbst 0, %0" : : "r"(p) : "memory");
+ }
+ __asm__ volatile ("sync" : : : "memory");
+ for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
+ __asm__ volatile ("icbi 0, %0" : : "r"(p) : "memory");
+ }
+ __asm__ volatile ("isync" : : : "memory");
+}
+
+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;
+
+ // fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
+ // fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
+ // fflush(stderr);
+
+ 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,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_macosx_powerpc/except.cxx b/bridges/source/cpp_uno/gcc3_macosx_powerpc/except.cxx
new file mode 100644
index 000000000000..c7584ef5f20e
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_powerpc/except.cxx
@@ -0,0 +1,289 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#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( () )
+{
+#ifdef DEBUG
+ 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)'.' );
+ }
+
+#ifdef DEBUG
+ 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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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 iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iiFind( m_generatedRttis.find( unoName ) );
+ if (iiFind == 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() +4;
+#ifdef DEBUG
+ 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 = iiFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 )
+{
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ terminate();
+
+ 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)
+ terminate();
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
+{
+ OSL_ENSURE( header, "### no exception header!!!" );
+ if (! header)
+ terminate();
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
+ if (! pExcTypeDescr)
+ terminate();
+
+ // construct uno exception any
+ ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ ::typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_macosx_powerpc/makefile.mk b/bridges/source/cpp_uno/gcc3_macosx_powerpc/makefile.mk
new file mode 100644
index 000000000000..93e62299d3ce
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_powerpc/makefile.mk
@@ -0,0 +1,82 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.8 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCMACOSXPgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+NOOPTFILES= \
+ $(SLO)$/uno2cpp.obj
+
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS= $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB) \
+ -ldl
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_macosx_powerpc/share.hxx b/bridges/source/cpp_uno/gcc3_macosx_powerpc/share.hxx
new file mode 100644
index 000000000000..6f86271076a6
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_powerpc/share.hxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
diff --git a/bridges/source/cpp_uno/gcc3_macosx_powerpc/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_macosx_powerpc/uno2cpp.cxx
new file mode 100644
index 000000000000..e3f4d36e3962
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_powerpc/uno2cpp.cxx
@@ -0,0 +1,637 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sys/types.h>
+#include <sys/malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.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 "share.hxx"
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+static void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ char * pPT,
+ sal_Int32 * pStackLongs,
+ sal_Int32 /* nStackLongs */)
+{
+
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ // the basic idea here is to use gpr[8] as a storage area for
+ // the future values of registers r3 to r10 needed for the call,
+ // and similarly fpr[13] as a storage area for the future values
+ // of floating point registers f1 to f13
+
+ unsigned long * mfunc; // actual function to be invoked
+ void (*ptr)();
+ int gpr[8]; // storage for gpregisters, map to r3-r10
+ int off; // offset used to find function
+ double fpr[13]; // storage for fpregisters, map to f1-f13
+ int n; // number of gprs mapped so far
+ int f; // number of fprs mapped so far
+ volatile long *p; // pointer to parameter overflow area
+ int c; // character of parameter type being decoded
+ volatile double dret; // temporary function return values
+ volatile int iret, iret2;
+
+ // Because of the Power PC 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.
+
+ // Note: This keeps us from having to decode the signature twice and
+ // prevents problems with later local variables.
+
+ // FIXME: I do not believe the following is true but we will keep the
+ // FIXME: extra space just to be safe until proven otherwise
+
+ // Note: could require up to 2*nStackLongs words of parameter stack area
+ // if the call has many float parameters (i.e. floats take up only 1
+ // word on the stack but take 2 words in parameter area in the
+ // stack frame .
+
+
+ // unsigned long param[(2*nStackLongs)];
+
+ /* now begin to load the C++ function arguments into storage */
+ n = 0;
+ f = 0;
+
+
+ /* set up a pointer to the stack parameter area */
+ __asm__ ( "addi %0,r1,24" : "=r" (p) : /* no inputs */ );
+
+ // #i94421#, work around compiler error:
+ volatile long * pCopy = p;
+ (void) pCopy; // avoid warning about unused variable
+
+ // never called
+ // if (! pAdjustedThisPtr )CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+
+ // now we need to parse the entire signature string
+ // until we get the END indicator
+
+ // treat complex return pointer like any other parameter
+
+ // parse the argument list up to the ending )
+
+ while (*pPT != 'X') {
+ c = *pPT;
+ switch (c) {
+
+ case 'D': /* type is double */
+ if (f < 13) {
+ fpr[f++] = *((double *)pStackLongs); /* store in register */
+ n+=2;
+ p+=2;
+ } else {
+ *p++ = *pStackLongs; /* or on the parameter stack */
+ *p++ = *(pStackLongs + 1);
+ }
+ pStackLongs += 2;
+ break;
+
+ case 'F': /* type is float */
+ /* floats are stored as 1 32 bit word on param stack */
+ if (f < 13) {
+ fpr[f++] = *((float *)pStackLongs);
+ n+=1;
+ p++;
+ } else {
+ *((float *)p) = *((float *)pStackLongs);
+ p += 1;
+ }
+ pStackLongs += 1;
+ break;
+
+ case 'H': /* type is long long */
+ if (n < 8)
+ {
+ gpr[n++] = *pStackLongs;
+ p++;
+ }
+ else
+ *p++ = *pStackLongs;
+ if(n < 8)
+ {
+ gpr[n++] = *(pStackLongs+1);
+ p++;
+ }
+ else
+ *p++ = *(pStackLongs+1);
+ pStackLongs += 2;
+ break;
+
+ case 'S':
+ if (n < 8) {
+ gpr[n++] = *((unsigned short*)pStackLongs);
+ p++;
+ } else {
+ *p++ = *((unsigned short *)pStackLongs);
+ }
+ pStackLongs += 1;
+ break;
+
+ case 'B':
+ if (n < 8) {
+ gpr[n++] = *((char *)pStackLongs);
+ p++;
+ } else {
+ *p++ = *((char *)pStackLongs);
+ }
+ pStackLongs += 1;
+ break;
+
+ default:
+ if (n < 8) {
+ gpr[n++] = *pStackLongs;
+ p++;
+ } else {
+ *p++ = *pStackLongs;
+ }
+ pStackLongs += 1;
+ break;
+ }
+ pPT++;
+ }
+
+
+ /* figure out the address of the function we need to invoke */
+ off = nVtableIndex;
+ off = off * 4; // 4 bytes per slot
+ mfunc = *((unsigned long **)pAdjustedThisPtr); // get the address of the vtable
+ mfunc = (unsigned long *)((char *)mfunc + off); // get the address from the vtable entry at offset
+ mfunc = *((unsigned long **)mfunc); // the function is stored at the address
+ ptr = (void (*)())mfunc;
+
+ /* Set up the machine registers and invoke the function */
+
+ __asm__ __volatile__ (
+ "lwz r3, 0(%0)\n\t"
+ "lwz r4, 4(%0)\n\t"
+ "lwz r5, 8(%0)\n\t"
+ "lwz r6, 12(%0)\n\t"
+ "lwz r7, 16(%0)\n\t"
+ "lwz r8, 20(%0)\n\t"
+ "lwz r9, 24(%0)\n\t"
+ "lwz r10, 28(%0)\n\t"
+ "lfd f1, 0(%1)\n\t"
+ "lfd f2, 8(%1)\n\t"
+ "lfd f3, 16(%1)\n\t"
+ "lfd f4, 24(%1)\n\t"
+ "lfd f5, 32(%1)\n\t"
+ "lfd f6, 40(%1)\n\t"
+ "lfd f7, 48(%1)\n\t"
+ "lfd f8, 56(%1)\n\t"
+ "lfd f9, 64(%1)\n\t"
+ "lfd f10, 72(%1)\n\t"
+ "lfd f11, 80(%1)\n\t"
+ "lfd f12, 88(%1)\n\t"
+ "lfd f13, 96(%1)\n\t"
+ : : "r" (gpr), "r" (fpr)
+ : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
+ "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9",
+ "f10", "f11", "f12", "f13"
+ );
+
+ (*ptr)();
+
+
+ __asm__ __volatile__ (
+ "stw r3, %1\n\t"
+ "stw r4, %2\n\t"
+ "stfd f1, %0\n\t"
+ : : "m" (dret), "m" (iret), "m" (iret2)
+ );
+
+
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = iret2;
+ // fall thru on purpose
+ 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:
+ *(unsigned short*)pRegisterReturn = (unsigned short)iret;
+ break;
+
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)iret;
+ break;
+
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = (float)dret;
+ break;
+
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = dret;
+ break;
+ default:
+ break;
+ }
+}
+
+
+//==================================================================================================
+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 =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // need to know parameter types for callVirtualMethod so generate a signature string
+ char * pParamType = (char *) alloca(nParams+2);
+ char * pPT = pParamType;
+
+ // 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 = *(void **)pCppStack
+ = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ *pPT++ = 'C'; //signify that a complex return type on stack
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+ *pPT++ = 'I';
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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)
+ {
+
+ // 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
+ 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 );
+ 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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 );
+ }
+ *pPT++='I';
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // terminate the signature string
+ *pPT++='X';
+ *pPT=0;
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass, pParamType,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *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 );
+
+ 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( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+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);
+ // typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/gcc3_netbsd_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_netbsd_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..a103da1e0d48
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_netbsd_intel/cpp2uno.cxx
@@ -0,0 +1,566 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <hash_map>
+
+#include <sal/alloca.h>
+#include <rtl/alloc.h>
+#include <osl/mutex.hxx>
+
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include <bridges/cpp_uno/bridge.hxx>
+#include <bridges/cpp_uno/type_misc.hxx>
+
+#include "share.hxx"
+
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+//==================================================================================================
+rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+//==================================================================================================
+static typelib_TypeClass cpp2uno_call(
+ cppu_cppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // 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 (cppu_isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+
+ pUnoReturn = (cppu_relatesToInterface( 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 && cppu_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
+ }
+ // 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 (cppu_relatesToInterface( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ &pThis->pBridge->aCpp2Uno );
+ 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->pUnoI->pDispatcher)( pThis->pUnoI, pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ 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 );
+
+ raiseException( &aUnoExc, &pThis->pBridge->aUno2Cpp ); // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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->pBridge->aUno2Cpp );
+ }
+ // 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->pBridge->aUno2Cpp );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nVtableCall,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: ret adr, [ret *], this, params
+ // _this_ ptr is patched cppu_XInterfaceProxy object
+ cppu_cppInterfaceProxy * pCppI = NULL;
+ if( nVtableCall & 0x80000000 )
+ {
+ nVtableCall &= 0x7fffffff;
+ pCppI = (cppu_cppInterfaceProxy *)(XInterface *)*(pCallStack +2);
+ }
+ else
+ {
+ pCppI = (cppu_cppInterfaceProxy *)(XInterface *)*(pCallStack +1);
+ }
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->pTypeDescr;
+
+ OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nVtableCall >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pCppI );
+ }
+
+ // determine called method
+ OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nVtableCall];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nVtableCall)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nVtableCall)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ 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->pBridge->pCppEnv->getRegisteredInterface)(
+ pCppI->pBridge->pCppEnv,
+ (void **)&pInterface, pCppI->oid.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 );
+ *(void **)pRegisterReturn = pCallStack[1];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ OUString::createFromAscii("no member description found!"),
+ (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static void cpp_vtable_call( int nTableEntry, void** pCallStack ) __attribute__((regparm(2)));
+
+void cpp_vtable_call( int nTableEntry, void** pCallStack )
+{
+ volatile long nRegReturn[2];
+ typelib_TypeClass aType = cpp_mediate( nTableEntry, pCallStack, (sal_Int64*)nRegReturn );
+
+ switch( aType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ __asm__( "movl %1, %%edx\n\t"
+ "movl %0, %%eax\n"
+ : : "m"(nRegReturn[0]), "m"(nRegReturn[1]) );
+ break;
+ case typelib_TypeClass_FLOAT:
+ __asm__( "flds %0\n\t"
+ "fstp %%st(0)\n\t"
+ "flds %0\n"
+ : : "m"(*(float *)nRegReturn) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ __asm__( "fldl %0\n\t"
+ "fstp %%st(0)\n\t"
+ "fldl %0\n"
+ : : "m"(*(double *)nRegReturn) );
+ break;
+// case typelib_TypeClass_UNSIGNED_SHORT:
+// case typelib_TypeClass_SHORT:
+// __asm__( "movswl %0, %%eax\n"
+// : : "m"(nRegReturn) );
+// break;
+ default:
+ __asm__( "movl %0, %%eax\n"
+ : : "m"(nRegReturn[0]) );
+ break;
+ }
+}
+
+
+//==================================================================================================
+class MediateClassData
+{
+ typedef ::std::hash_map< OUString, void *, OUStringHash > t_classdata_map;
+ t_classdata_map m_map;
+ Mutex m_mutex;
+
+public:
+ void const * get_vtable( typelib_InterfaceTypeDescription * pTD ) SAL_THROW( () );
+
+ inline MediateClassData() SAL_THROW( () )
+ {}
+ ~MediateClassData() SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+MediateClassData::~MediateClassData() SAL_THROW( () )
+{
+ OSL_TRACE( "> calling ~MediateClassData(): freeing mediate vtables." );
+
+ for ( t_classdata_map::const_iterator iPos( m_map.begin() ); iPos != m_map.end(); ++iPos )
+ {
+ ::rtl_freeMemory( iPos->second );
+ }
+}
+//--------------------------------------------------------------------------------------------------
+static inline void codeSnippet( char * code, sal_uInt32 vtable_pos, bool simple_ret_type ) SAL_THROW( () )
+{
+ if (! simple_ret_type)
+ vtable_pos |= 0x80000000;
+ OSL_ASSERT( sizeof (long) == 4 );
+ // mov $nPos, %eax
+ *code++ = 0xb8;
+ *(long *)code = vtable_pos;
+ code += sizeof (long);
+ // mov %esp, %edx
+ *code++ = 0x89;
+ *code++ = 0xe2;
+ // jmp cpp_vtable_call
+ *code++ = 0xe9;
+ *(long *)code = ((char *)cpp_vtable_call) - code - sizeof (long);
+}
+//__________________________________________________________________________________________________
+void const * MediateClassData::get_vtable( typelib_InterfaceTypeDescription * pTD ) SAL_THROW( () )
+{
+ void * buffer;
+
+ // avoiding locked counts
+ OUString const & unoName = *(OUString const *)&((typelib_TypeDescription *)pTD)->pTypeName;
+ {
+ MutexGuard aGuard( m_mutex );
+ t_classdata_map::const_iterator iFind( m_map.find( unoName ) );
+ if (iFind == m_map.end())
+ {
+ // create new vtable
+ sal_Int32 nSlots = pTD->nMapFunctionIndexToMemberIndex;
+ buffer = ::rtl_allocateMemory( ((2+ nSlots) * sizeof (void *)) + (nSlots *20) );
+
+ ::std::pair< t_classdata_map::iterator, bool > insertion(
+ m_map.insert( t_classdata_map::value_type( unoName, buffer ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new vtable buffer failed?!" );
+
+ void ** slots = (void **)buffer;
+ *slots++ = 0;
+ *slots++ = 0; // rtti
+ char * code = (char *)(slots + nSlots);
+
+ sal_uInt32 vtable_pos = 0;
+ sal_Int32 nAllMembers = pTD->nAllMembers;
+ typelib_TypeDescriptionReference ** ppAllMembers = pTD->ppAllMembers;
+ for ( sal_Int32 nPos = 0; nPos < nAllMembers; ++nPos )
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, ppAllMembers[ nPos ] );
+ OSL_ASSERT( pTD );
+ if (typelib_TypeClass_INTERFACE_ATTRIBUTE == pTD->eTypeClass)
+ {
+ bool simple_ret = cppu_isSimpleType(
+ ((typelib_InterfaceAttributeTypeDescription *)pTD)->pAttributeTypeRef->eTypeClass );
+ // get method
+ *slots++ = code;
+ codeSnippet( code, vtable_pos++, simple_ret );
+ code += 20;
+ if (! ((typelib_InterfaceAttributeTypeDescription *)pTD)->bReadOnly)
+ {
+ // set method
+ *slots++ = code;
+ codeSnippet( code, vtable_pos++, true );
+ code += 20;
+ }
+ }
+ else
+ {
+ bool simple_ret = cppu_isSimpleType(
+ ((typelib_InterfaceMethodTypeDescription *)pTD)->pReturnTypeRef->eTypeClass );
+ *slots++ = code;
+ codeSnippet( code, vtable_pos++, simple_ret );
+ code += 20;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ OSL_ASSERT( vtable_pos == nSlots );
+ }
+ else
+ {
+ buffer = iFind->second;
+ }
+ }
+
+ return ((void **)buffer +2);
+}
+
+//==================================================================================================
+void SAL_CALL cppu_cppInterfaceProxy_patchVtable(
+ XInterface * pCppI, typelib_InterfaceTypeDescription * pTypeDescr ) throw ()
+{
+ static MediateClassData * s_pMediateClassData = 0;
+ if (! s_pMediateClassData)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_pMediateClassData)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_pMediateClassData = new MediateClassData();
+#else
+ static MediateClassData s_aMediateClassData;
+ s_pMediateClassData = &s_aMediateClassData;
+#endif
+ }
+ }
+ *(void const **)pCppI = s_pMediateClassData->get_vtable( pTypeDescr );
+}
+
+}
+
+extern "C"
+{
+//##################################################################################################
+sal_Bool SAL_CALL component_canUnload( TimeValue * pTime )
+ SAL_THROW_EXTERN_C()
+{
+ return CPPU_CURRENT_NAMESPACE::g_moduleCount.canUnload(
+ &CPPU_CURRENT_NAMESPACE::g_moduleCount, pTime );
+}
+//##################################################################################################
+void SAL_CALL uno_initEnvironment( uno_Environment * pCppEnv )
+ SAL_THROW_EXTERN_C()
+{
+ CPPU_CURRENT_NAMESPACE::cppu_cppenv_initEnvironment(
+ pCppEnv );
+}
+//##################################################################################################
+void SAL_CALL uno_ext_getMapping(
+ uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo )
+ SAL_THROW_EXTERN_C()
+{
+ CPPU_CURRENT_NAMESPACE::cppu_ext_getMapping(
+ ppMapping, pFrom, pTo );
+}
+}
diff --git a/bridges/source/cpp_uno/gcc3_netbsd_intel/except.cxx b/bridges/source/cpp_uno/gcc3_netbsd_intel/except.cxx
new file mode 100644
index 000000000000..e47d2b4b4d34
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_netbsd_intel/except.cxx
@@ -0,0 +1,334 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <bridges/cpp_uno/bridge.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+#ifndef RTLD_DEFAULT
+#define RTLD_DEFAULT ((void *) -2)
+#endif
+
+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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0 , RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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 iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( RTLD_DEFAULT, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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() +4;
+#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 = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 defined DEBUG
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if defined _DEBUG
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if defined DEBUG
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if defined _DEBUG
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_netbsd_intel/makefile.mk b/bridges/source/cpp_uno/gcc3_netbsd_intel/makefile.mk
new file mode 100644
index 000000000000..b510f5a132d8
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_netbsd_intel/makefile.mk
@@ -0,0 +1,79 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCNETBSDIgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_netbsd_intel/share.hxx b/bridges/source/cpp_uno/gcc3_netbsd_intel/share.hxx
new file mode 100644
index 000000000000..9f7c6b8fae9a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_netbsd_intel/share.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+// ----- 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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
diff --git a/bridges/source/cpp_uno/gcc3_netbsd_intel/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_netbsd_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..0d4343d20d43
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_netbsd_intel/uno2cpp.cxx
@@ -0,0 +1,436 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+#include <rtl/alloc.h>
+
+#include <uno/data.h>
+#include <bridges/cpp_uno/bridge.hxx>
+#include <bridges/cpp_uno/type_misc.hxx>
+
+#include "share.hxx"
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * );
+
+//==================================================================================================
+// 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):
+void callVirtualMethod(
+ void * pThis,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs ) __attribute__((noinline));
+
+void callVirtualMethod(
+ void * pThis,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs )
+{
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ OSL_ENSURE( pStackLongs && pThis, "### 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 (! pThis) 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"(pThis), "m"(nVtableIndex),
+ "m"(eax), "m"(edx), "m"(stackptr)
+ : "eax", "edx" );
+ switch( eReturnType )
+ {
+ 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;
+ }
+}
+
+//==================================================================================================
+static void cpp_call(
+ cppu_unoInterfaceProxy * pThis,
+ sal_Int32 nVtableCall,
+ 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 =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ 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 (cppu_isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack = (cppu_relatesToInterface( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ *(void**)pCppStack = pThis->pCppI;
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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 && cppu_isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
+ &pThis->pBridge->aUno2Cpp );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ }
+ // 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 );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (cppu_relatesToInterface( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, &pThis->pBridge->aUno2Cpp );
+
+ 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)" );
+ callVirtualMethod(
+ pThis->pCppI, nVtableCall,
+ pCppReturn, pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *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->pBridge->aCpp2Uno );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ &pThis->pBridge->aCpp2Uno );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ &pThis->pBridge->aCpp2Uno );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( __cxa_get_globals()->caughtExceptions, *ppUnoExc, &pThis->pBridge->aCpp2Uno );
+
+ // 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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+
+//==================================================================================================
+void SAL_CALL cppu_unoInterfaceProxy_dispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException ) throw ()
+{
+ // is my surrogate
+ cppu_unoInterfaceProxy * pThis = (cppu_unoInterfaceProxy *)pUnoI;
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos];
+ OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, nVtableCall,
+ ((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( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ cpp_call(
+ pThis, nVtableCall +1, // get, then set method
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos];
+ OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+
+ switch (nVtableCall)
+ {
+ // 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->pUnoEnv->getRegisteredInterface)(
+ pThis->pBridge->pUnoEnv,
+ (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, nVtableCall,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_os2_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_os2_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..d6589b8d86cf
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_os2_intel/cpp2uno.cxx
@@ -0,0 +1,528 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <sal/alloca.h>
+#include <stdio.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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"
+
+using namespace ::com::sun::star::uno;
+
+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 ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // 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 = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+
+ 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
+ }
+ // 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 = {0}; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+#if OSL_DEBUG_LEVEL > 1
+ if (pUnoExc != NULL)
+ fprintf( stderr, ">cpp2uno_call pUnoExc %x\n", pUnoExc);
+#endif
+
+ // in case an exception occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ 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(
+ rtl::OUString::createFromAscii("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] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ 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 );
+ *(void **)pRegisterReturn = pCallStack[1];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static void cpp_vtable_call(
+ int nFunctionIndex, int nVtableOffset, void** pCallStack )
+ __attribute__((regparm(3)));
+
+void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** pCallStack )
+{
+ volatile long nRegReturn[2];
+ typelib_TypeClass aType = cpp_mediate(
+ nFunctionIndex, nVtableOffset, pCallStack, (sal_Int64*)nRegReturn );
+
+ switch( aType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ __asm__( "movl %1, %%edx\n\t"
+ "movl %0, %%eax\n"
+ : : "m"(nRegReturn[0]), "m"(nRegReturn[1]) );
+ break;
+ case typelib_TypeClass_FLOAT:
+ __asm__( "flds %0\n\t"
+ "fstp %%st(0)\n\t"
+ "flds %0\n"
+ : : "m"(*(float *)nRegReturn) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ __asm__( "fldl %0\n\t"
+ "fstp %%st(0)\n\t"
+ "fldl %0\n"
+ : : "m"(*(double *)nRegReturn) );
+ break;
+// case typelib_TypeClass_UNSIGNED_SHORT:
+// case typelib_TypeClass_SHORT:
+// __asm__( "movswl %0, %%eax\n"
+// : : "m"(nRegReturn) );
+// break;
+ default:
+ __asm__( "movl %0, %%eax\n"
+ : : "m"(nRegReturn[0]) );
+ break;
+ }
+}
+
+
+//==================================================================================================
+int const codeSnippetSize = 20;
+
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool simpleRetType)
+{
+ if (!simpleRetType) {
+ functionIndex |= 0x80000000;
+ }
+ 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);
+ // mov %esp, %ecx:
+ *p++ = 0x89;
+ *p++ = 0xE1;
+ // jmp cpp_vtable_call:
+ *p++ = 0xE9;
+ *reinterpret_cast< sal_Int32 * >(p)
+ = ((unsigned char *) cpp_vtable_call) - 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,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ 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 *)
+{}
diff --git a/bridges/source/cpp_uno/gcc3_os2_intel/defs/gcc3_uno.def b/bridges/source/cpp_uno/gcc3_os2_intel/defs/gcc3_uno.def
new file mode 100644
index 000000000000..1d7ee1a7a571
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_os2_intel/defs/gcc3_uno.def
@@ -0,0 +1,915 @@
+LIBRARY gcc3_uno INITINSTANCE TERMINSTANCE
+DATA MULTIPLE
+DESCRIPTION 'StarView 3.00 680 '
+EXPORTS
+_GetVersionInfo
+_component_canUnload
+_uno_initEnvironment
+_uno_ext_getMapping
+
+;lmax=20
+;smax=_component_canUnload
+
+;__ZTIN4test19TestBridgeExceptionE
+
+__ZTIN10comphelper18OPropertyContainerE
+__ZTIN10comphelper24OPropertyContainerHelperE
+__ZTIN10comphelper25OPropertyArrayUsageHelperIN9configmgr22OConfigurationProviderEEE
+__ZTIN3com3sun4star13configuration17XTemplateInstanceE
+__ZTIN3com3sun4star13configuration18XTemplateContainerE
+__ZTIN3com3sun4star13configuration29InvalidBootstrapFileExceptionE
+__ZTIN3com3sun4star13configuration29MissingBootstrapFileExceptionE
+__ZTIN3com3sun4star13configuration31InstallationIncompleteExceptionE
+__ZTIN3com3sun4star13configuration32CannotLoadConfigurationExceptionE
+__ZTIN3com3sun4star13configuration7backend13XLayerHandlerE
+__ZTIN3com3sun4star13configuration7backend14XSchemaHandlerE
+__ZTIN3com3sun4star13configuration7backend14XUpdateHandlerE
+__ZTIN3com3sun4star13configuration7backend15XCompositeLayerE
+__ZTIN3com3sun4star13configuration7backend15XSchemaSupplierE
+__ZTIN3com3sun4star13configuration7backend15XUpdatableLayerE
+__ZTIN3com3sun4star13configuration7backend16XBackendEntitiesE
+__ZTIN3com3sun4star13configuration7backend18XMultiLayerStratumE
+__ZTIN3com3sun4star13configuration7backend21BackendSetupExceptionE
+__ZTIN3com3sun4star13configuration7backend22BackendAccessExceptionE
+__ZTIN3com3sun4star13configuration7backend22CannotConnectExceptionE
+__ZTIN3com3sun4star13configuration7backend22MalformedDataExceptionE
+__ZTIN3com3sun4star13configuration7backend23ConnectionLostExceptionE
+__ZTIN3com3sun4star13configuration7backend23XBackendChangesListenerE
+__ZTIN3com3sun4star13configuration7backend23XBackendChangesNotifierE
+__ZTIN3com3sun4star13configuration7backend24StratumCreationExceptionE
+__ZTIN3com3sun4star13configuration7backend24XVersionedSchemaSupplierE
+__ZTIN3com3sun4star13configuration7backend29AuthenticationFailedExceptionE
+__ZTIN3com3sun4star13configuration7backend33InsufficientAccessRightsExceptionE
+__ZTIN3com3sun4star13configuration7backend39InvalidAuthenticationMechanismExceptionE
+__ZTIN3com3sun4star13configuration7backend6XLayerE
+__ZTIN3com3sun4star13configuration7backend7XSchemaE
+__ZTIN3com3sun4star13configuration7backend8XBackendE
+__ZTIN3com3sun4star2io11IOExceptionE
+__ZTIN3com3sun4star2io12XInputStreamE
+__ZTIN3com3sun4star2io13XOutputStreamE
+__ZTIN3com3sun4star2io15XActiveDataSinkE
+__ZTIN3com3sun4star2io16XDataInputStreamE
+__ZTIN3com3sun4star2io17XActiveDataSourceE
+__ZTIN3com3sun4star2io20WrongFormatExceptionE
+__ZTIN3com3sun4star2io21NotConnectedExceptionE
+__ZTIN3com3sun4star2io22UnexpectedEOFExceptionE
+__ZTIN3com3sun4star2io27BufferSizeExceededExceptionE
+__ZTIN3com3sun4star3uno10XInterfaceE
+__ZTIN3com3sun4star3uno15XCurrentContextE
+__ZTIN3com3sun4star3uno16RuntimeExceptionE
+__ZTIN3com3sun4star3uno17XComponentContextE
+__ZTIN3com3sun4star3uno5XWeakE
+__ZTIN3com3sun4star3uno9ExceptionE
+__ZTIN3com3sun4star3xml3sax12SAXExceptionE
+__ZTIN3com3sun4star3xml3sax14XAttributeListE
+__ZTIN3com3sun4star3xml3sax16XDocumentHandlerE
+;__ZTIN3com3sun4star4l
+__ZTIN3com3sun4star4lang10XComponentE
+__ZTIN3com3sun4star4lang10XUnoTunnelE
+__ZTIN3com3sun4star4lang12XLocalizableE
+__ZTIN3com3sun4star4lang12XServiceInfoE
+__ZTIN3com3sun4star4lang13XTypeProviderE
+__ZTIN3com3sun4star4lang14XEventListenerE
+__ZTIN3com3sun4star4lang15XInitializationE
+__ZTIN3com3sun4star4lang17DisposedExceptionE
+__ZTIN3com3sun4star4lang18NoSupportExceptionE
+__ZTIN3com3sun4star4lang20NullPointerExceptionE
+__ZTIN3com3sun4star4lang20XMultiServiceFactoryE
+__ZTIN3com3sun4star4lang21XSingleServiceFactoryE
+__ZTIN3com3sun4star4lang22IllegalAccessExceptionE
+__ZTIN3com3sun4star4lang22WrappedTargetExceptionE
+__ZTIN3com3sun4star4lang23XSingleComponentFactoryE
+__ZTIN3com3sun4star4lang24IllegalArgumentExceptionE
+__ZTIN3com3sun4star4lang29ServiceNotRegisteredExceptionE
+__ZTIN3com3sun4star4lang29WrappedTargetRuntimeExceptionE
+__ZTIN3com3sun4star4task17XInteractionAbortE
+__ZTIN3com3sun4star4task17XInteractionRetryE
+__ZTIN3com3sun4star4task19XInteractionApproveE
+__ZTIN3com3sun4star4task19XInteractionRequestE
+__ZTIN3com3sun4star4task22XInteractionDisapproveE
+__ZTIN3com3sun4star4task24XInteractionContinuationE
+__ZTIN3com3sun4star4util10XFlushableE
+__ZTIN3com3sun4star4util12XRefreshableE
+__ZTIN3com3sun4star4util12XTimeStampedE
+__ZTIN3com3sun4star4util13XChangesBatchE
+__ZTIN3com3sun4star4util13XStringEscapeE
+__ZTIN3com3sun4star4util16XChangesNotifierE
+__ZTIN3com3sun4star5beans10XExactNameE
+__ZTIN3com3sun4star5beans12XPropertySetE
+__ZTIN3com3sun4star5beans14XPropertyStateE
+__ZTIN3com3sun4star5beans16XFastPropertySetE
+__ZTIN3com3sun4star5beans16XPropertySetInfoE
+__ZTIN3com3sun4star5beans17XMultiPropertySetE
+__ZTIN3com3sun4star5beans18XPropertyWithStateE
+__ZTIN3com3sun4star5beans20XMultiPropertyStatesE
+__ZTIN3com3sun4star5beans21PropertyVetoExceptionE
+__ZTIN3com3sun4star5beans24UnknownPropertyExceptionE
+__ZTIN3com3sun4star5beans24XHierarchicalPropertySetE
+__ZTIN3com3sun4star5beans29XMultiHierarchicalPropertySetE
+__ZTIN3com3sun4star5beans9XPropertyE
+__ZTIN3com3sun4star6script22CannotConvertExceptionE
+__ZTIN3com3sun4star8registry12XRegistryKeyE
+__ZTIN3com3sun4star8registry15XSimpleRegistryE
+__ZTIN3com3sun4star8registry21InvalidValueExceptionE
+__ZTIN3com3sun4star8registry22MergeConflictExceptionE
+__ZTIN3com3sun4star8registry24InvalidRegistryExceptionE
+__ZTIN3com3sun4star9container10XContainerE
+__ZTIN3com3sun4star9container11XNameAccessE
+__ZTIN3com3sun4star9container12XNameReplaceE
+__ZTIN3com3sun4star9container14XElementAccessE
+__ZTIN3com3sun4star9container14XNameContainerE
+__ZTIN3com3sun4star9container17XHierarchicalNameE
+__ZTIN3com3sun4star9container21ElementExistExceptionE
+__ZTIN3com3sun4star9container22NoSuchElementExceptionE
+__ZTIN3com3sun4star9container23XHierarchicalNameAccessE
+__ZTIN3com3sun4star9container6XChildE
+__ZTIN3com3sun4star9container6XNamedE
+__ZTIN3vos10IReferenceE
+__ZTIN3vos10OReferenceE
+__ZTIN3vos6OTimerE
+__ZTIN3vos7OObjectE
+__ZTIN3vos7OThreadE
+__ZTIN3vos9IRunnableE
+__ZTIN4cppu11ImplHelper2IN3com3sun4star8registry15XSimpleRegistryENS3_4util10XFlushableEEE
+__ZTIN4cppu11ImplHelper4IN3com3sun4star4lang20XMultiServiceFactoryENS4_12XLocalizableENS3_4util12XRefreshableENS7_10XFlushableEEE
+__ZTIN4cppu11ImplHelper6IN3com3sun4star5beans12XPropertySetENS4_17XMultiPropertySetENS4_24XHierarchicalPropertySetENS4_29XMultiHierarchicalPropertySetENS4_14XPropertyStateENS4_20XMultiPropertyStatesEEE
+__ZTIN4cppu11ImplHelper6IN3com3sun4star9container11XNameAccessENS4_17XHierarchicalNameENS4_23XHierarchicalNameAccessENS4_10XContainerENS3_5beans10XExactNameENS9_9XPropertyEEE
+__ZTIN4cppu11ImplHelper9IN3com3sun4star9container11XNameAccessENS4_17XHierarchicalNameENS4_23XHierarchicalNameAccessENS4_10XContainerENS3_5beans10XExactNameENS9_9XPropertyENS9_16XPropertySetInfoENS3_13configuration18XTemplateCo!_yPkJc2
+__ZTIN4cppu11OWeakObjectE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend13XLayerHandlerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend14XSchemaHandlerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend15XCompositeLayerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend23XBackendChangesListenerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io13XOutputStreamEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io16XDataInputStreamEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3uno15XCurrentContextEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3xml3sax14XAttributeListEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3xml3sax16XDocumentHandlerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4lang14XEventListenerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4lang23XSingleComponentFactoryEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task17XInteractionAbortEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task17XInteractionRetryEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task19XInteractionApproveEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task19XInteractionRequestEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task22XInteractionDisapproveEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star5beans16XPropertySetInfoEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star8registry12XRegistryKeyEEE
+__ZTIN4cppu15WeakImplHelper2IN3com3sun4star13configuration7backend13XLayerHandlerENS5_6XLayerEEE
+__ZTIN4cppu15WeakImplHelper2IN3com3sun4star3uno15XCurrentContextENS3_4lang10XUnoTunnelEEE
+__ZTIN4cppu15WeakImplHelper3IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_13configuration7backend14XUpdateHandlerEEE
+__ZTIN4cppu15WeakImplHelper3IN3com3sun4star9container6XChildENS4_6XNamedENS3_4lang12XServiceInfoEEE
+__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io15XActiveDataSinkENS3_13configuration7backend6XLayerEEE
+__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io15XActiveDataSinkENS3_13configuration7backend7XSchemaEEE
+__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io17XActiveDataSourceENS3_13configuration7backend13XLayerHandlerEEE
+__ZTIN4cppu15WeakImplHelper5IN3com3sun4star9container6XNamedENS3_4util16XChangesNotifierENS3_4lang10XComponentENS8_12XServiceInfoENS8_12XLocalizableEEE
+__ZTIN4cppu15WeakImplHelper6IN3com3sun4star9container6XChildENS4_6XNamedENS3_4lang10XComponentENS7_12XServiceInfoENS3_13configuration17XTemplateInstanceENS7_10XUnoTunnelEEE
+__ZTIN4cppu15WeakImplHelper6IN3com3sun4star9container6XNamedENS3_4util16XChangesNotifierENS3_4lang10XComponentENS8_12XServiceInfoENS8_12XLocalizableENS6_13XChangesBatchEEE
+__ZTIN4cppu18OPropertySetHelperE
+__ZTIN4cppu22ImplInheritanceHelper1IN9configmgr7localbe16LocalStratumBaseEN3com3sun4star13configuration7backend18XMultiLayerStratumEEE
+__ZTIN4cppu22ImplInheritanceHelper2IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend15XUpdatableLayerENS6_4util12XTimeStampedEEE
+__ZTIN4cppu22ImplInheritanceHelper2IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend6XLayerENS6_4util12XTimeStampedEEE
+__ZTIN4cppu22ImplInheritanceHelper3IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend15XUpdatableLayerENS8_15XCompositeLayerENS6_4util12XTimeStampedEEE
+__ZTIN4cppu24WeakComponentImplHelper1IN3com3sun4star4lang12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper2IN3com3sun4star4lang20XMultiServiceFactoryENS4_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star13configuration7backend24XVersionedSchemaSupplierENS3_4lang15XInitializationENS7_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star3uno17XComponentContextENS4_15XCurrentContextENS3_4lang12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star4lang15XInitializationENS3_13configuration7backend16XBackendEntitiesENS4_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper5IN3com3sun4star13configuration7backend15XSchemaSupplierENS5_18XMultiLayerStratumENS5_16XBackendEntitiesENS3_4lang15XInitializationENS9_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper5IN3com3sun4star13configuration7backend8XBackendENS5_16XBackendEntitiesENS5_15XSchemaSupplierENS3_4lang15XInitializationENS9_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper7IN3com3sun4star13configuration7backend8XBackendENS5_16XBackendEntitiesENS5_24XVersionedSchemaSupplierENS5_23XBackendChangesNotifierENS5_23XBackendChangesListenerENS3_4lang15XInitializationEN!_7c1rO0
+__ZTIN4cppu27WeakComponentImplHelperBaseE
+__ZTIN9configmgr10BasicGroupE
+__ZTIN9configmgr10IInterfaceE
+__ZTIN9configmgr10NodeActionE
+__ZTIN9configmgr10RefcountedE
+__ZTIN9configmgr10RemoveNodeE
+__ZTIN9configmgr10SearchNodeE
+__ZTIN9configmgr11NoncopyableE
+__ZTIN9configmgr11TreeManagerE
+__ZTIN9configmgr11TreeUpdaterE
+__ZTIN9configmgr11ValueChangeE
+__ZTIN9configmgr12CollectNamesE
+__ZTIN9configmgr12ITreeManagerE
+__ZTIN9configmgr12ONameCreatorE
+__ZTIN9configmgr12OPathCreatorINS_13configuration12AbsolutePathEEE
+__ZTIN9configmgr12OPathCreatorINS_13configuration12RelativePathEEE
+__ZTIN9configmgr13BasicValueSetE
+__ZTIN9configmgr13configuration100_GLOBAL__N__ZN9configmgr13configuration12TemplateName18makeSimpleTypeNameERKN3com3sun4star3uno4TypeE12TypeDetectorE
+__ZTIN9configmgr13configuration11InvalidNameE
+__ZTIN9configmgr13configuration11NodeVisitorE
+__ZTIN9configmgr13configuration11SetNodeImplE
+__ZTIN9configmgr13configuration12TypeMismatchE
+__ZTIN9configmgr13configuration13GroupNodeImplE
+__ZTIN9configmgr13configuration14SetNodeVisitorE
+__ZTIN9configmgr13configuration15ValueMemberNode12DeferredImplE
+__ZTIN9configmgr13configuration18GroupMemberVisitorE
+__ZTIN9configmgr13configuration19ConstraintViolationE
+__ZTIN9configmgr13configuration19DeferredSetNodeImplE
+__ZTIN9configmgr13configuration19WrappedUnoExceptionE
+__ZTIN9configmgr13configuration21DeferredGroupNodeImplE
+__ZTIN9configmgr13configuration21TemplateProvider_ImplE
+__ZTIN9configmgr13configuration28SpecialTemplateProvider_ImplE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv15CollectValueIDsE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv17SetVisitorAdapterE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv19GroupVisitorAdapterE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv21FindNonDefaultElementE
+__ZTIN9configmgr13configuration88_GLOBAL__N__ZN9configmgr13configuration17GroupUpdateHelperC2ERKNS0_4TreeERKNS0_7NodeRefE13NodeDefaulterE
+__ZTIN9configmgr13configuration8NodeImplE
+__ZTIN9configmgr13configuration8TemplateE
+__ZTIN9configmgr13configuration9ExceptionE
+__ZTIN9configmgr13INodeListenerE
+__ZTIN9configmgr13OInnerSetInfoE
+__ZTIN9configmgr13OMergeChangesE
+__ZTIN9configmgr13OProviderImplE
+__ZTIN9configmgr13PWMutexHolderE
+__ZTIN9configmgr13SubtreeChangeE
+__ZTIN9configmgr14BasicSetAccessE
+__ZTIN9configmgr14OStripDefaultsE
+__ZTIN9configmgr15BasicSetElementE
+__ZTIN9configmgr15IConfigListenerE
+__ZTIN9configmgr15OInnerGroupInfoE
+__ZTIN9configmgr15ProviderFactoryE
+__ZTIN9configmgr15ProviderWrapperE
+__ZTIN9configmgr16BasicGroupAccessE
+__ZTIN9configmgr16BasicPropertySetE
+__ZTIN9configmgr16BasicRootElementE
+__ZTIN9configmgr16BootstrapContextE
+__ZTIN9configmgr16ChangeTreeActionE
+__ZTIN9configmgr16ComponentContextE
+__ZTIN9configmgr16IDefaultProviderE
+__ZTIN9configmgr16ITemplateManagerE
+__ZTIN9configmgr16NodeModificationE
+__ZTIN9configmgr16OMergeRemoveNodeE
+__ZTIN9configmgr16OPropagateLevelsE
+__ZTIN9configmgr16UnoContextTunnel6TunnelE
+__ZTIN9configmgr17AttributeListImplE
+__ZTIN9configmgr17BasicInnerElementE
+__ZTIN9configmgr17CacheClientAccessE
+__ZTIN9configmgr17ExtendedCacheDataE
+__ZTIN9configmgr17OInnerGroupUpdateE
+__ZTIN9configmgr17OMergeValueChangeE
+__ZTIN9configmgr17TemplateCacheDataE
+__ZTIN9configmgr18BasicUpdateElementE
+__ZTIN9configmgr18CacheLoadingAccessE
+__ZTIN9configmgr18DisposingForwarderE
+__ZTIN9configmgr18IConfigBroadcasterE
+__ZTIN9configmgr18IConfigTreeManagerE
+__ZTIN9configmgr18OSetElementSetInfoE
+__ZTIN9configmgr19OInnerTreeSetUpdateE
+__ZTIN9configmgr19ORootElementSetInfoE
+__ZTIN9configmgr20OCacheWriteScheduler5TimerE
+__ZTIN9configmgr20OInnerValueSetUpdateE
+__ZTIN9configmgr20OMergeTreeChangeListE
+__ZTIN9configmgr20OSetElementGroupInfoE
+__ZTIN9configmgr20ServiceComponentImplE
+__ZTIN9configmgr21ORootElementGroupInfoE
+__ZTIN9configmgr21OTreeDisposeScheduler5TimerE
+__ZTIN9configmgr21SubtreeChangeReferrerE
+__ZTIN9configmgr22ChangeTreeModificationE
+__ZTIN9configmgr22IConfigDefaultProviderE
+__ZTIN9configmgr22IConfigTemplateManagerE
+__ZTIN9configmgr22OConfigurationProviderE
+__ZTIN9configmgr22OConfigurationRegistryE
+__ZTIN9configmgr22OSetElementGroupUpdateE
+__ZTIN9configmgr23ConfigChangeBroadcasterE
+__ZTIN9configmgr23IDefaultableTreeManagerE
+__ZTIN9configmgr23ORootElementGroupUpdateE
+__ZTIN9configmgr24OSetElementTreeSetUpdateE
+__ZTIN9configmgr25OConfigurationRegistryKeyE
+__ZTIN9configmgr25ORootElementTreeSetUpdateE
+__ZTIN9configmgr25OSetElementValueSetUpdateE
+__ZTIN9configmgr26OProviderDisposingListenerE
+__ZTIN9configmgr26ORootElementValueSetUpdateE
+__ZTIN9configmgr3xml11BasicParserE
+__ZTIN9configmgr3xml11LayerWriterE
+__ZTIN9configmgr3xml13ElementParser12BadValueTypeE
+__ZTIN9configmgr3xml13ParserServiceIN3com3sun4star13configuration7backend6XLayerEEE
+__ZTIN9configmgr3xml13ParserServiceIN3com3sun4star13configuration7backend7XSchemaEEE
+__ZTIN9configmgr3xml13WriterServiceIN3com3sun4star13configuration7backend13XLayerHandlerEEE
+__ZTIN9configmgr3xml18LayerParserServiceE
+__ZTIN9configmgr3xml19SchemaParserServiceE
+__ZTIN9configmgr4data10SetVisitorE
+__ZTIN9configmgr4data11NodeVisitorE
+__ZTIN9configmgr4data11TreeSegment4ImplE
+__ZTIN9configmgr4data15TreeNodeBuilder12LinkSetNodesE
+__ZTIN9configmgr4data20BasicDataTreeBuilderE
+__ZTIN9configmgr4data21ConvertingNodeBuilderE
+__ZTIN9configmgr4data21DataTreeDefaultMergerE
+__ZTIN9configmgr4data22CopyingDataTreeBuilder18ElementListBuilderE
+__ZTIN9configmgr4data22CopyingDataTreeBuilderE
+__ZTIN9configmgr4data24ConvertingSubnodeBuilderE
+__ZTIN9configmgr4data25ConvertingDataTreeBuilder18ElementListBuilderE
+__ZTIN9configmgr4data25ConvertingDataTreeBuilderE
+__ZTIN9configmgr4view12ViewStrategyE
+__ZTIN9configmgr4view18DirectViewStrategyE
+__ZTIN9configmgr4view20ReadOnlyViewStrategyE
+__ZTIN9configmgr5INodeE
+__ZTIN9configmgr6ChangeE
+__ZTIN9configmgr6memory11HeapManagerE
+__ZTIN9configmgr6memory14SimpleHeapLockE
+__ZTIN9configmgr6memory21SimpleHeapManagerBaseE
+__ZTIN9configmgr6memory25SimpleCheckingHeapManagerE
+__ZTIN9configmgr6memory8DataLockE
+__ZTIN9configmgr7AddNodeE
+__ZTIN9configmgr7backend10NodeUpdateE
+__ZTIN9configmgr7backend11NamedUpdateE
+__ZTIN9configmgr7backend11NodeReplaceE
+__ZTIN9configmgr7backend11PropertyAddE
+__ZTIN9configmgr7backend12ResultHolderINS0_12NodeInstanceEE10RCInstanceE
+__ZTIN9configmgr7backend12ResultHolderINS0_16TemplateInstanceEE10RCInstanceE
+__ZTIN9configmgr7backend12ResultHolderINS0_17ComponentInstanceEE10RCInstanceE
+__ZTIN9configmgr7backend13BackendAccessE
+__ZTIN9configmgr7backend13ElementUpdateE
+__ZTIN9configmgr7backend13PropertyResetE
+__ZTIN9configmgr7backend13SchemaBuilderE
+__ZTIN9configmgr7backend13UpdateServiceE
+__ZTIN9configmgr7backend14PropertyUpdateE
+__ZTIN9configmgr7backend15CacheControllerE
+__ZTIN9configmgr7backend16NodeModificationE
+__ZTIN9configmgr7backend17BasicUpdateMergerE
+__ZTIN9configmgr7backend17BinaryReader_ImplE
+__ZTIN9configmgr7backend17INodeDataListenerE
+__ZTIN9configmgr7backend17INodeDataProviderE
+__ZTIN9configmgr7backend17LayerMergeHandlerE
+__ZTIN9configmgr7backend17LayerUpdateMergerE
+__ZTIN9configmgr7backend18BasicImportHandlerE
+__ZTIN9configmgr7backend18BinaryWriteHandlerE
+__ZTIN9configmgr7backend18ImportMergeHandlerE
+__ZTIN9configmgr7backend18LayerUpdateHandlerE
+__ZTIN9configmgr7backend19ICachedDataListenerE
+__ZTIN9configmgr7backend19ICachedDataNotifierE
+__ZTIN9configmgr7backend19ICachedDataProviderE
+__ZTIN9configmgr7backend19IDirectDataProviderE
+__ZTIN9configmgr7backend19IMergedDataProviderE
+__ZTIN9configmgr7backend19INodeUpdateProviderE
+__ZTIN9configmgr7backend19LayerDefaultRemoverE
+__ZTIN9configmgr7backend19MultiStratumBackendE
+__ZTIN9configmgr7backend20IDefaultDataProviderE
+__ZTIN9configmgr7backend20SingleBackendAdapterE
+__ZTIN9configmgr7backend21BackendChangeNotifierE
+__ZTIN9configmgr7backend21IDataProviderMetaDataE
+__ZTIN9configmgr7backend21ITemplateDataProviderE
+__ZTIN9configmgr7backend21OInvalidateTreeThreadE
+__ZTIN9configmgr7backend22CacheChangeMulticasterE
+__ZTIN9configmgr7backend22IComponentDataProviderE
+__ZTIN9configmgr7backend8NodeDropE
+__ZTIN9configmgr7localbe16LocalStratumBaseE
+__ZTIN9configmgr7localbe17LocalMultiStratumE
+__ZTIN9configmgr7localbe18FlatLocalFileLayerE
+__ZTIN9configmgr7localbe18LocalSingleBackendE
+__ZTIN9configmgr7localbe19BasicLocalFileLayerE
+__ZTIN9configmgr7localbe19LayerPropertyHelperE
+__ZTIN9configmgr7localbe19LocalSchemaSupplierE
+__ZTIN9configmgr7localbe20SimpleLocalFileLayerE
+__ZTIN9configmgr7localbe23CompositeLocalFileLayerE
+__ZTIN9configmgr7localbe23LocalStratumMutexHolderE
+__ZTIN9configmgr7localbe27FullCompositeLocalFileLayerE
+__ZTIN9configmgr7localbe28BasicCompositeLocalFileLayerE
+__ZTIN9configmgr7SubtreeE
+__ZTIN9configmgr8BasicSetE
+__ZTIN9configmgr8ISubtreeE
+__ZTIN9configmgr8OOptionsE
+__ZTIN9configmgr9apihelper15BroadcasterBaseE
+__ZTIN9configmgr9apihelper17PropertySetHelperE
+__ZTIN9configmgr9apihelper18InteractionRequestE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task17XInteractionAbortEEE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task17XInteractionRetryEEE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task19XInteractionApproveEEE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task22XInteractionDisapproveEEE
+__ZTIN9configmgr9apihelper24SimpleInteractionRequestE
+__ZTIN9configmgr9apihelper31ConfigurationInteractionHandler7ContextE
+__ZTIN9configmgr9CacheDataE
+__ZTIN9configmgr9configapi10NodeAccessE
+__ZTIN9configmgr9configapi10SetElementE
+__ZTIN9configmgr9configapi11ApiTreeImpl16ComponentAdapterE
+__ZTIN9configmgr9configapi11Broadcaster4ImplE
+__ZTIN9configmgr9configapi11NodeElementE
+__ZTIN9configmgr9configapi11OSetElementINS0_15NodeGroupAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_17NodeSetInfoAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_17NodeTreeSetAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_18NodeValueSetAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_19NodeGroupInfoAccessEEE
+__ZTIN9configmgr9configapi11RootElementE
+__ZTIN9configmgr9configapi11TreeElementE
+__ZTIN9configmgr9configapi12InnerElementE
+__ZTIN9configmgr9configapi13NodeSetAccessE
+__ZTIN9configmgr9configapi13OInnerElementINS0_15NodeGroupAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_17NodeSetInfoAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_17NodeTreeSetAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_18NodeValueSetAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_19NodeGroupInfoAccessEEE
+__ZTIN9configmgr9configapi14ObjectRegistryE
+__ZTIN9configmgr9configapi15ApiRootTreeImpl12NodeListenerE
+__ZTIN9configmgr9configapi15NodeGroupAccessE
+__ZTIN9configmgr9configapi16OReadRootElementINS0_17NodeSetInfoAccessEEE
+__ZTIN9configmgr9configapi16OReadRootElementINS0_19NodeGroupInfoAccessEEE
+__ZTIN9configmgr9configapi17CollectPropertiesE
+__ZTIN9configmgr9configapi17NodeSetInfoAccessE
+__ZTIN9configmgr9configapi17NodeTreeSetAccessE
+__ZTIN9configmgr9configapi17UpdateRootElementE
+__ZTIN9configmgr9configapi18NodeValueSetAccessE
+__ZTIN9configmgr9configapi18OUpdateRootElementINS0_15NodeGroupAccessEEE
+__ZTIN9configmgr9configapi18OUpdateRootElementINS0_17NodeTreeSetAccessEEE
+__ZTIN9configmgr9configapi18OUpdateRootElementINS0_18NodeValueSetAccessEEE
+__ZTIN9configmgr9configapi19NodeGroupInfoAccessE
+__ZTIN9configmgr9configapi19NodePropertySetInfoE
+__ZTIN9configmgr9configapi19UpdateObjectFactoryE
+__ZTIN9configmgr9configapi21ReadOnlyObjectFactoryE
+__ZTIN9configmgr9configapi7FactoryE
+__ZTIN9configmgr9configapi8internal15SearchExactNameE
+__ZTIN9configmgr9OProviderE
+__ZTIN9configmgr9ValueNodeE
+__ZTIN9salhelper21SimpleReferenceObjectE
+;__ZTISt9bad_alloc
+;__ZTISt9exception
+
+
+IMPORTS
+__ZTIN10comphelper18OPropertyContainerE=configmg.__ZTIN10comphelper18OPropertyContainerE
+__ZTIN10comphelper24OPropertyContainerHelperE=configmg.__ZTIN10comphelper24OPropertyContainerHelperE
+__ZTIN10comphelper25OPropertyArrayUsageHelperIN9configmgr22OConfigurationProviderEEE=configmg.__ZTIN10comphelper25OPropertyArrayUsageHelperIN9configmgr22OConfigurationProviderEEE
+__ZTIN3com3sun4star13configuration17XTemplateInstanceE=configmg.__ZTIN3com3sun4star13configuration17XTemplateInstanceE
+__ZTIN3com3sun4star13configuration18XTemplateContainerE=configmg.__ZTIN3com3sun4star13configuration18XTemplateContainerE
+__ZTIN3com3sun4star13configuration29InvalidBootstrapFileExceptionE=configmg.__ZTIN3com3sun4star13configuration29InvalidBootstrapFileExceptionE
+__ZTIN3com3sun4star13configuration29MissingBootstrapFileExceptionE=configmg.__ZTIN3com3sun4star13configuration29MissingBootstrapFileExceptionE
+__ZTIN3com3sun4star13configuration31InstallationIncompleteExceptionE=configmg.__ZTIN3com3sun4star13configuration31InstallationIncompleteExceptionE
+__ZTIN3com3sun4star13configuration32CannotLoadConfigurationExceptionE=configmg.__ZTIN3com3sun4star13configuration32CannotLoadConfigurationExceptionE
+__ZTIN3com3sun4star13configuration7backend13XLayerHandlerE=configmg.__ZTIN3com3sun4star13configuration7backend13XLayerHandlerE
+__ZTIN3com3sun4star13configuration7backend14XLayerImporterE=configmg.__ZTIN3com3sun4star13configuration7backend14XLayerImporterE
+__ZTIN3com3sun4star13configuration7backend14XSchemaHandlerE=configmg.__ZTIN3com3sun4star13configuration7backend14XSchemaHandlerE
+__ZTIN3com3sun4star13configuration7backend14XUpdateHandlerE=configmg.__ZTIN3com3sun4star13configuration7backend14XUpdateHandlerE
+__ZTIN3com3sun4star13configuration7backend15XCompositeLayerE=configmg.__ZTIN3com3sun4star13configuration7backend15XCompositeLayerE
+__ZTIN3com3sun4star13configuration7backend15XSchemaSupplierE=configmg.__ZTIN3com3sun4star13configuration7backend15XSchemaSupplierE
+__ZTIN3com3sun4star13configuration7backend15XUpdatableLayerE=configmg.__ZTIN3com3sun4star13configuration7backend15XUpdatableLayerE
+__ZTIN3com3sun4star13configuration7backend16XBackendEntitiesE=configmg.__ZTIN3com3sun4star13configuration7backend16XBackendEntitiesE
+__ZTIN3com3sun4star13configuration7backend18XMultiLayerStratumE=configmg.__ZTIN3com3sun4star13configuration7backend18XMultiLayerStratumE
+__ZTIN3com3sun4star13configuration7backend19XSingleLayerStratumE=configmg.__ZTIN3com3sun4star13configuration7backend19XSingleLayerStratumE
+__ZTIN3com3sun4star13configuration7backend21BackendSetupExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend21BackendSetupExceptionE
+__ZTIN3com3sun4star13configuration7backend22BackendAccessExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend22BackendAccessExceptionE
+__ZTIN3com3sun4star13configuration7backend22CannotConnectExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend22CannotConnectExceptionE
+__ZTIN3com3sun4star13configuration7backend22MalformedDataExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend22MalformedDataExceptionE
+__ZTIN3com3sun4star13configuration7backend23ConnectionLostExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend23ConnectionLostExceptionE
+__ZTIN3com3sun4star13configuration7backend23XBackendChangesListenerE=configmg.__ZTIN3com3sun4star13configuration7backend23XBackendChangesListenerE
+__ZTIN3com3sun4star13configuration7backend23XBackendChangesNotifierE=configmg.__ZTIN3com3sun4star13configuration7backend23XBackendChangesNotifierE
+__ZTIN3com3sun4star13configuration7backend24StratumCreationExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend24StratumCreationExceptionE
+__ZTIN3com3sun4star13configuration7backend24XVersionedSchemaSupplierE=configmg.__ZTIN3com3sun4star13configuration7backend24XVersionedSchemaSupplierE
+__ZTIN3com3sun4star13configuration7backend29AuthenticationFailedExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend29AuthenticationFailedExceptionE
+__ZTIN3com3sun4star13configuration7backend33InsufficientAccessRightsExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend33InsufficientAccessRightsExceptionE
+__ZTIN3com3sun4star13configuration7backend39InvalidAuthenticationMechanismExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend39InvalidAuthenticationMechanismExceptionE
+__ZTIN3com3sun4star13configuration7backend6XLayerE=configmg.__ZTIN3com3sun4star13configuration7backend6XLayerE
+__ZTIN3com3sun4star13configuration7backend7XSchemaE=configmg.__ZTIN3com3sun4star13configuration7backend7XSchemaE
+__ZTIN3com3sun4star13configuration7backend8XBackendE=configmg.__ZTIN3com3sun4star13configuration7backend8XBackendE
+__ZTIN3com3sun4star2io11IOExceptionE=configmg.__ZTIN3com3sun4star2io11IOExceptionE
+__ZTIN3com3sun4star2io12XInputStreamE=configmg.__ZTIN3com3sun4star2io12XInputStreamE
+__ZTIN3com3sun4star2io13XOutputStreamE=configmg.__ZTIN3com3sun4star2io13XOutputStreamE
+__ZTIN3com3sun4star2io15XActiveDataSinkE=configmg.__ZTIN3com3sun4star2io15XActiveDataSinkE
+__ZTIN3com3sun4star2io16XDataInputStreamE=configmg.__ZTIN3com3sun4star2io16XDataInputStreamE
+__ZTIN3com3sun4star2io17XActiveDataSourceE=configmg.__ZTIN3com3sun4star2io17XActiveDataSourceE
+__ZTIN3com3sun4star2io20WrongFormatExceptionE=configmg.__ZTIN3com3sun4star2io20WrongFormatExceptionE
+__ZTIN3com3sun4star2io21NotConnectedExceptionE=configmg.__ZTIN3com3sun4star2io21NotConnectedExceptionE
+__ZTIN3com3sun4star2io22UnexpectedEOFExceptionE=configmg.__ZTIN3com3sun4star2io22UnexpectedEOFExceptionE
+__ZTIN3com3sun4star2io27BufferSizeExceededExceptionE=configmg.__ZTIN3com3sun4star2io27BufferSizeExceededExceptionE
+__ZTIN3com3sun4star3uno10XInterfaceE=configmg.__ZTIN3com3sun4star3uno10XInterfaceE
+__ZTIN3com3sun4star3uno15XCurrentContextE=configmg.__ZTIN3com3sun4star3uno15XCurrentContextE
+;__ZTIN3com3sun4star3uno16RuntimeExceptionE=configmg.__ZTIN3com3sun4star3uno16RuntimeExceptionE
+__ZTIN3com3sun4star3uno17XComponentContextE=configmg.__ZTIN3com3sun4star3uno17XComponentContextE
+__ZTIN3com3sun4star3uno5XWeakE=configmg.__ZTIN3com3sun4star3uno5XWeakE
+;__ZTIN3com3sun4star3uno9ExceptionE=configmg.__ZTIN3com3sun4star3uno9ExceptionE
+__ZTIN3com3sun4star3xml3sax12SAXExceptionE=configmg.__ZTIN3com3sun4star3xml3sax12SAXExceptionE
+__ZTIN3com3sun4star3xml3sax14XAttributeListE=configmg.__ZTIN3com3sun4star3xml3sax14XAttributeListE
+__ZTIN3com3sun4star3xml3sax16XDocumentHandlerE=configmg.__ZTIN3com3sun4star3xml3sax16XDocumentHandlerE
+__ZTIN3com3sun4star4lang10XComponentE=configmg.__ZTIN3com3sun4star4lang10XComponentE
+__ZTIN3com3sun4star4lang10XUnoTunnelE=configmg.__ZTIN3com3sun4star4lang10XUnoTunnelE
+__ZTIN3com3sun4star4lang12XLocalizableE=configmg.__ZTIN3com3sun4star4lang12XLocalizableE
+__ZTIN3com3sun4star4lang12XServiceInfoE=configmg.__ZTIN3com3sun4star4lang12XServiceInfoE
+__ZTIN3com3sun4star4lang13XTypeProviderE=configmg.__ZTIN3com3sun4star4lang13XTypeProviderE
+__ZTIN3com3sun4star4lang14XEventListenerE=configmg.__ZTIN3com3sun4star4lang14XEventListenerE
+__ZTIN3com3sun4star4lang15XInitializationE=configmg.__ZTIN3com3sun4star4lang15XInitializationE
+__ZTIN3com3sun4star4lang17DisposedExceptionE=configmg.__ZTIN3com3sun4star4lang17DisposedExceptionE
+__ZTIN3com3sun4star4lang18NoSupportExceptionE=configmg.__ZTIN3com3sun4star4lang18NoSupportExceptionE
+__ZTIN3com3sun4star4lang20NullPointerExceptionE=configmg.__ZTIN3com3sun4star4lang20NullPointerExceptionE
+__ZTIN3com3sun4star4lang20XMultiServiceFactoryE=configmg.__ZTIN3com3sun4star4lang20XMultiServiceFactoryE
+__ZTIN3com3sun4star4lang21XSingleServiceFactoryE=configmg.__ZTIN3com3sun4star4lang21XSingleServiceFactoryE
+__ZTIN3com3sun4star4lang22IllegalAccessExceptionE=configmg.__ZTIN3com3sun4star4lang22IllegalAccessExceptionE
+__ZTIN3com3sun4star4lang22WrappedTargetExceptionE=configmg.__ZTIN3com3sun4star4lang22WrappedTargetExceptionE
+__ZTIN3com3sun4star4lang23XSingleComponentFactoryE=configmg.__ZTIN3com3sun4star4lang23XSingleComponentFactoryE
+__ZTIN3com3sun4star4lang24IllegalArgumentExceptionE=configmg.__ZTIN3com3sun4star4lang24IllegalArgumentExceptionE
+__ZTIN3com3sun4star4lang29ServiceNotRegisteredExceptionE=configmg.__ZTIN3com3sun4star4lang29ServiceNotRegisteredExceptionE
+__ZTIN3com3sun4star4lang29WrappedTargetRuntimeExceptionE=configmg.__ZTIN3com3sun4star4lang29WrappedTargetRuntimeExceptionE
+__ZTIN3com3sun4star4task17XInteractionAbortE=configmg.__ZTIN3com3sun4star4task17XInteractionAbortE
+__ZTIN3com3sun4star4task17XInteractionRetryE=configmg.__ZTIN3com3sun4star4task17XInteractionRetryE
+__ZTIN3com3sun4star4task19XInteractionApproveE=configmg.__ZTIN3com3sun4star4task19XInteractionApproveE
+__ZTIN3com3sun4star4task19XInteractionRequestE=configmg.__ZTIN3com3sun4star4task19XInteractionRequestE
+__ZTIN3com3sun4star4task22XInteractionDisapproveE=configmg.__ZTIN3com3sun4star4task22XInteractionDisapproveE
+__ZTIN3com3sun4star4task24XInteractionContinuationE=configmg.__ZTIN3com3sun4star4task24XInteractionContinuationE
+__ZTIN3com3sun4star4task4XJobE=configmg.__ZTIN3com3sun4star4task4XJobE
+__ZTIN3com3sun4star4util10XFlushableE=configmg.__ZTIN3com3sun4star4util10XFlushableE
+__ZTIN3com3sun4star4util12XRefreshableE=configmg.__ZTIN3com3sun4star4util12XRefreshableE
+__ZTIN3com3sun4star4util12XTimeStampedE=configmg.__ZTIN3com3sun4star4util12XTimeStampedE
+__ZTIN3com3sun4star4util13XChangesBatchE=configmg.__ZTIN3com3sun4star4util13XChangesBatchE
+__ZTIN3com3sun4star4util13XStringEscapeE=configmg.__ZTIN3com3sun4star4util13XStringEscapeE
+__ZTIN3com3sun4star4util16XChangesNotifierE=configmg.__ZTIN3com3sun4star4util16XChangesNotifierE
+__ZTIN3com3sun4star5beans10XExactNameE=configmg.__ZTIN3com3sun4star5beans10XExactNameE
+__ZTIN3com3sun4star5beans12XPropertySetE=configmg.__ZTIN3com3sun4star5beans12XPropertySetE
+__ZTIN3com3sun4star5beans14XPropertyStateE=configmg.__ZTIN3com3sun4star5beans14XPropertyStateE
+__ZTIN3com3sun4star5beans16XFastPropertySetE=configmg.__ZTIN3com3sun4star5beans16XFastPropertySetE
+__ZTIN3com3sun4star5beans16XPropertySetInfoE=configmg.__ZTIN3com3sun4star5beans16XPropertySetInfoE
+__ZTIN3com3sun4star5beans17XMultiPropertySetE=configmg.__ZTIN3com3sun4star5beans17XMultiPropertySetE
+__ZTIN3com3sun4star5beans18XPropertyWithStateE=configmg.__ZTIN3com3sun4star5beans18XPropertyWithStateE
+__ZTIN3com3sun4star5beans20XMultiPropertyStatesE=configmg.__ZTIN3com3sun4star5beans20XMultiPropertyStatesE
+__ZTIN3com3sun4star5beans21PropertyVetoExceptionE=configmg.__ZTIN3com3sun4star5beans21PropertyVetoExceptionE
+__ZTIN3com3sun4star5beans24UnknownPropertyExceptionE=configmg.__ZTIN3com3sun4star5beans24UnknownPropertyExceptionE
+__ZTIN3com3sun4star5beans24XHierarchicalPropertySetE=configmg.__ZTIN3com3sun4star5beans24XHierarchicalPropertySetE
+__ZTIN3com3sun4star5beans25XPropertiesChangeListenerE=configmg.__ZTIN3com3sun4star5beans25XPropertiesChangeListenerE
+__ZTIN3com3sun4star5beans29XMultiHierarchicalPropertySetE=configmg.__ZTIN3com3sun4star5beans29XMultiHierarchicalPropertySetE
+__ZTIN3com3sun4star5beans9XPropertyE=configmg.__ZTIN3com3sun4star5beans9XPropertyE
+__ZTIN3com3sun4star6script22CannotConvertExceptionE=configmg.__ZTIN3com3sun4star6script22CannotConvertExceptionE
+__ZTIN3com3sun4star8registry12XRegistryKeyE=configmg.__ZTIN3com3sun4star8registry12XRegistryKeyE
+__ZTIN3com3sun4star8registry15XSimpleRegistryE=configmg.__ZTIN3com3sun4star8registry15XSimpleRegistryE
+__ZTIN3com3sun4star8registry21InvalidValueExceptionE=configmg.__ZTIN3com3sun4star8registry21InvalidValueExceptionE
+__ZTIN3com3sun4star8registry22MergeConflictExceptionE=configmg.__ZTIN3com3sun4star8registry22MergeConflictExceptionE
+__ZTIN3com3sun4star8registry24InvalidRegistryExceptionE=configmg.__ZTIN3com3sun4star8registry24InvalidRegistryExceptionE
+__ZTIN3com3sun4star9container10XContainerE=configmg.__ZTIN3com3sun4star9container10XContainerE
+__ZTIN3com3sun4star9container11XNameAccessE=configmg.__ZTIN3com3sun4star9container11XNameAccessE
+__ZTIN3com3sun4star9container12XNameReplaceE=configmg.__ZTIN3com3sun4star9container12XNameReplaceE
+__ZTIN3com3sun4star9container14XElementAccessE=configmg.__ZTIN3com3sun4star9container14XElementAccessE
+__ZTIN3com3sun4star9container14XNameContainerE=configmg.__ZTIN3com3sun4star9container14XNameContainerE
+__ZTIN3com3sun4star9container17XHierarchicalNameE=configmg.__ZTIN3com3sun4star9container17XHierarchicalNameE
+__ZTIN3com3sun4star9container21ElementExistExceptionE=configmg.__ZTIN3com3sun4star9container21ElementExistExceptionE
+__ZTIN3com3sun4star9container22NoSuchElementExceptionE=configmg.__ZTIN3com3sun4star9container22NoSuchElementExceptionE
+__ZTIN3com3sun4star9container23XHierarchicalNameAccessE=configmg.__ZTIN3com3sun4star9container23XHierarchicalNameAccessE
+__ZTIN3com3sun4star9container6XChildE=configmg.__ZTIN3com3sun4star9container6XChildE
+__ZTIN3com3sun4star9container6XNamedE=configmg.__ZTIN3com3sun4star9container6XNamedE
+__ZTIN3vos10IReferenceE=configmg.__ZTIN3vos10IReferenceE
+__ZTIN3vos10OReferenceE=configmg.__ZTIN3vos10OReferenceE
+__ZTIN3vos6OTimerE=configmg.__ZTIN3vos6OTimerE
+__ZTIN3vos7OObjectE=configmg.__ZTIN3vos7OObjectE
+__ZTIN3vos7OThreadE=configmg.__ZTIN3vos7OThreadE
+__ZTIN3vos9IRunnableE=configmg.__ZTIN3vos9IRunnableE
+__ZTIN4cppu11ImplHelper2IN3com3sun4star8registry15XSimpleRegistryENS3_4util10XFlushableEEE=configmg.__ZTIN4cppu11ImplHelper2IN3com3sun4star8registry15XSimpleRegistryENS3_4util10XFlushableEEE
+__ZTIN4cppu11ImplHelper4IN3com3sun4star4lang20XMultiServiceFactoryENS4_12XLocalizableENS3_4util12XRefreshableENS7_10XFlushableEEE=configmg.__ZTIN4cppu11ImplHelper4IN3com3sun4star4lang20XMultiServiceFactoryENS4_12XLocalizableENS3_4util12XRefreshableENS7_10XFlushableEEE
+__ZTIN4cppu11ImplHelper6IN3com3sun4star5beans12XPropertySetENS4_17XMultiPropertySetENS4_24XHierarchicalPropertySetENS4_29XMultiHierarchicalPropertySetENS4_14XPropertyStateENS4_20XMultiPropertyStatesEEE=configmg.__ZTIN4cppu11ImplHelper6IN3com3sun4star5beans12XPropertySetENS4_17XMultiPropertySetENS4_24XHierarchicalPropertySetENS4_29XMultiHierarchicalPropertySetENS4_14XPropertyStateENS4_20XMultiPropertyStatesEEE
+__ZTIN4cppu11ImplHelper6IN3com3sun4star9container11XNameAccessENS4_17XHierarchicalNameENS4_23XHierarchicalNameAccessENS4_10XContainerENS3_5beans10XExactNameENS9_9XPropertyEEE=configmg.__ZTIN4cppu11ImplHelper6IN3com3sun4star9container11XNameAccessENS4_17XHierarchicalNameENS4_23XHierarchicalNameAccessENS4_10XContainerENS3_5beans10XExactNameENS9_9XPropertyEEE
+__ZTIN4cppu11ImplHelper9IN3com3sun4star9container11XNameAccessENS4_17XHierarchicalNameENS4_23XHierarchicalNameAccessENS4_10XContainerENS3_5beans10XExactNameENS9_9XPropertyENS9_16XPropertySetInfoENS3_13configuration18XTemplateCo!_yPkJc2=configmg.__ZTIN4cppu11ImplHelper9IN3com3sun4star9container11XNameAccessENS4_17XHierarchicalNameENS4_23XHierarchicalNameAccessENS4_10XContainerENS3_5beans10XExactNameENS9_9XPropertyENS9_16XPropertySetInfoENS3_13configuration18XTemplateCo!_yPkJc2
+__ZTIN4cppu11OWeakObjectE=configmg.__ZTIN4cppu11OWeakObjectE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend13XLayerHandlerEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend13XLayerHandlerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend14XSchemaHandlerEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend14XSchemaHandlerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend15XCompositeLayerEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend15XCompositeLayerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend23XBackendChangesListenerEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend23XBackendChangesListenerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend6XLayerEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend6XLayerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io12XInputStreamEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io12XInputStreamEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io13XOutputStreamEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io13XOutputStreamEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io16XDataInputStreamEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io16XDataInputStreamEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3uno15XCurrentContextEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3uno15XCurrentContextEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3xml3sax14XAttributeListEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3xml3sax14XAttributeListEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3xml3sax16XDocumentHandlerEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3xml3sax16XDocumentHandlerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4lang14XEventListenerEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4lang14XEventListenerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4lang23XSingleComponentFactoryEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4lang23XSingleComponentFactoryEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task17XInteractionAbortEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task17XInteractionAbortEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task17XInteractionRetryEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task17XInteractionRetryEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task19XInteractionApproveEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task19XInteractionApproveEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task19XInteractionRequestEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task19XInteractionRequestEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task22XInteractionDisapproveEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task22XInteractionDisapproveEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star5beans16XPropertySetInfoEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star5beans16XPropertySetInfoEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star8registry12XRegistryKeyEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star8registry12XRegistryKeyEEE
+__ZTIN4cppu15WeakImplHelper2IN3com3sun4star13configuration7backend13XLayerHandlerENS5_6XLayerEEE=configmg.__ZTIN4cppu15WeakImplHelper2IN3com3sun4star13configuration7backend13XLayerHandlerENS5_6XLayerEEE
+__ZTIN4cppu15WeakImplHelper2IN3com3sun4star3uno15XCurrentContextENS3_4lang10XUnoTunnelEEE=configmg.__ZTIN4cppu15WeakImplHelper2IN3com3sun4star3uno15XCurrentContextENS3_4lang10XUnoTunnelEEE
+__ZTIN4cppu15WeakImplHelper2IN3com3sun4star4task4XJobENS3_4lang12XServiceInfoEEE=configmg.__ZTIN4cppu15WeakImplHelper2IN3com3sun4star4task4XJobENS3_4lang12XServiceInfoEEE
+__ZTIN4cppu15WeakImplHelper3IN3com3sun4star13configuration7backend14XLayerImporterENS3_4lang15XInitializationENS7_12XServiceInfoEEE=configmg.__ZTIN4cppu15WeakImplHelper3IN3com3sun4star13configuration7backend14XLayerImporterENS3_4lang15XInitializationENS7_12XServiceInfoEEE
+__ZTIN4cppu15WeakImplHelper3IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_13configuration7backend14XUpdateHandlerEEE=configmg.__ZTIN4cppu15WeakImplHelper3IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_13configuration7backend14XUpdateHandlerEEE
+__ZTIN4cppu15WeakImplHelper3IN3com3sun4star9container6XChildENS4_6XNamedENS3_4lang12XServiceInfoEEE=configmg.__ZTIN4cppu15WeakImplHelper3IN3com3sun4star9container6XChildENS4_6XNamedENS3_4lang12XServiceInfoEEE
+__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io15XActiveDataSinkENS3_13configuration7backend6XLayerEEE=configmg.__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io15XActiveDataSinkENS3_13configuration7backend6XLayerEEE
+__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io15XActiveDataSinkENS3_13configuration7backend7XSchemaEEE=configmg.__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io15XActiveDataSinkENS3_13configuration7backend7XSchemaEEE
+__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io17XActiveDataSourceENS3_13configuration7backend13XLayerHandlerEEE=configmg.__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io17XActiveDataSourceENS3_13configuration7backend13XLayerHandlerEEE
+__ZTIN4cppu15WeakImplHelper5IN3com3sun4star9container6XNamedENS3_4util16XChangesNotifierENS3_4lang10XComponentENS8_12XServiceInfoENS8_12XLocalizableEEE=configmg.__ZTIN4cppu15WeakImplHelper5IN3com3sun4star9container6XNamedENS3_4util16XChangesNotifierENS3_4lang10XComponentENS8_12XServiceInfoENS8_12XLocalizableEEE
+__ZTIN4cppu15WeakImplHelper6IN3com3sun4star9container6XChildENS4_6XNamedENS3_4lang10XComponentENS7_12XServiceInfoENS3_13configuration17XTemplateInstanceENS7_10XUnoTunnelEEE=configmg.__ZTIN4cppu15WeakImplHelper6IN3com3sun4star9container6XChildENS4_6XNamedENS3_4lang10XComponentENS7_12XServiceInfoENS3_13configuration17XTemplateInstanceENS7_10XUnoTunnelEEE
+__ZTIN4cppu15WeakImplHelper6IN3com3sun4star9container6XNamedENS3_4util16XChangesNotifierENS3_4lang10XComponentENS8_12XServiceInfoENS8_12XLocalizableENS6_13XChangesBatchEEE=configmg.__ZTIN4cppu15WeakImplHelper6IN3com3sun4star9container6XNamedENS3_4util16XChangesNotifierENS3_4lang10XComponentENS8_12XServiceInfoENS8_12XLocalizableENS6_13XChangesBatchEEE
+__ZTIN4cppu18OPropertySetHelperE=configmg.__ZTIN4cppu18OPropertySetHelperE
+__ZTIN4cppu22ImplInheritanceHelper1IN9configmgr7localbe16LocalStratumBaseEN3com3sun4star13configuration7backend18XMultiLayerStratumEEE=configmg.__ZTIN4cppu22ImplInheritanceHelper1IN9configmgr7localbe16LocalStratumBaseEN3com3sun4star13configuration7backend18XMultiLayerStratumEEE
+__ZTIN4cppu22ImplInheritanceHelper1IN9configmgr7localbe16LocalStratumBaseEN3com3sun4star13configuration7backend19XSingleLayerStratumEEE=configmg.__ZTIN4cppu22ImplInheritanceHelper1IN9configmgr7localbe16LocalStratumBaseEN3com3sun4star13configuration7backend19XSingleLayerStratumEEE
+__ZTIN4cppu22ImplInheritanceHelper2IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend15XUpdatableLayerENS6_4util12XTimeStampedEEE=configmg.__ZTIN4cppu22ImplInheritanceHelper2IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend15XUpdatableLayerENS6_4util12XTimeStampedEEE
+__ZTIN4cppu22ImplInheritanceHelper2IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend6XLayerENS6_4util12XTimeStampedEEE=configmg.__ZTIN4cppu22ImplInheritanceHelper2IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend6XLayerENS6_4util12XTimeStampedEEE
+__ZTIN4cppu22ImplInheritanceHelper3IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend15XUpdatableLayerENS8_15XCompositeLayerENS6_4util12XTimeStampedEEE=configmg.__ZTIN4cppu22ImplInheritanceHelper3IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend15XUpdatableLayerENS8_15XCompositeLayerENS6_4util12XTimeStampedEEE
+__ZTIN4cppu24WeakComponentImplHelper1IN3com3sun4star4lang12XServiceInfoEEE=configmg.__ZTIN4cppu24WeakComponentImplHelper1IN3com3sun4star4lang12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper2IN3com3sun4star4lang20XMultiServiceFactoryENS4_12XServiceInfoEEE=configmg.__ZTIN4cppu24WeakComponentImplHelper2IN3com3sun4star4lang20XMultiServiceFactoryENS4_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star13configuration7backend24XVersionedSchemaSupplierENS3_4lang15XInitializationENS7_12XServiceInfoEEE=configmg.__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star13configuration7backend24XVersionedSchemaSupplierENS3_4lang15XInitializationENS7_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star3uno17XComponentContextENS4_15XCurrentContextENS3_4lang12XServiceInfoEEE=configmg.__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star3uno17XComponentContextENS4_15XCurrentContextENS3_4lang12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star4lang15XInitializationENS3_13configuration7backend16XBackendEntitiesENS4_12XServiceInfoEEE=configmg.__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star4lang15XInitializationENS3_13configuration7backend16XBackendEntitiesENS4_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper5IN3com3sun4star13configuration7backend15XSchemaSupplierENS5_18XMultiLayerStratumENS5_16XBackendEntitiesENS3_4lang15XInitializationENS9_12XServiceInfoEEE=configmg.__ZTIN4cppu24WeakComponentImplHelper5IN3com3sun4star13configuration7backend15XSchemaSupplierENS5_18XMultiLayerStratumENS5_16XBackendEntitiesENS3_4lang15XInitializationENS9_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper5IN3com3sun4star13configuration7backend8XBackendENS5_16XBackendEntitiesENS5_15XSchemaSupplierENS3_4lang15XInitializationENS9_12XServiceInfoEEE=configmg.__ZTIN4cppu24WeakComponentImplHelper5IN3com3sun4star13configuration7backend8XBackendENS5_16XBackendEntitiesENS5_15XSchemaSupplierENS3_4lang15XInitializationENS9_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper7IN3com3sun4star13configuration7backend8XBackendENS5_16XBackendEntitiesENS5_24XVersionedSchemaSupplierENS5_23XBackendChangesNotifierENS5_23XBackendChangesListenerENS3_4lang15XInitializationEN!_7c1rO0=configmg.__ZTIN4cppu24WeakComponentImplHelper7IN3com3sun4star13configuration7backend8XBackendENS5_16XBackendEntitiesENS5_24XVersionedSchemaSupplierENS5_23XBackendChangesNotifierENS5_23XBackendChangesListenerENS3_4lang15XInitializationEN!_7c1rO0
+__ZTIN4cppu27WeakComponentImplHelperBaseE=configmg.__ZTIN4cppu27WeakComponentImplHelperBaseE
+__ZTIN9configmgr10BasicGroupE=configmg.__ZTIN9configmgr10BasicGroupE
+__ZTIN9configmgr10IInterfaceE=configmg.__ZTIN9configmgr10IInterfaceE
+__ZTIN9configmgr10NodeActionE=configmg.__ZTIN9configmgr10NodeActionE
+__ZTIN9configmgr10RefcountedE=configmg.__ZTIN9configmgr10RefcountedE
+__ZTIN9configmgr10RemoveNodeE=configmg.__ZTIN9configmgr10RemoveNodeE
+__ZTIN9configmgr10SearchNodeE=configmg.__ZTIN9configmgr10SearchNodeE
+__ZTIN9configmgr11ApplyUpdateE=configmg.__ZTIN9configmgr11ApplyUpdateE
+__ZTIN9configmgr11NoncopyableE=configmg.__ZTIN9configmgr11NoncopyableE
+__ZTIN9configmgr11TreeManagerE=configmg.__ZTIN9configmgr11TreeManagerE
+__ZTIN9configmgr11TreeUpdaterE=configmg.__ZTIN9configmgr11TreeUpdaterE
+__ZTIN9configmgr11ValueChangeE=configmg.__ZTIN9configmgr11ValueChangeE
+__ZTIN9configmgr12AdjustUpdateE=configmg.__ZTIN9configmgr12AdjustUpdateE
+__ZTIN9configmgr12CollectNamesE=configmg.__ZTIN9configmgr12CollectNamesE
+__ZTIN9configmgr12ITreeManagerE=configmg.__ZTIN9configmgr12ITreeManagerE
+__ZTIN9configmgr12ONameCreatorE=configmg.__ZTIN9configmgr12ONameCreatorE
+__ZTIN9configmgr12OPathCreatorINS_13configuration12AbsolutePathEEE=configmg.__ZTIN9configmgr12OPathCreatorINS_13configuration12AbsolutePathEEE
+__ZTIN9configmgr12OPathCreatorINS_13configuration12RelativePathEEE=configmg.__ZTIN9configmgr12OPathCreatorINS_13configuration12RelativePathEEE
+__ZTIN9configmgr13BasicValueSetE=configmg.__ZTIN9configmgr13BasicValueSetE
+__ZTIN9configmgr13INodeListenerE=configmg.__ZTIN9configmgr13INodeListenerE
+__ZTIN9configmgr13OInnerSetInfoE=configmg.__ZTIN9configmgr13OInnerSetInfoE
+__ZTIN9configmgr13OMergeChangesE=configmg.__ZTIN9configmgr13OMergeChangesE
+__ZTIN9configmgr13OProviderImplE=configmg.__ZTIN9configmgr13OProviderImplE
+__ZTIN9configmgr13PWMutexHolderE=configmg.__ZTIN9configmgr13PWMutexHolderE
+__ZTIN9configmgr13SubtreeChangeE=configmg.__ZTIN9configmgr13SubtreeChangeE
+__ZTIN9configmgr13configuration100_GLOBAL__N__ZN9configmgr13configuration12TemplateName18makeSimpleTypeNameERKN3com3sun4star3uno4TypeE12TypeDetectorE=configmg.__ZTIN9configmgr13configuration100_GLOBAL__N__ZN9configmgr13configuration12TemplateName18makeSimpleTypeNameERKN3com3sun4star3uno4TypeE12TypeDetectorE
+__ZTIN9configmgr13configuration11InvalidNameE=configmg.__ZTIN9configmgr13configuration11InvalidNameE
+__ZTIN9configmgr13configuration11NodeVisitorE=configmg.__ZTIN9configmgr13configuration11NodeVisitorE
+__ZTIN9configmgr13configuration11SetNodeImplE=configmg.__ZTIN9configmgr13configuration11SetNodeImplE
+__ZTIN9configmgr13configuration12RootTreeImplE=configmg.__ZTIN9configmgr13configuration12RootTreeImplE
+__ZTIN9configmgr13configuration12SetResetImplE=configmg.__ZTIN9configmgr13configuration12SetResetImplE
+__ZTIN9configmgr13configuration12TypeMismatchE=configmg.__ZTIN9configmgr13configuration12TypeMismatchE
+__ZTIN9configmgr13configuration13GroupNodeImplE=configmg.__ZTIN9configmgr13configuration13GroupNodeImplE
+__ZTIN9configmgr13configuration13SetChangeImplE=configmg.__ZTIN9configmgr13configuration13SetChangeImplE
+__ZTIN9configmgr13configuration13SetInsertImplE=configmg.__ZTIN9configmgr13configuration13SetInsertImplE
+__ZTIN9configmgr13configuration13SetRemoveImplE=configmg.__ZTIN9configmgr13configuration13SetRemoveImplE
+__ZTIN9configmgr13configuration14CollectChangesE=configmg.__ZTIN9configmgr13configuration14CollectChangesE
+__ZTIN9configmgr13configuration14NodeChangeImplE=configmg.__ZTIN9configmgr13configuration14NodeChangeImplE
+__ZTIN9configmgr13configuration14SetNodeVisitorE=configmg.__ZTIN9configmgr13configuration14SetNodeVisitorE
+__ZTIN9configmgr13configuration14SetReplaceImplE=configmg.__ZTIN9configmgr13configuration14SetReplaceImplE
+__ZTIN9configmgr13configuration14ValueResetImplE=configmg.__ZTIN9configmgr13configuration14ValueResetImplE
+__ZTIN9configmgr13configuration15ElementTreeImplE=configmg.__ZTIN9configmgr13configuration15ElementTreeImplE
+__ZTIN9configmgr13configuration15TreeImplBuilderE=configmg.__ZTIN9configmgr13configuration15TreeImplBuilderE
+__ZTIN9configmgr13configuration15ValueChangeImplE=configmg.__ZTIN9configmgr13configuration15ValueChangeImplE
+__ZTIN9configmgr13configuration15ValueMemberNode12DeferredImplE=configmg.__ZTIN9configmgr13configuration15ValueMemberNode12DeferredImplE
+__ZTIN9configmgr13configuration16ValueReplaceImplE=configmg.__ZTIN9configmgr13configuration16ValueReplaceImplE
+__ZTIN9configmgr13configuration18GroupMemberVisitorE=configmg.__ZTIN9configmgr13configuration18GroupMemberVisitorE
+__ZTIN9configmgr13configuration19ConstraintViolationE=configmg.__ZTIN9configmgr13configuration19ConstraintViolationE
+__ZTIN9configmgr13configuration19DeferredSetNodeImplE=configmg.__ZTIN9configmgr13configuration19DeferredSetNodeImplE
+__ZTIN9configmgr13configuration19WrappedUnoExceptionE=configmg.__ZTIN9configmgr13configuration19WrappedUnoExceptionE
+__ZTIN9configmgr13configuration20DefaultProviderProxyE=configmg.__ZTIN9configmgr13configuration20DefaultProviderProxyE
+__ZTIN9configmgr13configuration20SetElementChangeImplE=configmg.__ZTIN9configmgr13configuration20SetElementChangeImplE
+__ZTIN9configmgr13configuration20ValueElementNodeImplE=configmg.__ZTIN9configmgr13configuration20ValueElementNodeImplE
+__ZTIN9configmgr13configuration21DeferredGroupNodeImplE=configmg.__ZTIN9configmgr13configuration21DeferredGroupNodeImplE
+__ZTIN9configmgr13configuration21TemplateProvider_ImplE=configmg.__ZTIN9configmgr13configuration21TemplateProvider_ImplE
+__ZTIN9configmgr13configuration28SpecialTemplateProvider_ImplE=configmg.__ZTIN9configmgr13configuration28SpecialTemplateProvider_ImplE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv15CollectValueIDsE=configmg.__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv15CollectValueIDsE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv17SetVisitorAdapterE=configmg.__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv17SetVisitorAdapterE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv19GroupVisitorAdapterE=configmg.__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv19GroupVisitorAdapterE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv21FindNonDefaultElementE=configmg.__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv21FindNonDefaultElementE
+__ZTIN9configmgr13configuration88_GLOBAL__N__ZN9configmgr13configuration17GroupUpdateHelperC2ERKNS0_4TreeERKNS0_7NodeRefE13NodeDefaulterE=configmg.__ZTIN9configmgr13configuration88_GLOBAL__N__ZN9configmgr13configuration17GroupUpdateHelperC2ERKNS0_4TreeERKNS0_7NodeRefE13NodeDefaulterE
+__ZTIN9configmgr13configuration8NodeImplE=configmg.__ZTIN9configmgr13configuration8NodeImplE
+__ZTIN9configmgr13configuration8TemplateE=configmg.__ZTIN9configmgr13configuration8TemplateE
+__ZTIN9configmgr13configuration8TreeImplE=configmg.__ZTIN9configmgr13configuration8TreeImplE
+__ZTIN9configmgr13configuration9ExceptionE=configmg.__ZTIN9configmgr13configuration9ExceptionE
+__ZTIN9configmgr14BasicSetAccessE=configmg.__ZTIN9configmgr14BasicSetAccessE
+__ZTIN9configmgr14ONodeConverterE=configmg.__ZTIN9configmgr14ONodeConverterE
+__ZTIN9configmgr14OStripDefaultsE=configmg.__ZTIN9configmgr14OStripDefaultsE
+__ZTIN9configmgr15BasicSetElementE=configmg.__ZTIN9configmgr15BasicSetElementE
+__ZTIN9configmgr15IConfigListenerE=configmg.__ZTIN9configmgr15IConfigListenerE
+__ZTIN9configmgr15OInnerGroupInfoE=configmg.__ZTIN9configmgr15OInnerGroupInfoE
+__ZTIN9configmgr15ProviderFactoryE=configmg.__ZTIN9configmgr15ProviderFactoryE
+__ZTIN9configmgr15ProviderWrapperE=configmg.__ZTIN9configmgr15ProviderWrapperE
+__ZTIN9configmgr16BasicGroupAccessE=configmg.__ZTIN9configmgr16BasicGroupAccessE
+__ZTIN9configmgr16BasicPropertySetE=configmg.__ZTIN9configmgr16BasicPropertySetE
+__ZTIN9configmgr16BasicRootElementE=configmg.__ZTIN9configmgr16BasicRootElementE
+__ZTIN9configmgr16BootstrapContextE=configmg.__ZTIN9configmgr16BootstrapContextE
+__ZTIN9configmgr16ChangeTreeActionE=configmg.__ZTIN9configmgr16ChangeTreeActionE
+__ZTIN9configmgr16ComponentContextE=configmg.__ZTIN9configmgr16ComponentContextE
+__ZTIN9configmgr16IDefaultProviderE=configmg.__ZTIN9configmgr16IDefaultProviderE
+__ZTIN9configmgr16ITemplateManagerE=configmg.__ZTIN9configmgr16ITemplateManagerE
+__ZTIN9configmgr16NodeModificationE=configmg.__ZTIN9configmgr16NodeModificationE
+__ZTIN9configmgr16OMergeRemoveNodeE=configmg.__ZTIN9configmgr16OMergeRemoveNodeE
+__ZTIN9configmgr16OPropagateLevelsE=configmg.__ZTIN9configmgr16OPropagateLevelsE
+__ZTIN9configmgr16UnoContextTunnel6TunnelE=configmg.__ZTIN9configmgr16UnoContextTunnel6TunnelE
+__ZTIN9configmgr17AttributeListImplE=configmg.__ZTIN9configmgr17AttributeListImplE
+__ZTIN9configmgr17BasicInnerElementE=configmg.__ZTIN9configmgr17BasicInnerElementE
+__ZTIN9configmgr17CacheClientAccessE=configmg.__ZTIN9configmgr17CacheClientAccessE
+__ZTIN9configmgr17ExtendedCacheDataE=configmg.__ZTIN9configmgr17ExtendedCacheDataE
+__ZTIN9configmgr17ExtendedCacheLineE=configmg.__ZTIN9configmgr17ExtendedCacheLineE
+__ZTIN9configmgr17OInnerGroupUpdateE=configmg.__ZTIN9configmgr17OInnerGroupUpdateE
+__ZTIN9configmgr17OMergeValueChangeE=configmg.__ZTIN9configmgr17OMergeValueChangeE
+__ZTIN9configmgr17TemplateCacheDataE=configmg.__ZTIN9configmgr17TemplateCacheDataE
+__ZTIN9configmgr18BasicUpdateElementE=configmg.__ZTIN9configmgr18BasicUpdateElementE
+__ZTIN9configmgr18CacheLoadingAccessE=configmg.__ZTIN9configmgr18CacheLoadingAccessE
+__ZTIN9configmgr18DisposingForwarderE=configmg.__ZTIN9configmgr18DisposingForwarderE
+__ZTIN9configmgr18IConfigBroadcasterE=configmg.__ZTIN9configmgr18IConfigBroadcasterE
+__ZTIN9configmgr18IConfigTreeManagerE=configmg.__ZTIN9configmgr18IConfigTreeManagerE
+__ZTIN9configmgr18OSetElementSetInfoE=configmg.__ZTIN9configmgr18OSetElementSetInfoE
+__ZTIN9configmgr19OInnerTreeSetUpdateE=configmg.__ZTIN9configmgr19OInnerTreeSetUpdateE
+__ZTIN9configmgr19ORootElementSetInfoE=configmg.__ZTIN9configmgr19ORootElementSetInfoE
+__ZTIN9configmgr20OCacheWriteScheduler5TimerE=configmg.__ZTIN9configmgr20OCacheWriteScheduler5TimerE
+__ZTIN9configmgr20OChangeActionCounterE=configmg.__ZTIN9configmgr20OChangeActionCounterE
+__ZTIN9configmgr20OCreateSubtreeActionE=configmg.__ZTIN9configmgr20OCreateSubtreeActionE
+__ZTIN9configmgr20OInnerValueSetUpdateE=configmg.__ZTIN9configmgr20OInnerValueSetUpdateE
+__ZTIN9configmgr20OMergeTreeChangeListE=configmg.__ZTIN9configmgr20OMergeTreeChangeListE
+__ZTIN9configmgr20OSetElementGroupInfoE=configmg.__ZTIN9configmgr20OSetElementGroupInfoE
+__ZTIN9configmgr20ServiceComponentImplE=configmg.__ZTIN9configmgr20ServiceComponentImplE
+__ZTIN9configmgr21ORootElementGroupInfoE=configmg.__ZTIN9configmgr21ORootElementGroupInfoE
+__ZTIN9configmgr21OSLInputStreamWrapperE=configmg.__ZTIN9configmgr21OSLInputStreamWrapperE
+__ZTIN9configmgr21OTreeDisposeScheduler5TimerE=configmg.__ZTIN9configmgr21OTreeDisposeScheduler5TimerE
+__ZTIN9configmgr21SubtreeChangeReferrerE=configmg.__ZTIN9configmgr21SubtreeChangeReferrerE
+__ZTIN9configmgr22ChangeTreeModificationE=configmg.__ZTIN9configmgr22ChangeTreeModificationE
+__ZTIN9configmgr22IConfigDefaultProviderE=configmg.__ZTIN9configmgr22IConfigDefaultProviderE
+__ZTIN9configmgr22IConfigTemplateManagerE=configmg.__ZTIN9configmgr22IConfigTemplateManagerE
+__ZTIN9configmgr22OConfigurationProviderE=configmg.__ZTIN9configmgr22OConfigurationProviderE
+__ZTIN9configmgr22OConfigurationRegistryE=configmg.__ZTIN9configmgr22OConfigurationRegistryE
+__ZTIN9configmgr22OSLOutputStreamWrapperE=configmg.__ZTIN9configmgr22OSLOutputStreamWrapperE
+__ZTIN9configmgr22OSetElementGroupUpdateE=configmg.__ZTIN9configmgr22OSetElementGroupUpdateE
+__ZTIN9configmgr23ConfigChangeBroadcasterE=configmg.__ZTIN9configmgr23ConfigChangeBroadcasterE
+__ZTIN9configmgr23IDefaultableTreeManagerE=configmg.__ZTIN9configmgr23IDefaultableTreeManagerE
+__ZTIN9configmgr23ORootElementGroupUpdateE=configmg.__ZTIN9configmgr23ORootElementGroupUpdateE
+__ZTIN9configmgr24OSetElementTreeSetUpdateE=configmg.__ZTIN9configmgr24OSetElementTreeSetUpdateE
+__ZTIN9configmgr25OConfigurationRegistryKeyE=configmg.__ZTIN9configmgr25OConfigurationRegistryKeyE
+__ZTIN9configmgr25ORootElementTreeSetUpdateE=configmg.__ZTIN9configmgr25ORootElementTreeSetUpdateE
+__ZTIN9configmgr25OSetElementValueSetUpdateE=configmg.__ZTIN9configmgr25OSetElementValueSetUpdateE
+__ZTIN9configmgr26OConfigurationProviderImplE=configmg.__ZTIN9configmgr26OConfigurationProviderImplE
+__ZTIN9configmgr26OProviderDisposingListenerE=configmg.__ZTIN9configmgr26OProviderDisposingListenerE
+__ZTIN9configmgr26ORootElementValueSetUpdateE=configmg.__ZTIN9configmgr26ORootElementValueSetUpdateE
+__ZTIN9configmgr26PropertiesFilteredNotifierE=configmg.__ZTIN9configmgr26PropertiesFilteredNotifierE
+__ZTIN9configmgr28ForwardTreeDifferenceBuilderE=configmg.__ZTIN9configmgr28ForwardTreeDifferenceBuilderE
+__ZTIN9configmgr29BackwardTreeDifferenceBuilderE=configmg.__ZTIN9configmgr29BackwardTreeDifferenceBuilderE
+__ZTIN9configmgr29OSLInputBufferedStreamWrapperE=configmg.__ZTIN9configmgr29OSLInputBufferedStreamWrapperE
+__ZTIN9configmgr3xml11BasicParserE=configmg.__ZTIN9configmgr3xml11BasicParserE
+__ZTIN9configmgr3xml11LayerParserE=configmg.__ZTIN9configmgr3xml11LayerParserE
+__ZTIN9configmgr3xml11LayerWriterE=configmg.__ZTIN9configmgr3xml11LayerWriterE
+__ZTIN9configmgr3xml12SchemaParserE=configmg.__ZTIN9configmgr3xml12SchemaParserE
+__ZTIN9configmgr3xml13ElementParser12BadValueTypeE=configmg.__ZTIN9configmgr3xml13ElementParser12BadValueTypeE
+__ZTIN9configmgr3xml13ParserServiceIN3com3sun4star13configuration7backend6XLayerEEE=configmg.__ZTIN9configmgr3xml13ParserServiceIN3com3sun4star13configuration7backend6XLayerEEE
+__ZTIN9configmgr3xml13ParserServiceIN3com3sun4star13configuration7backend7XSchemaEEE=configmg.__ZTIN9configmgr3xml13ParserServiceIN3com3sun4star13configuration7backend7XSchemaEEE
+__ZTIN9configmgr3xml13WriterServiceIN3com3sun4star13configuration7backend13XLayerHandlerEEE=configmg.__ZTIN9configmgr3xml13WriterServiceIN3com3sun4star13configuration7backend13XLayerHandlerEEE
+__ZTIN9configmgr3xml18LayerParserServiceE=configmg.__ZTIN9configmgr3xml18LayerParserServiceE
+__ZTIN9configmgr3xml19SchemaParserServiceE=configmg.__ZTIN9configmgr3xml19SchemaParserServiceE
+__ZTIN9configmgr4data10SetVisitorE=configmg.__ZTIN9configmgr4data10SetVisitorE
+__ZTIN9configmgr4data11NodeVisitorE=configmg.__ZTIN9configmgr4data11NodeVisitorE
+__ZTIN9configmgr4data11TreeSegment4ImplE=configmg.__ZTIN9configmgr4data11TreeSegment4ImplE
+__ZTIN9configmgr4data15TreeNodeBuilder12LinkSetNodesE=configmg.__ZTIN9configmgr4data15TreeNodeBuilder12LinkSetNodesE
+__ZTIN9configmgr4data20BasicDataTreeBuilderE=configmg.__ZTIN9configmgr4data20BasicDataTreeBuilderE
+__ZTIN9configmgr4data21ConvertingNodeBuilderE=configmg.__ZTIN9configmgr4data21ConvertingNodeBuilderE
+__ZTIN9configmgr4data21DataTreeDefaultMergerE=configmg.__ZTIN9configmgr4data21DataTreeDefaultMergerE
+__ZTIN9configmgr4data22CopyingDataTreeBuilder18ElementListBuilderE=configmg.__ZTIN9configmgr4data22CopyingDataTreeBuilder18ElementListBuilderE
+__ZTIN9configmgr4data22CopyingDataTreeBuilderE=configmg.__ZTIN9configmgr4data22CopyingDataTreeBuilderE
+__ZTIN9configmgr4data24ConvertingSubnodeBuilderE=configmg.__ZTIN9configmgr4data24ConvertingSubnodeBuilderE
+__ZTIN9configmgr4data25ConvertingDataTreeBuilder18ElementListBuilderE=configmg.__ZTIN9configmgr4data25ConvertingDataTreeBuilder18ElementListBuilderE
+__ZTIN9configmgr4data25ConvertingDataTreeBuilderE=configmg.__ZTIN9configmgr4data25ConvertingDataTreeBuilderE
+__ZTIN9configmgr4view11NodeFactoryE=configmg.__ZTIN9configmgr4view11NodeFactoryE
+__ZTIN9configmgr4view12ViewStrategyE=configmg.__ZTIN9configmgr4view12ViewStrategyE
+__ZTIN9configmgr4view18DirectViewStrategyE=configmg.__ZTIN9configmgr4view18DirectViewStrategyE
+__ZTIN9configmgr4view20DeferredViewStrategyE=configmg.__ZTIN9configmgr4view20DeferredViewStrategyE
+__ZTIN9configmgr4view20ReadOnlyViewStrategyE=configmg.__ZTIN9configmgr4view20ReadOnlyViewStrategyE
+__ZTIN9configmgr4view72_GLOBAL__N__ZNK9configmgr4view12ViewStrategy13checkInstanceERKNS0_4TreeE19GroupMemberDispatchE=configmg.__ZTIN9configmgr4view72_GLOBAL__N__ZNK9configmgr4view12ViewStrategy13checkInstanceERKNS0_4TreeE19GroupMemberDispatchE
+__ZTIN9configmgr5INodeE=configmg.__ZTIN9configmgr5INodeE
+__ZTIN9configmgr6ChangeE=configmg.__ZTIN9configmgr6ChangeE
+__ZTIN9configmgr6memory11HeapManagerE=configmg.__ZTIN9configmgr6memory11HeapManagerE
+__ZTIN9configmgr6memory14SimpleHeapLockE=configmg.__ZTIN9configmgr6memory14SimpleHeapLockE
+__ZTIN9configmgr6memory21SimpleHeapManagerBaseE=configmg.__ZTIN9configmgr6memory21SimpleHeapManagerBaseE
+__ZTIN9configmgr6memory25SimpleCheckingHeapManagerE=configmg.__ZTIN9configmgr6memory25SimpleCheckingHeapManagerE
+__ZTIN9configmgr6memory8DataLockE=configmg.__ZTIN9configmgr6memory8DataLockE
+__ZTIN9configmgr7AddNodeE=configmg.__ZTIN9configmgr7AddNodeE
+__ZTIN9configmgr7SubtreeE=configmg.__ZTIN9configmgr7SubtreeE
+__ZTIN9configmgr7backend10EmptyLayerE=configmg.__ZTIN9configmgr7backend10EmptyLayerE
+__ZTIN9configmgr7backend10NodeUpdateE=configmg.__ZTIN9configmgr7backend10NodeUpdateE
+__ZTIN9configmgr7backend11NamedUpdateE=configmg.__ZTIN9configmgr7backend11NamedUpdateE
+__ZTIN9configmgr7backend11NodeReplaceE=configmg.__ZTIN9configmgr7backend11NodeReplaceE
+__ZTIN9configmgr7backend11PropertyAddE=configmg.__ZTIN9configmgr7backend11PropertyAddE
+__ZTIN9configmgr7backend12ResultHolderINS0_12NodeInstanceEE10RCInstanceE=configmg.__ZTIN9configmgr7backend12ResultHolderINS0_12NodeInstanceEE10RCInstanceE
+__ZTIN9configmgr7backend12ResultHolderINS0_16TemplateInstanceEE10RCInstanceE=configmg.__ZTIN9configmgr7backend12ResultHolderINS0_16TemplateInstanceEE10RCInstanceE
+__ZTIN9configmgr7backend12ResultHolderINS0_17ComponentInstanceEE10RCInstanceE=configmg.__ZTIN9configmgr7backend12ResultHolderINS0_17ComponentInstanceEE10RCInstanceE
+__ZTIN9configmgr7backend13BackendAccessE=configmg.__ZTIN9configmgr7backend13BackendAccessE
+__ZTIN9configmgr7backend13ElementUpdateE=configmg.__ZTIN9configmgr7backend13ElementUpdateE
+__ZTIN9configmgr7backend13ImportServiceE=configmg.__ZTIN9configmgr7backend13ImportServiceE
+__ZTIN9configmgr7backend13PropertyResetE=configmg.__ZTIN9configmgr7backend13PropertyResetE
+__ZTIN9configmgr7backend13SchemaBuilderE=configmg.__ZTIN9configmgr7backend13SchemaBuilderE
+__ZTIN9configmgr7backend13UpdateServiceE=configmg.__ZTIN9configmgr7backend13UpdateServiceE
+__ZTIN9configmgr7backend14PropertyUpdateE=configmg.__ZTIN9configmgr7backend14PropertyUpdateE
+__ZTIN9configmgr7backend15CacheControllerE=configmg.__ZTIN9configmgr7backend15CacheControllerE
+__ZTIN9configmgr7backend16NodeModificationE=configmg.__ZTIN9configmgr7backend16NodeModificationE
+__ZTIN9configmgr7backend16UpdateDispatcherE=configmg.__ZTIN9configmgr7backend16UpdateDispatcherE
+__ZTIN9configmgr7backend17BasicUpdateMergerE=configmg.__ZTIN9configmgr7backend17BasicUpdateMergerE
+__ZTIN9configmgr7backend17BinaryReader_ImplE=configmg.__ZTIN9configmgr7backend17BinaryReader_ImplE
+__ZTIN9configmgr7backend17CopyImportServiceE=configmg.__ZTIN9configmgr7backend17CopyImportServiceE
+__ZTIN9configmgr7backend17INodeDataListenerE=configmg.__ZTIN9configmgr7backend17INodeDataListenerE
+__ZTIN9configmgr7backend17INodeDataProviderE=configmg.__ZTIN9configmgr7backend17INodeDataProviderE
+__ZTIN9configmgr7backend17LayerMergeHandlerE=configmg.__ZTIN9configmgr7backend17LayerMergeHandlerE
+__ZTIN9configmgr7backend17LayerUpdateMergerE=configmg.__ZTIN9configmgr7backend17LayerUpdateMergerE
+__ZTIN9configmgr7backend17RequireEmptyLayerE=configmg.__ZTIN9configmgr7backend17RequireEmptyLayerE
+__ZTIN9configmgr7backend18BasicImportHandlerE=configmg.__ZTIN9configmgr7backend18BasicImportHandlerE
+__ZTIN9configmgr7backend18BinaryWriteHandlerE=configmg.__ZTIN9configmgr7backend18BinaryWriteHandlerE
+__ZTIN9configmgr7backend18ImportMergeHandlerE=configmg.__ZTIN9configmgr7backend18ImportMergeHandlerE
+__ZTIN9configmgr7backend18LayerUpdateHandlerE=configmg.__ZTIN9configmgr7backend18LayerUpdateHandlerE
+__ZTIN9configmgr7backend18MergeImportServiceE=configmg.__ZTIN9configmgr7backend18MergeImportServiceE
+__ZTIN9configmgr7backend19ICachedDataListenerE=configmg.__ZTIN9configmgr7backend19ICachedDataListenerE
+__ZTIN9configmgr7backend19ICachedDataNotifierE=configmg.__ZTIN9configmgr7backend19ICachedDataNotifierE
+__ZTIN9configmgr7backend19ICachedDataProviderE=configmg.__ZTIN9configmgr7backend19ICachedDataProviderE
+__ZTIN9configmgr7backend19IDirectDataProviderE=configmg.__ZTIN9configmgr7backend19IDirectDataProviderE
+__ZTIN9configmgr7backend19IMergedDataProviderE=configmg.__ZTIN9configmgr7backend19IMergedDataProviderE
+__ZTIN9configmgr7backend19INodeUpdateProviderE=configmg.__ZTIN9configmgr7backend19INodeUpdateProviderE
+__ZTIN9configmgr7backend19LayerDefaultRemoverE=configmg.__ZTIN9configmgr7backend19LayerDefaultRemoverE
+__ZTIN9configmgr7backend19MultiStratumBackendE=configmg.__ZTIN9configmgr7backend19MultiStratumBackendE
+__ZTIN9configmgr7backend20IDefaultDataProviderE=configmg.__ZTIN9configmgr7backend20IDefaultDataProviderE
+__ZTIN9configmgr7backend20SingleBackendAdapterE=configmg.__ZTIN9configmgr7backend20SingleBackendAdapterE
+__ZTIN9configmgr7backend21BackendChangeNotifierE=configmg.__ZTIN9configmgr7backend21BackendChangeNotifierE
+__ZTIN9configmgr7backend21BackendStrataListenerE=configmg.__ZTIN9configmgr7backend21BackendStrataListenerE
+__ZTIN9configmgr7backend21IDataProviderMetaDataE=configmg.__ZTIN9configmgr7backend21IDataProviderMetaDataE
+__ZTIN9configmgr7backend21ITemplateDataProviderE=configmg.__ZTIN9configmgr7backend21ITemplateDataProviderE
+__ZTIN9configmgr7backend21OInvalidateTreeThreadE=configmg.__ZTIN9configmgr7backend21OInvalidateTreeThreadE
+__ZTIN9configmgr7backend22CacheChangeMulticasterE=configmg.__ZTIN9configmgr7backend22CacheChangeMulticasterE
+__ZTIN9configmgr7backend22IComponentDataProviderE=configmg.__ZTIN9configmgr7backend22IComponentDataProviderE
+__ZTIN9configmgr7backend8NodeDropE=configmg.__ZTIN9configmgr7backend8NodeDropE
+__ZTIN9configmgr7localbe16LocalDataStratumE=configmg.__ZTIN9configmgr7localbe16LocalDataStratumE
+__ZTIN9configmgr7localbe16LocalStratumBaseE=configmg.__ZTIN9configmgr7localbe16LocalStratumBaseE
+__ZTIN9configmgr7localbe17LocalMultiStratumE=configmg.__ZTIN9configmgr7localbe17LocalMultiStratumE
+__ZTIN9configmgr7localbe17LocalOutputStreamE=configmg.__ZTIN9configmgr7localbe17LocalOutputStreamE
+__ZTIN9configmgr7localbe18FlatLocalFileLayerE=configmg.__ZTIN9configmgr7localbe18FlatLocalFileLayerE
+__ZTIN9configmgr7localbe18LocalSingleBackendE=configmg.__ZTIN9configmgr7localbe18LocalSingleBackendE
+__ZTIN9configmgr7localbe18LocalSingleStratumE=configmg.__ZTIN9configmgr7localbe18LocalSingleStratumE
+__ZTIN9configmgr7localbe19BasicLocalFileLayerE=configmg.__ZTIN9configmgr7localbe19BasicLocalFileLayerE
+__ZTIN9configmgr7localbe19LayerPropertyHelperE=configmg.__ZTIN9configmgr7localbe19LayerPropertyHelperE
+__ZTIN9configmgr7localbe19LocalSchemaSupplierE=configmg.__ZTIN9configmgr7localbe19LocalSchemaSupplierE
+__ZTIN9configmgr7localbe20LocalReadonlyStratumE=configmg.__ZTIN9configmgr7localbe20LocalReadonlyStratumE
+__ZTIN9configmgr7localbe20LocalResourceStratumE=configmg.__ZTIN9configmgr7localbe20LocalResourceStratumE
+__ZTIN9configmgr7localbe20SimpleLocalFileLayerE=configmg.__ZTIN9configmgr7localbe20SimpleLocalFileLayerE
+__ZTIN9configmgr7localbe22LocalDataImportServiceE=configmg.__ZTIN9configmgr7localbe22LocalDataImportServiceE
+__ZTIN9configmgr7localbe22LocalSingleStratumBaseE=configmg.__ZTIN9configmgr7localbe22LocalSingleStratumBaseE
+__ZTIN9configmgr7localbe23CompositeLocalFileLayerE=configmg.__ZTIN9configmgr7localbe23CompositeLocalFileLayerE
+__ZTIN9configmgr7localbe23LocalStratumMutexHolderE=configmg.__ZTIN9configmgr7localbe23LocalStratumMutexHolderE
+__ZTIN9configmgr7localbe27FullCompositeLocalFileLayerE=configmg.__ZTIN9configmgr7localbe27FullCompositeLocalFileLayerE
+__ZTIN9configmgr7localbe28BasicCompositeLocalFileLayerE=configmg.__ZTIN9configmgr7localbe28BasicCompositeLocalFileLayerE
+__ZTIN9configmgr7localbe28LocalHierarchyBrowserServiceE=configmg.__ZTIN9configmgr7localbe28LocalHierarchyBrowserServiceE
+__ZTIN9configmgr8BasicSetE=configmg.__ZTIN9configmgr8BasicSetE
+__ZTIN9configmgr8ISubtreeE=configmg.__ZTIN9configmgr8ISubtreeE
+__ZTIN9configmgr8OOptionsE=configmg.__ZTIN9configmgr8OOptionsE
+__ZTIN9configmgr9CacheDataE=configmg.__ZTIN9configmgr9CacheDataE
+__ZTIN9configmgr9CacheLineE=configmg.__ZTIN9configmgr9CacheLineE
+__ZTIN9configmgr9OProviderE=configmg.__ZTIN9configmgr9OProviderE
+__ZTIN9configmgr9ValueNodeE=configmg.__ZTIN9configmgr9ValueNodeE
+__ZTIN9configmgr9apihelper15BroadcasterBaseE=configmg.__ZTIN9configmgr9apihelper15BroadcasterBaseE
+__ZTIN9configmgr9apihelper17PropertySetHelperE=configmg.__ZTIN9configmgr9apihelper17PropertySetHelperE
+__ZTIN9configmgr9apihelper18InteractionRequestE=configmg.__ZTIN9configmgr9apihelper18InteractionRequestE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task17XInteractionAbortEEE=configmg.__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task17XInteractionAbortEEE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task17XInteractionRetryEEE=configmg.__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task17XInteractionRetryEEE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task19XInteractionApproveEEE=configmg.__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task19XInteractionApproveEEE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task22XInteractionDisapproveEEE=configmg.__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task22XInteractionDisapproveEEE
+__ZTIN9configmgr9apihelper24SimpleInteractionRequestE=configmg.__ZTIN9configmgr9apihelper24SimpleInteractionRequestE
+__ZTIN9configmgr9apihelper31ConfigurationInteractionHandler7ContextE=configmg.__ZTIN9configmgr9apihelper31ConfigurationInteractionHandler7ContextE
+__ZTIN9configmgr9configapi10NodeAccessE=configmg.__ZTIN9configmgr9configapi10NodeAccessE
+__ZTIN9configmgr9configapi10SetElementE=configmg.__ZTIN9configmgr9configapi10SetElementE
+__ZTIN9configmgr9configapi11ApiTreeImpl16ComponentAdapterE=configmg.__ZTIN9configmgr9configapi11ApiTreeImpl16ComponentAdapterE
+__ZTIN9configmgr9configapi11Broadcaster4ImplE=configmg.__ZTIN9configmgr9configapi11Broadcaster4ImplE
+__ZTIN9configmgr9configapi11NodeElementE=configmg.__ZTIN9configmgr9configapi11NodeElementE
+__ZTIN9configmgr9configapi11OSetElementINS0_15NodeGroupAccessEEE=configmg.__ZTIN9configmgr9configapi11OSetElementINS0_15NodeGroupAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_17NodeSetInfoAccessEEE=configmg.__ZTIN9configmgr9configapi11OSetElementINS0_17NodeSetInfoAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_17NodeTreeSetAccessEEE=configmg.__ZTIN9configmgr9configapi11OSetElementINS0_17NodeTreeSetAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_18NodeValueSetAccessEEE=configmg.__ZTIN9configmgr9configapi11OSetElementINS0_18NodeValueSetAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_19NodeGroupInfoAccessEEE=configmg.__ZTIN9configmgr9configapi11OSetElementINS0_19NodeGroupInfoAccessEEE
+__ZTIN9configmgr9configapi11RootElementE=configmg.__ZTIN9configmgr9configapi11RootElementE
+__ZTIN9configmgr9configapi11TreeElementE=configmg.__ZTIN9configmgr9configapi11TreeElementE
+__ZTIN9configmgr9configapi12InnerElementE=configmg.__ZTIN9configmgr9configapi12InnerElementE
+__ZTIN9configmgr9configapi12NotifierImplE=configmg.__ZTIN9configmgr9configapi12NotifierImplE
+__ZTIN9configmgr9configapi13NodeSetAccessE=configmg.__ZTIN9configmgr9configapi13NodeSetAccessE
+__ZTIN9configmgr9configapi13OInnerElementINS0_15NodeGroupAccessEEE=configmg.__ZTIN9configmgr9configapi13OInnerElementINS0_15NodeGroupAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_17NodeSetInfoAccessEEE=configmg.__ZTIN9configmgr9configapi13OInnerElementINS0_17NodeSetInfoAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_17NodeTreeSetAccessEEE=configmg.__ZTIN9configmgr9configapi13OInnerElementINS0_17NodeTreeSetAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_18NodeValueSetAccessEEE=configmg.__ZTIN9configmgr9configapi13OInnerElementINS0_18NodeValueSetAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_19NodeGroupInfoAccessEEE=configmg.__ZTIN9configmgr9configapi13OInnerElementINS0_19NodeGroupInfoAccessEEE
+__ZTIN9configmgr9configapi14ObjectRegistryE=configmg.__ZTIN9configmgr9configapi14ObjectRegistryE
+__ZTIN9configmgr9configapi15ApiRootTreeImpl12NodeListenerE=configmg.__ZTIN9configmgr9configapi15ApiRootTreeImpl12NodeListenerE
+__ZTIN9configmgr9configapi15NodeGroupAccessE=configmg.__ZTIN9configmgr9configapi15NodeGroupAccessE
+__ZTIN9configmgr9configapi16CollectNodeNamesE=configmg.__ZTIN9configmgr9configapi16CollectNodeNamesE
+__ZTIN9configmgr9configapi16OReadRootElementINS0_17NodeSetInfoAccessEEE=configmg.__ZTIN9configmgr9configapi16OReadRootElementINS0_17NodeSetInfoAccessEEE
+__ZTIN9configmgr9configapi16OReadRootElementINS0_19NodeGroupInfoAccessEEE=configmg.__ZTIN9configmgr9configapi16OReadRootElementINS0_19NodeGroupInfoAccessEEE
+__ZTIN9configmgr9configapi17CollectPropertiesE=configmg.__ZTIN9configmgr9configapi17CollectPropertiesE
+__ZTIN9configmgr9configapi17NodeSetInfoAccessE=configmg.__ZTIN9configmgr9configapi17NodeSetInfoAccessE
+__ZTIN9configmgr9configapi17NodeTreeSetAccessE=configmg.__ZTIN9configmgr9configapi17NodeTreeSetAccessE
+__ZTIN9configmgr9configapi17UpdateRootElementE=configmg.__ZTIN9configmgr9configapi17UpdateRootElementE
+__ZTIN9configmgr9configapi18NodeValueSetAccessE=configmg.__ZTIN9configmgr9configapi18NodeValueSetAccessE
+__ZTIN9configmgr9configapi18OUpdateRootElementINS0_15NodeGroupAccessEEE=configmg.__ZTIN9configmgr9configapi18OUpdateRootElementINS0_15NodeGroupAccessEEE
+__ZTIN9configmgr9configapi18OUpdateRootElementINS0_17NodeTreeSetAccessEEE=configmg.__ZTIN9configmgr9configapi18OUpdateRootElementINS0_17NodeTreeSetAccessEEE
+__ZTIN9configmgr9configapi18OUpdateRootElementINS0_18NodeValueSetAccessEEE=configmg.__ZTIN9configmgr9configapi18OUpdateRootElementINS0_18NodeValueSetAccessEEE
+__ZTIN9configmgr9configapi19CollectPropertyInfoE=configmg.__ZTIN9configmgr9configapi19CollectPropertyInfoE
+__ZTIN9configmgr9configapi19NodeGroupInfoAccessE=configmg.__ZTIN9configmgr9configapi19NodeGroupInfoAccessE
+__ZTIN9configmgr9configapi19NodePropertySetInfoE=configmg.__ZTIN9configmgr9configapi19NodePropertySetInfoE
+__ZTIN9configmgr9configapi19UpdateObjectFactoryE=configmg.__ZTIN9configmgr9configapi19UpdateObjectFactoryE
+__ZTIN9configmgr9configapi21ReadOnlyObjectFactoryE=configmg.__ZTIN9configmgr9configapi21ReadOnlyObjectFactoryE
+__ZTIN9configmgr9configapi7FactoryE=configmg.__ZTIN9configmgr9configapi7FactoryE
+__ZTIN9configmgr9configapi8internal15SearchExactNameE=configmg.__ZTIN9configmgr9configapi8internal15SearchExactNameE
+__ZTIN9salhelper21SimpleReferenceObjectE=configmg.__ZTIN9salhelper21SimpleReferenceObjectE
+
+EXPORTS
+__ZTIN3com3sun4star3ucb31InteractiveAugmentedIOExceptionE
+__ZTIN3com3sun4star3ucb22InteractiveIOExceptionE
+__ZTIN3com3sun4star4task28ClassifiedInteractionRequestE
+__ZTIN3com3sun4star3ucb18NameClashExceptionE
+__ZTIN3com3sun4star3ucb27UnsupportedCommandExceptionE
+IMPORTS
+__ZTIN3com3sun4star3ucb31InteractiveAugmentedIOExceptionE=ucpfile1.__ZTIN3com3sun4star3ucb31InteractiveAugmentedIOExceptionE
+__ZTIN3com3sun4star3ucb22InteractiveIOExceptionE=ucpfile1.__ZTIN3com3sun4star3ucb22InteractiveIOExceptionE
+__ZTIN3com3sun4star4task28ClassifiedInteractionRequestE=ucpfile1.__ZTIN3com3sun4star4task28ClassifiedInteractionRequestE
+__ZTIN3com3sun4star3ucb18NameClashExceptionE=ucpfile1.__ZTIN3com3sun4star3ucb18NameClashExceptionE
+__ZTIN3com3sun4star3ucb27UnsupportedCommandExceptionE=ucpfile1.__ZTIN3com3sun4star3ucb27UnsupportedCommandExceptionE
+
+EXPORTS
+__ZTIN3com3sun4star3ucb34InteractiveBadTransferURLExceptionE
+IMPORTS
+__ZTIN3com3sun4star3ucb34InteractiveBadTransferURLExceptionE=ucb1.__ZTIN3com3sun4star3ucb34InteractiveBadTransferURLExceptionE
diff --git a/bridges/source/cpp_uno/gcc3_os2_intel/except.cxx b/bridges/source/cpp_uno/gcc3_os2_intel/except.cxx
new file mode 100644
index 000000000000..cf2936917bc0
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_os2_intel/except.cxx
@@ -0,0 +1,352 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#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"
+
+#ifdef TEST
+#include "test/TestBridgeException.hpp"
+#endif
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+//==================================================================================================
+//YD static handle to this dll, to allow rtti symbol lookup
+static void* hmod;
+
+//==================================================================================================
+//YD required to run test programs, because exe cannot export symbols!
+#ifdef TEST
+using namespace ::test;
+
+void dymmy_TestBridgeException() throw( ::test::TestBridgeException)
+{
+ throw TestBridgeException();
+}
+#endif
+
+//==================================================================================================
+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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ //void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+// : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+// dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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 iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("__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() );
+ //rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+ if (hmod == NULL)
+ hmod = dlopen( "gcc3_uno.dll", 0);
+
+ if (hmod)
+ rtti = (type_info *)dlsym( hmod, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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 = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 occured: %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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, 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 occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_os2_intel/makefile.mk b/bridges/source/cpp_uno/gcc3_os2_intel/makefile.mk
new file mode 100644
index 000000000000..04abbabe664c
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_os2_intel/makefile.mk
@@ -0,0 +1,77 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+NO_BSYMBOLIC=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCOS2Igcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=defs$/gcc3_uno.def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_os2_intel/share.hxx b/bridges/source/cpp_uno/gcc3_os2_intel/share.hxx
new file mode 100644
index 000000000000..7529230fde94
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_os2_intel/share.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
diff --git a/bridges/source/cpp_uno/gcc3_os2_intel/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_os2_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..f3f31236aea9
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_os2_intel/uno2cpp.cxx
@@ -0,0 +1,454 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <malloc.h>
+#include <sal/alloca.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.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 "share.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+// 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):
+static void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs );
+// __attribute__((noinline));
+
+//==================================================================================================
+static void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ 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
+
+ /* figure out the address of the function we need to invoke */
+ unsigned long * mfunc; // actual function to be invoked
+ int off; // offset used to find function
+ void (*ptr)();
+ off = nVtableIndex;
+ off = off * 4; // 4 bytes per slot
+ mfunc = *((unsigned long **)pAdjustedThisPtr); // get the address of the vtable
+ mfunc = (unsigned long *)((char *)mfunc + off); // get the address from the vtable entry at offset
+ mfunc = *((unsigned long **)mfunc); // the function is stored at the address
+ ptr = (void (*)())mfunc;
+
+ 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"
+ :
+ : "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr),
+ "m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr)
+ : "eax", "edx" );
+
+ (*ptr)();
+
+ asm volatile (
+ // 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", "edx" );
+ switch( eReturnType )
+ {
+ 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;
+ }
+}
+
+//==================================================================================================
+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 =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ 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 = *(void **)pCppStack
+ = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ 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
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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
+ }
+ // 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 );
+ 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *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 );
+
+ 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( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+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);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/gcc3_solaris_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_solaris_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..63457f7c7c95
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_intel/cpp2uno.cxx
@@ -0,0 +1,526 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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"
+
+using namespace ::com::sun::star::uno;
+
+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 ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // 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 = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+
+ 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
+ }
+ // 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 occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ 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(
+ rtl::OUString::createFromAscii("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] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ 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 );
+ *(void **)pRegisterReturn = pCallStack[1];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static void cpp_vtable_call(
+ int nFunctionIndex, int nVtableOffset, void** pCallStack )
+ __attribute__((regparm(3)));
+
+void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** pCallStack )
+{
+ volatile long nRegReturn[2];
+ typelib_TypeClass aType = cpp_mediate(
+ nFunctionIndex, nVtableOffset, pCallStack, (sal_Int64*)nRegReturn );
+
+ switch( aType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ __asm__( "movl %1, %%edx\n\t"
+ "movl %0, %%eax\n"
+ : : "m"(nRegReturn[0]), "m"(nRegReturn[1]) );
+ break;
+ case typelib_TypeClass_FLOAT:
+ __asm__( "flds %0\n\t"
+ "fstp %%st(0)\n\t"
+ "flds %0\n"
+ : : "m"(*(float *)nRegReturn) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ __asm__( "fldl %0\n\t"
+ "fstp %%st(0)\n\t"
+ "fldl %0\n"
+ : : "m"(*(double *)nRegReturn) );
+ break;
+// case typelib_TypeClass_UNSIGNED_SHORT:
+// case typelib_TypeClass_SHORT:
+// __asm__( "movswl %0, %%eax\n"
+// : : "m"(nRegReturn) );
+// break;
+ default:
+ __asm__( "movl %0, %%eax\n"
+ : : "m"(nRegReturn[0]) );
+ break;
+ }
+}
+
+
+//==================================================================================================
+int const codeSnippetSize = 20;
+
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool simpleRetType)
+{
+ if (!simpleRetType) {
+ functionIndex |= 0x80000000;
+ }
+ 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);
+ // mov %esp, %ecx:
+ *p++ = 0x89;
+ *p++ = 0xE1;
+ // jmp cpp_vtable_call:
+ *p++ = 0xE9;
+ *reinterpret_cast< sal_Int32 * >(p)
+ = ((unsigned char *) cpp_vtable_call) - 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,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ 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 *)
+{}
diff --git a/bridges/source/cpp_uno/gcc3_solaris_intel/except.cxx b/bridges/source/cpp_uno/gcc3_solaris_intel/except.cxx
new file mode 100644
index 000000000000..a04a8f6c9214
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_intel/except.cxx
@@ -0,0 +1,332 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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 iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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() +4;
+#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 = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 occured: %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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, 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 occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_solaris_intel/makefile.mk b/bridges/source/cpp_uno/gcc3_solaris_intel/makefile.mk
new file mode 100644
index 000000000000..0adc204a10f6
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_intel/makefile.mk
@@ -0,0 +1,77 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCSOLARISIgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_solaris_intel/share.hxx b/bridges/source/cpp_uno/gcc3_solaris_intel/share.hxx
new file mode 100644
index 000000000000..7529230fde94
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_intel/share.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
diff --git a/bridges/source/cpp_uno/gcc3_solaris_intel/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_solaris_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..9bda6dcf417f
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_intel/uno2cpp.cxx
@@ -0,0 +1,430 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+#include <sal/alloca.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.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 "share.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+static void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ 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", "edx" );
+ switch( eReturnType )
+ {
+ 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;
+ }
+}
+
+//==================================================================================================
+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 =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ 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 = *(void **)pCppStack
+ = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ 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
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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
+ }
+ // 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 );
+ 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *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 );
+
+ 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( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+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);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/gcc3_solaris_sparc/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_solaris_sparc/cpp2uno.cxx
new file mode 100644
index 000000000000..563991b05b56
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_sparc/cpp2uno.cxx
@@ -0,0 +1,567 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/data.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 <sal/alloca.h>
+
+using namespace com::sun::star::uno;
+
+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 ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // pCallStack: [ret ptr], this, params
+ char * pCppStack = (char *)pCallStack;
+
+ // 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 = pRegisterReturn; // direct way for simple types
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void**)pCppStack;
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ pCppStack += sizeof( void* );
+ }
+ }
+ // 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] = pUnoArgs[nPos] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack, pParamTypeDescr);
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ {
+ if ((reinterpret_cast< long >(pCppStack) & 7) != 0)
+ {
+ OSL_ASSERT( sizeof (double) == sizeof (sal_Int64) );
+ void * pDest = alloca( sizeof (sal_Int64) );
+ *reinterpret_cast< sal_Int32 * >(pDest) =
+ *reinterpret_cast< sal_Int32 const * >(pCppStack);
+ *(reinterpret_cast< sal_Int32 * >(pDest) + 1) =
+ *(reinterpret_cast< sal_Int32 const * >(pCppStack) + 1);
+ pCppArgs[nPos] = pUnoArgs[nPos] = pDest;
+ }
+ pCppStack += sizeof (sal_Int32); // extra long
+ 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 occured...
+ 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
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // 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 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: this, params
+ // eventual [ret*] lies at pCallStack -1
+ // so count down pCallStack by one to keep it simple
+ // pCallStack: this, params
+ // eventual [ret*] lies at pCallStack -1
+ // so count down pCallStack by one to keep it simple
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ static_cast< char * >(*pCallStack) - nVtableOffset);
+ if ((nFunctionIndex & 0x80000000) != 0) {
+ nFunctionIndex &= 0x7FFFFFFF;
+ --pCallStack;
+ }
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException( rtl::OUString::createFromAscii("illegal vtable index!"), (XInterface *)pCppI );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+#if defined BRIDGES_DEBUG
+ OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
+#endif
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[2] )->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[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = pCallStack[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(rtl::OUString::createFromAscii("no member description found!"), (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+ return eRet;
+}
+
+
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static void cpp_vtable_call()
+{
+ volatile sal_Int64 nRegReturn;
+ int nFunctionIndex;
+ void** pCallStack;
+ int vTableOffset;
+
+ __asm__( "st %%i0, %0\n\t"
+ "st %%i1, %1\n\t"
+ "st %%i2, %2\n\t"
+ : : "m"(nFunctionIndex), "m"(pCallStack), "m"(vTableOffset) );
+
+// fprintf(stderr,"cpp_mediate nFunctionIndex=%x\n",nFunctionIndex);
+// fflush(stderr);
+
+ sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False;
+ typelib_TypeClass aType =
+ cpp_mediate( nFunctionIndex, vTableOffset, pCallStack+17, (sal_Int64*)&nRegReturn );
+
+ switch( aType )
+ {
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ __asm__( "ld %0, %%l0\n\t"
+ "ldsb [%%l0], %%i0\n"
+ : : "m"(&nRegReturn) );
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ __asm__( "ld %0, %%l0\n\t"
+ "ldsh [%%l0], %%i0\n"
+ : : "m"(&nRegReturn) );
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+
+ __asm__( "ld %0, %%l0\n\t"
+ "ld [%%l0], %%i0\n\t"
+ "ld %1, %%l0\n\t"
+ "ld [%%l0], %%i1\n\t"
+ : : "m"(&nRegReturn), "m"(((long*)&nRegReturn) +1) );
+
+ break;
+ case typelib_TypeClass_FLOAT:
+ __asm__( "ld %0, %%l0\n\t"
+ "ld [%%l0], %%f0\n"
+ : : "m"(&nRegReturn) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ __asm__( "ld %0, %%l0\n\t"
+ "ldd [%%l0], %%f0\n"
+ : : "m"(&nRegReturn) );
+ break;
+ case typelib_TypeClass_VOID:
+ break;
+ default:
+ __asm__( "ld %0, %%l0\n\t"
+ "ld [%%l0], %%i0\n"
+ : : "m"(&nRegReturn) );
+ break;
+ }
+
+ if( bComplex )
+ {
+ __asm__( "add %i7, 4, %i7\n\t" );
+ // after call to complex return valued funcion there is an unimp instruction
+ }
+
+}
+//__________________________________________________________________________________________________
+
+int const codeSnippetSize = 56;
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool simpleRetType)
+{
+ sal_uInt32 index = functionIndex;
+ if (!simpleRetType) {
+ index |= 0x80000000;
+ }
+ unsigned int * p = reinterpret_cast< unsigned int * >(code);
+ OSL_ASSERT(sizeof (unsigned int) == 4);
+ // st %o0, [%sp+68]:
+ *p++ = 0xD023A044;
+ // st %o1, [%sp+72]:
+ *p++ = 0xD223A048;
+ // st %o2, [%sp+76]:
+ *p++ = 0xD423A04C;
+ // st %o3, [%sp+80]:
+ *p++ = 0xD623A050;
+ // st %o4, [%sp+84]:
+ *p++ = 0xD823A054;
+ // st %o5, [%sp+88]:
+ *p++ = 0xDA23A058;
+ // sethi %hi(index), %o0:
+ *p++ = 0x11000000 | (index >> 10);
+ // or %o0, %lo(index), %o0:
+ *p++ = 0x90122000 | (index & 0x3FF);
+ // sethi %hi(vtableOffset), %o2:
+ *p++ = 0x15000000 | (vtableOffset >> 10);
+ // or %o2, %lo(vtableOffset), %o2:
+ *p++ = 0x9412A000 | (vtableOffset & 0x3FF);
+ // sethi %hi(cpp_vtable_call), %o3:
+ *p++ = 0x17000000 | (reinterpret_cast< unsigned int >(cpp_vtable_call) >> 10);
+ // or %o3, %lo(cpp_vtable_call), %o3:
+ *p++ = 0x9612E000 | (reinterpret_cast< unsigned int >(cpp_vtable_call) & 0x3FF);
+ // jmpl %o3, %g0:
+ *p++ = 0x81C2C000;
+ // mov %sp, %o1:
+ *p++ = 0x9210000E;
+ OSL_ASSERT(
+ reinterpret_cast< unsigned char * >(p) - code <= codeSnippetSize);
+ return code + codeSnippetSize;
+}
+
+} //end of namespace
+
+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; //null
+ slots[-1].fn = 0; //destructor
+ 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,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vTableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vTableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ 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 *)
+ {
+ //TODO: IZ 25819 flush the instruction cache (there probably is OS support for this)
+ }
diff --git a/bridges/source/cpp_uno/gcc3_solaris_sparc/except.cxx b/bridges/source/cpp_uno/gcc3_solaris_sparc/except.cxx
new file mode 100644
index 000000000000..80884d013fdc
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_sparc/except.cxx
@@ -0,0 +1,330 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <stdio.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#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 defined BRIDGES_DEBUG
+ 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 defined BRIDGES_DEBUG
+ 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 hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+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 iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_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() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // 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() +4;
+#if defined BRIDGES_DEBUG
+ 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 = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 defined BRIDGES_DEBUG
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if defined _DEBUG
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if defined BRIDGES_DEBUG
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if defined _DEBUG
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/gcc3_solaris_sparc/makefile.mk b/bridges/source/cpp_uno/gcc3_solaris_sparc/makefile.mk
new file mode 100644
index 000000000000..253abffc2bc5
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_sparc/makefile.mk
@@ -0,0 +1,81 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)" == "GCCSOLARISS"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSNOOPT=-O0
+
+NOOPTFILES = \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/cpp2uno.obj
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+
+SHL1TARGET=$(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS= $(SLOFILES)
+SHL1LIBS =$(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_solaris_sparc/share.hxx b/bridges/source/cpp_uno/gcc3_solaris_sparc/share.hxx
new file mode 100644
index 000000000000..3ea6370f9a2c
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_sparc/share.hxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "uno/mapping.h"
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+
+inline char* adjustPointer( char* pIn, typelib_TypeDescription* pType )
+{
+ switch( pType->nSize )
+ {
+ case 1: return pIn + 3;
+ case 2: return pIn + 2;
+ case 3: return pIn + 1;
+ // Huh ? perhaps a char[3] ? Though that would be a pointer
+ // well, we have it anyway for symmetry
+ }
+ return pIn;
+}
+
+}
diff --git a/bridges/source/cpp_uno/gcc3_solaris_sparc/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_solaris_sparc/uno2cpp.cxx
new file mode 100644
index 000000000000..79ce6873fda9
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_sparc/uno2cpp.cxx
@@ -0,0 +1,598 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <malloc.h>
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.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 "share.hxx"
+
+#include <sal/alloca.h>
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+namespace
+{
+//==================================================================================================
+// 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):
+
+void callVirtualMethod( void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs ) __attribute__((noinline));
+
+void callVirtualMethod( void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ 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 o0 = 0, o1 = 0; // for register returns
+ volatile double f0d = 0;
+ volatile float f0f = 0;
+ volatile long long saveReg[7];
+
+ __asm__ (
+ // save registers
+ "std %%l0, [%4]\n\t"
+ "mov %4, %%l0\n\t"
+ "mov %%l0, %%l1\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%l2, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%l4, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%o0, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%o2, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%o4, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%l6, [%%l0]\n\t"
+ "mov %%l1, %%l7\n\t"
+
+ // increase our own stackframe if necessary
+ "mov %%sp, %%l3\n\t" // save stack ptr for readjustment
+
+ "subcc %%i5, 7, %%l0\n\t"
+ "ble .LmoveOn\n\t"
+ "nop\n\t"
+
+ "sll %%l0, 2, %%l0\n\t"
+ "add %%l0, 96, %%l0\n\t"
+ "mov %%sp, %%l1\n\t" // old stack ptr
+ "sub %%sp, %%l0, %%l0\n\t" // future stack ptr
+ "andcc %%l0, 7, %%g0\n\t" // align stack to 8
+ "be .LisAligned\n\t"
+ "nop\n\t"
+ "sub %%l0, 4, %%l0\n"
+ ".LisAligned:\n\t"
+ "mov %%l0, %%o5\n\t" // save newly computed stack ptr
+ "add %%g0, 16, %%o4\n"
+
+ // now copy longs down to save register window
+ // and local variables
+ ".LcopyDown:\n\t"
+ "ld [%%l1], %%l2\n\t"
+ "st %%l2,[%%l0]\n\t"
+ "add %%l0, 4, %%l0\n\t"
+ "add %%l1, 4, %%l1\n\t"
+ "subcc %%o4, 1, %%o4\n\t"
+ "bne .LcopyDown\n\t"
+
+ "mov %%o5, %%sp\n\t" // move new stack ptr (hopefully) atomically
+ // while register window is valid in both spaces
+ // (scheduling might hit in copyDown loop)
+
+ "sub %%i5, 7, %%l0\n\t" // copy parameters past the sixth to stack
+ "add %%i4, 28, %%l1\n\t"
+ "add %%sp, 92, %%l2\n"
+ ".LcopyLong:\n\t"
+ "ld [%%l1], %%o0\n\t"
+ "st %%o0, [%%l2]\n\t"
+ "add %%l1, 4, %%l1\n\t"
+ "add %%l2, 4, %%l2\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "bne .LcopyLong\n\t"
+ "nop\n"
+
+ ".LmoveOn:\n\t"
+ "mov %%i5, %%l0\n\t" // prepare out registers
+ "mov %%i4, %%l1\n\t"
+
+ "ld [%%l1], %%o0\n\t" // prepare complex return ptr
+ "st %%o0, [%%sp+64]\n\t"
+ "sub %%l0, 1, %%l0\n\t"
+ "add %%l1, 4, %%l1\n\t"
+
+ "ld [%%l1], %%o0\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o1\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o2\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o3\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o4\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o5\n"
+
+ ".LdoCall:\n\t"
+ "ld [%%i0], %%l0\n\t" // get vtable ptr
+
+"sll %%i1, 2, %%l6\n\t"
+// "add %%l6, 8, %%l6\n\t"
+ "add %%l6, %%l0, %%l0\n\t"
+// // vtable has 8byte wide entries,
+// // upper half contains 2 half words, of which the first
+// // is the this ptr patch !
+// // first entry is (or __tf)
+
+// "ldsh [%%l0], %%l6\n\t" // load this ptr patch
+// "add %%l6, %%o0, %%o0\n\t" // patch this ptr
+
+// "add %%l0, 4, %%l0\n\t" // get virtual function ptr
+ "ld [%%l0], %%l0\n\t"
+
+ "ld [%%i4], %%l2\n\t"
+ "subcc %%l2, %%g0, %%l2\n\t"
+ "bne .LcomplexCall\n\t"
+ "nop\n\t"
+ "call %%l0\n\t"
+ "nop\n\t"
+ "ba .LcallReturned\n\t"
+ "nop\n"
+ ".LcomplexCall:\n\t"
+ "call %%l0\n\t"
+ "nop\n\t"
+ "unimp\n"
+
+ ".LcallReturned:\n\t"
+ "mov %%l3, %%sp\n\t" // readjust stack so that our locals are where they belong
+ "st %%o0, %0\n\t" // save possible return registers into our locals
+ "st %%o1, %1\n\t"
+ "std %%f0, %2\n\t"
+ "st %%f0, %3\n\t"
+
+ // restore registers
+ "ldd [%%l7], %%l0\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%l2\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%l4\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%o0\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%o2\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%o4\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%l6\n\t"
+ : :
+ "m"(o0),
+ "m"(o1),
+ "m"(f0d),
+ "m"(f0f),
+ "r"(&saveReg[0])
+ );
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = o1;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = o0;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = (unsigned short)o0;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)o0;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = f0f;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = f0d;
+ break;
+ }
+}
+
+//=================================================================================================
+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, this, values|ptr ...
+ char * pCppStack =
+ (char *)alloca( (nParams+2) * sizeof(sal_Int64) );
+ 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
+ *(void**)pCppStack = NULL;
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack = (bridges::cpp_uno::shared::relatesToInterfaceType(pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ }
+ 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
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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 ))
+ {
+ pCppArgs[ nPos ] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack, pParamTypeDescr );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ OSL_ASSERT( sizeof (double) == sizeof (sal_Int64) );
+ *reinterpret_cast< sal_Int32 * >(pCppStack) =
+ *reinterpret_cast< sal_Int32 const * >(pUnoArgs[ nPos ]);
+ pCppStack += sizeof (sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(pCppStack) =
+ *(reinterpret_cast< sal_Int32 const * >(pUnoArgs[ nPos ] ) + 1);
+ break;
+ default:
+ uno_copyAndConvertData(
+ pCppArgs[nPos], pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ 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 );
+ 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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
+ {
+ int nStackLongs = (pCppStack - pCppStackStart)/sizeof(sal_Int32);
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic" );
+
+ if( nStackLongs & 1 )
+ // stack has to be 8 byte aligned
+ nStackLongs++;
+ callVirtualMethod(
+ pAdjustedThisPtr,
+ aVtableSlot.index,
+ pCppReturn,
+ pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart,
+ nStackLongs);
+ // NO exception occured...
+ *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 );
+
+ 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( ... )
+ {
+ // get exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+#if defined BRIDGES_DEBUG
+ OString cstr( OUStringToOString( pMemberDescr->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "received dispatch( %s )\n", cstr.getStr() );
+#endif
+
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ 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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/mingw_intel/call.s b/bridges/source/cpp_uno/mingw_intel/call.s
new file mode 100644
index 000000000000..47327d9a4650
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/call.s
@@ -0,0 +1,261 @@
+ .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_intel/cpp2uno.cxx b/bridges/source/cpp_uno/mingw_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..f9ffe7c1a46d
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/cpp2uno.cxx
@@ -0,0 +1,521 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#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 occured...
+ 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 occured...
+ {
+ // 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(
+ rtl::OUString::createFromAscii("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(
+ rtl::OUString::createFromAscii("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;
+ 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 *)
+{}
diff --git a/bridges/source/cpp_uno/mingw_intel/dllinit.cxx b/bridges/source/cpp_uno/mingw_intel/dllinit.cxx
new file mode 100644
index 000000000000..75f8043d1ad3
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/dllinit.cxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: dllinit.cxx,v $
+ * $Revision: 1.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+
+#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;
+}
diff --git a/bridges/source/cpp_uno/mingw_intel/except.cxx b/bridges/source/cpp_uno/mingw_intel/except.cxx
new file mode 100644
index 000000000000..5285b709b7b5
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/except.cxx
@@ -0,0 +1,317 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#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 hash_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( RTL_CONSTASCII_STRINGPARAM("__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;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void 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 occured: %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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, 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 occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("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_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
diff --git a/bridges/source/cpp_uno/mingw_intel/makefile.mk b/bridges/source/cpp_uno/mingw_intel/makefile.mk
new file mode 100644
index 000000000000..242d21617d5e
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/makefile.mk
@@ -0,0 +1,98 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)" == "GCC"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+.IF "$(EXCEPTIONS)" == "sjlj"
+CFLAGS += -DBROKEN_ALLOCA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer
+
+NOOPTFILES= \
+ $(SLO)$/uno2cpp.obj
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/dllinit.obj \
+ $(SLO)$/smallstruct.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+DEF1NAME= $(SHL1TARGET)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+#cmc: Ideally --noexecstack would be in operations, but with #i51385# pyuno
+#remote bridgeing breaks
+# $(CC) -Wa,--noexecstack -c -o $(SLO)$/$(@:b).o $<
+ $(CC) -c -o $(SLO)$/$(@:b).obj $<
+ touch $@
diff --git a/bridges/source/cpp_uno/mingw_intel/share.hxx b/bridges/source/cpp_uno/mingw_intel/share.hxx
new file mode 100644
index 000000000000..6aa69f0470e4
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/share.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+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;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
diff --git a/bridges/source/cpp_uno/mingw_intel/smallstruct.cxx b/bridges/source/cpp_uno/mingw_intel/smallstruct.cxx
new file mode 100644
index 000000000000..26e05ba73b51
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/smallstruct.cxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: $
+ * $Revision: $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#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));
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/mingw_intel/smallstruct.hxx b/bridges/source/cpp_uno/mingw_intel/smallstruct.hxx
new file mode 100644
index 000000000000..e676778a8430
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/smallstruct.hxx
@@ -0,0 +1,38 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: $
+ * $Revision: $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+bool isSmallStruct(typelib_TypeDescription const * type);
+
+} } }
diff --git a/bridges/source/cpp_uno/mingw_intel/uno2cpp.cxx b/bridges/source/cpp_uno/mingw_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..f6b6a1c6511d
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/uno2cpp.cxx
@@ -0,0 +1,503 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#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 "share.hxx"
+#include "smallstruct.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+// 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):
+void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeDescription const * returnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs ) __attribute__((noinline));
+
+void 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", "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;
+ }
+}
+
+//==================================================================================================
+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)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *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( CPPU_CURRENT_NAMESPACE::__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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx b/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..7b21b5d53f23
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
@@ -0,0 +1,491 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.20 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#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 "msci.hxx"
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+static inline 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 ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // pCallStack: ret, this, [complex return ptr], params
+ char * pCppStack = (char *)(pCallStack +2);
+
+ // 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 = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+
+ // 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 occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ while (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::msci_raiseException(
+ &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ while (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 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+//==================================================================================================
+static typelib_TypeClass __cdecl cpp_mediate(
+ void ** pCallStack, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: ret adr, this, [ret *], params
+ void * pThis = static_cast< char * >(pCallStack[1]) - 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( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("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] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ // standard XInterface vtable calls
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ 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[2] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = pCallStack[2];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("no member description found!") ),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static __declspec(naked) void __cdecl cpp_vtable_call(void)
+{
+__asm
+ {
+ sub esp, 8 // space for immediate return type
+ push esp
+ push edx // vtable offset
+ push eax // function index
+ mov eax, esp
+ add eax, 20
+ push eax // original stack ptr
+
+ call cpp_mediate
+ add esp, 16
+
+ cmp eax, typelib_TypeClass_FLOAT
+ je Lfloat
+ cmp eax, typelib_TypeClass_DOUBLE
+ je Ldouble
+ cmp eax, typelib_TypeClass_HYPER
+ je Lhyper
+ cmp eax, typelib_TypeClass_UNSIGNED_HYPER
+ je Lhyper
+ // rest is eax
+ pop eax
+ add esp, 4
+ ret
+Lhyper:
+ pop eax
+ pop edx
+ ret
+Lfloat:
+ fld dword ptr [esp]
+ add esp, 8
+ ret
+Ldouble:
+ fld qword ptr [esp]
+ add esp, 8
+ ret
+ }
+}
+
+//==================================================================================================
+int const codeSnippetSize = 16;
+
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset)
+{
+ unsigned char * p = code;
+ OSL_ASSERT(sizeof (sal_Int32) == 4);
+ // mov eax, functionIndex:
+ *p++ = 0xB8;
+ *reinterpret_cast< sal_Int32 * >(p) = functionIndex;
+ p += sizeof (sal_Int32);
+ // mov edx, vtableOffset:
+ *p++ = 0xBA;
+ *reinterpret_cast< sal_Int32 * >(p) = vtableOffset;
+ p += sizeof (sal_Int32);
+ // jmp rel32 cpp_vtable_call:
+ *p++ = 0xE9;
+ *reinterpret_cast< sal_Int32 * >(p)
+ = ((unsigned char *) cpp_vtable_call) - 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) + 1;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 1) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ struct Rtti {
+ sal_Int32 n0, n1, n2;
+ type_info * rtti;
+ Rtti():
+ n0(0), n1(0), n2(0),
+ rtti(CPPU_CURRENT_NAMESPACE::msci_getRTTI(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.uno.XInterface"))))
+ {}
+ };
+ static Rtti rtti;
+
+ Slot * slots = mapBlockToVtable(block);
+ slots[-1].fn = &rtti;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code,
+ typelib_InterfaceTypeDescription const *, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < functionCount; ++i) {
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *, unsigned char const *)
+{}
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/dllinit.cxx b/bridges/source/cpp_uno/msvc_win32_intel/dllinit.cxx
new file mode 100644
index 000000000000..51624c3022ea
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/dllinit.cxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: dllinit.cxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+
+#pragma warning(push,1) // disable warnings within system headers
+#include <windows.h>
+#pragma warning(pop)
+
+
+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;
+}
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/except.cxx b/bridges/source/cpp_uno/msvc_win32_intel/except.cxx
new file mode 100644
index 000000000000..fbdf13680aae
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/except.cxx
@@ -0,0 +1,635 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.17 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#pragma warning( disable : 4237 )
+#include <hash_map>
+#include <sal/config.h>
+#include <malloc.h>
+#include <new.h>
+#include <typeinfo.h>
+#include <signal.h>
+
+#include "rtl/alloc.h"
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+
+#include "com/sun/star/uno/Any.hxx"
+
+#include "msci.hxx"
+
+
+#pragma pack(push, 8)
+
+using namespace ::com::sun::star::uno;
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+//==================================================================================================
+static inline OUString toUNOname( OUString const & rRTTIname ) throw ()
+{
+ OUStringBuffer aRet( 64 );
+ OUString aStr( rRTTIname.copy( 4, rRTTIname.getLength()-4-2 ) ); // filter .?AUzzz@yyy@xxx@@
+ sal_Int32 nPos = aStr.getLength();
+ while (nPos > 0)
+ {
+ sal_Int32 n = aStr.lastIndexOf( '@', nPos );
+ aRet.append( aStr.copy( n +1, nPos -n -1 ) );
+ if (n >= 0)
+ {
+ aRet.append( (sal_Unicode)'.' );
+ }
+ nPos = n;
+ }
+ return aRet.makeStringAndClear();
+}
+//==================================================================================================
+static inline OUString toRTTIname( OUString const & rUNOname ) throw ()
+{
+ OUStringBuffer aRet( 64 );
+ aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM(".?AV") ); // class ".?AV"; struct ".?AU"
+ sal_Int32 nPos = rUNOname.getLength();
+ while (nPos > 0)
+ {
+ sal_Int32 n = rUNOname.lastIndexOf( '.', nPos );
+ aRet.append( rUNOname.copy( n +1, nPos -n -1 ) );
+ aRet.append( (sal_Unicode)'@' );
+ nPos = n;
+ }
+ aRet.append( (sal_Unicode)'@' );
+ return aRet.makeStringAndClear();
+}
+
+
+//##################################################################################################
+//#### RTTI simulation #############################################################################
+//##################################################################################################
+
+
+typedef hash_map< OUString, void *, OUStringHash, equal_to< OUString > > t_string2PtrMap;
+
+//==================================================================================================
+class RTTInfos
+{
+ Mutex _aMutex;
+ t_string2PtrMap _allRTTI;
+
+ static OUString toRawName( OUString const & rUNOname ) throw ();
+public:
+ type_info * getRTTI( OUString const & rUNOname ) throw ();
+
+ RTTInfos();
+ ~RTTInfos();
+};
+
+//==================================================================================================
+class __type_info
+{
+ friend type_info * RTTInfos::getRTTI( OUString const & ) throw ();
+ friend int msci_filterCppException(
+ LPEXCEPTION_POINTERS, uno_Any *, uno_Mapping * );
+
+public:
+ virtual ~__type_info() throw ();
+
+ inline __type_info( void * m_data, const char * m_d_name ) throw ()
+ : _m_data( m_data )
+ { ::strcpy( _m_d_name, m_d_name ); } // #100211# - checked
+
+private:
+ void * _m_data;
+ char _m_d_name[1];
+};
+//__________________________________________________________________________________________________
+__type_info::~__type_info() throw ()
+{
+}
+//__________________________________________________________________________________________________
+type_info * RTTInfos::getRTTI( OUString const & rUNOname ) throw ()
+{
+ // a must be
+ OSL_ENSURE( sizeof(__type_info) == sizeof(type_info), "### type info structure size differ!" );
+
+ MutexGuard aGuard( _aMutex );
+ t_string2PtrMap::const_iterator const iFind( _allRTTI.find( rUNOname ) );
+
+ // check if type is already available
+ if (iFind == _allRTTI.end())
+ {
+ // insert new type_info
+ OString aRawName( OUStringToOString( toRTTIname( rUNOname ), RTL_TEXTENCODING_ASCII_US ) );
+ __type_info * pRTTI = new( ::rtl_allocateMemory( sizeof(__type_info) + aRawName.getLength() ) )
+ __type_info( NULL, aRawName.getStr() );
+
+ // put into map
+ pair< t_string2PtrMap::iterator, bool > insertion(
+ _allRTTI.insert( t_string2PtrMap::value_type( rUNOname, pRTTI ) ) );
+ OSL_ENSURE( insertion.second, "### rtti insertion failed?!" );
+
+ return (type_info *)pRTTI;
+ }
+ else
+ {
+ return (type_info *)iFind->second;
+ }
+}
+//__________________________________________________________________________________________________
+RTTInfos::RTTInfos() throw ()
+{
+}
+//__________________________________________________________________________________________________
+RTTInfos::~RTTInfos() throw ()
+{
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "> freeing generated RTTI infos... <\n" );
+#endif
+
+ MutexGuard aGuard( _aMutex );
+ for ( t_string2PtrMap::const_iterator iPos( _allRTTI.begin() );
+ iPos != _allRTTI.end(); ++iPos )
+ {
+ __type_info * pType = (__type_info *)iPos->second;
+ pType->~__type_info(); // obsolete, but good style...
+ ::rtl_freeMemory( pType );
+ }
+}
+
+
+//##################################################################################################
+//#### Exception raising ###########################################################################
+//##################################################################################################
+
+
+//==================================================================================================
+struct ObjectFunction
+{
+ char somecode[12];
+ typelib_TypeDescription * _pTypeDescr; // type of object
+
+ inline static void * operator new ( size_t nSize );
+ inline static void operator delete ( void * pMem );
+
+ ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpFunc ) throw ();
+ ~ObjectFunction() throw ();
+};
+
+inline void * ObjectFunction::operator new ( size_t nSize )
+{
+ void * pMem = rtl_allocateMemory( nSize );
+ if (pMem != 0)
+ {
+ DWORD old_protect;
+#if OSL_DEBUG_LEVEL > 0
+ BOOL success =
+#endif
+ VirtualProtect( pMem, nSize, PAGE_EXECUTE_READWRITE, &old_protect );
+ OSL_ENSURE( success, "VirtualProtect() failed!" );
+ }
+ return pMem;
+}
+
+inline void ObjectFunction::operator delete ( void * pMem )
+{
+ rtl_freeMemory( pMem );
+}
+
+//__________________________________________________________________________________________________
+ObjectFunction::ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpFunc ) throw ()
+ : _pTypeDescr( pTypeDescr )
+{
+ ::typelib_typedescription_acquire( _pTypeDescr );
+
+ unsigned char * pCode = (unsigned char *)somecode;
+ // a must be!
+ OSL_ENSURE( (void *)this == (void *)pCode, "### unexpected!" );
+
+ // push ObjectFunction this
+ *pCode++ = 0x68;
+ *(void **)pCode = this;
+ pCode += sizeof(void *);
+ // jmp rel32 fpFunc
+ *pCode++ = 0xe9;
+ *(sal_Int32 *)pCode = ((unsigned char *)fpFunc) - pCode - sizeof(sal_Int32);
+}
+//__________________________________________________________________________________________________
+ObjectFunction::~ObjectFunction() throw ()
+{
+ ::typelib_typedescription_release( _pTypeDescr );
+}
+
+//==================================================================================================
+static void * __cdecl __copyConstruct( void * pExcThis, void * pSource, ObjectFunction * pThis )
+ throw ()
+{
+ ::uno_copyData( pExcThis, pSource, pThis->_pTypeDescr, cpp_acquire );
+ return pExcThis;
+}
+//==================================================================================================
+static void * __cdecl __destruct( void * pExcThis, ObjectFunction * pThis )
+ throw ()
+{
+ ::uno_destructData( pExcThis, pThis->_pTypeDescr, cpp_release );
+ return pExcThis;
+}
+
+// these are non virtual object methods; there is no this ptr on stack => ecx supplies _this_ ptr
+
+//==================================================================================================
+static __declspec(naked) void copyConstruct() throw ()
+{
+ __asm
+ {
+ // ObjectFunction this already on stack
+ push [esp+8] // source exc object this
+ push ecx // exc object
+ call __copyConstruct
+ add esp, 12 // + ObjectFunction this
+ ret 4
+ }
+}
+//==================================================================================================
+static __declspec(naked) void destruct() throw ()
+{
+ __asm
+ {
+ // ObjectFunction this already on stack
+ push ecx // exc object
+ call __destruct
+ add esp, 8 // + ObjectFunction this
+ ret
+ }
+}
+
+//==================================================================================================
+struct ExceptionType
+{
+ sal_Int32 _n0;
+ type_info * _pTypeInfo;
+ sal_Int32 _n1, _n2, _n3, _n4;
+ ObjectFunction * _pCopyCtor;
+ sal_Int32 _n5;
+
+ inline ExceptionType( typelib_TypeDescription * pTypeDescr ) throw ()
+ : _n0( 0 )
+ , _n1( 0 )
+ , _n2( -1 )
+ , _n3( 0 )
+ , _n4( pTypeDescr->nSize )
+ , _pCopyCtor( new ObjectFunction( pTypeDescr, copyConstruct ) )
+ , _n5( 0 )
+ { _pTypeInfo = msci_getRTTI( pTypeDescr->pTypeName ); }
+ inline ~ExceptionType() throw ()
+ { delete _pCopyCtor; }
+};
+//==================================================================================================
+struct RaiseInfo
+{
+ sal_Int32 _n0;
+ ObjectFunction * _pDtor;
+ sal_Int32 _n2;
+ void * _types;
+ sal_Int32 _n3, _n4;
+
+ RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ();
+ ~RaiseInfo() throw ();
+};
+//__________________________________________________________________________________________________
+RaiseInfo::RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ()
+ : _n0( 0 )
+ , _pDtor( new ObjectFunction( pTypeDescr, destruct ) )
+ , _n2( 0 )
+ , _n3( 0 )
+ , _n4( 0 )
+{
+ // a must be
+ OSL_ENSURE( sizeof(sal_Int32) == sizeof(ExceptionType *), "### pointer size differs from sal_Int32!" );
+
+ typelib_CompoundTypeDescription * pCompTypeDescr;
+
+ // info count
+ sal_Int32 nLen = 0;
+ for ( pCompTypeDescr = (typelib_CompoundTypeDescription*)pTypeDescr;
+ pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
+ {
+ ++nLen;
+ }
+
+ // info count accompanied by type info ptrs: type, base type, base base type, ...
+ _types = ::rtl_allocateMemory( sizeof(sal_Int32) + (sizeof(ExceptionType *) * nLen) );
+ *(sal_Int32 *)_types = nLen;
+
+ ExceptionType ** ppTypes = (ExceptionType **)((sal_Int32 *)_types + 1);
+
+ sal_Int32 nPos = 0;
+ for ( pCompTypeDescr = (typelib_CompoundTypeDescription*)pTypeDescr;
+ pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
+ {
+ ppTypes[nPos++] = new ExceptionType( (typelib_TypeDescription *)pCompTypeDescr );
+ }
+}
+//__________________________________________________________________________________________________
+RaiseInfo::~RaiseInfo() throw ()
+{
+ ExceptionType ** ppTypes = (ExceptionType **)((sal_Int32 *)_types + 1);
+ for ( sal_Int32 nTypes = *(sal_Int32 *)_types; nTypes--; )
+ {
+ delete ppTypes[nTypes];
+ }
+ ::rtl_freeMemory( _types );
+
+ delete _pDtor;
+}
+
+//==================================================================================================
+class ExceptionInfos
+{
+ Mutex _aMutex;
+ t_string2PtrMap _allRaiseInfos;
+
+public:
+ static void * getRaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ();
+
+ ExceptionInfos() throw ();
+ ~ExceptionInfos() throw ();
+};
+//__________________________________________________________________________________________________
+ExceptionInfos::ExceptionInfos() throw ()
+{
+}
+//__________________________________________________________________________________________________
+ExceptionInfos::~ExceptionInfos() throw ()
+{
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "> freeing exception infos... <\n" );
+#endif
+
+ MutexGuard aGuard( _aMutex );
+ for ( t_string2PtrMap::const_iterator iPos( _allRaiseInfos.begin() );
+ iPos != _allRaiseInfos.end(); ++iPos )
+ {
+ delete (RaiseInfo *)iPos->second;
+ }
+}
+//__________________________________________________________________________________________________
+void * ExceptionInfos::getRaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ()
+{
+ static ExceptionInfos * s_pInfos = 0;
+ if (! s_pInfos)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_pInfos)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_pInfos = new ExceptionInfos();
+#else
+ static ExceptionInfos s_allExceptionInfos;
+ s_pInfos = &s_allExceptionInfos;
+#endif
+ }
+ }
+
+ OSL_ASSERT( pTypeDescr &&
+ (pTypeDescr->eTypeClass == typelib_TypeClass_STRUCT ||
+ pTypeDescr->eTypeClass == typelib_TypeClass_EXCEPTION) );
+
+ void * pRaiseInfo;
+
+ OUString const & rTypeName = *reinterpret_cast< OUString * >( &pTypeDescr->pTypeName );
+ MutexGuard aGuard( s_pInfos->_aMutex );
+ t_string2PtrMap::const_iterator const iFind(
+ s_pInfos->_allRaiseInfos.find( rTypeName ) );
+ if (iFind == s_pInfos->_allRaiseInfos.end())
+ {
+ pRaiseInfo = new RaiseInfo( pTypeDescr );
+ // put into map
+ pair< t_string2PtrMap::iterator, bool > insertion(
+ s_pInfos->_allRaiseInfos.insert( t_string2PtrMap::value_type( rTypeName, pRaiseInfo ) ) );
+ OSL_ENSURE( insertion.second, "### raise info insertion failed?!" );
+ }
+ else
+ {
+ // reuse existing info
+ pRaiseInfo = iFind->second;
+ }
+
+ return pRaiseInfo;
+}
+
+
+//##################################################################################################
+//#### exported ####################################################################################
+//##################################################################################################
+
+
+//##################################################################################################
+type_info * msci_getRTTI( OUString const & rUNOname )
+{
+ static RTTInfos * s_pRTTIs = 0;
+ if (! s_pRTTIs)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_pRTTIs)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_pRTTIs = new RTTInfos();
+#else
+ static RTTInfos s_aRTTIs;
+ s_pRTTIs = &s_aRTTIs;
+#endif
+ }
+ }
+ return s_pRTTIs->getRTTI( rUNOname );
+}
+
+//##################################################################################################
+void msci_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+ // no ctor/dtor in here: this leads to dtors called twice upon RaiseException()!
+ // thus this obj file will be compiled without opt, so no inling of
+ // ExceptionInfos::getRaiseInfo()
+
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+
+ void * pCppExc = alloca( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // a must be
+ OSL_ENSURE(
+ sizeof(sal_Int32) == sizeof(void *),
+ "### pointer size differs from sal_Int32!" );
+ DWORD arFilterArgs[3];
+ arFilterArgs[0] = MSVC_magic_number;
+ arFilterArgs[1] = (DWORD)pCppExc;
+ arFilterArgs[2] = (DWORD)ExceptionInfos::getRaiseInfo( pTypeDescr );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+
+ // last point to release anything not affected by stack unwinding
+ RaiseException( MSVC_ExceptionCode, EXCEPTION_NONCONTINUABLE, 3, arFilterArgs );
+}
+
+//##############################################################################
+int msci_filterCppException(
+ EXCEPTION_POINTERS * pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+{
+ if (pPointers == 0)
+ return EXCEPTION_CONTINUE_SEARCH;
+ EXCEPTION_RECORD * pRecord = pPointers->ExceptionRecord;
+ // handle only C++ exceptions:
+ if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+#if _MSC_VER < 1300 // MSVC -6
+ bool rethrow = (pRecord->NumberParameters < 3 ||
+ pRecord->ExceptionInformation[ 2 ] == 0);
+#else
+ bool rethrow = __CxxDetectRethrow( &pRecord );
+ OSL_ASSERT( pRecord == pPointers->ExceptionRecord );
+#endif
+ if (rethrow && pRecord == pPointers->ExceptionRecord)
+ {
+ // hack to get msvcrt internal _curexception field:
+ pRecord = *reinterpret_cast< EXCEPTION_RECORD ** >(
+ reinterpret_cast< char * >( __pxcptinfoptrs() ) +
+ // as long as we don't demand msvcr source as build prerequisite
+ // (->platform sdk), we have to code those offsets here.
+ //
+ // crt\src\mtdll.h:
+ // offsetof (_tiddata, _curexception) -
+ // offsetof (_tiddata, _tpxcptinfoptrs):
+#if _MSC_VER < 1300
+ 0x18 // msvcrt,dll
+#elif _MSC_VER < 1310
+ 0x20 // msvcr70.dll
+#elif _MSC_VER < 1400
+ 0x24 // msvcr71.dll
+#else
+ 0x28 // msvcr80.dll
+#endif
+ );
+ }
+ // rethrow: handle only C++ exceptions:
+ if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ if (pRecord->NumberParameters == 3 &&
+// pRecord->ExceptionInformation[ 0 ] == MSVC_magic_number &&
+ pRecord->ExceptionInformation[ 1 ] != 0 &&
+ pRecord->ExceptionInformation[ 2 ] != 0)
+ {
+ void * types = reinterpret_cast< RaiseInfo * >(
+ pRecord->ExceptionInformation[ 2 ] )->_types;
+ if (types != 0 && *reinterpret_cast< DWORD * >( types ) > 0) // count
+ {
+ ExceptionType * pType = *reinterpret_cast< ExceptionType ** >(
+ reinterpret_cast< DWORD * >( types ) + 1 );
+ if (pType != 0 && pType->_pTypeInfo != 0)
+ {
+ OUString aRTTIname(
+ OStringToOUString(
+ reinterpret_cast< __type_info * >(
+ pType->_pTypeInfo )->_m_d_name,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OUString aUNOname( toUNOname( aRTTIname ) );
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ typelib_typedescription_getByName(
+ &pExcTypeDescr, aUNOname.pData );
+ if (pExcTypeDescr == 0)
+ {
+ OUStringBuffer buf;
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM(
+ "[msci_uno bridge error] UNO type of "
+ "C++ exception unknown: \"") );
+ buf.append( aUNOname );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "\", RTTI-name=\"") );
+ buf.append( aRTTIname );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
+ RuntimeException exc(
+ buf.makeStringAndClear(), Reference< XInterface >() );
+ uno_type_any_constructAndConvert(
+ pUnoExc, &exc,
+ ::getCppuType( &exc ).getTypeLibType(), pCpp2Uno );
+#if _MSC_VER < 1400 // msvcr80.dll cleans up, different from former msvcrs
+ // if (! rethrow):
+ // though this unknown exception leaks now, no user-defined
+ // exception is ever thrown thru the binary C-UNO dispatcher
+ // call stack.
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert(
+ pUnoExc, (void *) pRecord->ExceptionInformation[1],
+ pExcTypeDescr, pCpp2Uno );
+#if _MSC_VER < 1400 // msvcr80.dll cleans up, different from former msvcrs
+ if (! rethrow)
+ {
+ uno_destructData(
+ (void *) pRecord->ExceptionInformation[1],
+ pExcTypeDescr, cpp_release );
+ }
+#endif
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
+ }
+ }
+ // though this unknown exception leaks now, no user-defined exception
+ // is ever thrown thru the binary C-UNO dispatcher call stack.
+ RuntimeException exc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "[msci_uno bridge error] unexpected "
+ "C++ exception occured!") ),
+ Reference< XInterface >() );
+ uno_type_any_constructAndConvert(
+ pUnoExc, &exc, ::getCppuType( &exc ).getTypeLibType(), pCpp2Uno );
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+}
+
+#pragma pack(pop)
+
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/makefile.mk b/bridges/source/cpp_uno/msvc_win32_intel/makefile.mk
new file mode 100644
index 000000000000..b044c09571ba
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/makefile.mk
@@ -0,0 +1,87 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.16 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=msci_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+.IF "$(COM)" == "MSC"
+
+.IF "$(debug)" != ""
+CFLAGS += -Ob0
+.ENDIF
+
+.IF "$(cppu_no_leak)" == ""
+.IF "$(bndchk)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+.ENDIF
+
+
+SLOFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/dllinit.obj \
+ $(SLO)$/except.obj
+
+NOOPTFILES= \
+ $(SLO)$/except.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+DEF1NAME=$(SHL1TARGET)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/msci.hxx b/bridges/source/cpp_uno/msvc_win32_intel/msci.hxx
new file mode 100644
index 000000000000..f56ee1e8bc09
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/msci.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: msci.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#pragma warning(push, 1)
+#include <windows.h>
+#pragma warning(pop)
+
+#include "rtl/ustring.hxx"
+
+
+class type_info;
+typedef struct _uno_Any uno_Any;
+typedef struct _uno_Mapping uno_Mapping;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+const DWORD MSVC_ExceptionCode = 0xe06d7363;
+const long MSVC_magic_number = 0x19930520L;
+
+//==============================================================================
+type_info * msci_getRTTI( ::rtl::OUString const & rUNOname );
+
+//==============================================================================
+int msci_filterCppException(
+ EXCEPTION_POINTERS * pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno );
+
+//==============================================================================
+void msci_raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+
+}
+
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx b/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..3fe4ed2e9f54
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx
@@ -0,0 +1,468 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.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 "msci.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+inline static void callVirtualMethod(
+ void * pAdjustedThisPtr, sal_Int32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeClass eReturnTypeClass,
+ 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!" );
+
+__asm
+ {
+ mov eax, nStackLongs
+ test eax, eax
+ je Lcall
+ // copy values
+ mov ecx, eax
+ shl eax, 2 // sizeof(sal_Int32) == 4
+ add eax, pStackLongs // params stack space
+Lcopy: sub eax, 4
+ push dword ptr [eax]
+ dec ecx
+ jne Lcopy
+Lcall:
+ // call
+ mov ecx, pAdjustedThisPtr
+ push ecx // this ptr
+ mov edx, [ecx] // pvft
+ mov eax, nVtableIndex
+ shl eax, 2 // sizeof(void *) == 4
+ add edx, eax
+ call [edx] // interface method call must be __cdecl!!!
+
+ // register return
+ mov ecx, eReturnTypeClass
+ cmp ecx, typelib_TypeClass_VOID
+ je Lcleanup
+ mov ebx, pRegisterReturn
+// int32
+ cmp ecx, typelib_TypeClass_LONG
+ je Lint32
+ cmp ecx, typelib_TypeClass_UNSIGNED_LONG
+ je Lint32
+ cmp ecx, typelib_TypeClass_ENUM
+ je Lint32
+// int8
+ cmp ecx, typelib_TypeClass_BOOLEAN
+ je Lint8
+ cmp ecx, typelib_TypeClass_BYTE
+ je Lint8
+// int16
+ cmp ecx, typelib_TypeClass_CHAR
+ je Lint16
+ cmp ecx, typelib_TypeClass_SHORT
+ je Lint16
+ cmp ecx, typelib_TypeClass_UNSIGNED_SHORT
+ je Lint16
+// float
+ cmp ecx, typelib_TypeClass_FLOAT
+ je Lfloat
+// double
+ cmp ecx, typelib_TypeClass_DOUBLE
+ je Ldouble
+// int64
+ cmp ecx, typelib_TypeClass_HYPER
+ je Lint64
+ cmp ecx, typelib_TypeClass_UNSIGNED_HYPER
+ je Lint64
+ jmp Lcleanup // no simple type
+Lint8:
+ mov byte ptr [ebx], al
+ jmp Lcleanup
+Lint16:
+ mov word ptr [ebx], ax
+ jmp Lcleanup
+Lfloat:
+ fstp dword ptr [ebx]
+ jmp Lcleanup
+Ldouble:
+ fstp qword ptr [ebx]
+ jmp Lcleanup
+Lint64:
+ mov dword ptr [ebx], eax
+ mov dword ptr [ebx+4], edx
+ jmp Lcleanup
+Lint32:
+ mov dword ptr [ebx], eax
+ jmp Lcleanup
+Lcleanup:
+ // cleanup stack (obsolete though because of function)
+ mov eax, nStackLongs
+ shl eax, 2 // sizeof(sal_Int32) == 4
+ add eax, 4 // this ptr
+ add esp, eax
+ }
+}
+
+//==================================================================================================
+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 ) throw ()
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack = (char *)alloca( sizeof(sal_Int32) + (nParams * sizeof(sal_Int64)) );
+ 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 = *(void **)pCppStack
+ = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ pCppStack += sizeof(void *);
+ }
+ }
+
+ // stack space
+
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ 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
+ {
+ // pCppI is msci this pointer
+ callVirtualMethod(
+ reinterpret_cast< void ** >(pThis->getCppI()) + aVtableSlot.offset,
+ aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart,
+ (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ }
+ __except (CPPU_CURRENT_NAMESPACE::msci_filterCppException(
+ GetExceptionInformation(),
+ *ppUnoExc, pThis->getBridge()->getCpp2Uno() ))
+ {
+ // *ppUnoExc was constructed by filter function
+ // temporary params
+ while (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] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ {
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+ // end here
+ return;
+ }
+
+ // NO exception occured
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ while (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 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ ::uno_copyAndConvertData(
+ pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ ::uno_destructData(
+ pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ {
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+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( RTL_CONSTASCII_USTRINGPARAM("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( RTL_CONSTASCII_USTRINGPARAM("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 );
+ }
+ }
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/shared/bridge.cxx b/bridges/source/cpp_uno/shared/bridge.cxx
new file mode 100644
index 000000000000..eac5d3f544ce
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/bridge.cxx
@@ -0,0 +1,229 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: bridge.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+
+#include "component.hxx"
+
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+
+#include "com/sun/star/uno/XInterface.hpp"
+#include "osl/diagnose.h"
+#include "osl/interlck.h"
+#include "rtl/ustring.h"
+#include "sal/types.h"
+#include "typelib/typedescription.h"
+#include "uno/dispatcher.h"
+#include "uno/environment.h"
+#include "uno/mapping.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void freeMapping(uno_Mapping * pMapping)
+{
+ delete static_cast< Bridge::Mapping * >( pMapping )->pBridge;
+}
+
+void acquireMapping(uno_Mapping * pMapping)
+{
+ static_cast< Bridge::Mapping * >( pMapping )->pBridge->acquire();
+}
+
+void releaseMapping(uno_Mapping * pMapping)
+{
+ static_cast< Bridge::Mapping * >( pMapping )->pBridge->release();
+}
+
+void cpp2unoMapping(
+ uno_Mapping * pMapping, void ** ppUnoI, void * pCppI,
+ typelib_InterfaceTypeDescription * pTypeDescr)
+{
+ OSL_ENSURE( ppUnoI && pTypeDescr, "### null ptr!" );
+ if (*ppUnoI)
+ {
+ (*reinterpret_cast< uno_Interface * >( *ppUnoI )->release)(
+ reinterpret_cast< uno_Interface * >( *ppUnoI ) );
+ *ppUnoI = 0;
+ }
+ if (pCppI)
+ {
+ Bridge * pBridge = static_cast< Bridge::Mapping * >( pMapping )->pBridge;
+
+ // get object id of interface to be wrapped
+ rtl_uString * pOId = 0;
+ (*pBridge->pCppEnv->getObjectIdentifier)(
+ pBridge->pCppEnv, &pOId, pCppI );
+ OSL_ASSERT( pOId );
+
+ // try to get any known interface from target environment
+ (*pBridge->pUnoEnv->getRegisteredInterface)(
+ pBridge->pUnoEnv, ppUnoI, pOId, pTypeDescr );
+
+ if (! *ppUnoI) // no existing interface, register new proxy interface
+ {
+ // try to publish a new proxy (refcount initially 1)
+ uno_Interface * pSurrogate
+ = bridges::cpp_uno::shared::UnoInterfaceProxy::create(
+ pBridge,
+ static_cast< ::com::sun::star::uno::XInterface * >( pCppI ),
+ pTypeDescr, pOId );
+
+ // proxy may be exchanged during registration
+ (*pBridge->pUnoEnv->registerProxyInterface)(
+ pBridge->pUnoEnv, reinterpret_cast< void ** >( &pSurrogate ),
+ freeUnoInterfaceProxy, pOId,
+ pTypeDescr );
+
+ *ppUnoI = pSurrogate;
+ }
+ ::rtl_uString_release( pOId );
+ }
+}
+
+void uno2cppMapping(
+ uno_Mapping * pMapping, void ** ppCppI, void * pUnoI,
+ typelib_InterfaceTypeDescription * pTypeDescr)
+{
+ OSL_ASSERT( ppCppI && pTypeDescr );
+ if (*ppCppI)
+ {
+ static_cast< ::com::sun::star::uno::XInterface * >( *ppCppI )->
+ release();
+ *ppCppI = 0;
+ }
+ if (pUnoI)
+ {
+ Bridge * pBridge = static_cast< Bridge::Mapping * >( pMapping )->pBridge;
+
+ // get object id of uno interface to be wrapped
+ rtl_uString * pOId = 0;
+ (*pBridge->pUnoEnv->getObjectIdentifier)(
+ pBridge->pUnoEnv, &pOId, pUnoI );
+ OSL_ASSERT( pOId );
+
+ // try to get any known interface from target environment
+ (*pBridge->pCppEnv->getRegisteredInterface)(
+ pBridge->pCppEnv, ppCppI, pOId, pTypeDescr );
+
+ if (! *ppCppI) // no existing interface, register new proxy interface
+ {
+ // try to publish a new proxy (ref count initially 1)
+ com::sun::star::uno::XInterface * pProxy
+ = bridges::cpp_uno::shared::CppInterfaceProxy::create(
+ pBridge, static_cast< uno_Interface * >( pUnoI ),
+ pTypeDescr, pOId );
+
+ // proxy may be exchanged during registration
+ (*pBridge->pCppEnv->registerProxyInterface)(
+ pBridge->pCppEnv, reinterpret_cast< void ** >( &pProxy ),
+ freeCppInterfaceProxy, pOId,
+ pTypeDescr );
+
+ *ppCppI = pProxy;
+ }
+ ::rtl_uString_release( pOId );
+ }
+}
+
+uno_Mapping * Bridge::createMapping(
+ uno_ExtEnvironment * pCppEnv, uno_ExtEnvironment * pUnoEnv,
+ bool bExportCpp2Uno) SAL_THROW(())
+{
+ Bridge * bridge = new Bridge(pCppEnv, pUnoEnv, bExportCpp2Uno);
+ return bExportCpp2Uno ? &bridge->aCpp2Uno : &bridge->aUno2Cpp;
+}
+
+void Bridge::acquire() SAL_THROW(())
+{
+ if (1 == osl_incrementInterlockedCount( &nRef ))
+ {
+ if (bExportCpp2Uno)
+ {
+ uno_Mapping * pMapping = &aCpp2Uno;
+ ::uno_registerMapping(
+ &pMapping, freeMapping, (uno_Environment *)pCppEnv,
+ (uno_Environment *)pUnoEnv, 0 );
+ }
+ else
+ {
+ uno_Mapping * pMapping = &aUno2Cpp;
+ ::uno_registerMapping(
+ &pMapping, freeMapping, (uno_Environment *)pUnoEnv,
+ (uno_Environment *)pCppEnv, 0 );
+ }
+ }
+}
+
+void Bridge::release() SAL_THROW(())
+{
+ if (! osl_decrementInterlockedCount( &nRef ))
+ {
+ ::uno_revokeMapping( bExportCpp2Uno ? &aCpp2Uno : &aUno2Cpp );
+ }
+}
+
+Bridge::Bridge(
+ uno_ExtEnvironment * pCppEnv_, uno_ExtEnvironment * pUnoEnv_,
+ bool bExportCpp2Uno_) SAL_THROW(())
+ : nRef( 1 )
+ , pCppEnv( pCppEnv_ )
+ , pUnoEnv( pUnoEnv_ )
+ , bExportCpp2Uno( bExportCpp2Uno_ )
+{
+ bridges::cpp_uno::shared::g_moduleCount.modCnt.acquire(
+ &bridges::cpp_uno::shared::g_moduleCount.modCnt );
+
+ aCpp2Uno.pBridge = this;
+ aCpp2Uno.acquire = acquireMapping;
+ aCpp2Uno.release = releaseMapping;
+ aCpp2Uno.mapInterface = cpp2unoMapping;
+
+ aUno2Cpp.pBridge = this;
+ aUno2Cpp.acquire = acquireMapping;
+ aUno2Cpp.release = releaseMapping;
+ aUno2Cpp.mapInterface = uno2cppMapping;
+
+ (*((uno_Environment *)pCppEnv)->acquire)( (uno_Environment *)pCppEnv );
+ (*((uno_Environment *)pUnoEnv)->acquire)( (uno_Environment *)pUnoEnv );
+}
+
+Bridge::~Bridge() SAL_THROW(())
+{
+ (*((uno_Environment *)pUnoEnv)->release)( (uno_Environment *)pUnoEnv );
+ (*((uno_Environment *)pCppEnv)->release)( (uno_Environment *)pCppEnv );
+ bridges::cpp_uno::shared::g_moduleCount.modCnt.release(
+ &bridges::cpp_uno::shared::g_moduleCount.modCnt );
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/shared/component.cxx b/bridges/source/cpp_uno/shared/component.cxx
new file mode 100644
index 000000000000..a5da641a761c
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/component.cxx
@@ -0,0 +1,275 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: component.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "component.hxx"
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "osl/diagnose.h"
+#include "osl/mutex.hxx"
+#include "osl/time.h"
+#include "rtl/process.h"
+#include "rtl/unload.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "uno/environment.h"
+#include "uno/lbnames.h"
+#include "uno/mapping.h"
+#include "cppu/EnvDcp.hxx"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+} } }
+
+namespace {
+
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) \
+ || (defined(__GNUC__) && defined(__APPLE__))
+static ::rtl::OUString * s_pStaticOidPart = 0;
+#endif
+
+const ::rtl::OUString & SAL_CALL cppu_cppenv_getStaticOIdPart() SAL_THROW( () )
+{
+#if ! ((defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) \
+ || (defined(__GNUC__) && defined(__APPLE__)))
+ static ::rtl::OUString * s_pStaticOidPart = 0;
+#endif
+ if (! s_pStaticOidPart)
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if (! s_pStaticOidPart)
+ {
+ ::rtl::OUStringBuffer aRet( 64 );
+ aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") );
+ // good guid
+ sal_uInt8 ar[16];
+ ::rtl_getGlobalProcessId( ar );
+ for ( sal_Int32 i = 0; i < 16; ++i )
+ {
+ aRet.append( (sal_Int32)ar[i], 16 );
+ }
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) \
+ || (defined(__GNUC__) && defined(__APPLE__))
+ s_pStaticOidPart = new ::rtl::OUString( aRet.makeStringAndClear() );
+#else
+ static ::rtl::OUString s_aStaticOidPart(
+ aRet.makeStringAndClear() );
+ s_pStaticOidPart = &s_aStaticOidPart;
+#endif
+ }
+ }
+ return *s_pStaticOidPart;
+}
+
+}
+
+extern "C" {
+
+static void s_stub_computeObjectIdentifier(va_list * pParam)
+ SAL_THROW( () )
+{
+ uno_ExtEnvironment * pEnv = va_arg(*pParam, uno_ExtEnvironment *);
+ rtl_uString ** ppOId = va_arg(*pParam, rtl_uString **);
+ void * pInterface = va_arg(*pParam, void *);
+
+
+ OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
+ if (pEnv && ppOId && pInterface)
+ {
+ if (*ppOId)
+ {
+ rtl_uString_release( *ppOId );
+ *ppOId = 0;
+ }
+
+ try
+ {
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XInterface > xHome(
+ reinterpret_cast< ::com::sun::star::uno::XInterface * >(
+ pInterface ),
+ ::com::sun::star::uno::UNO_QUERY );
+ OSL_ENSURE( xHome.is(), "### query to XInterface failed!" );
+ if (xHome.is())
+ {
+ // interface
+ ::rtl::OUStringBuffer oid( 64 );
+ oid.append( reinterpret_cast< sal_Int64 >(xHome.get()), 16 );
+ oid.append( (sal_Unicode)';' );
+ // ;environment[context]
+ oid.append(
+ *reinterpret_cast< ::rtl::OUString const * >(
+ &((uno_Environment *) pEnv)->pTypeName ) );
+ oid.append( (sal_Unicode)'[' );
+ oid.append(
+ reinterpret_cast< sal_Int64 >(
+ ((uno_Environment *)pEnv)->pContext),
+ 16 );
+ // ];good guid
+ oid.append( cppu_cppenv_getStaticOIdPart() );
+ ::rtl::OUString aRet( oid.makeStringAndClear() );
+ ::rtl_uString_acquire( *ppOId = aRet.pData );
+ }
+ }
+ catch (::com::sun::star::uno::RuntimeException &)
+ {
+ OSL_ENSURE(
+ 0, "### RuntimeException occured udring queryInterface()!" );
+ }
+ }
+}
+
+static void SAL_CALL computeObjectIdentifier(
+ uno_ExtEnvironment * pExtEnv, rtl_uString ** ppOId, void * pInterface )
+ SAL_THROW( () )
+{
+ uno_Environment_invoke(&pExtEnv->aBase, s_stub_computeObjectIdentifier, pExtEnv, ppOId, pInterface);
+}
+
+static void s_stub_acquireInterface(va_list * pParam)
+ SAL_THROW( () )
+{
+ /*uno_ExtEnvironment * pExtEnv = */va_arg(*pParam, uno_ExtEnvironment *);
+ void * pCppI = va_arg(*pParam, void *);
+
+ reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->acquire();
+}
+
+static void SAL_CALL acquireInterface( uno_ExtEnvironment * pExtEnv, void * pCppI )
+ SAL_THROW( () )
+{
+ uno_Environment_invoke(&pExtEnv->aBase, s_stub_acquireInterface, pExtEnv, pCppI);
+}
+
+static void s_stub_releaseInterface(va_list * pParam)
+ SAL_THROW( () )
+{
+ /*uno_ExtEnvironment * pExtEnv = */va_arg(*pParam, uno_ExtEnvironment *);
+ void * pCppI = va_arg(*pParam, void *);
+
+ reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->release();
+}
+
+static void SAL_CALL releaseInterface( uno_ExtEnvironment * pExtEnv, void * pCppI )
+ SAL_THROW( () )
+{
+ uno_Environment_invoke(&pExtEnv->aBase, s_stub_releaseInterface, pExtEnv, pCppI);
+}
+
+static void SAL_CALL environmentDisposing( uno_Environment * ) SAL_THROW( () )
+{
+ bridges::cpp_uno::shared::g_moduleCount.modCnt.release(
+ &bridges::cpp_uno::shared::g_moduleCount.modCnt );
+}
+
+sal_Bool SAL_CALL component_canUnload(TimeValue * pTime) SAL_THROW_EXTERN_C() {
+ return bridges::cpp_uno::shared::g_moduleCount.canUnload(
+ &bridges::cpp_uno::shared::g_moduleCount, pTime);
+}
+
+void SAL_CALL uno_initEnvironment(uno_Environment * pCppEnv)
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ENSURE( pCppEnv->pExtEnv, "### expected extended environment!" );
+ OSL_ENSURE(
+ ::rtl_ustr_ascii_compare_WithLength(
+ pCppEnv->pTypeName->buffer, rtl_str_getLength(CPPU_CURRENT_LANGUAGE_BINDING_NAME), CPPU_CURRENT_LANGUAGE_BINDING_NAME )
+ == 0,
+ "### wrong environment type!" );
+ bridges::cpp_uno::shared::g_moduleCount.modCnt.acquire(
+ &bridges::cpp_uno::shared::g_moduleCount.modCnt );
+ ((uno_ExtEnvironment *)pCppEnv)->computeObjectIdentifier
+ = computeObjectIdentifier;
+ ((uno_ExtEnvironment *)pCppEnv)->acquireInterface = acquireInterface;
+ ((uno_ExtEnvironment *)pCppEnv)->releaseInterface = releaseInterface;
+ pCppEnv->environmentDisposing = environmentDisposing;
+}
+
+void SAL_CALL uno_ext_getMapping(
+ uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo)
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ASSERT( ppMapping && pFrom && pTo );
+ if (ppMapping && pFrom && pTo && pFrom->pExtEnv && pTo->pExtEnv)
+ {
+ uno_Mapping * pMapping = 0;
+
+ rtl::OUString from_envTypeName(cppu::EnvDcp::getTypeName(pFrom->pTypeName));
+ rtl::OUString to_envTypeName(cppu::EnvDcp::getTypeName(pTo->pTypeName));
+
+ if (0 == rtl_ustr_ascii_compare(
+ from_envTypeName.pData->buffer,
+ CPPU_CURRENT_LANGUAGE_BINDING_NAME ) &&
+ 0 == rtl_ustr_ascii_compare(
+ to_envTypeName.pData->buffer, UNO_LB_UNO ))
+ {
+ // ref count initially 1
+ pMapping = bridges::cpp_uno::shared::Bridge::createMapping(
+ pFrom->pExtEnv, pTo->pExtEnv, sal_True );
+ ::uno_registerMapping(
+ &pMapping, bridges::cpp_uno::shared::freeMapping,
+ (uno_Environment *)pFrom->pExtEnv,
+ (uno_Environment *)pTo->pExtEnv, 0 );
+ }
+ else if (0 == rtl_ustr_ascii_compare(
+ to_envTypeName.pData->buffer,
+ CPPU_CURRENT_LANGUAGE_BINDING_NAME ) &&
+ 0 == rtl_ustr_ascii_compare(
+ from_envTypeName.pData->buffer, UNO_LB_UNO ))
+ {
+ // ref count initially 1
+ pMapping = bridges::cpp_uno::shared::Bridge::createMapping(
+ pTo->pExtEnv, pFrom->pExtEnv, sal_False );
+ ::uno_registerMapping(
+ &pMapping, bridges::cpp_uno::shared::freeMapping,
+ (uno_Environment *)pFrom->pExtEnv,
+ (uno_Environment *)pTo->pExtEnv, 0 );
+ }
+
+ if (*ppMapping)
+ {
+ (*(*ppMapping)->release)( *ppMapping );
+ }
+ if (pMapping)
+ *ppMapping = pMapping;
+ }
+}
+
+}
diff --git a/bridges/source/cpp_uno/shared/component.hxx b/bridges/source/cpp_uno/shared/component.hxx
new file mode 100644
index 000000000000..0ef2665ddf32
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/component.hxx
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: component.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_SHARED_COMPONENT_HXX
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_SHARED_COMPONENT_HXX
+
+#include "rtl/unload.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+extern rtl_StandardModuleCount g_moduleCount;
+
+} } }
+
+#endif
diff --git a/bridges/source/cpp_uno/shared/cppinterfaceproxy.cxx b/bridges/source/cpp_uno/shared/cppinterfaceproxy.cxx
new file mode 100644
index 000000000000..0863c629797b
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/cppinterfaceproxy.cxx
@@ -0,0 +1,208 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cppinterfaceproxy.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+
+#include "guardedarray.hxx"
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "com/sun/star/uno/XInterface.hpp"
+#include "osl/diagnose.h"
+#include "osl/getglobalmutex.hxx"
+#include "osl/interlck.h"
+#include "osl/mutex.hxx"
+#include "rtl/instance.hxx"
+#include "typelib/typedescription.h"
+
+#include <cstddef>
+#include <new>
+
+
+static bridges::cpp_uno::shared::VtableFactory * pInstance;
+
+#if defined(__GNUG__) && !defined(__MINGW32__)
+void dso_init(void) __attribute__((constructor));
+void dso_exit(void) __attribute__((destructor));
+#endif
+
+void dso_init(void) {
+ if (!pInstance)
+ pInstance = new bridges::cpp_uno::shared::VtableFactory();
+}
+
+void dso_exit(void) {
+ if (pInstance)
+ {
+ delete pInstance;
+ pInstance = NULL;
+ }
+}
+
+#ifdef __SUNPRO_CC
+# pragma init(dso_init)
+# pragma fini(dso_exit)
+#endif
+
+
+
+namespace {
+
+struct InitVtableFactory {
+ bridges::cpp_uno::shared::VtableFactory * operator()() {
+ return pInstance;
+ }
+};
+
+bridges::cpp_uno::shared::VtableFactory * getVtableFactory() {
+ return rtl_Instance<
+ bridges::cpp_uno::shared::VtableFactory, InitVtableFactory,
+ osl::MutexGuard, osl::GetGlobalMutex >::create(
+ InitVtableFactory(), osl::GetGlobalMutex());
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void freeCppInterfaceProxy(uno_ExtEnvironment * pEnv, void * pInterface)
+{
+ CppInterfaceProxy * pThis = CppInterfaceProxy::castInterfaceToProxy(
+ pInterface);
+ if (pEnv != pThis->pBridge->getCppEnv()) {
+ OSL_ASSERT(false);
+ }
+
+ (*pThis->pBridge->getUnoEnv()->revokeInterface)(
+ pThis->pBridge->getUnoEnv(), pThis->pUnoI );
+ (*pThis->pUnoI->release)( pThis->pUnoI );
+ ::typelib_typedescription_release(
+ (typelib_TypeDescription *)pThis->pTypeDescr );
+ pThis->pBridge->release();
+
+#if OSL_DEBUG_LEVEL > 1
+ *(int *)pInterface = 0xdeadbabe;
+#endif
+ pThis->~CppInterfaceProxy();
+ delete[] reinterpret_cast< char * >(pThis);
+}
+
+com::sun::star::uno::XInterface * CppInterfaceProxy::create(
+ bridges::cpp_uno::shared::Bridge * pBridge, uno_Interface * pUnoI,
+ typelib_InterfaceTypeDescription * pTypeDescr, rtl::OUString const & rOId)
+ SAL_THROW(())
+{
+ typelib_typedescription_complete(
+ reinterpret_cast< typelib_TypeDescription ** >(&pTypeDescr));
+ bridges::cpp_uno::shared::VtableFactory::Vtables aVtables(
+ getVtableFactory()->getVtables(pTypeDescr));
+ bridges::cpp_uno::shared::GuardedArray< char > pMemory(
+ new char[
+ sizeof (CppInterfaceProxy)
+ + (aVtables.count - 1) * sizeof (void **)]);
+ new(pMemory.get()) CppInterfaceProxy(pBridge, pUnoI, pTypeDescr, rOId);
+ CppInterfaceProxy * pProxy = reinterpret_cast< CppInterfaceProxy * >(
+ pMemory.release());
+ for (sal_Int32 i = 0; i < aVtables.count; ++i) {
+ pProxy->vtables[i] = VtableFactory::mapBlockToVtable(
+ aVtables.blocks[i].start);
+ }
+ return castProxyToInterface(pProxy);
+}
+
+void CppInterfaceProxy::acquireProxy() SAL_THROW(())
+{
+ if (1 == osl_incrementInterlockedCount( &nRef ))
+ {
+ // rebirth of proxy zombie
+ // register at cpp env
+ void * pThis = castProxyToInterface( this );
+ (*pBridge->getCppEnv()->registerProxyInterface)(
+ pBridge->getCppEnv(), &pThis, freeCppInterfaceProxy, oid.pData,
+ pTypeDescr );
+ OSL_ASSERT( pThis == castProxyToInterface( this ) );
+ }
+}
+
+void CppInterfaceProxy::releaseProxy() SAL_THROW(())
+{
+ if (! osl_decrementInterlockedCount( &nRef )) // last release
+ {
+ // revoke from cpp env
+ (*pBridge->getCppEnv()->revokeInterface)(
+ pBridge->getCppEnv(), castProxyToInterface( this ) );
+ }
+}
+
+CppInterfaceProxy::CppInterfaceProxy(
+ bridges::cpp_uno::shared::Bridge * pBridge_, uno_Interface * pUnoI_,
+ typelib_InterfaceTypeDescription * pTypeDescr_, rtl::OUString const & rOId_)
+ SAL_THROW(())
+ : nRef( 1 )
+ , pBridge( pBridge_ )
+ , pUnoI( pUnoI_ )
+ , pTypeDescr( pTypeDescr_ )
+ , oid( rOId_ )
+{
+ pBridge->acquire();
+ ::typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr );
+ (*pUnoI->acquire)( pUnoI );
+ (*pBridge->getUnoEnv()->registerInterface)(
+ pBridge->getUnoEnv(), reinterpret_cast< void ** >( &pUnoI ), oid.pData,
+ pTypeDescr );
+}
+
+CppInterfaceProxy::~CppInterfaceProxy()
+{}
+
+com::sun::star::uno::XInterface * CppInterfaceProxy::castProxyToInterface(
+ CppInterfaceProxy * pProxy)
+{
+ return reinterpret_cast< com::sun::star::uno::XInterface * >(
+ &pProxy->vtables);
+}
+
+CppInterfaceProxy * CppInterfaceProxy::castInterfaceToProxy(void * pInterface)
+{
+ // pInterface == &pProxy->vtables (this emulated offsetof is not truly
+ // portable):
+ char const * const base = reinterpret_cast< char const * >(16);
+ std::ptrdiff_t const offset = reinterpret_cast< char const * >(
+ &reinterpret_cast< CppInterfaceProxy const * >(base)->vtables) - base;
+ return reinterpret_cast< CppInterfaceProxy * >(
+ static_cast< char * >(pInterface) - offset);
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/shared/guardedarray.hxx b/bridges/source/cpp_uno/shared/guardedarray.hxx
new file mode 100644
index 000000000000..670dc30ea9a9
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/guardedarray.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: guardedarray.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_SHARED_GUARDEDARRAY_HXX
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_SHARED_GUARDEDARRAY_HXX
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+template< typename T > class GuardedArray {
+public:
+ explicit GuardedArray(T * thePointer): pointer(thePointer) {}
+
+ ~GuardedArray() { delete[] pointer; }
+
+ T * get() const { return pointer; }
+
+ T * release() { T * p = pointer; pointer = 0; return p; }
+
+private:
+ GuardedArray(GuardedArray &); // not implemented
+ void operator =(GuardedArray); // not implemented
+
+ T * pointer;
+};
+
+} } }
+
+#endif
diff --git a/bridges/source/cpp_uno/shared/makefile.mk b/bridges/source/cpp_uno/shared/makefile.mk
new file mode 100644
index 000000000000..93a1c7512567
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/makefile.mk
@@ -0,0 +1,57 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.5 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+PRJNAME = bridges
+
+TARGET = cpp_uno_shared
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE: settings.mk
+
+SLOFILES = \
+ $(SLO)$/bridge.obj \
+ $(SLO)$/component.obj \
+ $(SLO)$/cppinterfaceproxy.obj \
+ $(SLO)$/types.obj \
+ $(SLO)$/unointerfaceproxy.obj \
+ $(SLO)$/vtablefactory.obj \
+ $(SLO)$/vtables.obj
+
+# Disable optimization for cppinterfaceproxy.cxx -
+# attribute constructor / destructor do not get called otherwise.
+.IF "$(COM)" == "GCC"
+NOOPTFILES = \
+ $(SLO)$/cppinterfaceproxy.obj
+.ENDIF
+
+
+.INCLUDE: target.mk
diff --git a/bridges/source/cpp_uno/shared/types.cxx b/bridges/source/cpp_uno/shared/types.cxx
new file mode 100644
index 000000000000..dcefd515da37
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/types.cxx
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: types.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "bridges/cpp_uno/shared/types.hxx"
+#define INCLUDED_BRIDGES_CPP_UNO_SHARED_VTABLES_HXX
+
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+bool isSimpleType(typelib_TypeClass typeClass) {
+ return typeClass <= typelib_TypeClass_DOUBLE
+ || typeClass == typelib_TypeClass_ENUM;
+}
+
+bool isSimpleType(typelib_TypeDescriptionReference const * type) {
+ return isSimpleType(type->eTypeClass);
+}
+
+bool isSimpleType(typelib_TypeDescription const * type) {
+ return isSimpleType(type->eTypeClass);
+}
+
+bool relatesToInterfaceType(typelib_TypeDescription const * type) {
+ switch (type->eTypeClass) {
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_INTERFACE:
+ return true;
+
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ 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_ANY:
+ case typelib_TypeClass_INTERFACE:
+ return true;
+
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_SEQUENCE:
+ {
+ typelib_TypeDescription * t = 0;
+ TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
+ bool b = relatesToInterfaceType(t);
+ TYPELIB_DANGER_RELEASE(t);
+ if (b) {
+ return true;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ if (p->pBaseTypeDescription != 0) {
+ return relatesToInterfaceType(&p->pBaseTypeDescription->aBase);
+ }
+ }
+ break;
+
+ case typelib_TypeClass_SEQUENCE:
+ switch (reinterpret_cast< typelib_IndirectTypeDescription const * >(
+ type)->pType->eTypeClass) {
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_INTERFACE:
+ return true;
+
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_SEQUENCE:
+ {
+ typelib_TypeDescription * t = 0;
+ TYPELIB_DANGER_GET(
+ &t,
+ reinterpret_cast< typelib_IndirectTypeDescription const * >(
+ type)->pType);
+ bool b = relatesToInterfaceType(t);
+ TYPELIB_DANGER_RELEASE(t);
+ return b;
+ }
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return false;
+}
+
+} } }
diff --git a/bridges/source/cpp_uno/shared/unointerfaceproxy.cxx b/bridges/source/cpp_uno/shared/unointerfaceproxy.cxx
new file mode 100644
index 000000000000..9b7a136979d6
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/unointerfaceproxy.cxx
@@ -0,0 +1,145 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unointerfaceproxy.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+
+#include "com/sun/star/uno/XInterface.hpp"
+#include "osl/diagnose.h"
+#include "osl/interlck.h"
+#include "typelib/typedescription.h"
+#include "uno/dispatcher.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void freeUnoInterfaceProxy(uno_ExtEnvironment * pEnv, void * pProxy)
+{
+ UnoInterfaceProxy * pThis =
+ static_cast< UnoInterfaceProxy * >(
+ reinterpret_cast< uno_Interface * >( pProxy ) );
+ if (pEnv != pThis->pBridge->getUnoEnv()) {
+ OSL_ASSERT(false);
+ }
+
+ (*pThis->pBridge->getCppEnv()->revokeInterface)(
+ pThis->pBridge->getCppEnv(), pThis->pCppI );
+ pThis->pCppI->release();
+ ::typelib_typedescription_release(
+ (typelib_TypeDescription *)pThis->pTypeDescr );
+ pThis->pBridge->release();
+
+#if OSL_DEBUG_LEVEL > 1
+ *(int *)pProxy = 0xdeadbabe;
+#endif
+ delete pThis;
+}
+
+void acquireProxy(uno_Interface * pUnoI)
+{
+ if (1 == osl_incrementInterlockedCount(
+ & static_cast< UnoInterfaceProxy * >( pUnoI )->nRef ))
+ {
+ // rebirth of proxy zombie
+ // register at uno env
+#if OSL_DEBUG_LEVEL > 1
+ void * pThis = pUnoI;
+#endif
+ (*static_cast< UnoInterfaceProxy * >( pUnoI )->pBridge->getUnoEnv()->
+ registerProxyInterface)(
+ static_cast< UnoInterfaceProxy * >( pUnoI )->pBridge->getUnoEnv(),
+ reinterpret_cast< void ** >( &pUnoI ), freeUnoInterfaceProxy,
+ static_cast< UnoInterfaceProxy * >( pUnoI )->oid.pData,
+ static_cast< UnoInterfaceProxy * >( pUnoI )->pTypeDescr );
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ASSERT( pThis == pUnoI );
+#endif
+ }
+}
+
+void releaseProxy(uno_Interface * pUnoI)
+{
+ if (! osl_decrementInterlockedCount(
+ & static_cast< UnoInterfaceProxy * >( pUnoI )->nRef ))
+ {
+ // revoke from uno env on last release
+ (*static_cast< UnoInterfaceProxy * >( pUnoI )->pBridge->getUnoEnv()->
+ revokeInterface)(
+ static_cast< UnoInterfaceProxy * >( pUnoI )->pBridge->getUnoEnv(),
+ pUnoI );
+ }
+}
+
+UnoInterfaceProxy * UnoInterfaceProxy::create(
+ bridges::cpp_uno::shared::Bridge * pBridge,
+ com::sun::star::uno::XInterface * pCppI,
+ typelib_InterfaceTypeDescription * pTypeDescr,
+ rtl::OUString const & rOId) SAL_THROW(())
+{
+ return new UnoInterfaceProxy(pBridge, pCppI, pTypeDescr, rOId);
+}
+
+UnoInterfaceProxy::UnoInterfaceProxy(
+ bridges::cpp_uno::shared::Bridge * pBridge_,
+ com::sun::star::uno::XInterface * pCppI_,
+ typelib_InterfaceTypeDescription * pTypeDescr_, rtl::OUString const & rOId_)
+ SAL_THROW(())
+ : nRef( 1 )
+ , pBridge( pBridge_ )
+ , pCppI( pCppI_ )
+ , pTypeDescr( pTypeDescr_ )
+ , oid( rOId_ )
+{
+ pBridge->acquire();
+ ::typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr );
+ if (! ((typelib_TypeDescription *)pTypeDescr)->bComplete)
+ ::typelib_typedescription_complete(
+ (typelib_TypeDescription **)&pTypeDescr );
+ OSL_ENSURE(
+ ((typelib_TypeDescription *)pTypeDescr)->bComplete,
+ "### type is incomplete!" );
+ pCppI->acquire();
+ (*pBridge->getCppEnv()->registerInterface)(
+ pBridge->getCppEnv(), reinterpret_cast< void ** >( &pCppI ), oid.pData,
+ pTypeDescr );
+
+ // uno_Interface
+ acquire = acquireProxy;
+ release = releaseProxy;
+ pDispatcher = unoInterfaceProxyDispatch;
+}
+
+UnoInterfaceProxy::~UnoInterfaceProxy()
+{}
+
+} } }
diff --git a/bridges/source/cpp_uno/shared/vtablefactory.cxx b/bridges/source/cpp_uno/shared/vtablefactory.cxx
new file mode 100644
index 000000000000..3784f3959594
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/vtablefactory.cxx
@@ -0,0 +1,385 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: vtablefactory.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#if defined OS2
+#define INCL_DOS
+#define INCL_DOSMISC
+#endif
+
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "guardedarray.hxx"
+
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "osl/thread.h"
+#include "osl/security.hxx"
+#include "osl/file.hxx"
+#include "osl/diagnose.h"
+#include "osl/mutex.hxx"
+#include "rtl/alloc.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "typelib/typedescription.hxx"
+
+#include <hash_map>
+#include <new>
+#include <vector>
+
+#if defined SAL_UNX
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+#elif defined SAL_W32
+#define WIN32_LEAN_AND_MEAN
+#ifdef _MSC_VER
+#pragma warning(push,1) // disable warnings within system headers
+#endif
+#include <windows.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+#elif defined SAL_OS2
+#define INCL_DOS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#error Unsupported platform
+#endif
+
+using bridges::cpp_uno::shared::VtableFactory;
+
+namespace {
+
+extern "C" void * SAL_CALL allocExec(rtl_arena_type *, sal_Size * size) {
+ sal_Size pagesize;
+#if defined SAL_UNX
+#if defined FREEBSD || defined NETBSD
+ pagesize = getpagesize();
+#else
+ pagesize = sysconf(_SC_PAGESIZE);
+#endif
+#elif defined SAL_W32
+ SYSTEM_INFO info;
+ GetSystemInfo(&info);
+ pagesize = info.dwPageSize;
+#elif defined(SAL_OS2)
+ ULONG ulPageSize;
+ DosQuerySysInfo(QSV_PAGE_SIZE, QSV_PAGE_SIZE, &ulPageSize, sizeof(ULONG));
+ pagesize = (sal_Size)ulPageSize;
+#else
+#error Unsupported platform
+#endif
+ sal_Size n = (*size + (pagesize - 1)) & ~(pagesize - 1);
+ void * p;
+#if defined SAL_UNX
+ p = mmap(
+ 0, n, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1,
+ 0);
+ if (p == MAP_FAILED) {
+ p = 0;
+ }
+ else if (mprotect (static_cast<char*>(p), n, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
+ {
+ munmap (static_cast<char*>(p), n);
+ p = 0;
+ }
+#elif defined SAL_W32
+ p = VirtualAlloc(0, n, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+#elif defined(SAL_OS2)
+ p = 0;
+ DosAllocMem( &p, n, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_ANY);
+#endif
+ if (p != 0) {
+ *size = n;
+ }
+ return p;
+}
+
+extern "C" void SAL_CALL freeExec(
+ rtl_arena_type *, void * address, sal_Size size)
+{
+#if defined SAL_UNX
+ munmap(static_cast< char * >(address), size);
+#elif defined SAL_W32
+ (void) size; // unused
+ VirtualFree(address, 0, MEM_RELEASE);
+#elif defined(SAL_OS2)
+ (void) DosFreeMem( address);
+#endif
+}
+
+}
+
+class VtableFactory::GuardedBlocks: public std::vector< Block > {
+public:
+ GuardedBlocks(VtableFactory const & factory):
+ m_factory(factory), m_guarded(true) {}
+
+ ~GuardedBlocks();
+
+ void unguard() { m_guarded = false; }
+
+private:
+ GuardedBlocks(GuardedBlocks &); // not implemented
+ void operator =(GuardedBlocks); // not implemented
+
+ VtableFactory const & m_factory;
+ bool m_guarded;
+};
+
+VtableFactory::GuardedBlocks::~GuardedBlocks() {
+ if (m_guarded) {
+ for (iterator i(begin()); i != end(); ++i) {
+ m_factory.freeBlock(*i);
+ }
+ }
+}
+
+class VtableFactory::BaseOffset {
+public:
+ BaseOffset(typelib_InterfaceTypeDescription * type) { calculate(type, 0); }
+
+ sal_Int32 getFunctionOffset(rtl::OUString const & name) const
+ { return m_map.find(name)->second; }
+
+private:
+ sal_Int32 calculate(
+ typelib_InterfaceTypeDescription * type, sal_Int32 offset);
+
+ typedef std::hash_map< rtl::OUString, sal_Int32, rtl::OUStringHash > Map;
+
+ Map m_map;
+};
+
+sal_Int32 VtableFactory::BaseOffset::calculate(
+ typelib_InterfaceTypeDescription * type, sal_Int32 offset)
+{
+ rtl::OUString name(type->aBase.pTypeName);
+ if (m_map.find(name) == m_map.end()) {
+ for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
+ offset = calculate(type->ppBaseTypes[i], offset);
+ }
+ m_map.insert(Map::value_type(name, offset));
+ typelib_typedescription_complete(
+ reinterpret_cast< typelib_TypeDescription ** >(&type));
+ offset += bridges::cpp_uno::shared::getLocalFunctions(type);
+ }
+ return offset;
+}
+
+VtableFactory::VtableFactory(): m_arena(
+ rtl_arena_create(
+ "bridges::cpp_uno::shared::VtableFactory",
+ sizeof (void *), // to satisfy alignment requirements
+ 0, reinterpret_cast< rtl_arena_type * >(-1), allocExec, freeExec, 0))
+{
+ if (m_arena == 0) {
+ throw std::bad_alloc();
+ }
+}
+
+VtableFactory::~VtableFactory() {
+ {
+ osl::MutexGuard guard(m_mutex);
+ for (Map::iterator i(m_map.begin()); i != m_map.end(); ++i) {
+ for (sal_Int32 j = 0; j < i->second.count; ++j) {
+ freeBlock(i->second.blocks[j]);
+ }
+ delete[] i->second.blocks;
+ }
+ }
+ rtl_arena_destroy(m_arena);
+}
+
+VtableFactory::Vtables VtableFactory::getVtables(
+ typelib_InterfaceTypeDescription * type)
+{
+ rtl::OUString name(type->aBase.pTypeName);
+ osl::MutexGuard guard(m_mutex);
+ Map::iterator i(m_map.find(name));
+ if (i == m_map.end()) {
+ GuardedBlocks blocks(*this);
+ createVtables(blocks, BaseOffset(type), type, true);
+ Vtables vtables;
+ OSL_ASSERT(blocks.size() <= SAL_MAX_INT32);
+ vtables.count = static_cast< sal_Int32 >(blocks.size());
+ bridges::cpp_uno::shared::GuardedArray< Block > guardedBlocks(
+ new Block[vtables.count]);
+ vtables.blocks = guardedBlocks.get();
+ for (sal_Int32 j = 0; j < vtables.count; ++j) {
+ vtables.blocks[j] = blocks[j];
+ }
+ i = m_map.insert(Map::value_type(name, vtables)).first;
+ guardedBlocks.release();
+ blocks.unguard();
+ }
+ return i->second;
+}
+
+#ifdef USE_DOUBLE_MMAP
+bool VtableFactory::createBlock(Block &block, sal_Int32 slotCount) const
+{
+ sal_Size size = getBlockSize(slotCount);
+ sal_Size pagesize = sysconf(_SC_PAGESIZE);
+ block.size = (size + (pagesize - 1)) & ~(pagesize - 1);
+ block.start = block.exec = NULL;
+ block.fd = -1;
+
+ osl::Security aSecurity;
+ rtl::OUString strDirectory;
+ rtl::OUString strURLDirectory;
+ if (aSecurity.getHomeDir(strURLDirectory))
+ osl::File::getSystemPathFromFileURL(strURLDirectory, strDirectory);
+
+ for (int i = strDirectory.getLength() == 0 ? 1 : 0; i < 2; ++i)
+ {
+ if (!strDirectory.getLength())
+ strDirectory = rtl::OUString::createFromAscii("/tmp");
+
+ strDirectory += rtl::OUString::createFromAscii("/.execoooXXXXXX");
+ rtl::OString aTmpName = rtl::OUStringToOString(strDirectory, osl_getThreadTextEncoding());
+ char *tmpfname = new char[aTmpName.getLength()+1];
+ strncpy(tmpfname, aTmpName.getStr(), aTmpName.getLength()+1);
+ if ((block.fd = mkstemp(tmpfname)) == -1)
+ perror("creation of executable memory area failed");
+ if (block.fd == -1)
+ {
+ delete[] tmpfname;
+ break;
+ }
+ unlink(tmpfname);
+ delete[] tmpfname;
+ if (ftruncate(block.fd, block.size) == -1)
+ {
+ perror("truncation of executable memory area failed");
+ close(block.fd);
+ block.fd = -1;
+ break;
+ }
+ block.start = mmap(NULL, block.size, PROT_READ | PROT_WRITE, MAP_SHARED, block.fd, 0);
+ if (block.start== MAP_FAILED) {
+ block.start = 0;
+ }
+ block.exec = mmap(NULL, block.size, PROT_READ | PROT_EXEC, MAP_SHARED, block.fd, 0);
+ if (block.exec == MAP_FAILED) {
+ block.exec = 0;
+ }
+
+ //All good
+ if (block.start && block.exec && block.fd != -1)
+ break;
+
+ freeBlock(block);
+
+ strDirectory = rtl::OUString();
+ }
+ if (!block.start || !block.exec || block.fd == -1)
+ {
+ //Fall back to non-doublemmaped allocation
+ block.fd = -1;
+ block.start = block.exec = rtl_arena_alloc(m_arena, &block.size);
+ }
+ return (block.start != 0 && block.exec != 0);
+}
+
+void VtableFactory::freeBlock(Block const & block) const {
+ //if the double-map failed we were allocated on the arena
+ if (block.fd == -1 && block.start == block.exec && block.start != NULL)
+ rtl_arena_free(m_arena, block.start, block.size);
+ else
+ {
+ if (block.start) munmap(block.start, block.size);
+ if (block.exec) munmap(block.exec, block.size);
+ if (block.fd != -1) close(block.fd);
+ }
+}
+#else
+bool VtableFactory::createBlock(Block &block, sal_Int32 slotCount) const
+{
+ block.size = getBlockSize(slotCount);
+ block.start = rtl_arena_alloc(m_arena, &block.size);
+ return block.start != 0;
+}
+
+void VtableFactory::freeBlock(Block const & block) const {
+ rtl_arena_free(m_arena, block.start, block.size);
+}
+#endif
+
+void VtableFactory::createVtables(
+ GuardedBlocks & blocks, BaseOffset const & baseOffset,
+ typelib_InterfaceTypeDescription * type, bool includePrimary) const
+{
+ if (includePrimary) {
+ sal_Int32 slotCount
+ = bridges::cpp_uno::shared::getPrimaryFunctions(type);
+ Block block;
+ if (!createBlock(block, slotCount)) {
+ throw std::bad_alloc();
+ }
+ try {
+ Slot * slots = initializeBlock(block.start, slotCount);
+ unsigned char * codeBegin =
+ reinterpret_cast< unsigned char * >(slots);
+ unsigned char * code = codeBegin;
+ sal_Int32 vtableOffset = blocks.size() * sizeof (Slot *);
+ for (typelib_InterfaceTypeDescription const * type2 = type;
+ type2 != 0; type2 = type2->pBaseTypeDescription)
+ {
+ code = addLocalFunctions(
+ &slots, code,
+#ifdef USE_DOUBLE_MMAP
+ sal_IntPtr(block.exec) - sal_IntPtr(block.start),
+#endif
+ type2,
+ baseOffset.getFunctionOffset(type2->aBase.pTypeName),
+ bridges::cpp_uno::shared::getLocalFunctions(type2),
+ vtableOffset);
+ }
+ flushCode(codeBegin, code);
+#ifdef USE_DOUBLE_MMAP
+ //Finished generating block, swap writable pointer with executable
+ //pointer
+ ::std::swap(block.start, block.exec);
+#endif
+ blocks.push_back(block);
+ } catch (...) {
+ freeBlock(block);
+ throw;
+ }
+ }
+ for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
+ createVtables(blocks, baseOffset, type->ppBaseTypes[i], i != 0);
+ }
+}
diff --git a/bridges/source/cpp_uno/shared/vtables.cxx b/bridges/source/cpp_uno/shared/vtables.cxx
new file mode 100644
index 000000000000..a18e04a8da71
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/vtables.cxx
@@ -0,0 +1,157 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: vtables.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "osl/diagnose.h"
+#include "sal/types.h"
+#include "typelib/typedescription.h"
+
+#include <algorithm>
+
+namespace
+{
+
+/**
+ * Calculates the number of vtables associated with an interface type.
+ *
+ * <p>Multiple-inheritance C++ classes have more than one vtable.</p>
+ *
+ * @param type a non-null pointer to an interface type description
+ * @return the number of vtables associated with the given interface type
+ */
+sal_Int32 getVtableCount(typelib_InterfaceTypeDescription const * type) {
+ sal_Int32 n = 0;
+ for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
+ n += getVtableCount(type->ppBaseTypes[i]);
+ }
+ return std::max< sal_Int32 >(n, 1);
+}
+
+/**
+ * Maps a local member index to a local function index.
+ *
+ * <p><em>Local</em> members/functions are those not inherited from any base
+ * types. The number of <em>functions</em> is potentially larger than the
+ * number of <em>members</em>, as each read&ndash;write attribute member counts
+ * as two functions.</p>
+ *
+ * @param type a non-null pointer to an interface type description
+ * @param localMember a local member index, relative to the given interface type
+ * @return the local function index corresponding to the given local member
+ * index, relative to the given interface type
+ */
+sal_Int32 mapLocalMemberToLocalFunction(
+ typelib_InterfaceTypeDescription * type, sal_Int32 localMember)
+{
+ typelib_typedescription_complete(
+ reinterpret_cast< typelib_TypeDescription ** >(&type));
+ sal_Int32 localMemberOffset = type->nAllMembers - type->nMembers;
+ sal_Int32 localFunctionOffset = type->nMapFunctionIndexToMemberIndex
+ - bridges::cpp_uno::shared::getLocalFunctions(type);
+ return type->pMapMemberIndexToFunctionIndex[localMemberOffset + localMember]
+ - localFunctionOffset;
+}
+
+// Since on Solaris we compile with --instances=static, getVtableSlot cannot be
+// a template function, with explicit instantiates for
+// T = typelib_InterfaceAttributeTypeDescription and
+// T = typelib_InterfaceMethodTypeDescription in this file; hence, there are two
+// overloaded versions of getVtableSlot that both delegate to this template
+// function:
+template< typename T > bridges::cpp_uno::shared::VtableSlot doGetVtableSlot(
+ T const * ifcMember)
+{
+ bridges::cpp_uno::shared::VtableSlot slot;
+ slot.offset = 0;
+ T * member = const_cast< T * >(ifcMember);
+ while (member->pBaseRef != 0) {
+ OSL_ASSERT(member->nIndex < member->pInterface->nBaseTypes);
+ for (sal_Int32 i = 0; i < member->nIndex; ++i) {
+ slot.offset += getVtableCount(member->pInterface->ppBaseTypes[i]);
+ }
+ typelib_TypeDescription * desc = 0;
+ typelib_typedescriptionreference_getDescription(
+ &desc, member->pBaseRef);
+ OSL_ASSERT(
+ desc != 0 && desc->eTypeClass == member->aBase.aBase.eTypeClass);
+ if (member != ifcMember) {
+ typelib_typedescription_release(&member->aBase.aBase);
+ }
+ member = reinterpret_cast< T * >(desc);
+ }
+ slot.index
+ = bridges::cpp_uno::shared::getPrimaryFunctions(
+ member->pInterface->pBaseTypeDescription)
+ + mapLocalMemberToLocalFunction(member->pInterface, member->nIndex);
+ if (member != ifcMember) {
+ typelib_typedescription_release(&member->aBase.aBase);
+ }
+ return slot;
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+sal_Int32 getLocalFunctions(typelib_InterfaceTypeDescription const * type) {
+ return type->nMembers == 0
+ ? 0
+ : (type->nMapFunctionIndexToMemberIndex
+ - type->pMapMemberIndexToFunctionIndex[
+ type->nAllMembers - type->nMembers]);
+}
+
+sal_Int32 getPrimaryFunctions(typelib_InterfaceTypeDescription * type) {
+ sal_Int32 n = 0;
+ for (; type != 0; type = type->pBaseTypeDescription) {
+ typelib_typedescription_complete(
+ reinterpret_cast< typelib_TypeDescription ** >(&type));
+ n += getLocalFunctions(type);
+ }
+ return n;
+}
+
+VtableSlot getVtableSlot(
+ typelib_InterfaceAttributeTypeDescription const * ifcMember)
+{
+ return doGetVtableSlot(ifcMember);
+}
+
+VtableSlot getVtableSlot(
+ typelib_InterfaceMethodTypeDescription const * ifcMember)
+{
+ return doGetVtableSlot(ifcMember);
+}
+
+} } }
diff --git a/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_info_holder.java b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_info_holder.java
new file mode 100644
index 000000000000..6323a4f89710
--- /dev/null
+++ b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_info_holder.java
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: JNI_info_holder.java,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package com.sun.star.bridges.jni_uno;
+
+import com.sun.star.lib.util.NativeLibraryLoader;
+
+//==============================================================================
+public final class JNI_info_holder
+{
+ static {
+ NativeLibraryLoader.loadLibrary(JNI_info_holder.class.getClassLoader(),
+ "java_uno");
+ }
+
+ private static JNI_info_holder s_holder = new JNI_info_holder();
+
+ private static long s_jni_info_handle;
+
+ //__________________________________________________________________________
+ private native void finalize( long jni_info_handle );
+
+ //__________________________________________________________________________
+ protected void finalize()
+ {
+ finalize( s_jni_info_handle );
+ }
+}
diff --git a/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_proxy.java b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_proxy.java
new file mode 100644
index 000000000000..e5e55783454c
--- /dev/null
+++ b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_proxy.java
@@ -0,0 +1,221 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: JNI_proxy.java,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package com.sun.star.bridges.jni_uno;
+
+import com.sun.star.lib.util.AsynchronousFinalizer;
+import com.sun.star.lib.util.NativeLibraryLoader;
+import com.sun.star.uno.Type;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.IEnvironment;
+import com.sun.star.uno.IQueryInterface;
+
+
+//==============================================================================
+public final class JNI_proxy implements java.lang.reflect.InvocationHandler
+{
+ static {
+ NativeLibraryLoader.loadLibrary(JNI_proxy.class.getClassLoader(),
+ "java_uno");
+ }
+ protected static ClassLoader s_classloader =
+ JNI_proxy.class.getClassLoader();
+ protected static Class s_InvocationHandler [] =
+ new Class [] { java.lang.reflect.InvocationHandler.class };
+
+ protected long m_bridge_handle;
+ protected IEnvironment m_java_env;
+ protected long m_receiver_handle;
+ protected long m_td_handle;
+ protected Type m_type;
+ protected String m_oid;
+ protected Class m_class;
+
+ //__________________________________________________________________________
+ public static String get_stack_trace( Throwable throwable )
+ throws Throwable
+ {
+ boolean current_trace = false;
+ if (null == throwable)
+ {
+ throwable = new Throwable();
+ current_trace = true;
+ }
+ java.io.StringWriter string_writer =
+ new java.io.StringWriter();
+ java.io.PrintWriter print_writer =
+ new java.io.PrintWriter( string_writer, true );
+ throwable.printStackTrace( print_writer );
+ print_writer.flush();
+ print_writer.close();
+ string_writer.flush();
+ String trace = string_writer.toString();
+ if (current_trace)
+ {
+ // cut out first two lines
+ int n = trace.indexOf( '\n' );
+ n = trace.indexOf( '\n', n +1 );
+ trace = trace.substring( n +1 );
+ }
+ return "\njava stack trace:\n" + trace;
+ }
+
+ //__________________________________________________________________________
+ private native void finalize( long bridge_handle );
+
+ //__________________________________________________________________________
+ public void finalize()
+ {
+ AsynchronousFinalizer.add(new AsynchronousFinalizer.Job() {
+ public void run() throws Throwable {
+ JNI_proxy.this.finalize( m_bridge_handle );
+ }
+ });
+ }
+
+ //__________________________________________________________________________
+ private JNI_proxy(
+ long bridge_handle, IEnvironment java_env,
+ long receiver_handle, long td_handle, Type type, String oid )
+ {
+ m_bridge_handle = bridge_handle;
+ m_java_env = java_env;
+ m_receiver_handle = receiver_handle;
+ m_td_handle = td_handle;
+ m_type = type;
+ m_oid = oid;
+ m_class = m_type.getZClass();
+ }
+
+ //__________________________________________________________________________
+ public static Object create(
+ long bridge_handle, IEnvironment java_env,
+ long receiver_handle, long td_handle, Type type, String oid,
+ java.lang.reflect.Constructor proxy_ctor )
+ throws Throwable
+ {
+ JNI_proxy handler = new JNI_proxy(
+ bridge_handle, java_env, receiver_handle, td_handle, type, oid );
+ Object proxy = proxy_ctor.newInstance( new Object [] { handler } );
+ return java_env.registerInterface( proxy, new String [] { oid }, type );
+ }
+
+ //__________________________________________________________________________
+ public static java.lang.reflect.Constructor get_proxy_ctor( Class clazz )
+ throws Throwable
+ {
+ Class proxy_class = java.lang.reflect.Proxy.getProxyClass(
+ s_classloader,
+ new Class [] { clazz, IQueryInterface.class,
+ com.sun.star.lib.uno.Proxy.class } );
+ return proxy_class.getConstructor( s_InvocationHandler );
+ }
+
+ //__________________________________________________________________________
+ private native Object dispatch_call(
+ long bridge_handle, String decl_class, String method, Object args [] )
+ throws Throwable;
+
+ // InvocationHandler impl
+ //__________________________________________________________________________
+ public Object invoke(
+ Object proxy, java.lang.reflect.Method method, Object args [] )
+ throws Throwable
+ {
+ Class decl_class = method.getDeclaringClass();
+ String method_name = method.getName();
+
+ if (Object.class.equals( decl_class ))
+ {
+ if (method_name.equals( "hashCode" ))
+ {
+ // int hashCode()
+ return new Integer( m_oid.hashCode() );
+ }
+ else if (method_name.equals( "equals" ))
+ {
+ // boolean equals( Object obj )
+ return isSame(args[0]);
+ }
+ else if (method_name.equals( "toString" ))
+ {
+ // String toString()
+ return this.toString() + " [oid=" + m_oid +
+ ", type=" + m_type.getTypeName() + "]";
+ }
+ }
+ // UNO interface call
+ else if (decl_class.isAssignableFrom( m_class ))
+ {
+ // dispatch interface call
+ return dispatch_call(
+ m_bridge_handle, decl_class.getName(), method_name, args );
+ }
+ // IQueryInterface impl
+ else if (IQueryInterface.class.equals( decl_class ))
+ {
+ if (method_name.equals( "queryInterface" ))
+ {
+ // Object queryInterface( Type type )
+ Object registered_proxy =
+ m_java_env.getRegisteredInterface( m_oid, (Type)args[ 0 ] );
+ if (null == registered_proxy)
+ {
+ return dispatch_call(
+ m_bridge_handle,
+ "com.sun.star.uno.XInterface", method_name, args );
+ }
+ else
+ {
+ return registered_proxy;
+ }
+ }
+ else if (method_name.equals( "isSame" ))
+ {
+ // boolean isSame( Object object )
+ return isSame(args[0]);
+ }
+ else if (method_name.equals( "getOid" ))
+ {
+ // String getOid()
+ return m_oid;
+ }
+ }
+
+ throw new com.sun.star.uno.RuntimeException(
+ "[jni_uno bridge error] unexpected call on proxy " +
+ proxy.toString() + ": " + method.toString() );
+ }
+
+ private Boolean isSame(Object obj) {
+ return new Boolean(obj != null
+ && m_oid.equals(UnoRuntime.generateOid(obj)));
+ }
+}
diff --git a/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/makefile.mk b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/makefile.mk
new file mode 100644
index 000000000000..cc23338ac05b
--- /dev/null
+++ b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/makefile.mk
@@ -0,0 +1,57 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..$/..$/..$/..$/..$/..$/..
+
+PRJNAME=bridges
+TARGET=java_uno
+PACKAGE=com$/sun$/star$/bridges$/jni_uno
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+JARFILES=jurt.jar ridl.jar
+JAVAFILES=$(subst,$(CLASSDIR)$/$(PACKAGE)$/, $(subst,.class,.java $(JAVACLASSFILES)))
+
+JAVACLASSFILES= \
+ $(CLASSDIR)$/$(PACKAGE)$/JNI_proxy.class \
+ $(CLASSDIR)$/$(PACKAGE)$/JNI_info_holder.class
+
+JARCLASSDIRS=$(PACKAGE)
+JARTARGET=$(TARGET).jar
+JARCOMPRESS=TRUE
+JARCLASSPATH = $(JARFILES) ../../lib/ ../bin/
+CUSTOMMANIFESTFILE = manifest
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/manifest b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/manifest
new file mode 100644
index 000000000000..7ad02e156d9a
--- /dev/null
+++ b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/manifest
@@ -0,0 +1 @@
+Sealed: true
diff --git a/bridges/source/jni_uno/java_uno.map b/bridges/source/jni_uno/java_uno.map
new file mode 100644
index 000000000000..376f7ea979bb
--- /dev/null
+++ b/bridges/source/jni_uno/java_uno.map
@@ -0,0 +1,27 @@
+UDK_3_0_0 {
+ global:
+ uno_initEnvironment;
+ uno_ext_getMapping;
+ component_canUnload;
+ local:
+ *;
+};
+
+UDK_3.1 {
+ global:
+ Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J;
+ Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call;
+ Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize__J;
+} UDK_3_0_0;
+
+UDK_3.2 {
+ global:
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_attach;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_create;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_destroy;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_detach;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_dispose;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_enter;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_threadId;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_putJob;
+} UDK_3.1;
diff --git a/bridges/source/jni_uno/jni_base.h b/bridges/source/jni_uno/jni_base.h
new file mode 100644
index 000000000000..90270d250608
--- /dev/null
+++ b/bridges/source/jni_uno/jni_base.h
@@ -0,0 +1,295 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: jni_base.h,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_JNI_BASE_H
+#define INCLUDED_JNI_BASE_H
+
+#if defined (__SUNPRO_CC) || defined (__SUNPRO_C)
+// workaround solaris include trouble on jumbo
+#include <stdarg.h>
+namespace std
+{
+typedef __va_list va_list;
+}
+#endif
+#include <memory>
+
+#include "jvmaccess/unovirtualmachine.hxx"
+#include "jvmaccess/virtualmachine.hxx"
+
+#include "osl/diagnose.h"
+
+#include "rtl/alloc.h"
+#include "rtl/ustring.hxx"
+
+#include "uno/environment.h"
+#include "typelib/typedescription.h"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+
+namespace jni_uno
+{
+
+class JNI_info;
+
+//==============================================================================
+struct BridgeRuntimeError
+{
+ ::rtl::OUString m_message;
+
+ inline BridgeRuntimeError( ::rtl::OUString const & message )
+ : m_message( message )
+ {}
+};
+
+
+//==============================================================================
+class JNI_context
+{
+ JNI_info const * m_jni_info;
+ JNIEnv * m_env;
+ jobject m_class_loader;
+
+ JNI_context( JNI_context & ); // not impl
+ void operator = ( JNI_context ); // not impl
+
+ void java_exc_occured() const;
+public:
+ inline explicit JNI_context(
+ JNI_info const * jni_info, JNIEnv * env, jobject class_loader )
+ : m_jni_info( jni_info ),
+ m_env( env ),
+ m_class_loader( class_loader )
+ {}
+
+ inline JNI_info const * get_info() const
+ { return m_jni_info; }
+
+ inline JNIEnv * operator -> () const
+ { return m_env; }
+ inline JNIEnv * get_jni_env() const
+ { return m_env; }
+
+ // does not handle exceptions, *classClass will be null if exception
+ // occurred:
+ void getClassForName(jclass * classClass, jmethodID * methodForName) const;
+
+ // if inException, does not handle exceptions, in which case returned value
+ // will be null if exception occurred:
+ jclass findClass(
+ char const * name, jclass classClass, jmethodID methodForName,
+ bool inException) const;
+
+ inline void ensure_no_exception() const; // throws BridgeRuntimeError
+ inline bool assert_no_exception() const; // asserts and clears exception
+
+ ::rtl::OUString get_stack_trace( jobject jo_exc = 0 ) const;
+};
+
+//______________________________________________________________________________
+inline void JNI_context::ensure_no_exception() const
+{
+ if (JNI_FALSE != m_env->ExceptionCheck())
+ {
+ java_exc_occured();
+ }
+}
+
+//______________________________________________________________________________
+inline bool JNI_context::assert_no_exception() const
+{
+ if (JNI_FALSE != m_env->ExceptionCheck())
+ {
+ m_env->ExceptionClear();
+ OSL_ENSURE( 0, "unexpected java exception occured!" );
+ return false;
+ }
+ return true;
+}
+
+
+//==============================================================================
+class JNI_guarded_context
+ : private ::jvmaccess::VirtualMachine::AttachGuard,
+ public JNI_context
+{
+ JNI_guarded_context( JNI_guarded_context & ); // not impl
+ void operator = ( JNI_guarded_context ); // not impl
+
+public:
+ inline explicit JNI_guarded_context(
+ JNI_info const * jni_info, ::jvmaccess::UnoVirtualMachine * vm_access )
+ : AttachGuard( vm_access->getVirtualMachine() ),
+ JNI_context(
+ jni_info, AttachGuard::getEnvironment(),
+ static_cast< jobject >(vm_access->getClassLoader()) )
+ {}
+};
+
+
+//==============================================================================
+class JLocalAutoRef
+{
+ JNI_context const & m_jni;
+ jobject m_jo;
+
+public:
+ inline JLocalAutoRef( JNI_context const & jni )
+ : m_jni( jni ),
+ m_jo( 0 )
+ {}
+ inline explicit JLocalAutoRef( JNI_context const & jni, jobject jo )
+ : m_jni( jni ),
+ m_jo( jo )
+ {}
+ inline JLocalAutoRef( JLocalAutoRef & auto_ref );
+ inline ~JLocalAutoRef() SAL_THROW( () );
+
+ inline jobject get() const
+ { return m_jo; }
+ inline bool is() const
+ { return (0 != m_jo); }
+ inline jobject release();
+ inline void reset();
+ inline void reset( jobject jo );
+ inline JLocalAutoRef & operator = ( JLocalAutoRef & auto_ref );
+};
+
+//______________________________________________________________________________
+inline JLocalAutoRef::~JLocalAutoRef() SAL_THROW( () )
+{
+ if (0 != m_jo)
+ m_jni->DeleteLocalRef( m_jo );
+}
+
+//______________________________________________________________________________
+inline JLocalAutoRef::JLocalAutoRef( JLocalAutoRef & auto_ref )
+ : m_jni( auto_ref.m_jni ),
+ m_jo( auto_ref.m_jo )
+{
+ auto_ref.m_jo = 0;
+}
+
+//______________________________________________________________________________
+inline jobject JLocalAutoRef::release()
+{
+ jobject jo = m_jo;
+ m_jo = 0;
+ return jo;
+}
+
+//______________________________________________________________________________
+inline void JLocalAutoRef::reset()
+{
+ if (0 != m_jo)
+ m_jni->DeleteLocalRef( m_jo );
+ m_jo = 0;
+}
+
+//______________________________________________________________________________
+inline void JLocalAutoRef::reset( jobject jo )
+{
+ if (jo != m_jo)
+ {
+ if (0 != m_jo)
+ m_jni->DeleteLocalRef( m_jo );
+ m_jo = jo;
+ }
+}
+
+//______________________________________________________________________________
+inline JLocalAutoRef & JLocalAutoRef::operator = ( JLocalAutoRef & auto_ref )
+{
+ OSL_ASSERT( m_jni.get_jni_env() == auto_ref.m_jni.get_jni_env() );
+ reset( auto_ref.m_jo );
+ auto_ref.m_jo = 0;
+ return *this;
+}
+
+
+//==============================================================================
+struct rtl_mem
+{
+ inline static void * operator new ( size_t nSize )
+ { return rtl_allocateMemory( nSize ); }
+ inline static void operator delete ( void * mem )
+ { if (mem) rtl_freeMemory( mem ); }
+ inline static void * operator new ( size_t, void * mem )
+ { return mem; }
+ inline static void operator delete ( void *, void * )
+ {}
+
+ static inline ::std::auto_ptr< rtl_mem > allocate( ::std::size_t bytes );
+};
+
+//______________________________________________________________________________
+inline ::std::auto_ptr< rtl_mem > rtl_mem::allocate( ::std::size_t bytes )
+{
+ void * p = rtl_allocateMemory( bytes );
+ if (0 == p)
+ throw BridgeRuntimeError( OUSTR("out of memory!") );
+ return ::std::auto_ptr< rtl_mem >( (rtl_mem *)p );
+}
+
+
+//==============================================================================
+class TypeDescr
+{
+ typelib_TypeDescription * m_td;
+
+ TypeDescr( TypeDescr & ); // not impl
+ void operator = ( TypeDescr ); // not impl
+
+public:
+ inline explicit TypeDescr( typelib_TypeDescriptionReference * td_ref );
+ inline ~TypeDescr() SAL_THROW( () )
+ { TYPELIB_DANGER_RELEASE( m_td ); }
+
+ inline typelib_TypeDescription * get() const
+ { return m_td; }
+};
+
+//______________________________________________________________________________
+inline TypeDescr::TypeDescr( typelib_TypeDescriptionReference * td_ref )
+ : m_td( 0 )
+{
+ TYPELIB_DANGER_GET( &m_td, td_ref );
+ if (0 == m_td)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("cannot get comprehensive type description for ") +
+ ::rtl::OUString::unacquired( &td_ref->pTypeName ) );
+ }
+}
+
+}
+
+#endif
diff --git a/bridges/source/jni_uno/jni_bridge.cxx b/bridges/source/jni_uno/jni_bridge.cxx
new file mode 100644
index 000000000000..9f9a0487ca17
--- /dev/null
+++ b/bridges/source/jni_uno/jni_bridge.cxx
@@ -0,0 +1,572 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: jni_bridge.cxx,v $
+ * $Revision: 1.18 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "jni_bridge.h"
+
+#include "jvmaccess/unovirtualmachine.hxx"
+#include "rtl/ref.hxx"
+#include "rtl/unload.h"
+#include "rtl/strbuf.hxx"
+#include "uno/lbnames.h"
+
+
+using namespace ::std;
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::jni_uno;
+
+namespace
+{
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+void SAL_CALL Mapping_acquire( uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ Mapping const * that = static_cast< Mapping const * >( mapping );
+ that->m_bridge->acquire();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL Mapping_release( uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ Mapping const * that = static_cast< Mapping const * >( mapping );
+ that->m_bridge->release();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL Mapping_map_to_uno(
+ uno_Mapping * mapping, void ** ppOut,
+ void * pIn, typelib_InterfaceTypeDescription * td )
+ SAL_THROW_EXTERN_C()
+{
+ uno_Interface ** ppUnoI = (uno_Interface **)ppOut;
+ jobject javaI = (jobject) pIn;
+
+ OSL_ASSERT( sizeof (void *) == sizeof (jobject) );
+ OSL_ENSURE( ppUnoI && td, "### null ptr!" );
+
+ if (0 == javaI)
+ {
+ if (0 != *ppUnoI)
+ {
+ uno_Interface * p = *(uno_Interface **)ppUnoI;
+ (*p->release)( p );
+ *ppUnoI = 0;
+ }
+ }
+ else
+ {
+ try
+ {
+ Bridge const * bridge =
+ static_cast< Mapping const * >( mapping )->m_bridge;
+ JNI_guarded_context jni(
+ bridge->m_jni_info,
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext ) );
+
+ JNI_interface_type_info const * info =
+ static_cast< JNI_interface_type_info const * >(
+ bridge->m_jni_info->get_type_info(
+ jni, (typelib_TypeDescription *)td ) );
+ uno_Interface * pUnoI = bridge->map_to_uno( jni, javaI, info );
+ if (0 != *ppUnoI)
+ {
+ uno_Interface * p = *(uno_Interface **)ppUnoI;
+ (*p->release)( p );
+ }
+ *ppUnoI = pUnoI;
+ }
+ catch (BridgeRuntimeError & err)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("[jni_uno bridge error] ") + err.m_message,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+#else
+ (void) err; // unused
+#endif
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OSL_ENSURE(
+ 0,
+ "[jni_uno bridge error] attaching current thread "
+ "to java failed!" );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL Mapping_map_to_java(
+ uno_Mapping * mapping, void ** ppOut,
+ void * pIn, typelib_InterfaceTypeDescription * td )
+ SAL_THROW_EXTERN_C()
+{
+ jobject * ppJavaI = (jobject *) ppOut;
+ uno_Interface * pUnoI = (uno_Interface *)pIn;
+
+ OSL_ASSERT( sizeof (void *) == sizeof (jobject) );
+ OSL_ENSURE( ppJavaI && td, "### null ptr!" );
+
+ try
+ {
+ if (0 == pUnoI)
+ {
+ if (0 != *ppJavaI)
+ {
+ Bridge const * bridge =
+ static_cast< Mapping const * >( mapping )->m_bridge;
+ JNI_guarded_context jni(
+ bridge->m_jni_info,
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext ) );
+ jni->DeleteGlobalRef( *ppJavaI );
+ *ppJavaI = 0;
+ }
+ }
+ else
+ {
+ Bridge const * bridge =
+ static_cast< Mapping const * >( mapping )->m_bridge;
+ JNI_guarded_context jni(
+ bridge->m_jni_info,
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext ) );
+
+ JNI_interface_type_info const * info =
+ static_cast< JNI_interface_type_info const * >(
+ bridge->m_jni_info->get_type_info(
+ jni, (typelib_TypeDescription *)td ) );
+ jobject jlocal = bridge->map_to_java( jni, pUnoI, info );
+ if (0 != *ppJavaI)
+ jni->DeleteGlobalRef( *ppJavaI );
+ *ppJavaI = jni->NewGlobalRef( jlocal );
+ jni->DeleteLocalRef( jlocal );
+ }
+ }
+ catch (BridgeRuntimeError & err)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("[jni_uno bridge error] ") + err.m_message,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+#else
+ (void) err; // unused
+#endif
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OSL_ENSURE(
+ 0,
+ "[jni_uno bridge error] attaching current thread to java failed!" );
+ }
+}
+
+//______________________________________________________________________________
+void SAL_CALL Bridge_free( uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ Mapping * that = static_cast< Mapping * >( mapping );
+ delete that->m_bridge;
+}
+
+}
+
+rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+}
+
+namespace jni_uno
+{
+
+//______________________________________________________________________________
+void Bridge::acquire() const SAL_THROW( () )
+{
+ if (1 == osl_incrementInterlockedCount( &m_ref ))
+ {
+ if (m_registered_java2uno)
+ {
+ uno_Mapping * mapping = const_cast< Mapping * >( &m_java2uno );
+ uno_registerMapping(
+ &mapping, Bridge_free,
+ m_java_env, (uno_Environment *)m_uno_env, 0 );
+ }
+ else
+ {
+ uno_Mapping * mapping = const_cast< Mapping * >( &m_uno2java );
+ uno_registerMapping(
+ &mapping, Bridge_free,
+ (uno_Environment *)m_uno_env, m_java_env, 0 );
+ }
+ }
+}
+
+//______________________________________________________________________________
+void Bridge::release() const SAL_THROW( () )
+{
+ if (! osl_decrementInterlockedCount( &m_ref ))
+ {
+ uno_revokeMapping(
+ m_registered_java2uno
+ ? const_cast< Mapping * >( &m_java2uno )
+ : const_cast< Mapping * >( &m_uno2java ) );
+ }
+}
+
+//______________________________________________________________________________
+Bridge::Bridge(
+ uno_Environment * java_env, uno_ExtEnvironment * uno_env,
+ bool registered_java2uno )
+ : m_ref( 1 ),
+ m_uno_env( uno_env ),
+ m_java_env( java_env ),
+ m_registered_java2uno( registered_java2uno )
+{
+ // bootstrapping bridge jni_info
+ m_jni_info = JNI_info::get_jni_info(
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ m_java_env->pContext ) );
+
+ OSL_ASSERT( 0 != m_java_env && 0 != m_uno_env );
+ (*((uno_Environment *)m_uno_env)->acquire)( (uno_Environment *)m_uno_env );
+ (*m_java_env->acquire)( m_java_env );
+
+ // java2uno
+ m_java2uno.acquire = Mapping_acquire;
+ m_java2uno.release = Mapping_release;
+ m_java2uno.mapInterface = Mapping_map_to_uno;
+ m_java2uno.m_bridge = this;
+ // uno2java
+ m_uno2java.acquire = Mapping_acquire;
+ m_uno2java.release = Mapping_release;
+ m_uno2java.mapInterface = Mapping_map_to_java;
+ m_uno2java.m_bridge = this;
+
+ (*g_moduleCount.modCnt.acquire)( &g_moduleCount.modCnt );
+}
+
+//______________________________________________________________________________
+Bridge::~Bridge() SAL_THROW( () )
+{
+ (*m_java_env->release)( m_java_env );
+ (*((uno_Environment *)m_uno_env)->release)( (uno_Environment *)m_uno_env );
+
+ (*g_moduleCount.modCnt.release)( &g_moduleCount.modCnt );
+}
+
+
+//______________________________________________________________________________
+void JNI_context::java_exc_occured() const
+{
+ // !don't rely on JNI_info!
+
+ JLocalAutoRef jo_exc( *this, m_env->ExceptionOccurred() );
+ m_env->ExceptionClear();
+ OSL_ASSERT( jo_exc.is() );
+ if (! jo_exc.is())
+ {
+ throw BridgeRuntimeError(
+ OUSTR("java exception occured, but not available!?") +
+ get_stack_trace() );
+ }
+
+ // call toString(); don't rely on m_jni_info
+ jclass jo_class = m_env->FindClass( "java/lang/Object" );
+ if (JNI_FALSE != m_env->ExceptionCheck())
+ {
+ m_env->ExceptionClear();
+ throw BridgeRuntimeError(
+ OUSTR("cannot get class java.lang.Object!") + get_stack_trace() );
+ }
+ JLocalAutoRef jo_Object( *this, jo_class );
+ // method Object.toString()
+ jmethodID method_Object_toString = m_env->GetMethodID(
+ (jclass) jo_Object.get(), "toString", "()Ljava/lang/String;" );
+ if (JNI_FALSE != m_env->ExceptionCheck())
+ {
+ m_env->ExceptionClear();
+ throw BridgeRuntimeError(
+ OUSTR("cannot get method id of java.lang.Object.toString()!") +
+ get_stack_trace() );
+ }
+ OSL_ASSERT( 0 != method_Object_toString );
+
+ JLocalAutoRef jo_descr(
+ *this, m_env->CallObjectMethodA(
+ jo_exc.get(), method_Object_toString, 0 ) );
+ if (m_env->ExceptionCheck()) // no chance at all
+ {
+ m_env->ExceptionClear();
+ throw BridgeRuntimeError(
+ OUSTR("error examining java exception object!") +
+ get_stack_trace() );
+ }
+
+ jsize len = m_env->GetStringLength( (jstring) jo_descr.get() );
+ auto_ptr< rtl_mem > ustr_mem(
+ rtl_mem::allocate(
+ sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ) );
+ rtl_uString * ustr = (rtl_uString *)ustr_mem.get();
+ m_env->GetStringRegion( (jstring) jo_descr.get(), 0, len, ustr->buffer );
+ if (m_env->ExceptionCheck())
+ {
+ m_env->ExceptionClear();
+ throw BridgeRuntimeError(
+ OUSTR("invalid java string object!") + get_stack_trace() );
+ }
+ ustr->refCount = 1;
+ ustr->length = len;
+ ustr->buffer[ len ] = '\0';
+ OUString message( (rtl_uString *)ustr_mem.release(), SAL_NO_ACQUIRE );
+
+ throw BridgeRuntimeError( message + get_stack_trace( jo_exc.get() ) );
+}
+
+//______________________________________________________________________________
+void JNI_context::getClassForName(
+ jclass * classClass, jmethodID * methodForName) const
+{
+ jclass c = m_env->FindClass("java/lang/Class");
+ if (c != 0) {
+ *methodForName = m_env->GetStaticMethodID(
+ c, "forName",
+ "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;");
+ }
+ *classClass = c;
+}
+
+//______________________________________________________________________________
+jclass JNI_context::findClass(
+ char const * name, jclass classClass, jmethodID methodForName,
+ bool inException) const
+{
+ jclass c = 0;
+ JLocalAutoRef s(*this, m_env->NewStringUTF(name));
+ if (s.is()) {
+ jvalue a[3];
+ a[0].l = s.get();
+ a[1].z = JNI_FALSE;
+ a[2].l = m_class_loader;
+ c = static_cast< jclass >(
+ m_env->CallStaticObjectMethodA(classClass, methodForName, a));
+ }
+ if (!inException) {
+ ensure_no_exception();
+ }
+ return c;
+}
+
+//______________________________________________________________________________
+OUString JNI_context::get_stack_trace( jobject jo_exc ) const
+{
+ JLocalAutoRef jo_JNI_proxy(
+ *this,
+ find_class( *this, "com.sun.star.bridges.jni_uno.JNI_proxy", true ) );
+ if (assert_no_exception())
+ {
+ // static method JNI_proxy.get_stack_trace()
+ jmethodID method = m_env->GetStaticMethodID(
+ (jclass) jo_JNI_proxy.get(), "get_stack_trace",
+ "(Ljava/lang/Throwable;)Ljava/lang/String;" );
+ if (assert_no_exception() && (0 != method))
+ {
+ jvalue arg;
+ arg.l = jo_exc;
+ JLocalAutoRef jo_stack_trace(
+ *this, m_env->CallStaticObjectMethodA(
+ (jclass) jo_JNI_proxy.get(), method, &arg ) );
+ if (assert_no_exception())
+ {
+ jsize len =
+ m_env->GetStringLength( (jstring) jo_stack_trace.get() );
+ auto_ptr< rtl_mem > ustr_mem(
+ rtl_mem::allocate(
+ sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ) );
+ rtl_uString * ustr = (rtl_uString *)ustr_mem.get();
+ m_env->GetStringRegion(
+ (jstring) jo_stack_trace.get(), 0, len, ustr->buffer );
+ if (assert_no_exception())
+ {
+ ustr->refCount = 1;
+ ustr->length = len;
+ ustr->buffer[ len ] = '\0';
+ return OUString(
+ (rtl_uString *)ustr_mem.release(), SAL_NO_ACQUIRE );
+ }
+ }
+ }
+ }
+ return OUString();
+}
+
+}
+
+using namespace ::jni_uno;
+
+extern "C"
+{
+namespace
+{
+
+//------------------------------------------------------------------------------
+void SAL_CALL java_env_disposing( uno_Environment * java_env )
+ SAL_THROW_EXTERN_C()
+{
+ ::jvmaccess::UnoVirtualMachine * machine =
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ java_env->pContext );
+ java_env->pContext = 0;
+ machine->release();
+}
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL uno_initEnvironment( uno_Environment * java_env )
+ SAL_THROW_EXTERN_C()
+{
+ java_env->environmentDisposing = java_env_disposing;
+ java_env->pExtEnv = 0; // no extended support
+ OSL_ASSERT( 0 != java_env->pContext );
+
+ ::jvmaccess::UnoVirtualMachine * machine =
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ java_env->pContext );
+ machine->acquire();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL uno_ext_getMapping(
+ uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo )
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ASSERT( 0 != ppMapping && 0 != pFrom && 0 != pTo );
+ if (0 != *ppMapping)
+ {
+ (*(*ppMapping)->release)( *ppMapping );
+ *ppMapping = 0;
+ }
+
+ OSL_ASSERT( JNI_FALSE == sal_False );
+ OSL_ASSERT( JNI_TRUE == sal_True );
+ OSL_ASSERT( sizeof (jboolean) == sizeof (sal_Bool) );
+ OSL_ASSERT( sizeof (jchar) == sizeof (sal_Unicode) );
+ OSL_ASSERT( sizeof (jdouble) == sizeof (double) );
+ OSL_ASSERT( sizeof (jfloat) == sizeof (float) );
+ OSL_ASSERT( sizeof (jbyte) == sizeof (sal_Int8) );
+ OSL_ASSERT( sizeof (jshort) == sizeof (sal_Int16) );
+ OSL_ASSERT( sizeof (jint) == sizeof (sal_Int32) );
+ OSL_ASSERT( sizeof (jlong) == sizeof (sal_Int64) );
+ if ((JNI_FALSE == sal_False) &&
+ (JNI_TRUE == sal_True) &&
+ (sizeof (jboolean) == sizeof (sal_Bool)) &&
+ (sizeof (jchar) == sizeof (sal_Unicode)) &&
+ (sizeof (jdouble) == sizeof (double)) &&
+ (sizeof (jfloat) == sizeof (float)) &&
+ (sizeof (jbyte) == sizeof (sal_Int8)) &&
+ (sizeof (jshort) == sizeof (sal_Int16)) &&
+ (sizeof (jint) == sizeof (sal_Int32)) &&
+ (sizeof (jlong) == sizeof (sal_Int64)))
+ {
+ OUString const & from_env_typename =
+ OUString::unacquired( &pFrom->pTypeName );
+ OUString const & to_env_typename =
+ OUString::unacquired( &pTo->pTypeName );
+
+ uno_Mapping * mapping = 0;
+
+ try
+ {
+ if (from_env_typename.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(UNO_LB_JAVA) ) &&
+ to_env_typename.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) ))
+ {
+ Bridge * bridge =
+ new Bridge( pFrom, pTo->pExtEnv, true ); // ref count = 1
+ mapping = &bridge->m_java2uno;
+ uno_registerMapping(
+ &mapping, Bridge_free,
+ pFrom, (uno_Environment *)pTo->pExtEnv, 0 );
+ }
+ else if (from_env_typename.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) ) &&
+ to_env_typename.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(UNO_LB_JAVA) ))
+ {
+ Bridge * bridge =
+ new Bridge( pTo, pFrom->pExtEnv, false ); // ref count = 1
+ mapping = &bridge->m_uno2java;
+ uno_registerMapping(
+ &mapping, Bridge_free,
+ (uno_Environment *)pFrom->pExtEnv, pTo, 0 );
+ }
+ }
+ catch (BridgeRuntimeError & err)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("[jni_uno bridge error] ") + err.m_message,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+#else
+ (void) err; // unused
+#endif
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OSL_ENSURE(
+ 0,
+ "[jni_uno bridge error] attaching current thread "
+ "to java failed!" );
+ }
+
+ *ppMapping = mapping;
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL component_canUnload( TimeValue * pTime )
+ SAL_THROW_EXTERN_C()
+{
+ return (*g_moduleCount.canUnload)( &g_moduleCount, pTime );
+}
+}
diff --git a/bridges/source/jni_uno/jni_bridge.h b/bridges/source/jni_uno/jni_bridge.h
new file mode 100644
index 000000000000..b5bd963694c0
--- /dev/null
+++ b/bridges/source/jni_uno/jni_bridge.h
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: jni_bridge.h,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_JNI_BRIDGE_H
+#define INCLUDED_JNI_BRIDGE_H
+
+#include "jni_base.h"
+#include "jni_info.h"
+#include "jni_helper.h"
+
+#include "osl/diagnose.h"
+#include "osl/interlck.h"
+
+#include "uno/mapping.h"
+#include "uno/dispatcher.h"
+
+#include "com/sun/star/uno/XInterface.hpp"
+
+
+namespace jni_uno
+{
+
+//==== holds environments and mappings =========================================
+struct Bridge;
+struct Mapping : public uno_Mapping
+{
+ Bridge * m_bridge;
+};
+
+//==============================================================================
+struct Bridge
+{
+ mutable oslInterlockedCount m_ref;
+
+ uno_ExtEnvironment * m_uno_env;
+ uno_Environment * m_java_env;
+
+ Mapping m_java2uno;
+ Mapping m_uno2java;
+ bool m_registered_java2uno;
+
+ JNI_info const * m_jni_info;
+
+ //
+ ~Bridge() SAL_THROW( () );
+ explicit Bridge(
+ uno_Environment * java_env, uno_ExtEnvironment * uno_env,
+ bool registered_java2uno );
+
+ void acquire() const;
+ void release() const;
+
+ // jni_data.cxx
+ void map_to_uno(
+ JNI_context const & jni,
+ void * uno_data, jvalue java_data,
+ typelib_TypeDescriptionReference * type,
+ JNI_type_info const * info /* maybe 0 */,
+ bool assign, bool out_param,
+ bool special_wrapped_integral_types = false ) const;
+ void map_to_java(
+ JNI_context const & jni,
+ jvalue * java_data, void const * uno_data,
+ typelib_TypeDescriptionReference * type,
+ JNI_type_info const * info /* maybe 0 */,
+ bool in_param, bool out_param,
+ bool special_wrapped_integral_types = false ) const;
+
+ // jni_uno2java.cxx
+ void handle_uno_exc(
+ JNI_context const & jni, uno_Any * uno_exc ) const;
+ void call_java(
+ jobject javaI,
+ typelib_InterfaceTypeDescription * iface_td,
+ sal_Int32 local_member_index, sal_Int32 function_pos_offset,
+ typelib_TypeDescriptionReference * return_type,
+ typelib_MethodParameter * params, sal_Int32 nParams,
+ void * uno_ret, void * uno_args [], uno_Any ** uno_exc ) const;
+ jobject map_to_java(
+ JNI_context const & jni,
+ uno_Interface * pUnoI, JNI_interface_type_info const * info ) const;
+
+ // jni_java2uno.cxx
+ void handle_java_exc(
+ JNI_context const & jni,
+ JLocalAutoRef const & jo_exc, uno_Any * uno_exc ) const;
+ jobject call_uno(
+ JNI_context const & jni,
+ uno_Interface * pUnoI, typelib_TypeDescription * member_td,
+ typelib_TypeDescriptionReference * return_tdref,
+ sal_Int32 nParams, typelib_MethodParameter const * pParams,
+ jobjectArray jo_args ) const;
+ uno_Interface * map_to_uno(
+ JNI_context const & jni,
+ jobject javaI, JNI_interface_type_info const * info ) const;
+};
+
+}
+
+#endif
diff --git a/bridges/source/jni_uno/jni_data.cxx b/bridges/source/jni_uno/jni_data.cxx
new file mode 100644
index 000000000000..5d87eb0d1043
--- /dev/null
+++ b/bridges/source/jni_uno/jni_data.cxx
@@ -0,0 +1,2579 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: jni_data.cxx,v $
+ * $Revision: 1.23 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "jni_bridge.h"
+
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "uno/sequence2.h"
+
+
+using namespace ::std;
+using namespace ::rtl;
+
+namespace jni_uno
+{
+
+//------------------------------------------------------------------------------
+inline rtl_mem * seq_allocate( sal_Int32 nElements, sal_Int32 nSize )
+{
+ auto_ptr< rtl_mem > seq(
+ rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE + (nElements * nSize) ) );
+ uno_Sequence * p = (uno_Sequence *)seq.get();
+ p->nRefCount = 1;
+ p->nElements = nElements;
+ return seq.release();
+}
+
+//______________________________________________________________________________
+namespace {
+
+void createDefaultUnoValue(
+ JNI_context const & jni, void * uno_data,
+ typelib_TypeDescriptionReference * type,
+ JNI_type_info const * info /* maybe 0 */, bool assign)
+{
+ switch (type->eTypeClass) {
+ case typelib_TypeClass_BOOLEAN:
+ *static_cast< sal_Bool * >(uno_data) = false;
+ break;
+
+ case typelib_TypeClass_BYTE:
+ *static_cast< sal_Int8 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_SHORT:
+ *static_cast< sal_Int16 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *static_cast< sal_uInt16 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_LONG:
+ *static_cast< sal_Int32 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_UNSIGNED_LONG:
+ *static_cast< sal_uInt32 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_HYPER:
+ *static_cast< sal_Int64 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *static_cast< sal_uInt64 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_FLOAT:
+ *static_cast< float * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_DOUBLE:
+ *static_cast< double * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_CHAR:
+ *static_cast< sal_Unicode * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_STRING:
+ if (!assign) {
+ *static_cast< rtl_uString ** >(uno_data) = 0;
+ }
+ rtl_uString_new(static_cast< rtl_uString ** >(uno_data));
+ break;
+
+ case typelib_TypeClass_TYPE:
+ if (assign) {
+ typelib_typedescriptionreference_release(
+ *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
+ }
+ *static_cast< typelib_TypeDescriptionReference ** >(uno_data)
+ = *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID);
+ OSL_ASSERT(
+ *static_cast< typelib_TypeDescriptionReference ** >(uno_data) != 0);
+ typelib_typedescriptionreference_acquire(
+ *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
+ break;
+
+ case typelib_TypeClass_ANY:
+ if (assign) {
+ uno_any_destruct(static_cast< uno_Any * >(uno_data), 0);
+ }
+ uno_any_construct(
+ static_cast< uno_Any * >(uno_data), 0,
+ jni.get_info()->m_XInterface_type_info->m_td.get(), 0);
+ break;
+
+ case typelib_TypeClass_SEQUENCE:
+ {
+ auto_ptr< rtl_mem > seq(seq_allocate(0, 0));
+ if (assign) {
+ uno_type_destructData(uno_data, type, 0);
+ }
+ *static_cast< uno_Sequence ** >(uno_data)
+ = reinterpret_cast< uno_Sequence * >(seq.release());
+ break;
+ }
+
+ case typelib_TypeClass_ENUM:
+ {
+ typelib_TypeDescription * td = 0;
+ TYPELIB_DANGER_GET(&td, type);
+ *static_cast< sal_Int32 * >(uno_data)
+ = (reinterpret_cast< typelib_EnumTypeDescription * >(td)->
+ nDefaultEnumValue);
+ TYPELIB_DANGER_RELEASE(td);
+ break;
+ }
+
+ case typelib_TypeClass_STRUCT:
+ {
+ if (info == 0) {
+ info = jni.get_info()->get_type_info(jni, type);
+ }
+ JNI_compound_type_info const * comp_info
+ = static_cast< JNI_compound_type_info const * >(info);
+ typelib_CompoundTypeDescription * comp_td
+ = reinterpret_cast< typelib_CompoundTypeDescription * >(
+ comp_info->m_td.get());
+ sal_Int32 nPos = 0;
+ sal_Int32 nMembers = comp_td->nMembers;
+ try {
+ if (comp_td->pBaseTypeDescription != 0) {
+ createDefaultUnoValue(
+ jni, uno_data,
+ comp_td->pBaseTypeDescription->aBase.pWeakRef,
+ comp_info->m_base, assign);
+ }
+ for (; nPos < nMembers; ++nPos) {
+ createDefaultUnoValue(
+ jni,
+ (static_cast< char * >(uno_data)
+ + comp_td->pMemberOffsets[nPos]),
+ comp_td->ppTypeRefs[nPos], 0, assign);
+ }
+ } catch (...) {
+ if (!assign) {
+ for (sal_Int32 i = 0; i < nPos; ++i) {
+ uno_type_destructData(
+ (static_cast< char * >(uno_data)
+ + comp_td->pMemberOffsets[i]),
+ comp_td->ppTypeRefs[i], 0);
+ }
+ if (comp_td->pBaseTypeDescription != 0) {
+ uno_destructData(
+ uno_data, &comp_td->pBaseTypeDescription->aBase, 0);
+ }
+ }
+ throw;
+ }
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE:
+ if (assign) {
+ uno_Interface * p = *static_cast< uno_Interface ** >(uno_data);
+ if (p != 0) {
+ (*p->release)(p);
+ }
+ }
+ *static_cast< uno_Interface ** >(uno_data) = 0;
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+}
+
+}
+
+void Bridge::map_to_uno(
+ JNI_context const & jni,
+ void * uno_data, jvalue java_data,
+ typelib_TypeDescriptionReference * type,
+ JNI_type_info const * info /* maybe 0 */,
+ bool assign, bool out_param,
+ bool special_wrapped_integral_types ) const
+{
+ OSL_ASSERT(
+ !out_param ||
+ (1 == jni->GetArrayLength( (jarray) java_data.l )) );
+
+ switch (type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ if (out_param)
+ {
+ jni->GetCharArrayRegion(
+ (jcharArray) java_data.l, 0, 1, (jchar *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jchar *) uno_data = jni->CallCharMethodA(
+ java_data.l, m_jni_info->m_method_Character_charValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jchar *) uno_data = java_data.c;
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ if (out_param)
+ {
+ jni->GetBooleanArrayRegion(
+ (jbooleanArray) java_data.l, 0, 1, (jboolean *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jboolean *) uno_data = jni->CallBooleanMethodA(
+ java_data.l, m_jni_info->m_method_Boolean_booleanValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jboolean *) uno_data = java_data.z;
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ if (out_param)
+ {
+ jni->GetByteArrayRegion(
+ (jbyteArray) java_data.l, 0, 1, (jbyte *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jbyte *) uno_data = jni->CallByteMethodA(
+ java_data.l, m_jni_info->m_method_Byte_byteValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jbyte *) uno_data = java_data.b;
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (out_param)
+ {
+ jni->GetShortArrayRegion(
+ (jshortArray) java_data.l, 0, 1, (jshort *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jshort *) uno_data = jni->CallShortMethodA(
+ java_data.l, m_jni_info->m_method_Short_shortValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jshort *) uno_data = java_data.s;
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (out_param)
+ {
+ jni->GetIntArrayRegion(
+ (jintArray) java_data.l, 0, 1, (jint *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jint *) uno_data = jni->CallIntMethodA(
+ java_data.l, m_jni_info->m_method_Integer_intValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jint *) uno_data = java_data.i;
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (out_param)
+ {
+ jni->GetLongArrayRegion(
+ (jlongArray) java_data.l, 0, 1, (jlong *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jlong *) uno_data = jni->CallLongMethodA(
+ java_data.l, m_jni_info->m_method_Long_longValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jlong *) uno_data = java_data.j;
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (out_param)
+ {
+ jni->GetFloatArrayRegion(
+ (jfloatArray) java_data.l, 0, 1, (jfloat *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jfloat *) uno_data = jni->CallFloatMethodA(
+ java_data.l, m_jni_info->m_method_Float_floatValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jfloat *) uno_data = java_data.f;
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (out_param)
+ {
+ jni->GetDoubleArrayRegion(
+ (jdoubleArray) java_data.l, 0, 1, (jdouble *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jdouble *) uno_data = jni->CallDoubleMethodA(
+ java_data.l, m_jni_info->m_method_Double_doubleValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jdouble *) uno_data = java_data.d;
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+ if (0 == java_data.l)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ if (! assign)
+ *(rtl_uString **)uno_data = 0;
+ jstring_to_ustring(
+ jni, (rtl_uString **)uno_data, (jstring) java_data.l );
+ break;
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+ if (0 == java_data.l)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+
+ // type name
+ JLocalAutoRef jo_type_name(
+ jni, jni->GetObjectField(
+ java_data.l, m_jni_info->m_field_Type__typeName ) );
+ if (! jo_type_name.is())
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] incomplete type object: "
+ "no type name!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ OUString type_name(
+ jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
+ ::com::sun::star::uno::TypeDescription td( type_name );
+ if (! td.is())
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] UNO type not found: ") );
+ buf.append( type_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
+ if (assign)
+ {
+ typelib_typedescriptionreference_release(
+ *(typelib_TypeDescriptionReference **)uno_data );
+ }
+ *(typelib_TypeDescriptionReference **)uno_data = td.get()->pWeakRef;
+ break;
+ }
+ case typelib_TypeClass_ANY:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+
+ uno_Any * pAny = (uno_Any *)uno_data;
+ if (0 == java_data.l) // null-ref maps to XInterface null-ref
+ {
+ if (assign)
+ uno_any_destruct( pAny, 0 );
+ uno_any_construct(
+ pAny, 0, m_jni_info->m_XInterface_type_info->m_td.get(), 0 );
+ break;
+ }
+
+ JLocalAutoRef jo_type( jni );
+ JLocalAutoRef jo_wrapped_holder( jni );
+
+ if (JNI_FALSE != jni->IsInstanceOf(
+ java_data.l, m_jni_info->m_class_Any ))
+ {
+ // boxed any
+ jo_type.reset( jni->GetObjectField(
+ java_data.l, m_jni_info->m_field_Any__type ) );
+ if (! jo_type.is())
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] no type set at "
+ "com.sun.star.uno.Any!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ // wrapped value
+ jo_wrapped_holder.reset(
+ jni->GetObjectField(
+ java_data.l, m_jni_info->m_field_Any__object ) );
+ java_data.l = jo_wrapped_holder.get();
+ }
+ else
+ {
+ // create type out of class
+ JLocalAutoRef jo_class( jni, jni->GetObjectClass( java_data.l ) );
+ jo_type.reset( create_type( jni, (jclass) jo_class.get() ) );
+#if OSL_DEBUG_LEVEL > 1
+ {
+ JLocalAutoRef jo_toString(
+ jni, jni->CallObjectMethodA(
+ java_data.l, m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ OUString toString(
+ jstring_to_oustring( jni, (jstring) jo_toString.get() ) );
+ }
+#endif
+ }
+
+ // get type name
+ JLocalAutoRef jo_type_name(
+ jni, jni->GetObjectField(
+ jo_type.get(), m_jni_info->m_field_Type__typeName ) );
+ jni.ensure_no_exception();
+ OUString type_name(
+ jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
+
+ ::com::sun::star::uno::TypeDescription value_td( type_name );
+ if (! value_td.is())
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] UNO type not found: ") );
+ buf.append( type_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ typelib_TypeClass type_class = value_td.get()->eTypeClass;
+
+ if (assign)
+ {
+ uno_any_destruct( pAny, 0 );
+ }
+ try
+ {
+ switch (type_class)
+ {
+ case typelib_TypeClass_VOID:
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_CHAR:
+ *(jchar *) &pAny->pReserved = jni->CallCharMethodA(
+ java_data.l, m_jni_info->m_method_Character_charValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ *(jboolean *) &pAny->pReserved = jni->CallBooleanMethodA(
+ java_data.l, m_jni_info->m_method_Boolean_booleanValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_BYTE:
+ *(jbyte *) &pAny->pReserved = jni->CallByteMethodA(
+ java_data.l, m_jni_info->m_method_Byte_byteValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(jshort *) &pAny->pReserved = jni->CallShortMethodA(
+ java_data.l, m_jni_info->m_method_Short_shortValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ *(jint *) &pAny->pReserved = jni->CallIntMethodA(
+ java_data.l, m_jni_info->m_method_Integer_intValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (sizeof (sal_Int64) <= sizeof (void *))
+ {
+ *(jlong *) &pAny->pReserved = jni->CallLongMethodA(
+ java_data.l, m_jni_info->m_method_Long_longValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ }
+ else
+ {
+ auto_ptr< rtl_mem > mem(
+ rtl_mem::allocate( sizeof (sal_Int64) ) );
+ *(jlong *) mem.get() = jni->CallLongMethodA(
+ java_data.l, m_jni_info->m_method_Long_longValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = mem.release();
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (sizeof (float) <= sizeof (void *))
+ {
+ *(jfloat *) &pAny->pReserved = jni->CallFloatMethodA(
+ java_data.l, m_jni_info->m_method_Float_floatValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ }
+ else
+ {
+ auto_ptr< rtl_mem > mem(
+ rtl_mem::allocate( sizeof (float) ) );
+ *(jfloat *) mem.get() = jni->CallFloatMethodA(
+ java_data.l, m_jni_info->m_method_Float_floatValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = mem.release();
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (sizeof (double) <= sizeof (void *))
+ {
+ *(jdouble *) &pAny->pReserved =
+ jni->CallDoubleMethodA(
+ java_data.l,
+ m_jni_info->m_method_Double_doubleValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ }
+ else
+ {
+ auto_ptr< rtl_mem > mem(
+ rtl_mem::allocate( sizeof (double) ) );
+ *(jdouble *) mem.get() =
+ jni->CallDoubleMethodA(
+ java_data.l,
+ m_jni_info->m_method_Double_doubleValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = mem.release();
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ // opt: anies often contain strings; copy string directly
+ pAny->pReserved = 0;
+ jstring_to_ustring(
+ jni, (rtl_uString **)&pAny->pReserved,
+ (jstring) java_data.l );
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ map_to_uno(
+ jni, &pAny->pReserved, java_data,
+ value_td.get()->pWeakRef, 0,
+ false /* no assign */, false /* no out param */ );
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ auto_ptr< rtl_mem > mem(
+ rtl_mem::allocate( value_td.get()->nSize ) );
+ map_to_uno(
+ jni, mem.get(), java_data, value_td.get()->pWeakRef, 0,
+ false /* no assign */, false /* no out param */ );
+ pAny->pData = mem.release();
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( type_name );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] unsupported value type "
+ "of any!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+ }
+ catch (...)
+ {
+ if (assign)
+ {
+ // restore to valid any
+ uno_any_construct( pAny, 0, 0, 0 );
+ }
+ throw;
+ }
+ typelib_typedescriptionreference_acquire( value_td.get()->pWeakRef );
+ pAny->pType = value_td.get()->pWeakRef;
+ break;
+ }
+ case typelib_TypeClass_ENUM:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+ if (0 == java_data.l)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+
+ *(jint *) uno_data = jni->GetIntField(
+ java_data.l, m_jni_info->m_field_Enum_m_value );
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+ if (0 == java_data.l)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+
+ if (0 == info)
+ info = m_jni_info->get_type_info( jni, type );
+ JNI_compound_type_info const * comp_info =
+ static_cast< JNI_compound_type_info const * >( info );
+
+ typelib_CompoundTypeDescription * comp_td =
+ (typelib_CompoundTypeDescription *)comp_info->m_td.get();
+ bool polymorphic
+ = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
+ && reinterpret_cast< typelib_StructTypeDescription * >(
+ comp_td)->pParameterizedTypes != 0;
+
+ sal_Int32 nPos = 0;
+ sal_Int32 nMembers = comp_td->nMembers;
+ try
+ {
+ if (0 != comp_td->pBaseTypeDescription)
+ {
+ map_to_uno(
+ jni, uno_data, java_data,
+ ((typelib_TypeDescription *) comp_td->pBaseTypeDescription)
+ ->pWeakRef,
+ comp_info->m_base,
+ assign, false /* no out param */ );
+ }
+
+ for ( ; nPos < nMembers; ++nPos )
+ {
+ void * p = (char *)uno_data + comp_td->pMemberOffsets[ nPos ];
+ typelib_TypeDescriptionReference * member_type =
+ comp_td->ppTypeRefs[ nPos ];
+ jfieldID field_id = comp_info->m_fields[ nPos ];
+ bool parameterizedType = polymorphic
+ && reinterpret_cast< typelib_StructTypeDescription * >(
+ comp_td)->pParameterizedTypes[nPos];
+ switch (member_type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jchar *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jchar *) p = jni->GetCharField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jboolean *) p = false;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jboolean *) p = jni->GetBooleanField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jbyte *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jbyte *) p = jni->GetByteField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jshort *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jshort *) p = jni->GetShortField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jint *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jint *) p = jni->GetIntField( java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jlong *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jlong *) p = jni->GetLongField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jfloat *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jfloat *) p = jni->GetFloatField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jdouble *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jdouble *) p = jni->GetDoubleField(
+ java_data.l, field_id );
+ }
+ break;
+ default:
+ {
+ JLocalAutoRef jo_field( jni );
+ bool checkNull;
+ if (0 == field_id)
+ {
+ // special for Message: call Throwable.getMessage()
+ OSL_ASSERT(
+ type_equals(
+ type,
+ m_jni_info->m_Exception_type.getTypeLibType() )
+ || type_equals(
+ type,
+ m_jni_info->m_RuntimeException_type.
+ getTypeLibType() ) );
+ OSL_ASSERT( 0 == nPos ); // first member
+ // call getMessage()
+ jo_field.reset(
+ jni->CallObjectMethodA(
+ java_data.l,
+ m_jni_info->m_method_Throwable_getMessage, 0 )
+ );
+ jni.ensure_no_exception();
+ checkNull = true;
+ }
+ else
+ {
+ jo_field.reset(
+ jni->GetObjectField( java_data.l, field_id ) );
+ checkNull = parameterizedType;
+ }
+ if (checkNull && !jo_field.is()) {
+ createDefaultUnoValue(jni, p, member_type, 0, assign);
+ } else {
+ jvalue val;
+ val.l = jo_field.get();
+ map_to_uno(
+ jni, p, val, member_type, 0,
+ assign, false /* no out param */ );
+ }
+ break;
+ }
+ }
+ }
+ }
+ catch (...)
+ {
+ if (! assign)
+ {
+ // cleanup
+ for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
+ {
+ void * p =
+ (char *)uno_data + comp_td->pMemberOffsets[ nCleanup ];
+ uno_type_destructData(
+ p, comp_td->ppTypeRefs[ nCleanup ], 0 );
+ }
+ if (0 != comp_td->pBaseTypeDescription)
+ {
+ uno_destructData(
+ uno_data,
+ (typelib_TypeDescription *) comp_td
+ ->pBaseTypeDescription, 0 );
+ }
+ }
+ throw;
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+ if (0 == java_data.l)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+
+ TypeDescr td( type );
+ typelib_TypeDescriptionReference * element_type =
+ ((typelib_IndirectTypeDescription *)td.get())->pType;
+
+ auto_ptr< rtl_mem > seq;
+ sal_Int32 nElements = jni->GetArrayLength( (jarray) java_data.l );
+
+ switch (element_type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Unicode) ) );
+ jni->GetCharArrayRegion(
+ (jcharArray) java_data.l, 0, nElements,
+ (jchar *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Bool) ) );
+ jni->GetBooleanArrayRegion(
+ (jbooleanArray) java_data.l, 0, nElements,
+ (jboolean *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_BYTE:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Int8) ) );
+ jni->GetByteArrayRegion(
+ (jbyteArray) java_data.l, 0, nElements,
+ (jbyte *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Int16) ) );
+ jni->GetShortArrayRegion(
+ (jshortArray) java_data.l, 0, nElements,
+ (jshort *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Int32) ) );
+ jni->GetIntArrayRegion(
+ (jintArray) java_data.l, 0, nElements,
+ (jint *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Int64) ) );
+ jni->GetLongArrayRegion(
+ (jlongArray) java_data.l, 0, nElements,
+ (jlong *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_FLOAT:
+ seq.reset( seq_allocate( nElements, sizeof (float) ) );
+ jni->GetFloatArrayRegion(
+ (jfloatArray) java_data.l, 0, nElements,
+ (jfloat *)((uno_Sequence *)seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_DOUBLE:
+ seq.reset( seq_allocate( nElements, sizeof (double) ) );
+ jni->GetDoubleArrayRegion(
+ (jdoubleArray) java_data.l, 0, nElements,
+ (jdouble *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ {
+ TypeDescr element_td( element_type );
+ seq.reset( seq_allocate( nElements, element_td.get()->nSize ) );
+
+ JNI_type_info const * element_info;
+ if (typelib_TypeClass_STRUCT == element_type->eTypeClass ||
+ typelib_TypeClass_EXCEPTION == element_type->eTypeClass ||
+ typelib_TypeClass_INTERFACE == element_type->eTypeClass)
+ {
+ element_info =
+ m_jni_info->get_type_info( jni, element_td.get() );
+ }
+ else
+ {
+ element_info = 0;
+ }
+
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ try
+ {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectArrayElement(
+ (jobjectArray) java_data.l, nPos ) );
+ jni.ensure_no_exception();
+ jvalue val;
+ val.l = jo.get();
+ void * p =
+ ((uno_Sequence *)seq.get())->elements +
+ (nPos * element_td.get()->nSize);
+ map_to_uno(
+ jni, p, val, element_td.get()->pWeakRef, element_info,
+ false /* no assign */, false /* no out param */ );
+ }
+ catch (...)
+ {
+ // cleanup
+ for ( sal_Int32 nCleanPos = 0;
+ nCleanPos < nPos; ++nCleanPos )
+ {
+ void * p =
+ ((uno_Sequence *)seq.get())->elements +
+ (nCleanPos * element_td.get()->nSize);
+ uno_destructData( p, element_td.get(), 0 );
+ }
+ throw;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] unsupported sequence element"
+ " type: ") );
+ buf.append( OUString::unacquired( &element_type->pTypeName ) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+
+ if (assign)
+ uno_destructData( uno_data, td.get(), 0 );
+ *(uno_Sequence **)uno_data = (uno_Sequence *)seq.release();
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+
+ if (0 == java_data.l) // null-ref
+ {
+ if (assign)
+ {
+ uno_Interface * p = *(uno_Interface **)uno_data;
+ if (0 != p)
+ (*p->release)( p );
+ }
+ *(uno_Interface **)uno_data = 0;
+ }
+ else
+ {
+ if (0 == info)
+ info = m_jni_info->get_type_info( jni, type );
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >( info );
+ uno_Interface * pUnoI = map_to_uno( jni, java_data.l, iface_info );
+ if (assign)
+ {
+ uno_Interface * p = *(uno_Interface **)uno_data;
+ if (0 != p)
+ (*p->release)( p );
+ }
+ *(uno_Interface **)uno_data = pUnoI;
+ }
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+}
+
+//##############################################################################
+
+//______________________________________________________________________________
+void Bridge::map_to_java(
+ JNI_context const & jni,
+ jvalue * java_data, void const * uno_data,
+ typelib_TypeDescriptionReference * type,
+ JNI_type_info const * info /* maybe 0 */,
+ bool in_param, bool out_param,
+ bool special_wrapped_integral_types ) const
+{
+ switch (type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewCharArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetCharArrayRegion(
+ (jcharArray) jo_ar.get(), 0, 1, (jchar *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetCharArrayRegion(
+ (jcharArray) java_data->l, 0, 1, (jchar *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.c = *(jchar const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Character,
+ m_jni_info->m_ctor_Character_with_char, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->c = *(jchar const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewBooleanArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetBooleanArrayRegion(
+ (jbooleanArray) jo_ar.get(),
+ 0, 1, (jboolean *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetBooleanArrayRegion(
+ (jbooleanArray) java_data->l,
+ 0, 1, (jboolean *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.z = *(jboolean const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Boolean,
+ m_jni_info->m_ctor_Boolean_with_boolean, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->z = *(jboolean const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewByteArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetByteArrayRegion(
+ (jbyteArray) jo_ar.get(), 0, 1, (jbyte *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetByteArrayRegion(
+ (jbyteArray) java_data->l, 0, 1, (jbyte *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.b = *(jbyte const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Byte,
+ m_jni_info->m_ctor_Byte_with_byte, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->b = *(jbyte const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewShortArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetShortArrayRegion(
+ (jshortArray) jo_ar.get(), 0, 1, (jshort *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetShortArrayRegion(
+ (jshortArray) java_data->l, 0, 1, (jshort *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.s = *(jshort const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Short,
+ m_jni_info->m_ctor_Short_with_short, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->s = *(jshort const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewIntArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetIntArrayRegion(
+ (jintArray) jo_ar.get(), 0, 1, (jint *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetIntArrayRegion(
+ (jintArray) java_data->l, 0, 1, (jint *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.i = *(jint const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Integer,
+ m_jni_info->m_ctor_Integer_with_int, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->i = *(jint const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewLongArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetLongArrayRegion(
+ (jlongArray)jo_ar.get(), 0, 1, (jlong *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetLongArrayRegion(
+ (jlongArray)java_data->l, 0, 1, (jlong *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.j = *(jlong const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Long,
+ m_jni_info->m_ctor_Long_with_long, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->j = *(jlong const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewFloatArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetFloatArrayRegion(
+ (jfloatArray) jo_ar.get(), 0, 1, (jfloat *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetFloatArrayRegion(
+ (jfloatArray) java_data->l, 0, 1, (jfloat *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.f = *(jfloat const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Float,
+ m_jni_info->m_ctor_Float_with_float, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->f = *(jfloat const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewDoubleArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetDoubleArrayRegion(
+ (jdoubleArray) jo_ar.get(),
+ 0, 1, (jdouble *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetDoubleArrayRegion(
+ (jdoubleArray) java_data->l,
+ 0, 1, (jdouble *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.d = *(double const *)uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Double,
+ m_jni_info->m_ctor_Double_with_double, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->d = *(jdouble const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ {
+ if (out_param)
+ {
+ JLocalAutoRef jo_in( jni );
+ if (in_param)
+ {
+ jo_in.reset(
+ ustring_to_jstring(
+ jni, *(rtl_uString * const *) uno_data ) );
+ }
+ if (0 == java_data->l)
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, m_jni_info->m_class_String, jo_in.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_in.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ OSL_ASSERT( in_param );
+ java_data->l =
+ ustring_to_jstring( jni, *(rtl_uString * const *) uno_data );
+ }
+ break;
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ if (out_param)
+ {
+ JLocalAutoRef jo_in( jni );
+ if (in_param)
+ {
+ jo_in.reset(
+ create_type(
+ jni,
+ *(typelib_TypeDescriptionReference * const *) uno_data )
+ );
+ }
+ if (0 == java_data->l)
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, m_jni_info->m_class_Type, jo_in.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_in.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ OSL_ASSERT( in_param );
+ java_data->l =
+ create_type(
+ jni,
+ *(typelib_TypeDescriptionReference * const *) uno_data );
+ }
+ break;
+ }
+ case typelib_TypeClass_ANY:
+ {
+ JLocalAutoRef jo_any( jni );
+ if (in_param)
+ {
+ uno_Any const * pAny = (uno_Any const *)uno_data;
+
+#if defined BRIDGES_JNI_UNO_FORCE_BOXED_ANY
+ if (typelib_TypeClass_VOID == pAny->pType->eTypeClass)
+ {
+ jo_any.reset(
+ jni->NewLocalRef( m_jni_info->m_object_Any_VOID ) );
+ }
+ else
+ {
+ jvalue args[ 2 ];
+ map_to_java(
+ jni, &args[ 1 ], pAny->pData, pAny->pType, 0,
+ true /* in */, false /* no out */,
+ true /* create integral wrappers */ );
+ jo_any.reset( args[ 1 ].l );
+ // build up com.sun.star.uno.Any
+ JLocalAutoRef jo_type( jni, create_type( jni, pAny->pType ) );
+ args[ 0 ].l = jo_type.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ }
+#else
+ switch (pAny->pType->eTypeClass)
+ {
+ case typelib_TypeClass_VOID:
+ jo_any.reset(
+ jni->NewLocalRef( m_jni_info->m_object_Any_VOID ) );
+ break;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ {
+ jvalue args[ 2 ];
+ args[ 0 ].s = *(jshort const *) &pAny->pReserved;
+ JLocalAutoRef jo_val(
+ jni, jni->NewObjectA(
+ m_jni_info->m_class_Short,
+ m_jni_info->m_ctor_Short_with_short, args ) );
+ jni.ensure_no_exception();
+ // box up in com.sun.star.uno.Any
+ args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_SHORT;
+ args[ 1 ].l = jo_val.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ break;
+ }
+ case typelib_TypeClass_UNSIGNED_LONG:
+ {
+ jvalue args[ 2 ];
+ args[ 0 ].i = *(jint const *) &pAny->pReserved;
+ JLocalAutoRef jo_val(
+ jni, jni->NewObjectA(
+ m_jni_info->m_class_Integer,
+ m_jni_info->m_ctor_Integer_with_int, args ) );
+ jni.ensure_no_exception();
+ // box up in com.sun.star.uno.Any
+ args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_LONG;
+ args[ 1 ].l = jo_val.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ break;
+ }
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ {
+ jvalue args[ 2 ];
+ args[ 0 ].j = *(jlong const *) pAny->pData;
+ JLocalAutoRef jo_val(
+ jni, jni->NewObjectA(
+ m_jni_info->m_class_Long,
+ m_jni_info->m_ctor_Long_with_long, args ) );
+ jni.ensure_no_exception();
+ // box up in com.sun.star.uno.Any
+ args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_HYPER;
+ args[ 1 ].l = jo_val.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ break;
+ }
+ case typelib_TypeClass_STRING: // opt strings
+ jo_any.reset( ustring_to_jstring(
+ jni, (rtl_uString *) pAny->pReserved ) );
+ break;
+ case typelib_TypeClass_SEQUENCE:
+ {
+ jvalue java_data2;
+ // prefetch sequence td
+ TypeDescr seq_td( pAny->pType );
+ map_to_java(
+ jni, &java_data2, pAny->pData, seq_td.get()->pWeakRef, 0,
+ true /* in */, false /* no out */,
+ true /* create integral wrappers */ );
+ jo_any.reset( java_data2.l );
+
+ // determine inner element type
+ ::com::sun::star::uno::Type element_type(
+ ((typelib_IndirectTypeDescription *)seq_td.get())->pType );
+ while (typelib_TypeClass_SEQUENCE ==
+ element_type.getTypeLibType()->eTypeClass)
+ {
+ TypeDescr element_td( element_type.getTypeLibType() );
+ typelib_typedescriptionreference_assign(
+ reinterpret_cast< typelib_TypeDescriptionReference ** >(
+ &element_type ),
+ ((typelib_IndirectTypeDescription *)element_td.get())
+ ->pType );
+ }
+ // box up only if unsigned element type
+ switch (element_type.getTypeLibType()->eTypeClass)
+ {
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ {
+ jvalue args[ 2 ];
+ JLocalAutoRef jo_type(
+ jni, create_type( jni, seq_td.get()->pWeakRef ) );
+ args[ 0 ].l = jo_type.get();
+ args[ 1 ].l = jo_any.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ uno_Interface * pUnoI = (uno_Interface *)pAny->pReserved;
+ if (is_XInterface( pAny->pType ))
+ {
+ if (0 != pUnoI)
+ {
+ jo_any.reset(
+ map_to_java(
+ jni, pUnoI,
+ m_jni_info->m_XInterface_type_info ) );
+ }
+ // else: empty XInterface ref maps to null-ref
+ }
+ else
+ {
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >(
+ m_jni_info->get_type_info( jni, pAny->pType ) );
+ if (0 != pUnoI)
+ {
+ jo_any.reset( map_to_java( jni, pUnoI, iface_info ) );
+ }
+ // box up in com.sun.star.uno.Any
+ jvalue args[ 2 ];
+ args[ 0 ].l = iface_info->m_type;
+ args[ 1 ].l = jo_any.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ }
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ {
+ // Do not lose information about type arguments of instantiated
+ // polymorphic struct types:
+ rtl::OUString const & name = rtl::OUString::unacquired(
+ &pAny->pType->pTypeName);
+ OSL_ASSERT(name.getLength() > 0);
+ if (name[name.getLength() - 1] == '>')
+ {
+ // Box up in com.sun.star.uno.Any:
+ JLocalAutoRef jo_type(jni, create_type(jni, pAny->pType));
+ jvalue java_data2;
+ map_to_java(
+ jni, &java_data2, pAny->pData, pAny->pType, 0, true,
+ false);
+ jo_any.reset(java_data2.l);
+ jvalue args[2];
+ args[0].l = jo_type.get();
+ args[1].l = jo_any.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args));
+ jni.ensure_no_exception();
+ break;
+ }
+ // fall through
+ }
+ default:
+ {
+ jvalue java_data2;
+ map_to_java(
+ jni, &java_data2, pAny->pData, pAny->pType, 0,
+ true /* in */, false /* no out */,
+ true /* create integral wrappers */ );
+ jo_any.reset( java_data2.l );
+ break;
+ }
+ }
+#endif
+ }
+
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, m_jni_info->m_class_Object, jo_any.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_any.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ java_data->l = jo_any.release();
+ }
+ break;
+ }
+ case typelib_TypeClass_ENUM:
+ {
+ OUString const & type_name = OUString::unacquired( &type->pTypeName );
+ OString class_name(
+ OUStringToOString( type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
+ JLocalAutoRef jo_enum_class(
+ jni, find_class( jni, class_name.getStr() ) );
+
+ JLocalAutoRef jo_enum( jni );
+ if (in_param)
+ {
+ // call static <enum_class>.fromInt( int )
+ OStringBuffer sig_buf( 5 + class_name.getLength() );
+ sig_buf.append( RTL_CONSTASCII_STRINGPARAM("(I)L") );
+ sig_buf.append( class_name.replace( '.', '/' ) );
+ sig_buf.append( ';' );
+ OString sig( sig_buf.makeStringAndClear() );
+ jmethodID method_id = jni->GetStaticMethodID(
+ (jclass) jo_enum_class.get(), "fromInt", sig.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != method_id );
+
+ jvalue arg;
+ arg.i = *(jint const *) uno_data;
+ jo_enum.reset(
+ jni->CallStaticObjectMethodA(
+ (jclass) jo_enum_class.get(), method_id, &arg ) );
+ jni.ensure_no_exception();
+ }
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, (jclass) jo_enum_class.get(), jo_enum.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_enum.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ java_data->l = jo_enum.release();
+ }
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ if (0 == info)
+ info = m_jni_info->get_type_info( jni, type );
+ JNI_compound_type_info const * comp_info =
+ static_cast< JNI_compound_type_info const * >( info );
+
+ JLocalAutoRef jo_comp( jni );
+ if (in_param)
+ {
+ if (typelib_TypeClass_EXCEPTION == type->eTypeClass)
+ {
+ JLocalAutoRef jo_message(
+ jni, ustring_to_jstring( jni, *(rtl_uString **)uno_data ) );
+ jvalue arg;
+ arg.l = jo_message.get();
+ jo_comp.reset(
+ jni->NewObjectA(
+ comp_info->m_class, comp_info->m_exc_ctor, &arg ) );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jo_comp.reset( jni->AllocObject( comp_info->m_class ) );
+ jni.ensure_no_exception();
+ }
+
+ for ( JNI_compound_type_info const * linfo = comp_info;
+ 0 != linfo;
+ linfo = static_cast< JNI_compound_type_info const * >(
+ linfo->m_base ) )
+ {
+ typelib_CompoundTypeDescription * comp_td =
+ (typelib_CompoundTypeDescription *)linfo->m_td.get();
+ typelib_TypeDescriptionReference ** ppMemberTypeRefs =
+ comp_td->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = comp_td->pMemberOffsets;
+ bool polymorphic
+ = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
+ && reinterpret_cast< typelib_StructTypeDescription * >(
+ comp_td)->pParameterizedTypes != 0;
+ for ( sal_Int32 nPos = comp_td->nMembers; nPos--; )
+ {
+ jfieldID field_id = linfo->m_fields[ nPos ];
+ if (0 != field_id)
+ {
+ void const * p =
+ (char const *)uno_data + pMemberOffsets[ nPos ];
+ typelib_TypeDescriptionReference * member_type =
+ ppMemberTypeRefs[ nPos ];
+ bool parameterizedType = polymorphic
+ && (reinterpret_cast<
+ typelib_StructTypeDescription * >(comp_td)->
+ pParameterizedTypes[nPos]);
+ switch (member_type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.c = *(jchar const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Character,
+ m_jni_info->m_ctor_Character_with_char,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetCharField(
+ jo_comp.get(),
+ field_id, *(jchar const *) p );
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.z = *(jboolean const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Boolean,
+ m_jni_info->m_ctor_Boolean_with_boolean,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetBooleanField(
+ jo_comp.get(),
+ field_id, *(jboolean const *) p );
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.b = *(jbyte const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Byte,
+ m_jni_info->m_ctor_Byte_with_byte,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetByteField(
+ jo_comp.get(),
+ field_id, *(jbyte const *) p );
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.s = *(jshort const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Short,
+ m_jni_info->m_ctor_Short_with_short,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetShortField(
+ jo_comp.get(),
+ field_id, *(jshort const *) p );
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.i = *(jint const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Integer,
+ m_jni_info->m_ctor_Integer_with_int,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetIntField(
+ jo_comp.get(),
+ field_id, *(jint const *) p );
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.j = *(jlong const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Long,
+ m_jni_info->m_ctor_Long_with_long,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetLongField(
+ jo_comp.get(),
+ field_id, *(jlong const *) p );
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.f = *(jfloat const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Float,
+ m_jni_info->m_ctor_Float_with_float,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetFloatField(
+ jo_comp.get(),
+ field_id, *(jfloat const *) p );
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.d = *(jdouble const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Double,
+ m_jni_info->m_ctor_Double_with_double,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetDoubleField(
+ jo_comp.get(),
+ field_id, *(jdouble const *) p );
+ }
+ break;
+ case typelib_TypeClass_STRING: // string opt here
+ {
+ JLocalAutoRef jo_string(
+ jni, ustring_to_jstring(
+ jni, *(rtl_uString * const *) p ) );
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo_string.get() );
+ break;
+ }
+ default:
+ {
+ jvalue java_data2;
+ map_to_java(
+ jni, &java_data2, p, member_type, 0,
+ true /* in */, false /* no out */ );
+ JLocalAutoRef jo_obj( jni, java_data2.l );
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo_obj.get() );
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ java_data->l =
+ jni->NewObjectArray( 1, comp_info->m_class, jo_comp.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_comp.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ java_data->l = jo_comp.release();
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ // xxx todo: possible opt for pure out sequences
+ JLocalAutoRef jo_ar( jni );
+
+ sal_Int32 nElements;
+ uno_Sequence const * seq = 0;
+ if (in_param)
+ {
+ seq = *(uno_Sequence * const *)uno_data;
+ nElements = seq->nElements;
+ }
+ else
+ {
+ nElements = 0;
+ }
+
+ TypeDescr td( type );
+ typelib_TypeDescriptionReference * element_type =
+ ((typelib_IndirectTypeDescription *)td.get())->pType;
+
+ switch (element_type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ jo_ar.reset( jni->NewCharArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetCharArrayRegion(
+ (jcharArray) jo_ar.get(),
+ 0, nElements, (jchar *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ jo_ar.reset( jni->NewBooleanArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetBooleanArrayRegion(
+ (jbooleanArray) jo_ar.get(),
+ 0, nElements, (jboolean *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ jo_ar.reset( jni->NewByteArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetByteArrayRegion(
+ (jbyteArray) jo_ar.get(),
+ 0, nElements, (jbyte *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ jo_ar.reset( jni->NewShortArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetShortArrayRegion(
+ (jshortArray) jo_ar.get(),
+ 0, nElements, (jshort *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ jo_ar.reset( jni->NewIntArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetIntArrayRegion(
+ (jintArray) jo_ar.get(),
+ 0, nElements, (jint *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ jo_ar.reset( jni->NewLongArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetLongArrayRegion(
+ (jlongArray) jo_ar.get(),
+ 0, nElements, (jlong *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ jo_ar.reset( jni->NewFloatArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetFloatArrayRegion(
+ (jfloatArray) jo_ar.get(),
+ 0, nElements, (jfloat *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ jo_ar.reset( jni->NewDoubleArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetDoubleArrayRegion(
+ (jdoubleArray) jo_ar.get(),
+ 0, nElements, (jdouble *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ jo_ar.reset(
+ jni->NewObjectArray(
+ nElements, m_jni_info->m_class_String, 0 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ rtl_uString * const * pp =
+ (rtl_uString * const *) seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ JLocalAutoRef jo_string(
+ jni, ustring_to_jstring( jni, pp[ nPos ] ) );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_string.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ case typelib_TypeClass_TYPE:
+ jo_ar.reset(
+ jni->NewObjectArray( nElements, m_jni_info->m_class_Type, 0 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ typelib_TypeDescriptionReference * const * pp =
+ (typelib_TypeDescriptionReference * const *)seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ jvalue val;
+ map_to_java(
+ jni, &val, &pp[ nPos ], element_type, 0,
+ true /* in */, false /* no out */ );
+ JLocalAutoRef jo_element( jni, val.l );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_element.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ case typelib_TypeClass_ANY:
+ jo_ar.reset(
+ jni->NewObjectArray(
+ nElements, m_jni_info->m_class_Object, 0 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ uno_Any const * p = (uno_Any const *)seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ jvalue val;
+ map_to_java(
+ jni, &val, &p[ nPos ], element_type, 0,
+ true /* in */, false /* no out */ );
+ JLocalAutoRef jo_element( jni, val.l );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_element.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ case typelib_TypeClass_ENUM:
+ {
+ OUString const & element_type_name =
+ OUString::unacquired( &element_type->pTypeName );
+ OString class_name(
+ OUStringToOString(
+ element_type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
+ JLocalAutoRef jo_enum_class(
+ jni, find_class( jni, class_name.getStr() ) );
+
+ jo_ar.reset(
+ jni->NewObjectArray(
+ nElements, (jclass) jo_enum_class.get(), 0 ) );
+ jni.ensure_no_exception();
+
+ if (0 < nElements)
+ {
+ // call static <enum_class>.fromInt( int )
+ OStringBuffer sig_buf( 5 + class_name.getLength() );
+ sig_buf.append( RTL_CONSTASCII_STRINGPARAM("(I)L") );
+ sig_buf.append( class_name.replace( '.', '/' ) );
+ sig_buf.append( ';' );
+ OString sig( sig_buf.makeStringAndClear() );
+ jmethodID method_id = jni->GetStaticMethodID(
+ (jclass) jo_enum_class.get(), "fromInt", sig.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != method_id );
+
+ sal_Int32 const * p = (sal_Int32 const *)seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ jvalue arg;
+ arg.i = p[ nPos ];
+ JLocalAutoRef jo_enum(
+ jni, jni->CallStaticObjectMethodA(
+ (jclass) jo_enum_class.get(), method_id, &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_enum.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ JNI_type_info const * element_info =
+ m_jni_info->get_type_info( jni, element_type );
+
+ jo_ar.reset(
+ jni->NewObjectArray( nElements, element_info->m_class, 0 ) );
+ jni.ensure_no_exception();
+
+ if (0 < nElements)
+ {
+ char * p = (char *)seq->elements;
+ sal_Int32 nSize = element_info->m_td.get()->nSize;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ jvalue val;
+ map_to_java(
+ jni, &val, p + (nSize * nPos),
+ element_type, element_info,
+ true /* in */, false /* no out */ );
+ JLocalAutoRef jo_element( jni, val.l );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_element.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ OStringBuffer buf( 64 );
+ JNI_info::append_sig(
+ &buf, element_type, false /* use class XInterface */,
+ false /* '.' instead of '/' */ );
+ OString class_name( buf.makeStringAndClear() );
+ JLocalAutoRef jo_seq_class(
+ jni, find_class( jni, class_name.getStr() ) );
+
+ jo_ar.reset(
+ jni->NewObjectArray(
+ nElements, (jclass) jo_seq_class.get(), 0 ) );
+ jni.ensure_no_exception();
+
+ if (0 < nElements)
+ {
+ TypeDescr element_td( element_type );
+ uno_Sequence ** elements = (uno_Sequence **) seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ jvalue java_data2;
+ map_to_java(
+ jni, &java_data2, elements + nPos, element_type, 0,
+ true /* in */, false /* no out */ );
+ JLocalAutoRef jo_seq( jni, java_data2.l );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_seq.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >(
+ m_jni_info->get_type_info( jni, element_type ) );
+
+ jo_ar.reset(
+ jni->NewObjectArray( nElements, iface_info->m_class, 0 ) );
+ jni.ensure_no_exception();
+
+ if (0 < nElements)
+ {
+ uno_Interface ** pp = (uno_Interface **)seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ uno_Interface * pUnoI = pp[ nPos ];
+ if (0 != pUnoI)
+ {
+ JLocalAutoRef jo_element(
+ jni, map_to_java( jni, pUnoI, iface_info ) );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(),
+ nPos, jo_element.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_java():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] unsupported element type: ") );
+ buf.append( OUString::unacquired( &element_type->pTypeName ) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_element_class(
+ jni, jni->GetObjectClass( jo_ar.get() ) );
+ if (in_param)
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, (jclass) jo_element_class.get(), jo_ar.get() );
+ }
+ else
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, (jclass) jo_element_class.get(), 0 );
+ }
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_ar.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ java_data->l = jo_ar.release();
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ JLocalAutoRef jo_iface( jni );
+ if (in_param)
+ {
+ uno_Interface * pUnoI = *(uno_Interface * const *)uno_data;
+ if (0 != pUnoI)
+ {
+ if (0 == info)
+ info = m_jni_info->get_type_info( jni, type );
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >( info );
+ jo_iface.reset( map_to_java( jni, pUnoI, iface_info ) );
+ }
+ }
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ if (0 == info)
+ info = m_jni_info->get_type_info( jni, type );
+ java_data->l =
+ jni->NewObjectArray( 1, info->m_class, jo_iface.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_iface.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ java_data->l = jo_iface.release();
+ }
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_java():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+}
+
+}
diff --git a/bridges/source/jni_uno/jni_helper.h b/bridges/source/jni_uno/jni_helper.h
new file mode 100644
index 000000000000..46a79818795c
--- /dev/null
+++ b/bridges/source/jni_uno/jni_helper.h
@@ -0,0 +1,165 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: jni_helper.h,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_JNI_HELPER_H
+#define INCLUDED_JNI_HELPER_H
+
+#include "jni_base.h"
+#include "jni_info.h"
+
+
+namespace jni_uno
+{
+
+//------------------------------------------------------------------------------
+inline void jstring_to_ustring(
+ JNI_context const & jni, rtl_uString ** out_ustr, jstring jstr )
+{
+ if (0 == jstr)
+ {
+ rtl_uString_new( out_ustr );
+ }
+ else
+ {
+ jsize len = jni->GetStringLength( jstr );
+ ::std::auto_ptr< rtl_mem > mem(
+ rtl_mem::allocate(
+ sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ) );
+ rtl_uString * ustr = (rtl_uString *)mem.get();
+ jni->GetStringRegion( jstr, 0, len, (jchar *) ustr->buffer );
+ jni.ensure_no_exception();
+ ustr->refCount = 1;
+ ustr->length = len;
+ ustr->buffer[ len ] = '\0';
+ mem.release();
+ if (0 != *out_ustr)
+ rtl_uString_release( *out_ustr );
+ *out_ustr = ustr;
+ }
+}
+
+//------------------------------------------------------------------------------
+inline ::rtl::OUString jstring_to_oustring(
+ JNI_context const & jni, jstring jstr )
+{
+ rtl_uString * ustr = 0;
+ jstring_to_ustring( jni, &ustr, jstr );
+ return ::rtl::OUString( ustr, SAL_NO_ACQUIRE );
+}
+
+//------------------------------------------------------------------------------
+inline jstring ustring_to_jstring(
+ JNI_context const & jni, rtl_uString const * ustr )
+{
+ jstring jstr = jni->NewString( (jchar const *) ustr->buffer, ustr->length );
+ jni.ensure_no_exception();
+ return jstr;
+}
+
+
+//------------------------------------------------------------------------------
+// if inException, does not handle exceptions, in which case returned value will
+// be null if exception occurred:
+inline jclass find_class(
+ JNI_context const & jni, char const * class_name, bool inException = false )
+{
+ // find_class may be called before the JNI_info is set:
+ jclass c=0;
+ jmethodID m;
+ JNI_info const * info = jni.get_info();
+ if (info == 0) {
+ jni.getClassForName(&c, &m);
+ if (c == 0) {
+ if (inException) {
+ return 0;
+ }
+ jni.ensure_no_exception();
+ }
+ } else {
+ c = info->m_class_Class;
+ m = info->m_method_Class_forName;
+ }
+ return jni.findClass(class_name, c, m, inException);
+}
+
+
+//------------------------------------------------------------------------------
+inline jobject create_type( JNI_context const & jni, jclass clazz )
+{
+ JNI_info const * jni_info = jni.get_info();
+ jvalue arg;
+ arg.l = clazz;
+ jobject jo_type = jni->NewObjectA(
+ jni_info->m_class_Type, jni_info->m_ctor_Type_with_Class, &arg );
+ jni.ensure_no_exception();
+ return jo_type;
+}
+
+//------------------------------------------------------------------------------
+inline jobject create_type(
+ JNI_context const & jni, typelib_TypeDescriptionReference * type )
+{
+ JNI_info const * jni_info = jni.get_info();
+ jvalue args[ 2 ];
+ // get type class
+ args[ 0 ].i = type->eTypeClass;
+ JLocalAutoRef jo_type_class(
+ jni, jni->CallStaticObjectMethodA(
+ jni_info->m_class_TypeClass,
+ jni_info->m_method_TypeClass_fromInt, args ) );
+ jni.ensure_no_exception();
+ // construct type
+ JLocalAutoRef jo_type_name(
+ jni, ustring_to_jstring( jni, type->pTypeName ) );
+ args[ 0 ].l = jo_type_name.get();
+ args[ 1 ].l = jo_type_class.get();
+ jobject jo_type = jni->NewObjectA(
+ jni_info->m_class_Type,
+ jni_info->m_ctor_Type_with_Name_TypeClass, args );
+ jni.ensure_no_exception();
+ return jo_type;
+}
+
+//------------------------------------------------------------------------------
+inline jobject compute_oid( JNI_context const & jni, jobject jo )
+{
+ JNI_info const * jni_info = jni.get_info();
+ jvalue arg;
+ arg.l= jo;
+ jobject jo_oid = jni->CallStaticObjectMethodA(
+ jni_info->m_class_UnoRuntime,
+ jni_info->m_method_UnoRuntime_generateOid, &arg );
+ jni.ensure_no_exception();
+ return jo_oid;
+}
+
+}
+
+#endif
diff --git a/bridges/source/jni_uno/jni_info.cxx b/bridges/source/jni_uno/jni_info.cxx
new file mode 100644
index 000000000000..941ac8a23a32
--- /dev/null
+++ b/bridges/source/jni_uno/jni_info.cxx
@@ -0,0 +1,999 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: jni_info.cxx,v $
+ * $Revision: 1.22 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include "jni_bridge.h"
+
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#include "jvmaccess/unovirtualmachine.hxx"
+#include "rtl/string.hxx"
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+
+#include "uno/lbnames.h"
+
+
+namespace css = ::com::sun::star;
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+
+namespace jni_uno
+{
+
+//______________________________________________________________________________
+JNI_type_info::JNI_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td )
+ : m_td( td ),
+ m_class( 0 )
+{
+ m_td.makeComplete();
+ if (! m_td.get()->bComplete)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("cannot make type complete: ") );
+ buf.append( OUString::unacquired( &m_td.get()->pTypeName ) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+}
+
+
+//______________________________________________________________________________
+void JNI_interface_type_info::destroy( JNIEnv * jni_env )
+{
+ JNI_type_info::destruct( jni_env );
+ jni_env->DeleteGlobalRef( m_proxy_ctor );
+ jni_env->DeleteGlobalRef( m_type );
+ delete [] m_methods;
+ delete this;
+}
+
+//______________________________________________________________________________
+JNI_interface_type_info::JNI_interface_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td_ )
+ : JNI_type_info( jni, td_ )
+{
+ OSL_ASSERT( typelib_TypeClass_INTERFACE == m_td.get()->eTypeClass );
+
+ OUString const & uno_name = OUString::unacquired( &m_td.get()->pTypeName );
+ JNI_info const * jni_info = jni.get_info();
+
+ JLocalAutoRef jo_class(
+ jni,
+ find_class(
+ jni,
+ ( OUStringToOString( uno_name, RTL_TEXTENCODING_JAVA_UTF8 ).
+ getStr() ) ) );
+ JLocalAutoRef jo_type( jni, create_type( jni, (jclass) jo_class.get() ) );
+
+ // get proxy ctor
+ jvalue arg;
+ arg.l = jo_class.get();
+ JLocalAutoRef jo_proxy_ctor(
+ jni, jni->CallStaticObjectMethodA(
+ jni_info->m_class_JNI_proxy,
+ jni_info->m_method_JNI_proxy_get_proxy_ctor, &arg ) );
+
+ if (is_XInterface( m_td.get()->pWeakRef ))
+ {
+ m_methods = 0; // no methods
+ }
+ else
+ {
+ // retrieve method ids for all direct members
+ try
+ {
+ typelib_InterfaceTypeDescription * td =
+ reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ m_td.get() );
+ m_methods = new jmethodID[ td->nMapFunctionIndexToMemberIndex ];
+ sal_Int32 nMethodIndex = 0;
+ typelib_TypeDescriptionReference ** ppMembers = td->ppMembers;
+ sal_Int32 nMembers = td->nMembers;
+
+ for ( sal_Int32 nPos = 0; nPos < nMembers; ++nPos )
+ {
+ TypeDescr member_td( ppMembers[ nPos ] );
+
+ OStringBuffer sig_buf( 64 );
+
+ if (typelib_TypeClass_INTERFACE_METHOD ==
+ member_td.get()->eTypeClass) // method
+ {
+ typelib_InterfaceMethodTypeDescription * method_td =
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member_td.get() );
+
+ sig_buf.append( '(' );
+ for ( sal_Int32 i = 0; i < method_td->nParams; ++i )
+ {
+ typelib_MethodParameter const & param =
+ method_td->pParams[ i ];
+ if (param.bOut)
+ sig_buf.append( '[' );
+ JNI_info::append_sig( &sig_buf, param.pTypeRef );
+ }
+ sig_buf.append( ')' );
+ JNI_info::append_sig( &sig_buf, method_td->pReturnTypeRef );
+
+ OString method_signature( sig_buf.makeStringAndClear() );
+ OString method_name(
+ OUStringToOString( OUString::unacquired(
+ &method_td->aBase.pMemberName ),
+ RTL_TEXTENCODING_JAVA_UTF8 ) );
+
+ m_methods[ nMethodIndex ] = jni->GetMethodID(
+ (jclass) jo_class.get(), method_name.getStr(),
+ method_signature.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_methods[ nMethodIndex ] );
+ ++nMethodIndex;
+ }
+ else // attribute
+ {
+ OSL_ASSERT(
+ typelib_TypeClass_INTERFACE_ATTRIBUTE ==
+ member_td.get()->eTypeClass );
+ typelib_InterfaceAttributeTypeDescription * attribute_td =
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member_td.get() );
+
+ // type sig
+ JNI_info::append_sig(
+ &sig_buf, attribute_td->pAttributeTypeRef );
+ OString type_sig( sig_buf.makeStringAndClear() );
+ sig_buf.ensureCapacity( 64 );
+ // member name
+ OUString const & member_name =
+ OUString::unacquired(
+ &attribute_td->aBase.pMemberName );
+
+ // getter
+ sig_buf.append( RTL_CONSTASCII_STRINGPARAM("()") );
+ sig_buf.append( type_sig );
+ OString method_signature( sig_buf.makeStringAndClear() );
+ OUStringBuffer name_buf( 3 + member_name.getLength() );
+ name_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("get") );
+ name_buf.append( member_name );
+ OString method_name(
+ OUStringToOString(
+ name_buf.makeStringAndClear(),
+ RTL_TEXTENCODING_JAVA_UTF8 ) );
+ m_methods[ nMethodIndex ] = jni->GetMethodID(
+ (jclass) jo_class.get(), method_name.getStr(),
+ method_signature.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_methods[ nMethodIndex ] );
+ ++nMethodIndex;
+ if (! attribute_td->bReadOnly)
+ {
+ // setter
+ sig_buf.ensureCapacity( 64 );
+ sig_buf.append( '(' );
+ sig_buf.append( type_sig );
+ sig_buf.append( RTL_CONSTASCII_STRINGPARAM(")V") );
+ method_signature = sig_buf.makeStringAndClear();
+ name_buf.ensureCapacity( 3 + member_name.getLength() );
+ name_buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("set") );
+ name_buf.append( member_name );
+ method_name = OUStringToOString(
+ name_buf.makeStringAndClear(),
+ RTL_TEXTENCODING_JAVA_UTF8 );
+ m_methods[ nMethodIndex ] = jni->GetMethodID(
+ (jclass) jo_class.get(), method_name.getStr(),
+ method_signature.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_methods[ nMethodIndex ] );
+ ++nMethodIndex;
+ }
+ }
+ }
+ }
+ catch (...)
+ {
+ delete [] m_methods;
+ throw;
+ }
+ }
+ m_class = (jclass) jni->NewGlobalRef( jo_class.get() );
+ m_type = jni->NewGlobalRef( jo_type.get() );
+ m_proxy_ctor = jni->NewGlobalRef( jo_proxy_ctor.get() );
+}
+
+
+//______________________________________________________________________________
+void JNI_compound_type_info::destroy( JNIEnv * jni_env )
+{
+ JNI_type_info::destruct( jni_env );
+ delete [] m_fields;
+ delete this;
+}
+
+//______________________________________________________________________________
+JNI_compound_type_info::JNI_compound_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td_ )
+ : JNI_type_info( jni, td_ ),
+ m_exc_ctor( 0 ),
+ m_fields( 0 )
+{
+ OSL_ASSERT( typelib_TypeClass_STRUCT == m_td.get()->eTypeClass ||
+ typelib_TypeClass_EXCEPTION == m_td.get()->eTypeClass );
+ typelib_CompoundTypeDescription * td =
+ reinterpret_cast< typelib_CompoundTypeDescription * >( m_td.get() );
+
+ OUString const & uno_name =
+ OUString::unacquired( &((typelib_TypeDescription *)td)->pTypeName );
+
+ // Erase type arguments of instantiated polymorphic struct types:
+ OUString nucleus;
+ sal_Int32 i = uno_name.indexOf( '<' );
+ if ( i < 0 ) {
+ nucleus = uno_name;
+ } else {
+ nucleus = uno_name.copy( 0, i );
+ }
+ JLocalAutoRef jo_class(
+ jni,
+ find_class(
+ jni,
+ OUStringToOString(
+ nucleus, RTL_TEXTENCODING_JAVA_UTF8 ).getStr() ) );
+
+ JNI_info const * jni_info = jni.get_info();
+
+ if (typelib_TypeClass_EXCEPTION == m_td.get()->eTypeClass)
+ {
+ // retrieve exc ctor( msg )
+ m_exc_ctor = jni->GetMethodID(
+ (jclass) jo_class.get(), "<init>", "(Ljava/lang/String;)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_exc_ctor );
+ }
+
+ // retrieve info for base type
+ typelib_TypeDescription * base_td =
+ reinterpret_cast< typelib_TypeDescription * >(
+ td->pBaseTypeDescription );
+ m_base = (0 == base_td ? 0 : jni_info->get_type_info( jni, base_td ));
+
+ try
+ {
+ if (type_equals(
+ ((typelib_TypeDescription *)td)->pWeakRef,
+ jni_info->m_Exception_type.getTypeLibType() ) ||
+ type_equals(
+ ((typelib_TypeDescription *)td)->pWeakRef,
+ jni_info->m_RuntimeException_type.getTypeLibType() ))
+ {
+ m_fields = new jfieldID[ 2 ];
+ m_fields[ 0 ] = 0; // special Throwable.getMessage()
+ // field Context
+ m_fields[ 1 ] = jni->GetFieldID(
+ (jclass) jo_class.get(), "Context", "Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_fields[ 1 ] );
+ }
+ else
+ {
+ // retrieve field ids for all direct members
+ sal_Int32 nMembers = td->nMembers;
+ m_fields = new jfieldID[ nMembers ];
+
+ for ( sal_Int32 nPos = 0; nPos < nMembers; ++nPos )
+ {
+ OString sig;
+ if (td->aBase.eTypeClass == typelib_TypeClass_STRUCT
+ && reinterpret_cast< typelib_StructTypeDescription * >(
+ td)->pParameterizedTypes != 0
+ && reinterpret_cast< typelib_StructTypeDescription * >(
+ td)->pParameterizedTypes[nPos])
+ {
+ sig = OString(
+ RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;"));
+ } else {
+ OStringBuffer sig_buf( 32 );
+ JNI_info::append_sig( &sig_buf, td->ppTypeRefs[ nPos ] );
+ sig = sig_buf.makeStringAndClear();
+ }
+
+ OString member_name(
+ OUStringToOString(
+ OUString::unacquired( &td->ppMemberNames[ nPos ] ),
+ RTL_TEXTENCODING_JAVA_UTF8 ) );
+
+ m_fields[ nPos ] = jni->GetFieldID(
+ (jclass) jo_class.get(), member_name.getStr(),
+ sig.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_fields[ nPos ] );
+ }
+ }
+ }
+ catch (...)
+ {
+ delete [] m_fields;
+ throw;
+ }
+
+ m_class = (jclass) jni->NewGlobalRef( jo_class.get() );
+}
+
+
+//______________________________________________________________________________
+JNI_type_info const * JNI_info::create_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td ) const
+{
+ OUString const & uno_name = OUString::unacquired( &td->pTypeName );
+
+ JNI_type_info * new_info;
+ switch (td->eTypeClass)
+ {
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ new_info = new JNI_compound_type_info( jni, td );
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ new_info = new JNI_interface_type_info( jni, td );
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("type info not supported for ") );
+ buf.append( uno_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+
+ // look up
+ JNI_type_info * info;
+ ClearableMutexGuard guard( m_mutex );
+ JNI_type_info_holder & holder = m_type_map[ uno_name ];
+ if (0 == holder.m_info) // new insertion
+ {
+ holder.m_info = new_info;
+ guard.clear();
+ info = new_info;
+ }
+ else // inserted in the meantime
+ {
+ info = holder.m_info;
+ guard.clear();
+ new_info->destroy( jni.get_jni_env() );
+ }
+ return info;
+}
+
+//______________________________________________________________________________
+JNI_type_info const * JNI_info::get_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td ) const
+{
+ if (is_XInterface( td->pWeakRef ))
+ {
+ return m_XInterface_type_info;
+ }
+
+ OUString const & uno_name = OUString::unacquired( &td->pTypeName );
+ JNI_type_info const * info;
+ ClearableMutexGuard guard( m_mutex );
+
+ t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
+ if (iFind == m_type_map.end())
+ {
+ guard.clear();
+ info = create_type_info( jni, td );
+ }
+ else
+ {
+ info = iFind->second.m_info;
+ }
+
+ return info;
+}
+
+//______________________________________________________________________________
+JNI_type_info const * JNI_info::get_type_info(
+ JNI_context const & jni, typelib_TypeDescriptionReference * type ) const
+{
+ if (is_XInterface( type ))
+ {
+ return m_XInterface_type_info;
+ }
+
+ OUString const & uno_name = OUString::unacquired( &type->pTypeName );
+ JNI_type_info const * info;
+ ClearableMutexGuard guard( m_mutex );
+ t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
+ if (iFind == m_type_map.end())
+ {
+ guard.clear();
+ TypeDescr td( type );
+ info = create_type_info( jni, td.get() );
+ }
+ else
+ {
+ info = iFind->second.m_info;
+ }
+
+ return info;
+}
+
+//______________________________________________________________________________
+JNI_type_info const * JNI_info::get_type_info(
+ JNI_context const & jni, OUString const & uno_name ) const
+{
+ if (uno_name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ))
+ {
+ return m_XInterface_type_info;
+ }
+
+ JNI_type_info const * info;
+ ClearableMutexGuard guard( m_mutex );
+ t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
+ if (iFind == m_type_map.end())
+ {
+ guard.clear();
+ css::uno::TypeDescription td( uno_name );
+ if (! td.is())
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("UNO type not found: ") );
+ buf.append( uno_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ info = create_type_info( jni, td.get() );
+ }
+ else
+ {
+ info = iFind->second.m_info;
+ }
+
+ return info;
+}
+
+//______________________________________________________________________________
+JNI_info::JNI_info(
+ JNIEnv * jni_env, jobject class_loader, jclass classClass,
+ jmethodID methodForName )
+ : m_class_Class( classClass ),
+ m_method_Class_forName( methodForName ),
+ m_class_JNI_proxy( 0 ),
+ m_XInterface_queryInterface_td(
+ (reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ css::uno::TypeDescription(
+ ::getCppuType(
+ (css::uno::Reference< css::uno::XInterface > const *)0 ) )
+ .get())->ppMembers[ 0 ] ) ),
+ m_Exception_type( ::getCppuType( (css::uno::Exception const *)0 ) ),
+ m_RuntimeException_type(
+ ::getCppuType( (css::uno::RuntimeException const *)0 ) ),
+ m_void_type( ::getCppuVoidType() ),
+ m_XInterface_type_info( 0 )
+{
+ JNI_context jni( this, jni_env, class_loader ); // !no proper jni_info!
+
+ // class lookup
+ JLocalAutoRef jo_Object(
+ jni, find_class( jni, "java.lang.Object" ) );
+ JLocalAutoRef jo_Class(
+ jni, find_class( jni, "java.lang.Class" ) );
+ JLocalAutoRef jo_Throwable(
+ jni, find_class( jni, "java.lang.Throwable" ) );
+ JLocalAutoRef jo_Character(
+ jni, find_class( jni, "java.lang.Character" ) );
+ JLocalAutoRef jo_Boolean(
+ jni, find_class( jni, "java.lang.Boolean" ) );
+ JLocalAutoRef jo_Byte(
+ jni, find_class( jni, "java.lang.Byte" ) );
+ JLocalAutoRef jo_Short(
+ jni, find_class( jni, "java.lang.Short" ) );
+ JLocalAutoRef jo_Integer(
+ jni, find_class( jni, "java.lang.Integer" ) );
+ JLocalAutoRef jo_Long(
+ jni, find_class( jni, "java.lang.Long" ) );
+ JLocalAutoRef jo_Float(
+ jni, find_class( jni, "java.lang.Float" ) );
+ JLocalAutoRef jo_Double(
+ jni, find_class( jni, "java.lang.Double" ) );
+ JLocalAutoRef jo_String(
+ jni, find_class( jni, "java.lang.String" ) );
+ JLocalAutoRef jo_RuntimeException(
+ jni, find_class( jni, "com.sun.star.uno.RuntimeException" ) );
+ JLocalAutoRef jo_UnoRuntime(
+ jni, find_class( jni, "com.sun.star.uno.UnoRuntime" ) );
+ JLocalAutoRef jo_Any(
+ jni, find_class( jni, "com.sun.star.uno.Any" ) );
+ JLocalAutoRef jo_Enum(
+ jni, find_class( jni, "com.sun.star.uno.Enum" ) );
+ JLocalAutoRef jo_Type(
+ jni, find_class( jni, "com.sun.star.uno.Type" ) );
+ JLocalAutoRef jo_TypeClass(
+ jni, find_class( jni, "com.sun.star.uno.TypeClass" ) );
+ JLocalAutoRef jo_IEnvironment(
+ jni, find_class( jni, "com.sun.star.uno.IEnvironment" ) );
+ JLocalAutoRef jo_JNI_proxy(
+ jni, find_class( jni, "com.sun.star.bridges.jni_uno.JNI_proxy" ) );
+
+ // method Object.toString()
+ m_method_Object_toString = jni->GetMethodID(
+ (jclass) jo_Object.get(), "toString", "()Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Object_toString );
+ // method Class.getName()
+ m_method_Class_getName = jni->GetMethodID(
+ (jclass) jo_Class.get(), "getName", "()Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Class_getName );
+
+ // method Throwable.getMessage()
+ m_method_Throwable_getMessage = jni->GetMethodID(
+ (jclass) jo_Throwable.get(), "getMessage", "()Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Throwable_getMessage );
+
+ // method Character.charValue()
+ m_method_Character_charValue = jni->GetMethodID(
+ (jclass) jo_Character.get(), "charValue", "()C" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Character_charValue );
+ // method Boolean.booleanValue()
+ m_method_Boolean_booleanValue = jni->GetMethodID(
+ (jclass) jo_Boolean.get(), "booleanValue", "()Z" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Boolean_booleanValue );
+ // method Byte.byteValue()
+ m_method_Byte_byteValue = jni->GetMethodID(
+ (jclass) jo_Byte.get(), "byteValue", "()B" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Byte_byteValue );
+ // method Short.shortValue()
+ m_method_Short_shortValue = jni->GetMethodID(
+ (jclass) jo_Short.get(), "shortValue", "()S" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Short_shortValue );
+ // method Integer.intValue()
+ m_method_Integer_intValue = jni->GetMethodID(
+ (jclass) jo_Integer.get(), "intValue", "()I" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Integer_intValue );
+ // method Long.longValue()
+ m_method_Long_longValue = jni->GetMethodID(
+ (jclass) jo_Long.get(), "longValue", "()J" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Long_longValue );
+ // method Float.floatValue()
+ m_method_Float_floatValue = jni->GetMethodID(
+ (jclass) jo_Float.get(), "floatValue", "()F" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Float_floatValue );
+ // method Double.doubleValue()
+ m_method_Double_doubleValue = jni->GetMethodID(
+ (jclass) jo_Double.get(), "doubleValue", "()D" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Double_doubleValue );
+
+ // ctor Character( char )
+ m_ctor_Character_with_char = jni->GetMethodID(
+ (jclass) jo_Character.get(), "<init>", "(C)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Character_with_char );
+ // ctor Boolean( boolean )
+ m_ctor_Boolean_with_boolean = jni->GetMethodID(
+ (jclass) jo_Boolean.get(), "<init>", "(Z)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Boolean_with_boolean );
+ // ctor Byte( byte )
+ m_ctor_Byte_with_byte = jni->GetMethodID(
+ (jclass) jo_Byte.get(), "<init>", "(B)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Byte_with_byte );
+ // ctor Short( short )
+ m_ctor_Short_with_short = jni->GetMethodID(
+ (jclass) jo_Short.get(), "<init>", "(S)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Short_with_short );
+ // ctor Integer( int )
+ m_ctor_Integer_with_int = jni->GetMethodID(
+ (jclass) jo_Integer.get(), "<init>", "(I)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Integer_with_int );
+ // ctor Long( long )
+ m_ctor_Long_with_long = jni->GetMethodID(
+ (jclass) jo_Long.get(), "<init>", "(J)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Long_with_long );
+ // ctor Float( float )
+ m_ctor_Float_with_float = jni->GetMethodID(
+ (jclass) jo_Float.get(), "<init>", "(F)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Float_with_float );
+ // ctor Double( double )
+ m_ctor_Double_with_double = jni->GetMethodID(
+ (jclass) jo_Double.get(), "<init>", "(D)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Double_with_double );
+
+ // static method UnoRuntime.generateOid()
+ m_method_UnoRuntime_generateOid = jni->GetStaticMethodID(
+ (jclass) jo_UnoRuntime.get(),
+ "generateOid", "(Ljava/lang/Object;)Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_UnoRuntime_generateOid );
+ // static method UnoRuntime.queryInterface()
+ m_method_UnoRuntime_queryInterface = jni->GetStaticMethodID(
+ (jclass) jo_UnoRuntime.get(),
+ "queryInterface",
+ "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_UnoRuntime_queryInterface );
+
+ // field Enum.m_value
+ m_field_Enum_m_value = jni->GetFieldID(
+ (jclass) jo_Enum.get(), "m_value", "I" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_Enum_m_value );
+
+ // static method TypeClass.fromInt()
+ m_method_TypeClass_fromInt = jni->GetStaticMethodID(
+ (jclass) jo_TypeClass.get(),
+ "fromInt", "(I)Lcom/sun/star/uno/TypeClass;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_TypeClass_fromInt );
+
+ // ctor Type( Class )
+ m_ctor_Type_with_Class = jni->GetMethodID(
+ (jclass) jo_Type.get(), "<init>", "(Ljava/lang/Class;)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Type_with_Class );
+ // ctor Type( String, TypeClass )
+ m_ctor_Type_with_Name_TypeClass = jni->GetMethodID(
+ (jclass) jo_Type.get(),
+ "<init>", "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Type_with_Name_TypeClass );
+ // field Type._typeName
+ m_field_Type__typeName = jni->GetFieldID(
+ (jclass) jo_Type.get(), "_typeName", "Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_Type__typeName );
+
+ // ctor Any( Type, Object )
+ m_ctor_Any_with_Type_Object = jni->GetMethodID(
+ (jclass) jo_Any.get(),
+ "<init>", "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Any_with_Type_Object );
+
+ // field Any._type
+ m_field_Any__type = jni->GetFieldID(
+ (jclass) jo_Any.get(), "_type", "Lcom/sun/star/uno/Type;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_Any__type );
+ // field Any._object
+ m_field_Any__object = jni->GetFieldID(
+ (jclass) jo_Any.get(), "_object", "Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_Any__object );
+
+ // method IEnvironment.getRegisteredInterface()
+ m_method_IEnvironment_getRegisteredInterface = jni->GetMethodID(
+ (jclass) jo_IEnvironment.get(),
+ "getRegisteredInterface",
+ "(Ljava/lang/String;Lcom/sun/star/uno/Type;)Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_IEnvironment_getRegisteredInterface );
+ // method IEnvironment.registerInterface()
+ m_method_IEnvironment_registerInterface = jni->GetMethodID(
+ (jclass) jo_IEnvironment.get(), "registerInterface",
+ "(Ljava/lang/Object;[Ljava/lang/String;Lcom/sun/star/uno/Type;)"
+ "Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_IEnvironment_registerInterface );
+
+ // static method JNI_proxy.get_proxy_ctor()
+ m_method_JNI_proxy_get_proxy_ctor = jni->GetStaticMethodID(
+ (jclass) jo_JNI_proxy.get(), "get_proxy_ctor",
+ "(Ljava/lang/Class;)Ljava/lang/reflect/Constructor;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_JNI_proxy_get_proxy_ctor );
+ // static method JNI_proxy.create()
+ m_method_JNI_proxy_create = jni->GetStaticMethodID(
+ (jclass) jo_JNI_proxy.get(), "create",
+ "(JLcom/sun/star/uno/IEnvironment;JJLcom/sun/star/uno/Type;Ljava/lang"
+ "/String;Ljava/lang/reflect/Constructor;)Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_JNI_proxy_create );
+ // field JNI_proxy.m_receiver_handle
+ m_field_JNI_proxy_m_receiver_handle = jni->GetFieldID(
+ (jclass) jo_JNI_proxy.get(), "m_receiver_handle", "J" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_JNI_proxy_m_receiver_handle );
+ // field JNI_proxy.m_td_handle
+ m_field_JNI_proxy_m_td_handle = jni->GetFieldID(
+ (jclass) jo_JNI_proxy.get(), "m_td_handle", "J" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_JNI_proxy_m_td_handle );
+ // field JNI_proxy.m_type
+ m_field_JNI_proxy_m_type = jni->GetFieldID(
+ (jclass) jo_JNI_proxy.get(), "m_type", "Lcom/sun/star/uno/Type;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_JNI_proxy_m_type );
+ // field JNI_proxy.m_oid
+ m_field_JNI_proxy_m_oid = jni->GetFieldID(
+ (jclass) jo_JNI_proxy.get(), "m_oid", "Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_JNI_proxy_m_oid );
+
+ // get java env
+ OUString java_env_type_name( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_JAVA) );
+ JLocalAutoRef jo_java(
+ jni, ustring_to_jstring( jni, java_env_type_name.pData ) );
+ jvalue args[ 2 ];
+ args[ 0 ].l = jo_java.get();
+ args[ 1 ].l = 0;
+ jmethodID method_getEnvironment = jni->GetStaticMethodID(
+ (jclass) jo_UnoRuntime.get(), "getEnvironment",
+ "(Ljava/lang/String;Ljava/lang/Object;)"
+ "Lcom/sun/star/uno/IEnvironment;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != method_getEnvironment );
+ JLocalAutoRef jo_java_env(
+ jni, jni->CallStaticObjectMethodA(
+ (jclass) jo_UnoRuntime.get(), method_getEnvironment, args ) );
+
+ // get com.sun.star.uno.Any.VOID
+ jfieldID field_Any_VOID = jni->GetStaticFieldID(
+ (jclass) jo_Any.get(), "VOID", "Lcom/sun/star/uno/Any;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != field_Any_VOID );
+ JLocalAutoRef jo_Any_VOID(
+ jni, jni->GetStaticObjectField(
+ (jclass) jo_Any.get(), field_Any_VOID ) );
+ // get com.sun.star.uno.Type.UNSIGNED_SHORT
+ jfieldID field_Type_UNSIGNED_SHORT = jni->GetStaticFieldID(
+ (jclass) jo_Type.get(), "UNSIGNED_SHORT", "Lcom/sun/star/uno/Type;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != field_Type_UNSIGNED_SHORT );
+ JLocalAutoRef jo_Type_UNSIGNED_SHORT(
+ jni, jni->GetStaticObjectField(
+ (jclass) jo_Type.get(), field_Type_UNSIGNED_SHORT ) );
+ // get com.sun.star.uno.Type.UNSIGNED_LONG
+ jfieldID field_Type_UNSIGNED_LONG = jni->GetStaticFieldID(
+ (jclass) jo_Type.get(), "UNSIGNED_LONG", "Lcom/sun/star/uno/Type;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != field_Type_UNSIGNED_LONG );
+ JLocalAutoRef jo_Type_UNSIGNED_LONG(
+ jni, jni->GetStaticObjectField(
+ (jclass) jo_Type.get(), field_Type_UNSIGNED_LONG ) );
+ // get com.sun.star.uno.Type.UNSIGNED_HYPER
+ jfieldID field_Type_UNSIGNED_HYPER = jni->GetStaticFieldID(
+ (jclass) jo_Type.get(), "UNSIGNED_HYPER", "Lcom/sun/star/uno/Type;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != field_Type_UNSIGNED_HYPER );
+ JLocalAutoRef jo_Type_UNSIGNED_HYPER(
+ jni, jni->GetStaticObjectField(
+ (jclass) jo_Type.get(), field_Type_UNSIGNED_HYPER ) );
+
+ // make global refs
+ m_class_UnoRuntime =
+ (jclass) jni->NewGlobalRef( jo_UnoRuntime.get() );
+ m_class_RuntimeException =
+ (jclass) jni->NewGlobalRef( jo_RuntimeException.get() );
+ m_class_Any =
+ (jclass) jni->NewGlobalRef( jo_Any.get() );
+ m_class_Type =
+ (jclass) jni->NewGlobalRef( jo_Type.get() );
+ m_class_TypeClass =
+ (jclass) jni->NewGlobalRef( jo_TypeClass.get() );
+ m_class_JNI_proxy =
+ (jclass) jni->NewGlobalRef( jo_JNI_proxy.get() );
+
+ m_class_Character =
+ (jclass) jni->NewGlobalRef( jo_Character.get() );
+ m_class_Boolean =
+ (jclass) jni->NewGlobalRef( jo_Boolean.get() );
+ m_class_Byte =
+ (jclass) jni->NewGlobalRef( jo_Byte.get() );
+ m_class_Short =
+ (jclass) jni->NewGlobalRef( jo_Short.get() );
+ m_class_Integer =
+ (jclass) jni->NewGlobalRef( jo_Integer.get() );
+ m_class_Long =
+ (jclass) jni->NewGlobalRef( jo_Long.get() );
+ m_class_Float =
+ (jclass) jni->NewGlobalRef( jo_Float.get() );
+ m_class_Double =
+ (jclass) jni->NewGlobalRef( jo_Double.get() );
+ m_class_String =
+ (jclass) jni->NewGlobalRef( jo_String.get() );
+ m_class_Object =
+ (jclass) jni->NewGlobalRef( jo_Object.get() );
+ m_class_Class =
+ (jclass) jni->NewGlobalRef( m_class_Class );
+
+ m_object_Any_VOID =
+ jni->NewGlobalRef( jo_Any_VOID.get() );
+ m_object_Type_UNSIGNED_SHORT =
+ jni->NewGlobalRef( jo_Type_UNSIGNED_SHORT.get() );
+ m_object_Type_UNSIGNED_LONG =
+ jni->NewGlobalRef( jo_Type_UNSIGNED_LONG.get() );
+ m_object_Type_UNSIGNED_HYPER =
+ jni->NewGlobalRef( jo_Type_UNSIGNED_HYPER.get() );
+ m_object_java_env = jni->NewGlobalRef( jo_java_env.get() );
+
+ try
+ {
+ css::uno::TypeDescription XInterface_td(
+ ::getCppuType(
+ (css::uno::Reference< css::uno::XInterface > const *)0 ) );
+ m_XInterface_type_info =
+ new JNI_interface_type_info( jni, XInterface_td.get() );
+ }
+ catch (...)
+ {
+ destruct( jni_env );
+ throw;
+ }
+}
+
+//______________________________________________________________________________
+void JNI_info::destruct( JNIEnv * jni_env )
+{
+ t_str2type::const_iterator iPos( m_type_map.begin() );
+ t_str2type::const_iterator const iEnd( m_type_map.begin() );
+ for ( ; iPos != iEnd; ++iPos )
+ {
+ iPos->second.m_info->destroy( jni_env );
+ }
+ if (0 != m_XInterface_type_info)
+ {
+ const_cast< JNI_interface_type_info * >(
+ m_XInterface_type_info )->destroy( jni_env );
+ }
+
+ // free global refs
+ jni_env->DeleteGlobalRef( m_object_java_env );
+ jni_env->DeleteGlobalRef( m_object_Any_VOID );
+ jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_SHORT );
+ jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_LONG );
+ jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_HYPER );
+
+ jni_env->DeleteGlobalRef( m_class_Class );
+ jni_env->DeleteGlobalRef( m_class_Object );
+ jni_env->DeleteGlobalRef( m_class_String );
+ jni_env->DeleteGlobalRef( m_class_Double );
+ jni_env->DeleteGlobalRef( m_class_Float );
+ jni_env->DeleteGlobalRef( m_class_Long );
+ jni_env->DeleteGlobalRef( m_class_Integer );
+ jni_env->DeleteGlobalRef( m_class_Short );
+ jni_env->DeleteGlobalRef( m_class_Byte );
+ jni_env->DeleteGlobalRef( m_class_Boolean );
+ jni_env->DeleteGlobalRef( m_class_Character );
+
+ jni_env->DeleteGlobalRef( m_class_JNI_proxy );
+ jni_env->DeleteGlobalRef( m_class_RuntimeException );
+ jni_env->DeleteGlobalRef( m_class_UnoRuntime );
+ jni_env->DeleteGlobalRef( m_class_TypeClass );
+ jni_env->DeleteGlobalRef( m_class_Type );
+ jni_env->DeleteGlobalRef( m_class_Any );
+}
+
+//______________________________________________________________________________
+JNI_info const * JNI_info::get_jni_info(
+ rtl::Reference< jvmaccess::UnoVirtualMachine > const & uno_vm )
+{
+ // !!!no JNI_info available at JNI_context!!!
+ ::jvmaccess::VirtualMachine::AttachGuard guard(
+ uno_vm->getVirtualMachine() );
+ JNIEnv * jni_env = guard.getEnvironment();
+ JNI_context jni(
+ 0, jni_env, static_cast< jobject >(uno_vm->getClassLoader()) );
+
+ jclass jo_class;
+ jmethodID jo_forName;
+ jni.getClassForName( &jo_class, &jo_forName );
+ jni.ensure_no_exception();
+ JLocalAutoRef jo_JNI_info_holder(
+ jni,
+ jni.findClass(
+ "com.sun.star.bridges.jni_uno.JNI_info_holder", jo_class,
+ jo_forName, false ) );
+ // field JNI_info_holder.m_jni_info_handle
+ jfieldID field_s_jni_info_handle =
+ jni->GetStaticFieldID(
+ (jclass) jo_JNI_info_holder.get(), "s_jni_info_handle", "J" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != field_s_jni_info_handle );
+
+ JNI_info const * jni_info =
+ reinterpret_cast< JNI_info const * >(
+ jni->GetStaticLongField(
+ (jclass) jo_JNI_info_holder.get(), field_s_jni_info_handle ) );
+ if (0 == jni_info) // un-initialized?
+ {
+ JNI_info * new_info = new JNI_info(
+ jni_env, static_cast< jobject >(uno_vm->getClassLoader()), jo_class,
+ jo_forName );
+
+ ClearableMutexGuard g( Mutex::getGlobalMutex() );
+ jni_info =
+ reinterpret_cast< JNI_info const * >(
+ jni->GetStaticLongField(
+ (jclass) jo_JNI_info_holder.get(),
+ field_s_jni_info_handle ) );
+ if (0 == jni_info) // still un-initialized?
+ {
+ jni->SetStaticLongField(
+ (jclass) jo_JNI_info_holder.get(), field_s_jni_info_handle,
+ reinterpret_cast< jlong >( new_info ) );
+ jni_info = new_info;
+ }
+ else
+ {
+ g.clear();
+ new_info->destroy( jni_env );
+ }
+ }
+
+ return jni_info;
+}
+
+}
+
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+JNIEXPORT void
+JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize__J(
+ JNIEnv * jni_env, jobject, jlong jni_info_handle )
+ SAL_THROW_EXTERN_C()
+{
+ ::jni_uno::JNI_info * jni_info =
+ reinterpret_cast< ::jni_uno::JNI_info * >( jni_info_handle );
+ jni_info->destroy( jni_env );
+}
+
+}
diff --git a/bridges/source/jni_uno/jni_info.h b/bridges/source/jni_uno/jni_info.h
new file mode 100644
index 000000000000..bd211455c417
--- /dev/null
+++ b/bridges/source/jni_uno/jni_info.h
@@ -0,0 +1,378 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: jni_info.h,v $
+ * $Revision: 1.15 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_JNI_INFO_H
+#define INCLUDED_JNI_INFO_H
+
+#include <hash_map>
+
+#include "jni_base.h"
+
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+#include "rtl/ustring.hxx"
+#include "rtl/strbuf.hxx"
+
+#include "uno/environment.h"
+#include "typelib/typedescription.hxx"
+
+#include "com/sun/star/uno/Type.hxx"
+
+namespace jvmaccess { class UnoVirtualMachine; }
+
+namespace jni_uno
+{
+
+//------------------------------------------------------------------------------
+inline bool type_equals(
+ typelib_TypeDescriptionReference * type1,
+ typelib_TypeDescriptionReference * type2 )
+{
+ if (type1 == type2)
+ return true;
+ ::rtl::OUString const & name1 =
+ ::rtl::OUString::unacquired( &type1->pTypeName );
+ ::rtl::OUString const & name2 =
+ ::rtl::OUString::unacquired( &type2->pTypeName );
+ return ((type1->eTypeClass == type2->eTypeClass) && name1.equals( name2 ));
+}
+
+//------------------------------------------------------------------------------
+inline bool is_XInterface( typelib_TypeDescriptionReference * type )
+{
+ return ((typelib_TypeClass_INTERFACE == type->eTypeClass) &&
+ ::rtl::OUString::unacquired( &type->pTypeName ).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ));
+}
+
+//==============================================================================
+struct JNI_type_info
+{
+ ::com::sun::star::uno::TypeDescription m_td;
+ jclass m_class;
+
+ virtual void destroy( JNIEnv * jni_env ) = 0;
+protected:
+ inline void destruct( JNIEnv * jni_env )
+ { jni_env->DeleteGlobalRef( m_class ); }
+ virtual inline ~JNI_type_info() {}
+ explicit JNI_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td );
+};
+
+//==============================================================================
+struct JNI_interface_type_info : public JNI_type_info
+{
+ jobject m_proxy_ctor; // proxy ctor
+ jobject m_type;
+ // sorted via typelib function index
+ jmethodID * m_methods;
+
+ virtual void destroy( JNIEnv * jni_env );
+ explicit JNI_interface_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td );
+};
+
+//==============================================================================
+struct JNI_compound_type_info : public JNI_type_info
+{
+ JNI_type_info const * m_base;
+ // ctor( msg ) for exceptions
+ jmethodID m_exc_ctor;
+ // sorted via typelib member index
+ jfieldID * m_fields;
+
+ virtual void destroy( JNIEnv * jni_env );
+ explicit JNI_compound_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td );
+};
+
+//==============================================================================
+struct JNI_type_info_holder
+{
+ JNI_type_info * m_info;
+ inline JNI_type_info_holder()
+ : m_info( 0 )
+ {}
+};
+
+typedef ::std::hash_map<
+ ::rtl::OUString, JNI_type_info_holder, ::rtl::OUStringHash > t_str2type;
+
+//==============================================================================
+class JNI_info
+{
+ mutable ::osl::Mutex m_mutex;
+ mutable t_str2type m_type_map;
+
+public:
+ // These two are needed very early by find_class from within the ctor:
+ jclass m_class_Class;
+ jmethodID m_method_Class_forName;
+
+ //
+ jobject m_object_java_env;
+ jobject m_object_Any_VOID;
+ jobject m_object_Type_UNSIGNED_SHORT;
+ jobject m_object_Type_UNSIGNED_LONG;
+ jobject m_object_Type_UNSIGNED_HYPER;
+
+ //
+ jclass m_class_Object;
+ jclass m_class_Character;
+ jclass m_class_Boolean;
+ jclass m_class_Byte;
+ jclass m_class_Short;
+ jclass m_class_Integer;
+ jclass m_class_Long;
+ jclass m_class_Float;
+ jclass m_class_Double;
+ jclass m_class_String;
+
+ jclass m_class_UnoRuntime;
+ jclass m_class_RuntimeException;
+ jclass m_class_Any;
+ jclass m_class_Type;
+ jclass m_class_TypeClass;
+ jclass m_class_JNI_proxy;
+
+ //
+ jmethodID m_method_Object_toString;
+ jmethodID m_method_Class_getName;
+ jmethodID m_method_Throwable_getMessage;
+ jmethodID m_ctor_Character_with_char;
+ jmethodID m_ctor_Boolean_with_boolean;
+ jmethodID m_ctor_Byte_with_byte;
+ jmethodID m_ctor_Short_with_short;
+ jmethodID m_ctor_Integer_with_int;
+ jmethodID m_ctor_Long_with_long;
+ jmethodID m_ctor_Float_with_float;
+ jmethodID m_ctor_Double_with_double;
+ jmethodID m_method_Boolean_booleanValue;
+ jmethodID m_method_Byte_byteValue;
+ jmethodID m_method_Character_charValue;
+ jmethodID m_method_Double_doubleValue;
+ jmethodID m_method_Float_floatValue;
+ jmethodID m_method_Integer_intValue;
+ jmethodID m_method_Long_longValue;
+ jmethodID m_method_Short_shortValue;
+
+ //
+ jmethodID m_method_IEnvironment_getRegisteredInterface;
+ jmethodID m_method_IEnvironment_registerInterface;
+ jmethodID m_method_UnoRuntime_generateOid;
+ jmethodID m_method_UnoRuntime_queryInterface;
+ jmethodID m_ctor_Any_with_Type_Object;
+ jfieldID m_field_Any__type;
+ jfieldID m_field_Any__object;
+ jmethodID m_ctor_Type_with_Class;
+ jmethodID m_ctor_Type_with_Name_TypeClass;
+ jfieldID m_field_Type__typeName;
+ jmethodID m_method_TypeClass_fromInt;
+ jfieldID m_field_Enum_m_value;
+
+ //
+ jmethodID m_method_JNI_proxy_get_proxy_ctor;
+ jmethodID m_method_JNI_proxy_create;
+ jfieldID m_field_JNI_proxy_m_receiver_handle;
+ jfieldID m_field_JNI_proxy_m_td_handle;
+ jfieldID m_field_JNI_proxy_m_type;
+ jfieldID m_field_JNI_proxy_m_oid;
+
+ //
+ ::com::sun::star::uno::TypeDescription m_XInterface_queryInterface_td;
+ ::com::sun::star::uno::Type const & m_Exception_type;
+ ::com::sun::star::uno::Type const & m_RuntimeException_type;
+ ::com::sun::star::uno::Type const & m_void_type;
+ //
+ JNI_interface_type_info const * m_XInterface_type_info;
+
+ //
+ JNI_type_info const * get_type_info(
+ JNI_context const & jni,
+ typelib_TypeDescription * type ) const;
+ JNI_type_info const * get_type_info(
+ JNI_context const & jni,
+ typelib_TypeDescriptionReference * type ) const;
+ JNI_type_info const * get_type_info(
+ JNI_context const & jni,
+ ::rtl::OUString const & uno_name ) const;
+ //
+ inline static void append_sig(
+ ::rtl::OStringBuffer * buf, typelib_TypeDescriptionReference * type,
+ bool use_Object_for_type_XInterface = true, bool use_slashes = true );
+
+ // get this
+ static JNI_info const * get_jni_info(
+ rtl::Reference< jvmaccess::UnoVirtualMachine > const & uno_vm );
+ inline void destroy( JNIEnv * jni_env );
+
+private:
+ JNI_type_info const * create_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td ) const;
+
+ void destruct( JNIEnv * jni_env );
+
+ JNI_info( JNIEnv * jni_env, jobject class_loader,
+ jclass classClass, jmethodID methodForName );
+ inline ~JNI_info() {}
+};
+
+//______________________________________________________________________________
+inline void JNI_info::destroy( JNIEnv * jni_env )
+{
+ destruct( jni_env );
+ delete this;
+}
+
+//______________________________________________________________________________
+inline void JNI_info::append_sig(
+ ::rtl::OStringBuffer * buf, typelib_TypeDescriptionReference * type,
+ bool use_Object_for_type_XInterface, bool use_slashes )
+{
+ switch (type->eTypeClass)
+ {
+ case typelib_TypeClass_VOID:
+ buf->append( 'V' );
+ break;
+ case typelib_TypeClass_CHAR:
+ buf->append( 'C' );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ buf->append( 'Z' );
+ break;
+ case typelib_TypeClass_BYTE:
+ buf->append( 'B' );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ buf->append( 'S' );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ buf->append( 'I' );
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ buf->append( 'J' );
+ break;
+ case typelib_TypeClass_FLOAT:
+ buf->append( 'F' );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ buf->append( 'D' );
+ break;
+ case typelib_TypeClass_STRING:
+ if ( use_slashes ) {
+ buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava/lang/String;") );
+ } else {
+ buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava.lang.String;") );
+ }
+ break;
+ case typelib_TypeClass_TYPE:
+ if ( use_slashes ) {
+ buf->append(
+ RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/Type;") );
+ } else {
+ buf->append(
+ RTL_CONSTASCII_STRINGPARAM("Lcom.sun.star.uno.Type;") );
+ }
+ break;
+ case typelib_TypeClass_ANY:
+ if ( use_slashes ) {
+ buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;") );
+ } else {
+ buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava.lang.Object;") );
+ }
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ ::rtl::OUString const & uno_name =
+ ::rtl::OUString::unacquired( &type->pTypeName );
+ buf->append( 'L' );
+ // Erase type arguments of instantiated polymorphic struct types:
+ sal_Int32 i = uno_name.indexOf( '<' );
+ if ( i < 0 ) {
+ buf->append(
+ ::rtl::OUStringToOString(
+ use_slashes ? uno_name.replace( '.', '/' ) : uno_name,
+ RTL_TEXTENCODING_JAVA_UTF8 ) );
+ } else {
+ rtl::OUString s( uno_name.copy( 0, i ) );
+ buf->append(
+ ::rtl::OUStringToOString(
+ use_slashes ? s.replace( '.', '/' ) : s,
+ RTL_TEXTENCODING_JAVA_UTF8 ) );
+ }
+ buf->append( ';' );
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ buf->append( '[' );
+ TypeDescr td( type );
+ append_sig(
+ buf, ((typelib_IndirectTypeDescription *)td.get())->pType,
+ use_Object_for_type_XInterface, use_slashes );
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ if (use_Object_for_type_XInterface && is_XInterface( type ))
+ {
+ if ( use_slashes ) {
+ buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;") );
+ } else {
+ buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava.lang.Object;") );
+ }
+ }
+ else
+ {
+ ::rtl::OUString const & uno_name =
+ ::rtl::OUString::unacquired( &type->pTypeName );
+ buf->append( 'L' );
+ buf->append(
+ ::rtl::OUStringToOString(
+ use_slashes ? uno_name.replace( '.', '/' ) : uno_name,
+ RTL_TEXTENCODING_JAVA_UTF8 ) );
+ buf->append( ';' );
+ }
+ break;
+ default:
+ throw BridgeRuntimeError(
+ OUSTR("unsupported type: ") +
+ ::rtl::OUString::unacquired( &type->pTypeName ) );
+ }
+}
+
+}
+
+#endif
diff --git a/bridges/source/jni_uno/jni_java2uno.cxx b/bridges/source/jni_uno/jni_java2uno.cxx
new file mode 100644
index 000000000000..b3b4e5ab8b06
--- /dev/null
+++ b/bridges/source/jni_uno/jni_java2uno.cxx
@@ -0,0 +1,707 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: jni_java2uno.cxx,v $
+ * $Revision: 1.27 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include "jni_bridge.h"
+//#include "jni_finalizer.h"
+
+#include <rtl/ustrbuf.hxx>
+
+#include <algorithm>
+
+
+using namespace ::rtl;
+
+namespace jni_uno
+{
+
+//______________________________________________________________________________
+jobject Bridge::map_to_java(
+ JNI_context const & jni,
+ uno_Interface * pUnoI, JNI_interface_type_info const * info ) const
+{
+ // get oid
+ rtl_uString * pOid = 0;
+ (*m_uno_env->getObjectIdentifier)( m_uno_env, &pOid, pUnoI );
+ OSL_ASSERT( 0 != pOid );
+ OUString oid( pOid, SAL_NO_ACQUIRE );
+
+ // opt getRegisteredInterface()
+ JLocalAutoRef jo_oid( jni, ustring_to_jstring( jni, oid.pData ) );
+ jvalue args[ 2 ];
+ args[ 0 ].l = jo_oid.get();
+ args[ 1 ].l = info->m_type;
+ jobject jo_iface = jni->CallObjectMethodA(
+ m_jni_info->m_object_java_env,
+ m_jni_info->m_method_IEnvironment_getRegisteredInterface, args );
+ jni.ensure_no_exception();
+
+ if (0 == jo_iface) // no registered iface
+ {
+ // register uno interface
+ (*m_uno_env->registerInterface)(
+ m_uno_env, reinterpret_cast< void ** >( &pUnoI ),
+ oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
+
+ // create java and register java proxy
+ jvalue args2[ 7 ];
+ acquire();
+ args2[ 0 ].j = reinterpret_cast< sal_Int64 >( this );
+ (*pUnoI->acquire)( pUnoI );
+ args2[ 1 ].l = m_jni_info->m_object_java_env;
+ args2[ 2 ].j = reinterpret_cast< sal_Int64 >( pUnoI );
+ typelib_typedescription_acquire( info->m_td.get() );
+ args2[ 3 ].j = reinterpret_cast< sal_Int64 >( info->m_td.get() );
+ args2[ 4 ].l = info->m_type;
+ args2[ 5 ].l = jo_oid.get();
+ args2[ 6 ].l = info->m_proxy_ctor;
+ jo_iface = jni->CallStaticObjectMethodA(
+ m_jni_info->m_class_JNI_proxy,
+ m_jni_info->m_method_JNI_proxy_create, args2 );
+ jni.ensure_no_exception();
+ }
+
+ OSL_ASSERT( 0 != jo_iface );
+ return jo_iface;
+}
+
+
+//______________________________________________________________________________
+void Bridge::handle_uno_exc( JNI_context const & jni, uno_Any * uno_exc ) const
+{
+ if (typelib_TypeClass_EXCEPTION == uno_exc->pType->eTypeClass)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // append java stack trace to Message member
+ reinterpret_cast< ::com::sun::star::uno::Exception * >(
+ uno_exc->pData )->Message += jni.get_stack_trace();
+#endif
+
+#if OSL_DEBUG_LEVEL > 1
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("exception occured java->uno: [") );
+ buf.append( OUString::unacquired( &uno_exc->pType->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
+ buf.append(
+ reinterpret_cast< ::com::sun::star::uno::Exception const * >(
+ uno_exc->pData )->Message );
+ OString cstr_msg(
+ OUStringToOString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+ }
+#endif
+ // signal exception
+ jvalue java_exc;
+ try
+ {
+ map_to_java(
+ jni, &java_exc, uno_exc->pData, uno_exc->pType, 0,
+ true /* in */, false /* no out */ );
+ }
+ catch (...)
+ {
+ uno_any_destruct( uno_exc, 0 );
+ throw;
+ }
+ uno_any_destruct( uno_exc, 0 );
+
+ JLocalAutoRef jo_exc( jni, java_exc.l );
+ jint res = jni->Throw( (jthrowable) jo_exc.get() );
+ if (0 != res)
+ {
+ // call toString()
+ JLocalAutoRef jo_descr(
+ jni, jni->CallObjectMethodA(
+ jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "throwing java exception failed: ") );
+ buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ OUString message(
+ OUSTR("thrown exception is no uno exception: ") +
+ OUString::unacquired( &uno_exc->pType->pTypeName ) +
+ jni.get_stack_trace() );
+ uno_any_destruct( uno_exc, 0 );
+ throw BridgeRuntimeError( message );
+ }
+}
+
+union largest
+{
+ sal_Int64 n;
+ double d;
+ void * p;
+ uno_Any a;
+};
+
+//______________________________________________________________________________
+jobject Bridge::call_uno(
+ JNI_context const & jni,
+ uno_Interface * pUnoI, typelib_TypeDescription * member_td,
+ typelib_TypeDescriptionReference * return_type,
+ sal_Int32 nParams, typelib_MethodParameter const * pParams,
+ jobjectArray jo_args /* may be 0 */ ) const
+{
+ // return mem
+ sal_Int32 return_size;
+ switch (return_type->eTypeClass) {
+ case typelib_TypeClass_VOID:
+ return_size = 0;
+ break;
+
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ return_size = std::max(
+ TypeDescr(return_type).get()->nSize,
+ static_cast< sal_Int32 >(sizeof (largest)));
+ break;
+
+ default:
+ return_size = sizeof (largest);
+ break;
+ }
+
+#ifdef BROKEN_ALLOCA
+ char * mem = (char *) malloc(
+#else
+ char * mem = (char *) alloca(
+#endif
+ (nParams * sizeof (void *)) +
+ return_size + (nParams * sizeof (largest)) );
+ void ** uno_args = (void **) mem;
+ void * uno_ret = return_size == 0 ? 0 : (mem + (nParams * sizeof (void *)));
+ largest * uno_args_mem = (largest *)
+ (mem + (nParams * sizeof (void *)) + return_size);
+
+ OSL_ASSERT( (0 == nParams) || (nParams == jni->GetArrayLength( jo_args )) );
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = pParams[ nPos ];
+ typelib_TypeDescriptionReference * type = param.pTypeRef;
+
+ uno_args[ nPos ] = &uno_args_mem[ nPos ];
+ if (typelib_TypeClass_STRUCT == type->eTypeClass ||
+ typelib_TypeClass_EXCEPTION == type->eTypeClass)
+ {
+ TypeDescr td( type );
+ if (sal::static_int_cast< sal_uInt32 >(td.get()->nSize)
+ > sizeof (largest))
+#ifdef BROKEN_ALLOCA
+ uno_args[ nPos ] = malloc( td.get()->nSize );
+#else
+ uno_args[ nPos ] = alloca( td.get()->nSize );
+#endif
+ }
+
+ if (param.bIn)
+ {
+ try
+ {
+ JLocalAutoRef jo_arg(
+ jni, jni->GetObjectArrayElement( jo_args, nPos ) );
+ jni.ensure_no_exception();
+ jvalue java_arg;
+ java_arg.l = jo_arg.get();
+ map_to_uno(
+ jni, uno_args[ nPos ], java_arg, type, 0,
+ false /* no assign */, sal_False != param.bOut,
+ true /* special wrapped integral types */ );
+ }
+ catch (...)
+ {
+ // cleanup uno in args
+ for ( sal_Int32 n = 0; n < nPos; ++n )
+ {
+ typelib_MethodParameter const & p = pParams[ n ];
+ if (p.bIn)
+ {
+ uno_type_destructData(
+ uno_args[ n ], p.pTypeRef, 0 );
+ }
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ throw;
+ }
+ }
+ }
+
+ uno_Any uno_exc_holder;
+ uno_Any * uno_exc = &uno_exc_holder;
+ // call binary uno
+ (*pUnoI->pDispatcher)( pUnoI, member_td, uno_ret, uno_args, &uno_exc );
+
+ if (0 == uno_exc)
+ {
+ // convert out args; destruct uno args
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = pParams[ nPos ];
+ typelib_TypeDescriptionReference * type = param.pTypeRef;
+ if (param.bOut)
+ {
+ try
+ {
+ // get out holder array[ 1 ]
+ JLocalAutoRef jo_out_holder(
+ jni, jni->GetObjectArrayElement( jo_args, nPos ) );
+ jni.ensure_no_exception();
+ jvalue java_arg;
+ java_arg.l = jo_out_holder.get();
+ map_to_java(
+ jni, &java_arg, uno_args[ nPos ], type, 0,
+ true /* in */, true /* out holder */ );
+ }
+ catch (...)
+ {
+ // cleanup further uno args
+ for ( sal_Int32 n = nPos; n < nParams; ++n )
+ {
+ uno_type_destructData(
+ uno_args[ n ], pParams[ n ].pTypeRef, 0 );
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+ // cleanup uno return value
+ uno_type_destructData( uno_ret, return_type, 0 );
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ throw;
+ }
+ }
+ if (typelib_TypeClass_DOUBLE < type->eTypeClass &&
+ typelib_TypeClass_ENUM != type->eTypeClass) // opt
+ {
+ uno_type_destructData( uno_args[ nPos ], type, 0 );
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+ }
+
+ if (typelib_TypeClass_VOID != return_type->eTypeClass)
+ {
+ // convert uno return value
+ jvalue java_ret;
+ try
+ {
+ map_to_java(
+ jni, &java_ret, uno_ret, return_type, 0,
+ true /* in */, false /* no out */,
+ true /* special_wrapped_integral_types */ );
+ }
+ catch (...)
+ {
+ uno_type_destructData( uno_ret, return_type, 0 );
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ throw;
+ }
+ if (typelib_TypeClass_DOUBLE < return_type->eTypeClass &&
+ typelib_TypeClass_ENUM != return_type->eTypeClass) // opt
+ {
+ uno_type_destructData( uno_ret, return_type, 0 );
+ }
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ return java_ret.l;
+ }
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ return 0; // void return
+ }
+ else // exception occured
+ {
+ // destruct uno in args
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = pParams[ nPos ];
+ if (param.bIn)
+ uno_type_destructData( uno_args[ nPos ], param.pTypeRef, 0 );
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+
+ handle_uno_exc( jni, uno_exc );
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ return 0;
+ }
+}
+
+}
+
+using namespace ::jni_uno;
+
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+JNIEXPORT jobject
+JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call(
+ JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle, jstring,
+ jstring jo_method, jobjectArray jo_args /* may be 0 */ )
+ SAL_THROW_EXTERN_C()
+{
+ Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle );
+ JNI_info const * jni_info = bridge->m_jni_info;
+ JNI_context jni(
+ jni_info, jni_env,
+ static_cast< jobject >(
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext )->getClassLoader() ) );
+
+ OUString method_name;
+
+ try
+ {
+ method_name = jstring_to_oustring( jni, jo_method );
+#if OSL_DEBUG_LEVEL > 1
+ {
+ OUStringBuffer trace_buf( 64 );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("java->uno call: ") );
+ trace_buf.append( method_name );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on oid ") );
+ JLocalAutoRef jo_oid(
+ jni, jni->GetObjectField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
+ trace_buf.append( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
+ OString cstr_msg(
+ OUStringToOString(
+ trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+ }
+#endif
+
+ // special IQueryInterface.queryInterface()
+ if (method_name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("queryInterface") ))
+ {
+ // oid
+ JLocalAutoRef jo_oid(
+ jni, jni->GetObjectField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
+ // type
+ JLocalAutoRef jo_type(
+ jni, jni->GetObjectArrayElement( jo_args, 0 ) );
+ jni.ensure_no_exception();
+
+ JLocalAutoRef jo_type_name(
+ jni, jni->GetObjectField(
+ jo_type.get(), jni_info->m_field_Type__typeName ) );
+ if (! jo_type_name.is())
+ {
+ throw BridgeRuntimeError(
+ OUSTR("incomplete type object: no type name!") +
+ jni.get_stack_trace() );
+ }
+ OUString type_name(
+ jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
+ JNI_type_info const * info =
+ jni_info->get_type_info( jni, type_name );
+ if (typelib_TypeClass_INTERFACE != info->m_td.get()->eTypeClass)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("queryInterface() call demands an INTERFACE type!") );
+ }
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >( info );
+
+ // getRegisteredInterface() already tested in JNI_proxy:
+ // perform queryInterface call on binary uno interface
+ uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
+
+ uno_Any uno_ret;
+ void * uno_args[] = { &iface_info->m_td.get()->pWeakRef };
+ uno_Any uno_exc_holder;
+ uno_Any * uno_exc = &uno_exc_holder;
+ // call binary uno
+ (*pUnoI->pDispatcher)(
+ pUnoI, jni_info->m_XInterface_queryInterface_td.get(),
+ &uno_ret, uno_args, &uno_exc );
+ if (0 == uno_exc)
+ {
+ jobject jo_ret = 0;
+ if (typelib_TypeClass_INTERFACE == uno_ret.pType->eTypeClass)
+ {
+ uno_Interface * pUnoRet =
+ (uno_Interface *) uno_ret.pReserved;
+ if (0 != pUnoRet)
+ {
+ try
+ {
+ jo_ret =
+ bridge->map_to_java( jni, pUnoRet, iface_info );
+ }
+ catch (...)
+ {
+ uno_any_destruct( &uno_ret, 0 );
+ throw;
+ }
+ }
+ }
+ uno_any_destruct( &uno_ret, 0 );
+ return jo_ret;
+ }
+ else
+ {
+ bridge->handle_uno_exc( jni, uno_exc );
+ return 0;
+ }
+ }
+
+ typelib_InterfaceTypeDescription * td =
+ reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
+ uno_Interface * pUnoI =
+ reinterpret_cast< uno_Interface * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
+
+ typelib_TypeDescriptionReference ** ppAllMembers = td->ppAllMembers;
+ for ( sal_Int32 nPos = td->nAllMembers; nPos--; )
+ {
+ // try to avoid getting typedescription as long as possible,
+ // because of a Mutex.acquire() in
+ // typelib_typedescriptionreference_getDescription()
+ typelib_TypeDescriptionReference * member_type =
+ ppAllMembers[ nPos ];
+
+ // check method_name against fully qualified type_name
+ // of member_type; type_name is of the form
+ // <name> "::" <method_name> *(":@" <idx> "," <idx> ":" <name>)
+ OUString const & type_name =
+ OUString::unacquired( &member_type->pTypeName );
+ sal_Int32 offset = type_name.indexOf( ':' ) + 2;
+ OSL_ASSERT(
+ offset >= 2 && offset < type_name.getLength()
+ && type_name[offset - 1] == ':' );
+ sal_Int32 remainder = type_name.getLength() - offset;
+ if (typelib_TypeClass_INTERFACE_METHOD == member_type->eTypeClass)
+ {
+ if ((method_name.getLength() == remainder
+ || (method_name.getLength() < remainder
+ && type_name[offset + method_name.getLength()] == ':'))
+ && type_name.match(method_name, offset))
+ {
+ TypeDescr member_td( member_type );
+ typelib_InterfaceMethodTypeDescription * method_td =
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member_td.get() );
+ return bridge->call_uno(
+ jni, pUnoI, member_td.get(),
+ method_td->pReturnTypeRef,
+ method_td->nParams, method_td->pParams,
+ jo_args );
+ }
+ }
+ else // attribute
+ {
+ OSL_ASSERT(
+ typelib_TypeClass_INTERFACE_ATTRIBUTE ==
+ member_type->eTypeClass );
+
+ if (method_name.getLength() >= 3
+ && (method_name.getLength() - 3 == remainder
+ || (method_name.getLength() - 3 < remainder
+ && type_name[
+ offset + (method_name.getLength() - 3)] == ':'))
+ && method_name[1] == 'e' && method_name[2] == 't'
+ && rtl_ustr_compare_WithLength(
+ type_name.getStr() + offset,
+ method_name.getLength() - 3,
+ method_name.getStr() + 3,
+ method_name.getLength() - 3) == 0)
+ {
+ if ('g' == method_name[ 0 ])
+ {
+ TypeDescr member_td( member_type );
+ typelib_InterfaceAttributeTypeDescription * attr_td =
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member_td.get() );
+ return bridge->call_uno(
+ jni, pUnoI, member_td.get(),
+ attr_td->pAttributeTypeRef,
+ 0, 0,
+ jo_args );
+ }
+ else if ('s' == method_name[ 0 ])
+ {
+ TypeDescr member_td( member_type );
+ typelib_InterfaceAttributeTypeDescription * attr_td =
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member_td.get() );
+ if (! attr_td->bReadOnly)
+ {
+ typelib_MethodParameter param;
+ param.pTypeRef = attr_td->pAttributeTypeRef;
+ param.bIn = sal_True;
+ param.bOut = sal_False;
+ return bridge->call_uno(
+ jni, pUnoI, member_td.get(),
+ jni_info->m_void_type.getTypeLibType(),
+ 1, &param,
+ jo_args );
+ }
+ }
+ }
+ }
+ }
+ // the thing that should not be... no method info found!
+ OUStringBuffer buf( 64 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "calling undeclared function on interface ") );
+ buf.append( OUString::unacquired(
+ &((typelib_TypeDescription *)td)->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
+ buf.append( method_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ catch (BridgeRuntimeError & err)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("[jni_uno bridge error] "
+ "Java calling UNO method ") );
+ buf.append( method_name );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
+ buf.append( err.m_message );
+ // notify RuntimeException
+ OString cstr_msg(
+ OUStringToOString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_JAVA_UTF8 ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+ if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
+ != 0)
+ {
+ OSL_ASSERT( false );
+ }
+ return 0;
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OString cstr_msg(
+ OString( RTL_CONSTASCII_STRINGPARAM(
+ "[jni_uno bridge error] "
+ "attaching current thread to java failed!") ) +
+ OUStringToOString(
+ jni.get_stack_trace(), RTL_TEXTENCODING_JAVA_UTF8 ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+ if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
+ != 0)
+ {
+ OSL_ASSERT( false );
+ }
+ return 0;
+ }
+}
+
+//------------------------------------------------------------------------------
+JNIEXPORT void
+JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J(
+ JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle )
+ SAL_THROW_EXTERN_C()
+{
+ Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle );
+ JNI_info const * jni_info = bridge->m_jni_info;
+ JNI_context jni(
+ jni_info, jni_env,
+ static_cast< jobject >(
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext )->getClassLoader() ) );
+
+ uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
+ typelib_TypeDescription * td =
+ reinterpret_cast< typelib_TypeDescription * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
+
+#if OSL_DEBUG_LEVEL > 1
+ {
+ JLocalAutoRef jo_oid(
+ jni, jni->GetObjectField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
+ OUString oid( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("freeing java uno proxy: ") + oid,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+ }
+#endif
+ // revoke from uno env; has already been revoked from java env
+ (*bridge->m_uno_env->revokeInterface)( bridge->m_uno_env, pUnoI );
+ // release receiver
+ (*pUnoI->release)( pUnoI );
+ // release typedescription handle
+ typelib_typedescription_release( td );
+ // release bridge handle
+ bridge->release();
+}
+
+}
diff --git a/bridges/source/jni_uno/jni_uno2java.cxx b/bridges/source/jni_uno/jni_uno2java.cxx
new file mode 100644
index 000000000000..50c551427959
--- /dev/null
+++ b/bridges/source/jni_uno/jni_uno2java.cxx
@@ -0,0 +1,876 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: jni_uno2java.cxx,v $
+ * $Revision: 1.24 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#include "rtl/ustrbuf.hxx"
+
+#include "jni_bridge.h"
+
+
+using namespace ::std;
+using namespace ::rtl;
+
+namespace
+{
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_free( uno_ExtEnvironment * env, void * proxy )
+ SAL_THROW_EXTERN_C();
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_acquire( uno_Interface * pUnoI )
+ SAL_THROW_EXTERN_C();
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_release( uno_Interface * pUnoI )
+ SAL_THROW_EXTERN_C();
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_dispatch(
+ uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
+ void * uno_ret, void * uno_args[], uno_Any ** uno_exc )
+ SAL_THROW_EXTERN_C();
+}
+}
+
+namespace jni_uno
+{
+
+//______________________________________________________________________________
+void Bridge::handle_java_exc(
+ JNI_context const & jni,
+ JLocalAutoRef const & jo_exc, uno_Any * uno_exc ) const
+{
+ OSL_ASSERT( jo_exc.is() );
+ if (! jo_exc.is())
+ {
+ throw BridgeRuntimeError(
+ OUSTR("java exception occured, but no java exception available!?") +
+ jni.get_stack_trace() );
+ }
+
+ JLocalAutoRef jo_class( jni, jni->GetObjectClass( jo_exc.get() ) );
+ JLocalAutoRef jo_class_name(
+ jni, jni->CallObjectMethodA(
+ jo_class.get(), m_jni_info->m_method_Class_getName, 0 ) );
+ jni.ensure_no_exception();
+ OUString exc_name(
+ jstring_to_oustring( jni, (jstring) jo_class_name.get() ) );
+
+ ::com::sun::star::uno::TypeDescription td( exc_name.pData );
+ if (!td.is() || (typelib_TypeClass_EXCEPTION != td.get()->eTypeClass))
+ {
+ // call toString()
+ JLocalAutoRef jo_descr(
+ jni, jni->CallObjectMethodA(
+ jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("non-UNO exception occurred: ") );
+ buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ buf.append( jni.get_stack_trace( jo_exc.get() ) );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+
+ auto_ptr< rtl_mem > uno_data( rtl_mem::allocate( td.get()->nSize ) );
+ jvalue val;
+ val.l = jo_exc.get();
+ map_to_uno(
+ jni, uno_data.get(), val, td.get()->pWeakRef, 0,
+ false /* no assign */, false /* no out param */ );
+
+#if OSL_DEBUG_LEVEL > 0
+ // patch Message, append stack trace
+ reinterpret_cast< ::com::sun::star::uno::Exception * >(
+ uno_data.get() )->Message += jni.get_stack_trace( jo_exc.get() );
+#endif
+
+ typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
+ uno_exc->pType = td.get()->pWeakRef;
+ uno_exc->pData = uno_data.release();
+
+#if OSL_DEBUG_LEVEL > 1
+ OUStringBuffer trace_buf( 128 );
+ trace_buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("exception occured uno->java: [") );
+ trace_buf.append( exc_name );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
+ trace_buf.append(
+ reinterpret_cast< ::com::sun::star::uno::Exception const * >(
+ uno_exc->pData )->Message );
+ OString cstr_trace(
+ OUStringToOString(
+ trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_trace.getStr() );
+#endif
+}
+
+//______________________________________________________________________________
+void Bridge::call_java(
+ jobject javaI, typelib_InterfaceTypeDescription * iface_td,
+ sal_Int32 local_member_index, sal_Int32 function_pos_offset,
+ typelib_TypeDescriptionReference * return_type,
+ typelib_MethodParameter * params, sal_Int32 nParams,
+ void * uno_ret, void * uno_args [], uno_Any ** uno_exc ) const
+{
+ OSL_ASSERT( function_pos_offset == 0 || function_pos_offset == 1 );
+
+ JNI_guarded_context jni(
+ m_jni_info, reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ m_java_env->pContext ) );
+
+ // assure fully initialized iface_td:
+ ::com::sun::star::uno::TypeDescription iface_holder;
+ if (! iface_td->aBase.bComplete) {
+ iface_holder = ::com::sun::star::uno::TypeDescription(
+ reinterpret_cast<typelib_TypeDescription *>(iface_td) );
+ iface_holder.makeComplete();
+ if (! iface_holder.get()->bComplete) {
+ OUStringBuffer buf;
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("cannot make type complete: ") );
+ buf.append( OUString::unacquired(&iface_holder.get()->pTypeName) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ iface_td = reinterpret_cast<typelib_InterfaceTypeDescription *>(
+ iface_holder.get() );
+ OSL_ASSERT( iface_td->aBase.eTypeClass == typelib_TypeClass_INTERFACE );
+ }
+
+ // prepare java args, save param td
+#ifdef BROKEN_ALLOCA
+ jvalue * java_args = (jvalue *) malloc( sizeof (jvalue) * nParams );
+#else
+ jvalue * java_args = (jvalue *) alloca( sizeof (jvalue) * nParams );
+#endif
+
+ sal_Int32 nPos;
+ for ( nPos = 0; nPos < nParams; ++nPos )
+ {
+ try
+ {
+ typelib_MethodParameter const & param = params[ nPos ];
+ java_args[ nPos ].l = 0; // if out: build up array[ 1 ]
+ map_to_java(
+ jni, &java_args[ nPos ],
+ uno_args[ nPos ],
+ param.pTypeRef, 0,
+ sal_False != param.bIn /* convert uno value */,
+ sal_False != param.bOut /* build up array[ 1 ] */ );
+ }
+ catch (...)
+ {
+ // cleanup
+ for ( sal_Int32 n = 0; n < nPos; ++n )
+ {
+ typelib_MethodParameter const & param = params[ n ];
+ if (param.bOut ||
+ typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
+ {
+ jni->DeleteLocalRef( java_args[ n ].l );
+ }
+ }
+#ifdef BROKEN_ALLOCA
+ free( java_args );
+#endif
+ throw;
+ }
+ }
+
+ sal_Int32 base_members = iface_td->nAllMembers - iface_td->nMembers;
+ OSL_ASSERT( base_members < iface_td->nAllMembers );
+ sal_Int32 base_members_function_pos =
+ iface_td->pMapMemberIndexToFunctionIndex[ base_members ];
+ sal_Int32 member_pos = base_members + local_member_index;
+ OSL_ENSURE(
+ member_pos < iface_td->nAllMembers, "### member pos out of range!" );
+ sal_Int32 function_pos =
+ iface_td->pMapMemberIndexToFunctionIndex[ member_pos ]
+ + function_pos_offset;
+ OSL_ENSURE(
+ function_pos >= base_members_function_pos
+ && function_pos < iface_td->nMapFunctionIndexToMemberIndex,
+ "### illegal function index!" );
+ function_pos -= base_members_function_pos;
+
+ JNI_interface_type_info const * info =
+ static_cast< JNI_interface_type_info const * >(
+ m_jni_info->get_type_info( jni, &iface_td->aBase ) );
+ jmethodID method_id = info->m_methods[ function_pos ];
+
+#if OSL_DEBUG_LEVEL > 1
+ OUStringBuffer trace_buf( 128 );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("calling ") );
+ JLocalAutoRef jo_method(
+ jni, jni->ToReflectedMethod( info->m_class, method_id, JNI_FALSE ) );
+ jni.ensure_no_exception();
+ JLocalAutoRef jo_descr(
+ jni, jni->CallObjectMethodA(
+ jo_method.get(), m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ trace_buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on ") );
+ jo_descr.reset(
+ jni->CallObjectMethodA(
+ javaI, m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ trace_buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (") );
+ JLocalAutoRef jo_class( jni, jni->GetObjectClass( javaI ) );
+ jo_descr.reset(
+ jni->CallObjectMethodA(
+ jo_class.get(), m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ trace_buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(")") );
+ OString cstr_trace(
+ OUStringToOString(
+ trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_trace.getStr() );
+#endif
+
+ // complex return value
+ JLocalAutoRef java_ret( jni );
+
+ switch (return_type->eTypeClass)
+ {
+ case typelib_TypeClass_VOID:
+ jni->CallVoidMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_CHAR:
+ *(sal_Unicode *)uno_ret =
+ jni->CallCharMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ *(sal_Bool *)uno_ret =
+ jni->CallBooleanMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_BYTE:
+ *(sal_Int8 *)uno_ret =
+ jni->CallByteMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(sal_Int16 *)uno_ret =
+ jni->CallShortMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ *(sal_Int32 *)uno_ret =
+ jni->CallIntMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *(sal_Int64 *)uno_ret =
+ jni->CallLongMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float *)uno_ret =
+ jni->CallFloatMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double *)uno_ret =
+ jni->CallDoubleMethodA( javaI, method_id, java_args );
+ break;
+ default:
+ java_ret.reset(
+ jni->CallObjectMethodA( javaI, method_id, java_args ) );
+ break;
+ }
+
+ if (jni->ExceptionCheck())
+ {
+ JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
+ jni->ExceptionClear();
+
+ // release temp java local refs
+ for ( nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = params[ nPos ];
+ if (param.bOut ||
+ typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
+ {
+ jni->DeleteLocalRef( java_args[ nPos ].l );
+ }
+ }
+
+ handle_java_exc( jni, jo_exc, *uno_exc );
+ }
+ else // no exception
+ {
+ for ( nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = params[ nPos ];
+ if (param.bOut)
+ {
+ try
+ {
+ map_to_uno(
+ jni, uno_args[ nPos ],
+ java_args[ nPos ], param.pTypeRef, 0,
+ sal_False != param.bIn /* assign if inout */,
+ true /* out param */ );
+ }
+ catch (...)
+ {
+ // cleanup uno pure out
+ for ( sal_Int32 n = 0; n < nPos; ++n )
+ {
+ typelib_MethodParameter const & p = params[ n ];
+ if (! p.bIn)
+ {
+ uno_type_destructData(
+ uno_args[ n ], p.pTypeRef, 0 );
+ }
+ }
+ // cleanup java temp local refs
+ for ( ; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & p = params[ nPos ];
+ if (p.bOut ||
+ typelib_TypeClass_DOUBLE <
+ p.pTypeRef->eTypeClass)
+ {
+ jni->DeleteLocalRef( java_args[ nPos ].l );
+ }
+ }
+#ifdef BROKEN_ALLOCA
+ free( java_args );
+#endif
+ throw;
+ }
+ jni->DeleteLocalRef( java_args[ nPos ].l );
+ }
+ else // pure temp in param
+ {
+ if (typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
+ jni->DeleteLocalRef( java_args[ nPos ].l );
+ }
+ }
+
+ // return value
+ if (typelib_TypeClass_DOUBLE < return_type->eTypeClass)
+ {
+ try
+ {
+ jvalue val;
+ val.l = java_ret.get();
+ map_to_uno(
+ jni, uno_ret, val, return_type, 0,
+ false /* no assign */, false /* no out param */ );
+ }
+ catch (...)
+ {
+ // cleanup uno pure out
+ for ( sal_Int32 i = 0; i < nParams; ++i )
+ {
+ typelib_MethodParameter const & param = params[ i ];
+ if (! param.bIn)
+ {
+ uno_type_destructData(
+ uno_args[ i ], param.pTypeRef, 0 );
+ }
+ }
+#ifdef BROKEN_ALLOCA
+ free( java_args );
+#endif
+ throw;
+ }
+ } // else: already set integral uno return value
+
+ // no exception occured
+ *uno_exc = 0;
+ }
+#ifdef BROKEN_ALLOCA
+ free( java_args );
+#endif
+}
+
+//==== a uno proxy wrapping a java interface ===================================
+struct UNO_proxy : public uno_Interface
+{
+ mutable oslInterlockedCount m_ref;
+ Bridge const * m_bridge;
+
+ // mapping information
+ jobject m_javaI;
+ jstring m_jo_oid;
+ OUString m_oid;
+ JNI_interface_type_info const * m_type_info;
+
+ inline void acquire() const;
+ inline void release() const;
+
+ // ctor
+ inline UNO_proxy(
+ JNI_context const & jni, Bridge const * bridge,
+ jobject javaI, jstring jo_oid, OUString const & oid,
+ JNI_interface_type_info const * info );
+};
+
+//______________________________________________________________________________
+inline UNO_proxy::UNO_proxy(
+ JNI_context const & jni, Bridge const * bridge,
+ jobject javaI, jstring jo_oid, OUString const & oid,
+ JNI_interface_type_info const * info )
+ : m_ref( 1 ),
+ m_oid( oid ),
+ m_type_info( info )
+{
+ JNI_info const * jni_info = bridge->m_jni_info;
+ JLocalAutoRef jo_string_array(
+ jni, jni->NewObjectArray( 1, jni_info->m_class_String, jo_oid ) );
+ jni.ensure_no_exception();
+ jvalue args[ 3 ];
+ args[ 0 ].l = javaI;
+ args[ 1 ].l = jo_string_array.get();
+ args[ 2 ].l = info->m_type;
+ jobject jo_iface = jni->CallObjectMethodA(
+ jni_info->m_object_java_env,
+ jni_info->m_method_IEnvironment_registerInterface, args );
+ jni.ensure_no_exception();
+
+ m_javaI = jni->NewGlobalRef( jo_iface );
+ m_jo_oid = (jstring) jni->NewGlobalRef( jo_oid );
+ bridge->acquire();
+ m_bridge = bridge;
+
+ // uno_Interface
+ uno_Interface::acquire = UNO_proxy_acquire;
+ uno_Interface::release = UNO_proxy_release;
+ uno_Interface::pDispatcher = UNO_proxy_dispatch;
+}
+
+//______________________________________________________________________________
+inline void UNO_proxy::acquire() const
+{
+ if (1 == osl_incrementInterlockedCount( &m_ref ))
+ {
+ // rebirth of proxy zombie
+ void * that = const_cast< UNO_proxy * >( this );
+ // register at uno env
+ (*m_bridge->m_uno_env->registerProxyInterface)(
+ m_bridge->m_uno_env, &that,
+ UNO_proxy_free, m_oid.pData,
+ (typelib_InterfaceTypeDescription *)m_type_info->m_td.get() );
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ASSERT( this == (void const * const)that );
+#endif
+ }
+}
+
+//______________________________________________________________________________
+inline void UNO_proxy::release() const
+{
+ if (0 == osl_decrementInterlockedCount( &m_ref ))
+ {
+ // revoke from uno env on last release
+ (*m_bridge->m_uno_env->revokeInterface)(
+ m_bridge->m_uno_env, const_cast< UNO_proxy * >( this ) );
+ }
+}
+
+
+//______________________________________________________________________________
+uno_Interface * Bridge::map_to_uno(
+ JNI_context const & jni,
+ jobject javaI, JNI_interface_type_info const * info ) const
+{
+ JLocalAutoRef jo_oid( jni, compute_oid( jni, javaI ) );
+ OUString oid( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
+
+ uno_Interface * pUnoI = 0;
+ (*m_uno_env->getRegisteredInterface)(
+ m_uno_env, (void **)&pUnoI,
+ oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
+
+ if (0 == pUnoI) // no existing interface, register new proxy
+ {
+ // refcount initially 1
+ pUnoI = new UNO_proxy(
+ jni, const_cast< Bridge * >( this ),
+ javaI, (jstring) jo_oid.get(), oid, info );
+
+ (*m_uno_env->registerProxyInterface)(
+ m_uno_env, (void **)&pUnoI,
+ UNO_proxy_free,
+ oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
+ }
+ return pUnoI;
+}
+
+}
+
+using namespace ::jni_uno;
+
+namespace
+{
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_free( uno_ExtEnvironment * env, void * proxy )
+ SAL_THROW_EXTERN_C()
+{
+ UNO_proxy const * that = reinterpret_cast< UNO_proxy const * >( proxy );
+ Bridge const * bridge = that->m_bridge;
+
+ if ( env != bridge->m_uno_env ) {
+ OSL_ASSERT(false);
+ }
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("freeing binary uno proxy: ") + that->m_oid,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+#endif
+
+ try
+ {
+ JNI_guarded_context jni(
+ bridge->m_jni_info,
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext ) );
+
+ jni->DeleteGlobalRef( that->m_javaI );
+ jni->DeleteGlobalRef( that->m_jo_oid );
+ }
+ catch (BridgeRuntimeError & err)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg2(
+ OUStringToOString( err.m_message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg2.getStr() );
+#else
+ (void) err; // unused
+#endif
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OSL_ENSURE(
+ 0,
+ "[jni_uno bridge error] attaching current thread to java failed!" );
+ }
+
+ bridge->release();
+#if OSL_DEBUG_LEVEL > 1
+ *(int *)that = 0xdeadcafe;
+#endif
+ delete that;
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_acquire( uno_Interface * pUnoI )
+ SAL_THROW_EXTERN_C()
+{
+ UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
+ that->acquire();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_release( uno_Interface * pUnoI )
+ SAL_THROW_EXTERN_C()
+{
+ UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
+ that->release();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_dispatch(
+ uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
+ void * uno_ret, void * uno_args [], uno_Any ** uno_exc )
+ SAL_THROW_EXTERN_C()
+{
+ UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
+ Bridge const * bridge = that->m_bridge;
+
+#if OSL_DEBUG_LEVEL > 1
+ OUStringBuffer trace_buf( 64 );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno->java call: ") );
+ trace_buf.append( OUString::unacquired( &member_td->pTypeName ) );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on oid ") );
+ trace_buf.append( that->m_oid );
+ OString cstr_msg(
+ OUStringToOString(
+ trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+#endif
+
+ try
+ {
+ switch (member_td->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ typelib_InterfaceAttributeTypeDescription const * attrib_td =
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ member_td );
+ com::sun::star::uno::TypeDescription attrib_holder;
+ while ( attrib_td->pBaseRef != 0 ) {
+ attrib_holder = com::sun::star::uno::TypeDescription(
+ attrib_td->pBaseRef );
+ OSL_ASSERT(
+ attrib_holder.get()->eTypeClass
+ == typelib_TypeClass_INTERFACE_ATTRIBUTE );
+ attrib_td = reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ attrib_holder.get() );
+ }
+ typelib_InterfaceTypeDescription * iface_td = attrib_td->pInterface;
+
+ if (0 == uno_ret) // is setter method
+ {
+ typelib_MethodParameter param;
+ param.pTypeRef = attrib_td->pAttributeTypeRef;
+ param.bIn = sal_True;
+ param.bOut = sal_False;
+
+ bridge->call_java(
+ that->m_javaI, iface_td,
+ attrib_td->nIndex, 1, // get, then set method
+ bridge->m_jni_info->m_void_type.getTypeLibType(),
+ &param, 1,
+ 0, uno_args, uno_exc );
+ }
+ else // is getter method
+ {
+ bridge->call_java(
+ that->m_javaI, iface_td, attrib_td->nIndex, 0,
+ attrib_td->pAttributeTypeRef,
+ 0, 0, // no params
+ uno_ret, 0, uno_exc );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ typelib_InterfaceMethodTypeDescription const * method_td =
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ member_td );
+ com::sun::star::uno::TypeDescription method_holder;
+ while ( method_td->pBaseRef != 0 ) {
+ method_holder = com::sun::star::uno::TypeDescription(
+ method_td->pBaseRef );
+ OSL_ASSERT(
+ method_holder.get()->eTypeClass
+ == typelib_TypeClass_INTERFACE_METHOD );
+ method_td = reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ method_holder.get() );
+ }
+ typelib_InterfaceTypeDescription * iface_td = method_td->pInterface;
+
+ switch ( method_td->aBase.nPosition )
+ {
+ case 0: // queryInterface()
+ {
+ TypeDescr demanded_td(
+ *reinterpret_cast< typelib_TypeDescriptionReference ** >(
+ uno_args[ 0 ] ) );
+ if (typelib_TypeClass_INTERFACE !=
+ demanded_td.get()->eTypeClass)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("queryInterface() call demands "
+ "an INTERFACE type!") );
+ }
+
+ uno_Interface * pInterface = 0;
+ (*bridge->m_uno_env->getRegisteredInterface)(
+ bridge->m_uno_env,
+ (void **) &pInterface, that->m_oid.pData,
+ (typelib_InterfaceTypeDescription *)demanded_td.get() );
+
+ if (0 == pInterface)
+ {
+ JNI_info const * jni_info = bridge->m_jni_info;
+ JNI_guarded_context jni(
+ jni_info,
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext ) );
+
+ JNI_interface_type_info const * info =
+ static_cast< JNI_interface_type_info const * >(
+ jni_info->get_type_info( jni, demanded_td.get() ) );
+
+ jvalue args[ 2 ];
+ args[ 0 ].l = info->m_type;
+ args[ 1 ].l = that->m_javaI;
+
+ JLocalAutoRef jo_ret(
+ jni, jni->CallStaticObjectMethodA(
+ jni_info->m_class_UnoRuntime,
+ jni_info->m_method_UnoRuntime_queryInterface,
+ args ) );
+
+ if (jni->ExceptionCheck())
+ {
+ JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
+ jni->ExceptionClear();
+ bridge->handle_java_exc( jni, jo_exc, *uno_exc );
+ }
+ else
+ {
+ if (jo_ret.is())
+ {
+#if OSL_DEBUG_LEVEL > 0
+ JLocalAutoRef jo_oid(
+ jni, compute_oid( jni, jo_ret.get() ) );
+ OUString oid( jstring_to_oustring(
+ jni, (jstring) jo_oid.get() ) );
+ OSL_ENSURE(
+ oid.equals( that->m_oid ),
+ "### different oids!" );
+#endif
+ // refcount initially 1
+ uno_Interface * pUnoI2 = new UNO_proxy(
+ jni, bridge, jo_ret.get(),
+ that->m_jo_oid, that->m_oid, info );
+
+ (*bridge->m_uno_env->registerProxyInterface)(
+ bridge->m_uno_env,
+ (void **) &pUnoI2,
+ UNO_proxy_free, that->m_oid.pData,
+ reinterpret_cast<
+ typelib_InterfaceTypeDescription * >(
+ info->m_td.get() ) );
+
+ uno_any_construct(
+ (uno_Any *)uno_ret, &pUnoI2,
+ demanded_td.get(), 0 );
+ (*pUnoI2->release)( pUnoI2 );
+ }
+ else // object does not support demanded interface
+ {
+ uno_any_construct(
+ reinterpret_cast< uno_Any * >( uno_ret ),
+ 0, 0, 0 );
+ }
+ // no exception occured
+ *uno_exc = 0;
+ }
+ }
+ else
+ {
+ uno_any_construct(
+ reinterpret_cast< uno_Any * >( uno_ret ),
+ &pInterface, demanded_td.get(), 0 );
+ (*pInterface->release)( pInterface );
+ *uno_exc = 0;
+ }
+ break;
+ }
+ case 1: // acquire this proxy
+ that->acquire();
+ *uno_exc = 0;
+ break;
+ case 2: // release this proxy
+ that->release();
+ *uno_exc = 0;
+ break;
+ default: // arbitrary method call
+ bridge->call_java(
+ that->m_javaI, iface_td, method_td->nIndex, 0,
+ method_td->pReturnTypeRef,
+ method_td->pParams, method_td->nParams,
+ uno_ret, uno_args, uno_exc );
+ break;
+ }
+ break;
+ }
+ default:
+ {
+ throw BridgeRuntimeError(
+ OUSTR("illegal member type description!") );
+ }
+ }
+ }
+ catch (BridgeRuntimeError & err)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM(
+ "[jni_uno bridge error] UNO calling Java method ") );
+ if (typelib_TypeClass_INTERFACE_METHOD == member_td->eTypeClass ||
+ typelib_TypeClass_INTERFACE_ATTRIBUTE == member_td->eTypeClass)
+ {
+ buf.append( OUString::unacquired(
+ &reinterpret_cast<
+ typelib_InterfaceMemberTypeDescription const * >(
+ member_td )->pMemberName ) );
+ }
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
+ buf.append( err.m_message );
+ // binary identical struct
+ ::com::sun::star::uno::RuntimeException exc(
+ buf.makeStringAndClear(),
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XInterface >() );
+ ::com::sun::star::uno::Type const & exc_type = ::getCppuType( &exc );
+ uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), 0 );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg2(
+ OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg2.getStr() );
+#endif
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ // binary identical struct
+ ::com::sun::star::uno::RuntimeException exc(
+ OUSTR("[jni_uno bridge error] attaching current thread "
+ "to java failed!"),
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XInterface >() );
+ ::com::sun::star::uno::Type const & exc_type = ::getCppuType( &exc );
+ uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), 0 );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg2(
+ OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg2.getStr() );
+#endif
+ }
+}
+
+}
+}
diff --git a/bridges/source/jni_uno/makefile.mk b/bridges/source/jni_uno/makefile.mk
new file mode 100644
index 000000000000..d020eb7e91a1
--- /dev/null
+++ b/bridges/source/jni_uno/makefile.mk
@@ -0,0 +1,89 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.9 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=bridges
+TARGET=java_uno
+USE_DEFFILE=TRUE
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.IF "$(SOLAR_JAVA)"==""
+nojava:
+ @echo "Not building jni-uno bridge because Java is disabled"
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)$(COM)" == "WNTGCC"
+.IF "$(EXCEPTIONS)" == "sjlj"
+CFLAGS += -DBROKEN_ALLOCA
+.ENDIF
+.ENDIF
+
+SLOFILES= \
+ $(SLO)$/jni_info.obj \
+ $(SLO)$/jni_data.obj \
+ $(SLO)$/jni_uno2java.obj \
+ $(SLO)$/jni_java2uno.obj \
+ $(SLO)$/jni_bridge.obj \
+ $(SLO)$/nativethreadpool.obj
+
+SHL1TARGET=$(TARGET)
+
+SHL1STDLIBS= \
+ $(JVMACCESSLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(SALHELPERLIB)
+
+SHL1VERSIONMAP=$(TARGET).map
+
+SHL1IMPLIB=i$(TARGET)
+SHL1LIBS=$(SLB)$/$(TARGET).lib
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+SHL1RPATH=URELIB
+
+.IF "$(debug)" != ""
+.IF "$(COM)" == "MSC"
+CFLAGS += -Ob0
+.ENDIF
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/jni_uno/nativethreadpool.cxx b/bridges/source/jni_uno/nativethreadpool.cxx
new file mode 100644
index 000000000000..b19cbc829b66
--- /dev/null
+++ b/bridges/source/jni_uno/nativethreadpool.cxx
@@ -0,0 +1,233 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nativethreadpool.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "jvmaccess/virtualmachine.hxx"
+#include "rtl/byteseq.h"
+#include "rtl/byteseq.hxx"
+#include "rtl/memory.h"
+#include "rtl/ref.hxx"
+#include "sal/types.h"
+#include "uno/threadpool.h"
+
+#include "jni.h"
+
+#include <new>
+
+/* The native implementation part of
+ * jurt/com/sun/star/lib/uno/environments/remote/NativeThreadPool.java.
+ */
+
+namespace {
+
+struct Pool {
+ Pool(rtl::Reference< jvmaccess::VirtualMachine > const & theVirtualMachine,
+ jmethodID theExecute, uno_ThreadPool thePool):
+ virtualMachine(theVirtualMachine), execute(theExecute), pool(thePool) {}
+
+ rtl::Reference< jvmaccess::VirtualMachine > virtualMachine;
+ jmethodID execute;
+ uno_ThreadPool pool;
+};
+
+struct Job {
+ Job(Pool * thePool, jobject theJob): pool(thePool), job(theJob) {}
+
+ Pool * pool;
+ jobject job;
+};
+
+void throwOutOfMemory(JNIEnv * env) {
+ jclass c = env->FindClass("java/lang/OutOfMemoryError");
+ if (c != 0) {
+ env->ThrowNew(c, "");
+ }
+}
+
+}
+
+extern "C" {
+
+static void SAL_CALL executeRequest(void * data) {
+ Job * job = static_cast< Job * >(data);
+ try {
+ jvmaccess::VirtualMachine::AttachGuard guard(job->pool->virtualMachine);
+ JNIEnv * env = guard.getEnvironment();
+ // Failure of the following Job.execute Java call is ignored; if that
+ // call fails, it should be due to a java.lang.Error, which is not
+ // handled well, anyway:
+ env->CallObjectMethod(job->job, job->pool->execute);
+ env->DeleteGlobalRef(job->job);
+ delete job;
+ } catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &) {
+ //TODO: DeleteGlobalRef(job->job)
+ delete job;
+ }
+}
+
+}
+
+extern "C" JNIEXPORT jbyteArray JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_threadId(
+ JNIEnv * env, jclass) SAL_THROW_EXTERN_C()
+{
+ sal_Sequence * s = 0;
+ uno_getIdOfCurrentThread(&s); //TODO: out of memory
+ uno_releaseIdFromCurrentThread();
+ rtl::ByteSequence seq(s);
+ rtl_byte_sequence_release(s);
+ sal_Int32 n = seq.getLength();
+ jbyteArray a = env->NewByteArray(n);
+ // sal_Int32 and jsize are compatible here
+ if (a == 0) {
+ return 0;
+ }
+ void * p = env->GetPrimitiveArrayCritical(a, 0);
+ if (p == 0) {
+ return 0;
+ }
+ rtl_copyMemory(p, seq.getConstArray(), n);
+ // sal_Int8 and jbyte ought to be compatible
+ env->ReleasePrimitiveArrayCritical(a, p, 0);
+ return a;
+}
+
+extern "C" JNIEXPORT jlong JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_create(
+ JNIEnv * env, jclass) SAL_THROW_EXTERN_C()
+{
+ JavaVM * vm;
+ if (env->GetJavaVM(&vm) != JNI_OK) { //TODO: no Java exception raised?
+ jclass c = env->FindClass("java/lang/RuntimeException");
+ if (c != 0) {
+ env->ThrowNew(c, "JNI GetJavaVM failed");
+ }
+ return 0;
+ }
+ jclass c = env->FindClass("com/sun/star/lib/uno/environments/remote/Job");
+ if (c == 0) {
+ return 0;
+ }
+ jmethodID execute = env->GetMethodID(c, "execute", "()Ljava/lang/Object;");
+ if (execute == 0) {
+ return 0;
+ }
+ try {
+ return reinterpret_cast< jlong >(new Pool(
+ new jvmaccess::VirtualMachine(vm, env->GetVersion(), false, env),
+ execute, uno_threadpool_create()));
+ } catch (std::bad_alloc) {
+ throwOutOfMemory(env);
+ return 0;
+ }
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_attach(
+ JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C()
+{
+ uno_threadpool_attach(reinterpret_cast< Pool * >(pool)->pool);
+}
+
+extern "C" JNIEXPORT jobject JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_enter(
+ JNIEnv * env, jclass, jlong pool) SAL_THROW_EXTERN_C()
+{
+ jobject job;
+ uno_threadpool_enter(
+ reinterpret_cast< Pool * >(pool)->pool,
+ reinterpret_cast< void ** >(&job));
+ if (job == 0) {
+ return 0;
+ }
+ jobject ref = env->NewLocalRef(job);
+ env->DeleteGlobalRef(job);
+ return ref;
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_detach(
+ JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C()
+{
+ uno_threadpool_detach(reinterpret_cast< Pool * >(pool)->pool);
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_putJob(
+ JNIEnv * env, jclass, jlong pool, jbyteArray threadId, jobject job,
+ jboolean request, jboolean oneWay) SAL_THROW_EXTERN_C()
+{
+ void * s = env->GetPrimitiveArrayCritical(threadId, 0);
+ if (s == 0) {
+ return;
+ }
+ rtl::ByteSequence seq(
+ static_cast< sal_Int8 * >(s), env->GetArrayLength(threadId));
+ // sal_Int8 and jbyte ought to be compatible; sal_Int32 and jsize are
+ // compatible here
+ //TODO: out of memory
+ env->ReleasePrimitiveArrayCritical(threadId, s, JNI_ABORT);
+ Pool * p = reinterpret_cast< Pool * >(pool);
+ jobject ref = env->NewGlobalRef(job);
+ if (ref == 0) {
+ return;
+ }
+ Job * j = 0;
+ if (request) {
+ j = new(std::nothrow) Job(p, ref);
+ if (j == 0) {
+ env->DeleteGlobalRef(ref);
+ throwOutOfMemory(env);
+ return;
+ }
+ }
+ uno_threadpool_putJob(
+ p->pool, seq.getHandle(),
+ request ? static_cast< void * >(j) : static_cast< void * >(ref),
+ request ? executeRequest : 0, oneWay);
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_dispose(
+ JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C()
+{
+ uno_threadpool_dispose(reinterpret_cast< Pool * >(pool)->pool);
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_destroy(
+ JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C()
+{
+ Pool * p = reinterpret_cast< Pool * >(pool);
+ uno_threadpool_destroy(p->pool);
+ delete p;
+}
diff --git a/bridges/source/remote/context/context.cxx b/bridges/source/remote/context/context.cxx
new file mode 100644
index 000000000000..509f4b2a549c
--- /dev/null
+++ b/bridges/source/remote/context/context.cxx
@@ -0,0 +1,502 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: context.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <stdio.h>
+#include <string.h>
+#include <list>
+#include <hash_map>
+#include <utility>
+
+#include <osl/diagnose.h>
+#include <osl/interlck.h>
+#include <osl/mutex.hxx>
+
+#include "rtl/ustring.hxx"
+
+#include <bridges/remote/context.h>
+#include <bridges/remote/remote.h>
+#include <bridges/remote/connection.h>
+#include <bridges/remote/counter.hxx>
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+
+namespace {
+
+extern "C" typedef void * (SAL_CALL * MemAlloc)(sal_Size);
+
+}
+
+namespace remote_context
+{
+
+class remote_ContextImpl :
+ public remote_Context
+{
+public:
+ remote_ContextImpl( remote_Connection *pConnection,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *pProvider );
+ ~remote_ContextImpl();
+
+ static void SAL_CALL thisAcquire( uno_Context * );
+ static void SAL_CALL thisRelease( uno_Context * );
+ static void * SAL_CALL thisQuery( uno_Context * , rtl_uString * );
+ static void SAL_CALL thisAddDisposingListener( remote_Context * , remote_DisposingListener * );
+ static void SAL_CALL thisRemoveDisposingListener( remote_Context *, remote_DisposingListener *);
+ static void SAL_CALL thisDispose( remote_Context *);
+public:
+ oslInterlockedCount m_nRef;
+ sal_Bool m_bDisposed;
+ list < remote_DisposingListener * > m_lstListener;
+ Mutex m_mutex;
+};
+
+
+
+
+struct equalOUString_Impl
+{
+ sal_Bool operator()(const OUString & s1, const OUString & s2) const
+ { return s1 == s2; }
+};
+
+struct hashOUString_Impl
+{
+ size_t operator()(const OUString & rName) const
+ { return rName.hashCode(); }
+};
+
+typedef hash_map
+<
+ OUString,
+ void *,
+ hashOUString_Impl,
+ equalOUString_Impl
+>
+ContextMap;
+
+#if OSL_DEBUG_LEVEL > 1
+static MyCounter thisCounter( "DEBUG : Context" );
+#endif
+
+class ContextAdmin;
+
+ContextAdmin *g_pTheContext = 0;
+
+
+
+class ContextAdmin
+{
+public:
+ static ContextAdmin *getInstance();
+
+ // listener administration
+ void addContextListener( remote_contextListenerFunc listener , void *pObject );
+ void removeContextListener( remote_contextListenerFunc listener , void *pObject );
+
+ void fire( sal_Int32 nRemoteContextMode,
+ rtl_uString *sName,
+ rtl_uString *sDescription );
+
+ // context administration
+ uno_Context *createAndRegisterContext(
+ remote_Connection *pConnection,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *pInstanceProvider );
+
+ void revokeContext( uno_Context *pRemoteContext );
+
+ uno_Context *get( rtl_uString *pHost );
+
+ rtl_uString ** getConnectionList(
+ sal_Int32 *pnStringCount, MemAlloc memAlloc );
+
+private:
+ ::osl::Mutex m_mutex;
+
+ ContextMap m_mapContext;
+
+ typedef std::list< std::pair< remote_contextListenerFunc, void * > > List;
+ List m_lstListener;
+};
+
+ContextAdmin *ContextAdmin::getInstance()
+{
+ if( ! g_pTheContext ) {
+ ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
+ if( ! g_pTheContext ) {
+ //TODO This memory is leaked; see #i63473# for when this should be
+ // changed again:
+ g_pTheContext = new ContextAdmin;
+ }
+ }
+ return g_pTheContext;
+}
+
+void ContextAdmin::addContextListener( remote_contextListenerFunc listener , void *pObject )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ m_lstListener.push_back( std::make_pair( listener, pObject ) );
+}
+
+void ContextAdmin::removeContextListener( remote_contextListenerFunc listener , void *pObject )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ for (List::iterator ii(m_lstListener.begin()); ii != m_lstListener.end();
+ ++ii)
+ {
+ if (ii->first == listener && ii->second == pObject) {
+ m_lstListener.erase( ii );
+ break;
+ }
+ }
+}
+
+void ContextAdmin::fire(
+ sal_Int32 nRemoteContextMode,
+ rtl_uString *pName,
+ rtl_uString *sDescription )
+{
+ List lst;
+ {
+ ::osl::MutexGuard guard( m_mutex );
+ lst = m_lstListener;
+ }
+ for (List::iterator i(lst.begin()); i != lst.end(); ++i) {
+ (i->first)(i->second, nRemoteContextMode, pName, sDescription);
+ }
+}
+
+uno_Context *ContextAdmin::createAndRegisterContext( remote_Connection *pConnection,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *pInstanceProvider )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ uno_Context *pContext = get( pIdStr );
+ if( pContext )
+ {
+ pContext->release( pContext );
+ return 0;
+ }
+
+ remote_ContextImpl *p = new remote_ContextImpl( pConnection,
+ pIdStr,
+ pDescription,
+ pProtocol,
+ pInstanceProvider );
+
+ p->aBase.acquire( (uno_Context*) p );
+
+ m_mapContext[ OUString( pIdStr) ] = (void*) p;
+
+ fire( REMOTE_CONTEXT_CREATE , pIdStr , pDescription );
+ return ( uno_Context * )p;
+}
+
+
+void ContextAdmin::revokeContext( uno_Context *pRemoteContext )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ remote_ContextImpl *p = ( remote_ContextImpl * ) pRemoteContext;
+
+ ContextMap::iterator ii = m_mapContext.find( p->m_pName );
+ OSL_ASSERT( ii != m_mapContext.end() );
+ m_mapContext.erase( ii );
+
+ fire( REMOTE_CONTEXT_DESTROY , p->m_pName , p->m_pDescription );
+
+}
+
+uno_Context *ContextAdmin::get( rtl_uString *pHost )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ ContextMap::iterator ii = m_mapContext.find( OUString( (rtl_uString*)pHost ) );
+ if( ii == m_mapContext.end() )
+ {
+ return 0;
+ }
+
+ uno_Context *p = ( uno_Context * ) (*ii).second;
+ p->acquire( p );
+ return p;
+}
+
+
+rtl_uString ** ContextAdmin::getConnectionList(
+ sal_Int32 *pnStringCount, MemAlloc memAlloc )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ *pnStringCount = m_mapContext.size();
+ rtl_uString **ppReturn = ( rtl_uString ** )
+ memAlloc( sizeof( rtl_uString * ) * m_mapContext.size() );
+ memset( ppReturn , 0 , sizeof( rtl_uString * ) * m_mapContext.size() );
+
+ sal_Int32 i = 0;
+ for( ContextMap::iterator ii = m_mapContext.begin() ;
+ ii != m_mapContext.end();
+ ++ii, i++ )
+ {
+ rtl_uString_assign( &( ppReturn[i] ), (*ii).first.pData );
+ }
+
+ return ppReturn;
+}
+
+
+
+/*****************************
+ * remote_ContextImpl implementation
+ ****************************/
+
+
+
+remote_ContextImpl::remote_ContextImpl( remote_Connection *pConnection ,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *pProvider ) :
+ m_nRef( 0 ),
+ m_bDisposed( sal_False )
+{
+ m_pConnection = pConnection;
+ m_pConnection->acquire( m_pConnection );
+
+ m_pInstanceProvider = pProvider;
+ if( m_pInstanceProvider )
+ {
+ m_pInstanceProvider->acquire( pProvider );
+ }
+
+ m_pName = pIdStr;
+ rtl_uString_acquire( m_pName );
+
+ m_pDescription = pDescription;
+ rtl_uString_acquire( m_pDescription );
+
+ m_pProtocol = pProtocol;
+ rtl_uString_acquire( pProtocol );
+
+ aBase.acquire = thisAcquire;
+ aBase.release = thisRelease;
+ addDisposingListener = thisAddDisposingListener;
+ removeDisposingListener = thisRemoveDisposingListener;
+ dispose = thisDispose;
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+remote_ContextImpl::~remote_ContextImpl()
+{
+ // disposed must have been called
+ OSL_ASSERT( m_bDisposed );
+
+ rtl_uString_release( m_pName );
+ rtl_uString_release( m_pDescription );
+ rtl_uString_release( m_pProtocol );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+
+}
+
+
+void remote_ContextImpl::thisAddDisposingListener( remote_Context *pRemoteC ,
+ remote_DisposingListener *pListener )
+{
+ remote_ContextImpl *pImpl = (remote_ContextImpl * ) pRemoteC;
+
+ ::osl::MutexGuard guard( pImpl->m_mutex );
+
+ pListener->acquire( pListener );
+ pImpl->m_lstListener.push_back( pListener );
+}
+
+void remote_ContextImpl::thisRemoveDisposingListener( remote_Context *pRemoteC,
+ remote_DisposingListener *pListener)
+{
+ remote_ContextImpl *pImpl = (remote_ContextImpl * ) pRemoteC;
+ MutexGuard guard( pImpl->m_mutex );
+
+ for( list< remote_DisposingListener * >::iterator ii = pImpl->m_lstListener.begin() ;
+ ii != pImpl->m_lstListener.end();
+ ++ii )
+ {
+ if( (*ii) == pListener )
+ {
+ pImpl->m_lstListener.erase( ii );
+ pListener->release( pListener );
+ break;
+ }
+ }
+}
+
+void remote_ContextImpl::thisDispose( remote_Context *pRemoteC )
+{
+ remote_ContextImpl *pImpl = ( remote_ContextImpl * )pRemoteC;
+
+ MutexGuard guard( pImpl->m_mutex );
+ if( ! pImpl->m_bDisposed )
+ {
+ pImpl->m_bDisposed = sal_True;
+ ContextAdmin::getInstance()->revokeContext( (uno_Context * ) pRemoteC );
+
+ if( pImpl->m_pInstanceProvider )
+ {
+ pImpl->m_pInstanceProvider->release( pImpl->m_pInstanceProvider );
+ pImpl->m_pInstanceProvider = 0;
+ }
+
+ pImpl->m_pConnection->release( pImpl->m_pConnection );
+ pImpl->m_pConnection = 0;
+
+ list< remote_DisposingListener * > lst = pImpl->m_lstListener;
+ pImpl->m_lstListener.clear();
+
+ for( list < remote_DisposingListener * >::iterator ii = lst.begin();
+ ii != lst.end();
+ ++ii )
+ {
+ (*ii)->disposing( (*ii) , pImpl->m_pName );
+ (*ii)->release( (*ii) );
+ }
+
+ }
+}
+
+
+
+void remote_ContextImpl::thisAcquire( uno_Context *pRemoteC )
+{
+ remote_ContextImpl *p = SAL_REINTERPRET_CAST(remote_ContextImpl * ,pRemoteC );
+ osl_incrementInterlockedCount( &(p->m_nRef) );
+}
+
+void remote_ContextImpl::thisRelease( uno_Context *pRemoteC )
+{
+ remote_ContextImpl *p = SAL_REINTERPRET_CAST( remote_ContextImpl * , pRemoteC );
+ if (! osl_decrementInterlockedCount( &(p->m_nRef) ))
+ {
+ // enshure, that this piece of code is not reentered
+ osl_incrementInterlockedCount( &(p->m_nRef) );
+
+ // dispose, if necessary
+ p->dispose( p );
+
+ // restore the counter
+ osl_decrementInterlockedCount( &(p->m_nRef) );
+
+ if( 0 == p->m_nRef )
+ {
+ delete p;
+ }
+ else
+ {
+ // reanimated, but disposed !
+ }
+ }
+}
+
+void *remote_ContextImpl::thisQuery( uno_Context * , rtl_uString * )
+{
+ return 0;
+}
+
+
+} // end namespace remote_context
+
+
+using namespace remote_context;
+
+//-----------------------
+//
+// C-Interface
+//
+//-----------------------
+extern "C" remote_Context * SAL_CALL
+remote_getContext( rtl_uString *pIdString )
+{
+ return (remote_Context *) ContextAdmin::getInstance()->get( pIdString );
+}
+
+
+
+extern "C" remote_Context * SAL_CALL
+remote_createContext( remote_Connection *pConnection,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *pProvider )
+{
+ remote_ContextImpl *p = (remote_ContextImpl * )
+ ContextAdmin::getInstance()->createAndRegisterContext(
+ pConnection ,
+ pIdStr ,
+ pDescription,
+ pProtocol,
+ pProvider );
+
+ return (remote_Context * )p;
+}
+
+
+extern "C" void SAL_CALL
+remote_addContextListener( remote_contextListenerFunc listener, void *pObject )
+{
+ ContextAdmin::getInstance()->addContextListener( listener , pObject );
+}
+
+extern "C" void SAL_CALL
+remote_removeContextListener( remote_contextListenerFunc listener , void *pObject )
+{
+ ContextAdmin::getInstance()->removeContextListener( listener , pObject );
+}
+
+extern "C" rtl_uString ** SAL_CALL
+remote_getContextList( sal_Int32 *pnStringCount, MemAlloc memAlloc )
+{
+ return ContextAdmin::getInstance()->getConnectionList( pnStringCount , memAlloc );
+}
diff --git a/bridges/source/remote/context/exports.dxp b/bridges/source/remote/context/exports.dxp
new file mode 100644
index 000000000000..dcef3c369b10
--- /dev/null
+++ b/bridges/source/remote/context/exports.dxp
@@ -0,0 +1,5 @@
+remote_getContext
+remote_createContext
+remote_getContextList
+remote_removeContextListener
+remote_addContextListener \ No newline at end of file
diff --git a/bridges/source/remote/context/makefile.mk b/bridges/source/remote/context/makefile.mk
new file mode 100644
index 000000000000..4efb6214dc9e
--- /dev/null
+++ b/bridges/source/remote/context/makefile.mk
@@ -0,0 +1,69 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.7 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=rmcxt
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+
+UNIXVERSIONNAMES=UDK
+
+# --- Settings -----------------------------------------------------
+.INCLUDE : settings.mk
+# ------------------------------------------------------------------
+
+UNOUCRDEP=$(SOLARUCRDIR)$/uce.rdb
+UNOUCRRDB=$(SOLARUCRDIR)$/uce.rdb
+
+SLOFILES= $(SLO)$/context.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1STDLIBS= \
+ $(SALLIB)
+
+SHL1DEPN=
+SHL1IMPLIB= i$(TARGET)
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1RPATH=URELIB
+
+SHL1VERSIONMAP= $(TARGET).map
+
+DEF1NAME= $(SHL1TARGET)
+#DEF1EXPORTFILE= exports.dxp
+
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/bridges/source/remote/context/rmcxt.map b/bridges/source/remote/context/rmcxt.map
new file mode 100755
index 000000000000..182f6495ea9d
--- /dev/null
+++ b/bridges/source/remote/context/rmcxt.map
@@ -0,0 +1,10 @@
+UDK_3_0_0 {
+ global:
+ remote_getContext;
+ remote_createContext;
+ remote_getContextList;
+ remote_removeContextListener;
+ remote_addContextListener;
+ local:
+ *;
+};
diff --git a/bridges/source/remote/idl/corba.idl b/bridges/source/remote/idl/corba.idl
new file mode 100644
index 000000000000..a3eb595781a2
--- /dev/null
+++ b/bridges/source/remote/idl/corba.idl
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: corba.idl,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+module com
+{
+module sun
+{
+module star
+{
+
+module corba
+{
+
+ // CosBridging module
+ typedef unsigned long ObjectSystemID;
+ typedef sequence< byte > OpaqueData;
+
+ struct OneThreadID
+ {
+ ObjectSystemID objSysID;
+ OpaqueData threadID;
+ };
+
+ typedef sequence<OneThreadID> ThreadIDs;
+
+ struct LogicalThreadID // Service context
+ {
+ ThreadIDs IDs;
+ };
+
+ struct CorbaString8
+ {
+ string theString;
+ };
+
+ struct CorbaUnion
+ {
+ long dummy;
+ };
+
+ struct ObjectKey
+ {
+ CorbaString8 sOid;
+ CorbaString8 sType;
+ };
+
+ enum TCKind
+ {
+ tk_null, tk_void,
+ tk_short, tk_long, tk_ushort, tk_ulong,
+ tk_float, tk_double, tk_boolean, tk_char,
+ tk_octet, tk_any, tk_TypeCode, tk_Principal, tk_objref,
+ tk_struct, tk_union, tk_enum, tk_string,
+ tk_sequence, tk_array, tk_alias, tk_except,
+ tk_longlong, tk_ulonglong, tk_longdouble,
+ tk_wchar, tk_wstring, tk_fixed,
+ tk_value, tk_value_box,
+ tk_native,
+ tk_abstract_interface
+ };
+};
+
+};
+};
+};
diff --git a/bridges/source/remote/static/helper.cxx b/bridges/source/remote/static/helper.cxx
new file mode 100644
index 000000000000..c54075ce04a7
--- /dev/null
+++ b/bridges/source/remote/static/helper.cxx
@@ -0,0 +1,212 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: helper.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <rtl/alloc.h>
+#include <osl/diagnose.h>
+
+#include <bridges/remote/helper.hxx>
+
+#include <bridges/remote/stub.hxx>
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/remote.hxx>
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace bridges_remote
+{
+
+void SAL_CALL remote_createStub (
+ remote_Interface **ppRemoteI,
+ rtl_uString *pOid ,
+ typelib_TypeDescriptionReference *pTypeRef,
+ uno_Environment *pEnvRemote,
+ ReleaseRemoteCallbackFunc releaseRemoteCallback )
+{
+ typelib_TypeDescription *pType = 0;
+ typelib_typedescriptionreference_getDescription( &pType, pTypeRef );
+
+ (void) pEnvRemote->pExtEnv->getRegisteredInterface(
+ pEnvRemote->pExtEnv,
+ (void **)ppRemoteI,
+ pOid,
+ (typelib_InterfaceTypeDescription* )pType );
+
+ if( *ppRemoteI )
+ {
+ if( (*ppRemoteI)->acquire == acquireRemote2RemoteStub ) {
+
+ if( releaseRemoteCallback )
+ {
+ // use the callback handler, the bridge wants to send the call immeadiatly
+ releaseRemoteCallback( *ppRemoteI , pOid, pTypeRef , pEnvRemote );
+ }
+ else
+ {
+ ((::bridges_remote::Remote2RemoteStub *)*ppRemoteI)->releaseRemote();
+ }
+ }
+ else
+ {
+ // Uno2RemoteStub
+ // no release necessary
+ }
+ }
+ else
+ {
+ remote_BridgeImpl *pImpl = ((remote_Context *)pEnvRemote->pContext)->m_pBridgeImpl;
+ *ppRemoteI =
+ new ::bridges_remote::Remote2RemoteStub(
+ pOid,
+ (typelib_InterfaceTypeDescription * ) pType,
+ pEnvRemote,
+ pImpl->m_sendRequest);
+
+ // ppRemoteI may change during registration
+ pEnvRemote->pExtEnv->registerProxyInterface(
+ pEnvRemote->pExtEnv,
+ (void **) ppRemoteI,
+ freeRemote2RemoteStub,
+ pOid,
+ (typelib_InterfaceTypeDescription * ) pType );
+ }
+
+ typelib_typedescription_release( pType );
+}
+
+void SAL_CALL remote_sendQueryInterface(
+ uno_Environment *pEnvRemote,
+ remote_Interface **ppRemoteI,
+ rtl_uString *pOid ,
+ typelib_TypeDescriptionReference *pTypeRef,
+ uno_Any **ppException
+ )
+{
+ OSL_ASSERT( ppRemoteI );
+
+ typelib_InterfaceTypeDescription *pType = 0;
+ typelib_typedescriptionreference_getDescription( (typelib_TypeDescription ** )&pType, pTypeRef );
+
+ if( *ppRemoteI )
+ {
+ (*ppRemoteI)->release( *ppRemoteI );
+ (*ppRemoteI) = 0;
+ }
+
+ remote_BridgeImpl *pImpl = ((remote_Context *)pEnvRemote->pContext)->m_pBridgeImpl;
+
+ Type type = ::getCppuType( (Reference < XInterface > *)0 );
+
+ // get type for queryInterface
+ OUString sCompleteMethodName = type.getTypeName();
+ sCompleteMethodName += OUString::createFromAscii("::queryInterface");
+
+ typelib_InterfaceMemberTypeDescription *pMemberType = 0;
+ typelib_typedescription_getByName(
+ (typelib_TypeDescription **) &pMemberType,
+ sCompleteMethodName.pData );
+
+ OSL_ASSERT( pMemberType );
+
+ uno_Any anyInterface;
+ anyInterface.pType = 0;
+ anyInterface.pData = 0;
+
+ void *pReturn = &anyInterface;
+ void *ppArgs[1];
+
+ ppArgs[0] = 0;
+ typelib_TypeDescriptionReference *pRef = 0;
+ typelib_typedescriptionreference_new( &pRef ,
+ pType->aBase.eTypeClass,
+ pType->aBase.pTypeName);
+
+ ppArgs[0] = &pRef;
+
+// uno_Any anyException;
+// uno_Any *pAnyException = &anyException;
+
+ // do the queryInterface
+ pImpl->m_sendRequest(
+ pEnvRemote,
+ (typelib_TypeDescription * ) pMemberType,
+ pOid,
+ pType,
+ pReturn,
+ ppArgs,
+ ppException );
+
+
+ // now release everything
+ typelib_typedescriptionreference_release( pRef );
+ typelib_typedescription_release( (typelib_TypeDescription * ) pMemberType );
+
+ if( *ppException )
+ {
+ *ppRemoteI = 0;
+ }
+ else
+ {
+ // set out parameter
+ if( typelib_TypeClass_INTERFACE == anyInterface.pType->eTypeClass )
+ {
+ *ppRemoteI = ( remote_Interface * ) anyInterface.pReserved;
+ }
+ typelib_typedescriptionreference_release( anyInterface.pType );
+ }
+
+ typelib_typedescription_release( (typelib_TypeDescription * ) pType );
+}
+
+
+void SAL_CALL remote_retrieveOidFromProxy(
+ remote_Interface *pRemoteI,
+ rtl_uString **ppOid )
+{
+ if( pRemoteI->acquire == acquireRemote2RemoteStub )
+ {
+ // Remote2RemoteStub
+ ::bridges_remote::Remote2RemoteStub *pStub = (::bridges_remote::Remote2RemoteStub * ) pRemoteI;
+ rtl_uString_newFromString( ppOid , pStub->m_sOid.pData );
+ }
+ else
+ {
+ // Uno2RemoteStub
+ ::bridges_remote::Uno2RemoteStub *pStub = (::bridges_remote::Uno2RemoteStub * ) pRemoteI;
+ rtl_uString_newFromString( ppOid , pStub->m_sOid.pData );
+ pRemoteI->acquire( pRemoteI );
+ }
+}
+
+}
diff --git a/bridges/source/remote/static/makefile.mk b/bridges/source/remote/static/makefile.mk
new file mode 100644
index 000000000000..56237bb0a859
--- /dev/null
+++ b/bridges/source/remote/static/makefile.mk
@@ -0,0 +1,65 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.8 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=bridges_remote_static
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/proxy.obj \
+ $(SLO)$/stub.obj \
+ $(SLO)$/remote.obj \
+ $(SLO)$/mapping.obj \
+ $(SLO)$/helper.obj \
+ $(SLO)$/remote_types.obj
+
+# Forte6 update 1 on Solaris Intel dies with internal compiler error
+# on stub.cxx if optimization is on. Switch it off for now.
+# To be reevaluated on compiler upgrade
+.IF "$(OS)$(CPU)"=="SOLARISI"
+NOOPTFILES=\
+ $(SLO)$/stub.obj
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+
diff --git a/bridges/source/remote/static/mapping.cxx b/bridges/source/remote/static/mapping.cxx
new file mode 100644
index 000000000000..164481b5bfe0
--- /dev/null
+++ b/bridges/source/remote/static/mapping.cxx
@@ -0,0 +1,221 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: mapping.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <osl/diagnose.h>
+
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/stub.hxx>
+#include <bridges/remote/counter.hxx>
+#include <bridges/remote/mapping.hxx>
+
+using namespace bridges_remote;
+
+extern "C" {
+
+static void SAL_CALL thisAcquire( uno_Mapping *pMap )
+{
+ RemoteMapping *p = SAL_REINTERPRET_CAST( RemoteMapping * , pMap );
+ if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
+ {
+ if( remoteToUno == pMap->mapInterface )
+ {
+ uno_registerMapping( &pMap ,
+ freeRemoteMapping,
+ p->pEnvRemote ,
+ p->pEnvUno ,
+ p->m_sPurpose.pData );
+ }
+ else
+ {
+ uno_registerMapping( &pMap ,
+ freeRemoteMapping,
+ p->pEnvUno ,
+ p->pEnvRemote ,
+ p->m_sPurpose.pData );
+ }
+
+ }
+}
+
+static void SAL_CALL thisRelease( uno_Mapping *pMap )
+{
+ RemoteMapping *p = SAL_REINTERPRET_CAST( RemoteMapping * , pMap );
+ if (! osl_decrementInterlockedCount( &(p->m_nRef) ))
+ {
+ uno_revokeMapping( pMap );
+ }
+}
+
+}
+
+namespace bridges_remote {
+
+void remoteToUno( uno_Mapping *pMapping, void **ppUnoI, void *pRemoteI,
+ typelib_InterfaceTypeDescription *pTypeDescr )
+{
+ remote_Mapping *pRemoteMapping = ( remote_Mapping * ) pMapping;
+
+ OSL_ASSERT( ppUnoI && pTypeDescr );
+ if (*ppUnoI)
+ {
+ ((uno_Interface *)*ppUnoI)->release( (uno_Interface *)*ppUnoI );
+ *ppUnoI = 0;
+ }
+
+ if (pRemoteI && pTypeDescr)
+ {
+ // get object id of interface to be wrapped
+ rtl_uString * pOid = 0;
+ pRemoteMapping->pEnvRemote->pExtEnv->getObjectIdentifier(
+ pRemoteMapping->pEnvRemote->pExtEnv,
+ &pOid,
+ pRemoteI );
+
+ OSL_ASSERT(pOid);
+ if( ! pOid )
+ {
+ return;
+ }
+
+ // try to get any known interface from target environment
+ pRemoteMapping->pEnvUno->pExtEnv->getRegisteredInterface(
+ pRemoteMapping->pEnvUno->pExtEnv,
+ ppUnoI,
+ pOid,
+ pTypeDescr);
+
+ if ( ! *ppUnoI) // already existing interface
+ {
+ // try to publish a new proxy; proxy may be exchanged during registration
+ *ppUnoI = new Remote2UnoProxy(
+ ( remote_Interface * ) pRemoteI,
+ pOid,
+ pTypeDescr ,
+ pRemoteMapping->pEnvUno,
+ pRemoteMapping->pEnvRemote);
+
+ pRemoteMapping->pEnvUno->pExtEnv->registerProxyInterface(
+ pRemoteMapping->pEnvUno->pExtEnv,
+ ppUnoI,
+ freeRemote2UnoProxy,
+ pOid,
+ pTypeDescr );
+
+ OSL_ASSERT( *ppUnoI );
+ }
+ rtl_uString_release( pOid );
+ }
+}
+
+void unoToRemote( uno_Mapping *pMapping, void **ppRemoteI, void *pUnoI,
+ typelib_InterfaceTypeDescription *pTypeDescr )
+{
+ remote_Mapping *pRemoteMapping = ( remote_Mapping * ) pMapping;
+ OSL_ASSERT( ppRemoteI && pTypeDescr );
+ if (*ppRemoteI)
+ {
+ ((remote_Interface *)*ppRemoteI)->release( (remote_Interface *)*ppRemoteI);
+ *ppRemoteI = 0;
+ }
+ if (pUnoI && pTypeDescr)
+ {
+ // get object id of interface to be wrapped
+ rtl_uString * pOid = 0;
+ pRemoteMapping->pEnvUno->pExtEnv->getObjectIdentifier(
+ pRemoteMapping->pEnvUno->pExtEnv,
+ &pOid,
+ pUnoI );
+
+ OSL_ASSERT( pOid );
+ if( ! pOid )
+ {
+ return;
+ }
+
+ pRemoteMapping->pEnvRemote->pExtEnv->getRegisteredInterface(
+ pRemoteMapping->pEnvRemote->pExtEnv,
+ (void**)ppRemoteI,
+ pOid,
+ pTypeDescr );
+
+ if( !*ppRemoteI )
+ {
+ // try to publish a new proxy;
+ *ppRemoteI = new Uno2RemoteStub(
+ ( uno_Interface * ) pUnoI,
+ pOid,
+ pTypeDescr,
+ pRemoteMapping->pEnvUno,
+ pRemoteMapping->pEnvRemote );
+
+ // note : ppRemoteI may change during registration
+ pRemoteMapping->pEnvRemote->pExtEnv->registerProxyInterface(
+ pRemoteMapping->pEnvRemote->pExtEnv,
+ (void**) ppRemoteI,
+ freeUno2RemoteStub,
+ pOid,
+ pTypeDescr );
+ }
+
+ rtl_uString_release( pOid );
+ }
+}
+
+void freeRemoteMapping(uno_Mapping * mapping) {
+ delete reinterpret_cast< RemoteMapping * >(mapping);
+}
+
+RemoteMapping::RemoteMapping( uno_Environment *pEnvUno_ ,
+ uno_Environment *pEnvRemote_,
+ uno_MapInterfaceFunc func,
+ const ::rtl::OUString sPurpose) :
+ m_nRef( 1 ),
+ m_sPurpose( sPurpose )
+{
+ pEnvUno = pEnvUno_;
+ pEnvRemote = pEnvRemote_;
+
+ pEnvUno->acquire( pEnvUno );
+ pEnvRemote->acquire( pEnvRemote );
+
+ aBase.mapInterface = func;
+ aBase.acquire = thisAcquire;
+ aBase.release = thisRelease;
+}
+
+RemoteMapping::~RemoteMapping( )
+{
+ pEnvUno->release( pEnvUno );
+ pEnvRemote->release( pEnvRemote );
+}
+
+}
diff --git a/bridges/source/remote/static/proxy.cxx b/bridges/source/remote/static/proxy.cxx
new file mode 100644
index 000000000000..6f07ba95d6ff
--- /dev/null
+++ b/bridges/source/remote/static/proxy.cxx
@@ -0,0 +1,347 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: proxy.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#if OSL_DEBUG_LEVEL == 0
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+#include <sal/alloca.h>
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/context.h>
+
+#include <uno/data.h>
+#include <uno/mapping.hxx>
+#include <uno/environment.h>
+
+#include <com/sun/star/uno/Any.hxx>
+
+#include <bridges/remote/bridgeimpl.hxx>
+
+#include "remote_types.hxx"
+
+#if OSL_DEBUG_LEVEL > 1
+#include <bridges/remote/counter.hxx>
+static MyCounter thisCounter( "DEBUG : Remote2UnoProxy");
+#endif
+
+using namespace ::bridges_remote;
+using namespace ::com::sun::star::uno;
+
+extern "C" {
+
+void SAL_CALL remote_release( void *pRemoteI )
+{
+ ((remote_Interface * )pRemoteI)->release( (remote_Interface * ) pRemoteI );
+}
+
+}
+
+namespace bridges_remote {
+
+void freeRemote2UnoProxy(uno_ExtEnvironment *, void * proxy) {
+ delete static_cast< Remote2UnoProxy * >(proxy);
+}
+
+void acquireRemote2UnoProxy( uno_Interface *pThis )
+{
+ Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis;
+ if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
+ {
+ p->m_pEnvUno->pExtEnv->registerProxyInterface(
+ p->m_pEnvUno->pExtEnv,
+ (void**)&pThis,
+ freeRemote2UnoProxy,
+ p->m_sOid.pData,
+ p->m_pType );
+ assert( (uno_Interface *)p == pThis );
+ }
+}
+
+void releaseRemote2UnoProxy( uno_Interface *pThis )
+{
+ Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis;
+ if ( 0 == osl_decrementInterlockedCount( &(p->m_nRef) ))
+ {
+ p->m_pEnvUno->pExtEnv->revokeInterface( p->m_pEnvUno->pExtEnv, p );
+ }
+}
+
+void SAL_CALL dispatchRemote2UnoProxy(
+ uno_Interface * pUnoI,
+ typelib_TypeDescription const * pType,
+ void * pReturn,
+ void * ppArgs[],
+ uno_Any ** ppException )
+{
+ Remote2UnoProxy *p = ( Remote2UnoProxy * ) pUnoI;
+ RemoteThreadCounter counter( p->m_pEnvRemote );
+
+ typelib_InterfaceMethodTypeDescription *pMethodType = 0;
+ typelib_InterfaceAttributeTypeDescription *pAttributeType = 0;
+ typelib_TypeDescription *pReturnType = 0;
+ typelib_TypeDescription **ppArgType = 0;
+ sal_Int32 nArgCount = 0;
+ sal_Bool *pbIsIn = 0;
+ sal_Bool *pbIsOut = 0;
+ sal_Bool *pbConversionNeeded = 0;
+ sal_Bool bConversionNeededForReturn = 0;
+
+ //--------------------------------
+ // Collect all needed types !
+ //--------------------------------
+ if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pType->eTypeClass )
+ {
+ pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pType;
+ if( pReturn )
+ {
+ TYPELIB_DANGER_GET( &pReturnType , pAttributeType->pAttributeTypeRef );
+ bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
+ }
+ else
+ {
+ nArgCount = 1;
+ ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) );
+ pbIsIn = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
+ pbIsOut = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
+ pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) );
+
+ pbIsIn[0] = sal_True;
+ pbIsOut[0] = sal_False;
+ ppArgType[0] = 0;
+ TYPELIB_DANGER_GET( &( ppArgType[0] ) , pAttributeType->pAttributeTypeRef );
+ pbConversionNeeded[0] = remote_relatesToInterface( ppArgType[0] );
+
+ }
+ }
+ if( typelib_TypeClass_INTERFACE_METHOD == pType->eTypeClass )
+ {
+ pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pType;
+ TYPELIB_DANGER_GET( &pReturnType , pMethodType->pReturnTypeRef );
+ bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
+ nArgCount = pMethodType->nParams;
+ ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) * nArgCount );
+ pbIsIn = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
+ pbIsOut = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
+ pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) * nArgCount );
+ sal_Int32 i;
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ ppArgType[i] = 0;
+ TYPELIB_DANGER_GET( & (ppArgType[i]) , pMethodType->pParams[i].pTypeRef );
+ pbIsIn[i] = pMethodType->pParams[i].bIn;
+ pbIsOut[i] = pMethodType->pParams[i].bOut;
+ pbConversionNeeded[i] = remote_relatesToInterface( ppArgType[i] );
+ }
+ }
+
+ void *pRemoteReturn = 0;
+ if( pReturnType )
+ {
+ if( bConversionNeededForReturn )
+ {
+ pRemoteReturn = alloca( pReturnType->nSize );
+ }
+ else
+ {
+ pRemoteReturn = pReturn;
+ }
+ }
+
+ void ** ppRemoteArgs = 0;
+ if( nArgCount )
+ {
+ ppRemoteArgs = (void**) alloca( sizeof( void * ) * nArgCount );
+ }
+
+ sal_Int32 i;
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ if( pbConversionNeeded[i] )
+ {
+ ppRemoteArgs[i] = alloca( ppArgType[i]->nSize );
+
+ if( pbIsIn[i] ) {
+ uno_copyAndConvertData(
+ ppRemoteArgs[i],
+ ppArgs[i],
+ ppArgType[i],
+ p->m_mapUno2Remote.get() );
+ }
+ }
+ else
+ {
+ ppRemoteArgs[i] = ppArgs[i];
+ }
+ }
+
+ uno_Any any;
+ uno_Any *pAny = &any;
+
+ p->m_pRemoteI->pDispatcher( p->m_pRemoteI,
+ pType,
+ pRemoteReturn,
+ ppRemoteArgs,
+ &pAny );
+
+ if( ! pAny )
+ {
+ if( pReturn && bConversionNeededForReturn )
+ {
+ uno_copyAndConvertData(
+ pReturn ,
+ pRemoteReturn,
+ pReturnType,
+ p->m_mapRemote2Uno.get() );
+ uno_destructData( pRemoteReturn , pReturnType , remote_release );
+ }
+
+ sal_Int32 j;
+ for( j = 0 ; j < nArgCount ; j ++ )
+ {
+ if( pbConversionNeeded[j] )
+ {
+ if( pbIsIn[j] ) {
+ if( pbIsOut[j] ) {
+ uno_destructData( ppArgs[j] ,
+ ppArgType[j] ,
+ 0 );
+ uno_copyAndConvertData( ppArgs[j] ,
+ ppRemoteArgs[j],
+ ppArgType[j],
+ p->m_mapRemote2Uno.get() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( ppArgs[j] ,
+ ppRemoteArgs[j],
+ ppArgType[j],
+ p->m_mapRemote2Uno.get() );
+ }
+ uno_destructData( ppRemoteArgs[j],
+ ppArgType[j],
+ remote_release );
+ }
+ }
+ *ppException = 0;
+ }
+ else
+ {
+ // -----------------------
+ // an exception occured
+ // -----------------------
+ typelib_TypeDescription *pAnyType = 0;
+ getCppuType( (::com::sun::star::uno::Any*) 0 ).getDescription( &pAnyType );
+ uno_copyAndConvertData( *ppException ,
+ pAny ,
+ pAnyType,
+ p->m_mapRemote2Uno.get() );
+ uno_destructData( pAny , pAnyType , remote_release );
+ typelib_typedescription_release( pAnyType );
+
+ // destruct remote in parameters ( out parameters have not been constructed )
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ if( pbConversionNeeded[i] && pbIsIn[i] )
+ {
+ uno_destructData( ppRemoteArgs[i],
+ ppArgType[i],
+ remote_release );
+ }
+ }
+ }
+
+ //--------------------------
+ // release all acquired types
+ //--------------------------
+ if( pReturnType )
+ {
+ TYPELIB_DANGER_RELEASE( pReturnType );
+ }
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ TYPELIB_DANGER_RELEASE( ppArgType[ i] );
+ }
+
+}
+
+Remote2UnoProxy::Remote2UnoProxy( remote_Interface *pRemoteI,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pType,
+ uno_Environment *pEnvUno,
+ uno_Environment *pEnvRemote ) :
+ m_sOid( pOid ),
+ m_pType( pType ),
+ m_pRemoteI( pRemoteI ),
+ m_pEnvUno( pEnvUno ),
+ m_pEnvRemote( pEnvRemote ),
+ m_mapRemote2Uno( pEnvRemote, pEnvUno ),
+ m_mapUno2Remote( pEnvUno , pEnvRemote ),
+ m_nRef( 1 )
+{
+ typelib_typedescription_acquire( (typelib_TypeDescription * ) m_pType );
+ m_pEnvUno->acquire( m_pEnvUno );
+ m_pEnvRemote->acquire( m_pEnvRemote );
+
+ acquire = acquireRemote2UnoProxy;
+ release = releaseRemote2UnoProxy;
+ pDispatcher = dispatchRemote2UnoProxy;
+
+ m_pEnvRemote->pExtEnv->registerInterface(
+ m_pEnvRemote->pExtEnv,
+ (void**)&m_pRemoteI,
+ m_sOid.pData,
+ m_pType );
+ m_pRemoteI->acquire( m_pRemoteI );
+
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+Remote2UnoProxy::~Remote2UnoProxy()
+{
+ // revoke external ref (oid)
+ m_pEnvRemote->pExtEnv->revokeInterface( m_pEnvRemote->pExtEnv , m_pRemoteI );
+
+ typelib_typedescription_release( (typelib_TypeDescription * )m_pType );
+ m_pRemoteI->release( m_pRemoteI );
+ m_pEnvUno->release( m_pEnvUno );
+ m_pEnvRemote->release( m_pEnvRemote );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+} // end namespace bridge_remote
diff --git a/bridges/source/remote/static/remote.cxx b/bridges/source/remote/static/remote.cxx
new file mode 100644
index 000000000000..1cb26b4ccd9c
--- /dev/null
+++ b/bridges/source/remote/static/remote.cxx
@@ -0,0 +1,170 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: remote.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#if OSL_DEBUG_LEVEL == 0
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+#include <bridges/remote/remote.hxx>
+#include <bridges/remote/counter.hxx>
+
+#if OSL_DEBUG_LEVEL > 1
+static MyCounter thisCounter( "DEBUG : Remote2RemoteStub");
+#endif
+
+using namespace bridges_remote;
+
+extern "C" {
+
+static void SAL_CALL thisRelease( remote_Interface *pThis )
+{
+ Remote2RemoteStub *p = ( Remote2RemoteStub * ) pThis;
+ if (! osl_decrementInterlockedCount( &(p->m_nRef) ))
+ {
+ p->m_pEnvRemote->pExtEnv->revokeInterface( p->m_pEnvRemote->pExtEnv, pThis );
+
+ }
+}
+
+static void SAL_CALL thisDispatch(
+ remote_Interface * pRemoteI,
+ typelib_TypeDescription const * pMemberType,
+ void * pReturn,
+ void * pArgs[],
+ uno_Any ** ppException )
+{
+ Remote2RemoteStub *pThis = ( Remote2RemoteStub * ) pRemoteI;
+
+ pThis->m_dispatch( pThis->m_pEnvRemote,
+ pMemberType,
+ pThis->m_sOid.pData,
+ pThis->m_pType,
+ pReturn,
+ pArgs,
+ ppException );
+}
+
+}
+
+namespace bridges_remote {
+
+void acquireRemote2RemoteStub( remote_Interface *pThis )
+{
+ Remote2RemoteStub *p = ( Remote2RemoteStub * ) pThis;
+ if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
+ {
+ p->m_pEnvRemote->pExtEnv->registerProxyInterface(
+ p->m_pEnvRemote->pExtEnv,
+ (void**)&pThis,
+ freeRemote2RemoteStub,
+ p->m_sOid.pData,
+ p->m_pType );
+ assert( (remote_Interface *)p == pThis );
+ }
+}
+
+void freeRemote2RemoteStub(uno_ExtEnvironment *, void * stub) {
+ delete static_cast< Remote2RemoteStub * >(stub);
+}
+
+Remote2RemoteStub::Remote2RemoteStub( rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pType,
+ uno_Environment *pEnvRemote,
+ requestClientSideDispatcher dispatch ) :
+ m_sOid( pOid ),
+ m_pType( (typelib_InterfaceTypeDescription * ) pType ),
+ m_nRef( 1 ),
+ m_pEnvRemote( pEnvRemote ),
+ m_dispatch( dispatch ),
+ m_nReleaseRemote( 1 )
+{
+ typelib_typedescription_acquire( ( typelib_TypeDescription * ) m_pType );
+ m_pEnvRemote->acquire( m_pEnvRemote );
+
+ acquire = acquireRemote2RemoteStub;
+ release = thisRelease;
+ pDispatcher = thisDispatch;
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+Remote2RemoteStub::~Remote2RemoteStub()
+{
+
+ // send a release via the connection !
+ sal_Bool bNeedsRelease = sal_False;
+ if( ! m_pType->aBase.bComplete )
+ {
+ // m_pType may be exchanged during complete, so it needs to be acquired
+ // (MT : Another thread may use m_pType during e.g. dispatch ! ).
+ typelib_typedescription_acquire( (typelib_TypeDescription*)m_pType );
+ bNeedsRelease = sal_True;
+ typelib_typedescription_complete( (typelib_TypeDescription **) &m_pType );
+ }
+
+ uno_Any any;
+ uno_Any *pAny = &any;
+
+ typelib_TypeDescription *pReleaseMethod = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pReleaseMethod ,
+ m_pType->ppAllMembers[REMOTE_RELEASE_METHOD_INDEX] );
+ for( int i = 0 ; i < m_nReleaseRemote ; i ++ )
+ {
+ thisDispatch( this,
+ pReleaseMethod,
+ 0,
+ 0,
+ &pAny );
+ }
+ typelib_typedescription_release( pReleaseMethod );
+ if( bNeedsRelease )
+ {
+ typelib_typedescription_release( (typelib_TypeDescription * ) m_pType );
+ }
+
+ typelib_typedescription_release( (typelib_TypeDescription * ) m_pType );
+ m_pEnvRemote->release( m_pEnvRemote );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+void Remote2RemoteStub::releaseRemote()
+{
+ osl_incrementInterlockedCount( &m_nReleaseRemote );
+}
+
+} // end namespace bridges_remote
diff --git a/bridges/source/remote/static/remote_types.cxx b/bridges/source/remote/static/remote_types.cxx
new file mode 100644
index 000000000000..d2c8b17516de
--- /dev/null
+++ b/bridges/source/remote/static/remote_types.cxx
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: remote_types.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include "remote_types.hxx"
+
+namespace bridges_remote {
+
+sal_Bool SAL_CALL remote_relatesToInterface2( typelib_TypeDescription * pTypeDescr )
+{
+ switch (pTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_SEQUENCE:
+ {
+ switch (((typelib_IndirectTypeDescription *)pTypeDescr)->pType->eTypeClass)
+ {
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType );
+ sal_Bool bRel = remote_relatesToInterface( pTD );
+ TYPELIB_DANGER_RELEASE( pTD );
+ return bRel;
+ }
+ default:
+ break;
+ }
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ // ...optimized... to avoid getDescription() calls!
+ typelib_CompoundTypeDescription * pComp = (typelib_CompoundTypeDescription *)pTypeDescr;
+ typelib_TypeDescriptionReference ** pTypes = pComp->ppTypeRefs;
+ for ( sal_Int32 nPos = pComp->nMembers; nPos--; )
+ {
+ switch (pTypes[nPos]->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE:
+ case typelib_TypeClass_UNION: // might relate to interface
+ case typelib_TypeClass_ANY: // might relate to interface
+ return sal_True;
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, pTypes[nPos] );
+ sal_Bool bRel = remote_relatesToInterface( pTD );
+ TYPELIB_DANGER_RELEASE( pTD );
+ if (bRel)
+ return sal_True;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ if (pComp->pBaseTypeDescription)
+ return remote_relatesToInterface( (typelib_TypeDescription *)pComp->pBaseTypeDescription );
+ break;
+ }
+ default:
+ OSL_ASSERT( 0 );
+ }
+ return sal_False;
+}
+
+}
diff --git a/bridges/source/remote/static/remote_types.hxx b/bridges/source/remote/static/remote_types.hxx
new file mode 100644
index 000000000000..b6276f51a55a
--- /dev/null
+++ b/bridges/source/remote/static/remote_types.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: remote_types.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _BRIDGES_REMOTE_TYPES_HXX_
+#define _BRIDGES_REMOTE_TYPES_HXX_
+
+#include <osl/diagnose.h>
+#include <sal/types.h>
+#include <typelib/typedescription.h>
+
+namespace bridges_remote
+{
+
+inline sal_Bool SAL_CALL remote_relatesToInterface( typelib_TypeDescription *pTypeDescr );
+sal_Bool SAL_CALL remote_relatesToInterface2( typelib_TypeDescription * pTypeDescr );
+
+
+/** Determines whether given type might relate or relates to an interface,
+ i.e. values of this type are interface or may contain interface(s).<br>
+ @param pTypeDescr type description of type
+ @return true if type might relate to an interface, false otherwise
+*/
+inline sal_Bool SAL_CALL remote_relatesToInterface( typelib_TypeDescription * pTypeDescr )
+{
+ switch (pTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_SEQUENCE:
+ switch (((typelib_IndirectTypeDescription *)pTypeDescr)->pType->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE:
+ case typelib_TypeClass_UNION: // might relate to interface
+ case typelib_TypeClass_ANY: // might relate to interface
+ return sal_True;
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ return remote_relatesToInterface2( pTypeDescr );
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ return remote_relatesToInterface2( pTypeDescr );
+ case typelib_TypeClass_UNION: // might relate to interface
+ case typelib_TypeClass_ANY: // might relate to interface
+ case typelib_TypeClass_INTERFACE:
+ return sal_True;
+ default:
+ return sal_False;
+ }
+}
+
+/** Determines whether given type is a cpp simple type, e.g. int, enum.<br>
+ @param pTypeDescr type description of type
+ @return true if type is a cpp simple type, false otherwise
+*/
+inline sal_Bool SAL_CALL remote_isSimpleType( typelib_TypeDescription * pTypeDescr )
+{
+ return (pTypeDescr->eTypeClass <= typelib_TypeClass_ENUM &&
+ pTypeDescr->eTypeClass != typelib_TypeClass_STRING &&
+ pTypeDescr->eTypeClass != typelib_TypeClass_ANY &&
+ pTypeDescr->eTypeClass != typelib_TypeClass_TYPE);
+}
+
+}
+#endif
diff --git a/bridges/source/remote/static/stub.cxx b/bridges/source/remote/static/stub.cxx
new file mode 100644
index 000000000000..471d564fc219
--- /dev/null
+++ b/bridges/source/remote/static/stub.cxx
@@ -0,0 +1,339 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: stub.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <sal/alloca.h>
+#include <osl/diagnose.h>
+
+#include <uno/data.h>
+#include <uno/mapping.hxx>
+
+#include <bridges/remote/stub.hxx>
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/context.h>
+#include <bridges/remote/bridgeimpl.hxx>
+
+#include "remote_types.hxx"
+
+#if OSL_DEBUG_LEVEL > 1
+#include <bridges/remote/counter.hxx>
+static MyCounter thisCounter( "DEBUG : Uno2RemoteStub");
+#endif
+
+using namespace ::com::sun::star::uno;
+using namespace bridges_remote;
+
+extern "C" {
+
+void SAL_CALL thisRelease( remote_Interface *pThis )
+{
+ Uno2RemoteStub *p = ( Uno2RemoteStub * ) pThis;
+ if (! osl_decrementInterlockedCount( &(p->m_nRef) ))
+ {
+ p->m_pEnvRemote->pExtEnv->revokeInterface( p->m_pEnvRemote->pExtEnv, pThis );
+ }
+}
+
+void SAL_CALL thisDispatch(
+ remote_Interface * pRemoteI,
+ typelib_TypeDescription const * pType,
+ void * pReturn,
+ void * ppArgs[],
+ uno_Any ** ppException )
+{
+ Uno2RemoteStub *p = ( Uno2RemoteStub * ) pRemoteI;
+
+ RemoteThreadCounter counter( p->m_pEnvRemote );
+
+ typelib_InterfaceMethodTypeDescription *pMethodType = 0;
+ typelib_InterfaceAttributeTypeDescription *pAttributeType = 0;
+ typelib_TypeDescription *pReturnType = 0;
+ typelib_TypeDescription **ppArgType = 0;
+ sal_Int32 nArgCount = 0;
+ sal_Bool *pbIsIn = 0;
+ sal_Bool *pbIsOut = 0;
+ sal_Bool bConversionNeededForReturn = sal_False;
+ sal_Bool *pbConversionNeeded = 0;
+
+ sal_Int32 i;
+ //--------------------------------
+ // Collect all needed types !
+ //--------------------------------
+ if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pType->eTypeClass )
+ {
+ pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pType;
+ if( pReturn )
+ {
+ TYPELIB_DANGER_GET( &pReturnType , pAttributeType->pAttributeTypeRef );
+ bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
+ }
+ else
+ {
+ nArgCount = 1;
+ ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) );
+ pbIsIn = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
+ pbIsOut = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
+ pbConversionNeeded = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
+ pbIsIn[0] = sal_True;
+ pbIsOut[0] = sal_False;
+ ppArgType[0] = 0;
+ TYPELIB_DANGER_GET( &( ppArgType[0] ) , pAttributeType->pAttributeTypeRef );
+ pbConversionNeeded[0] = remote_relatesToInterface( ppArgType[0] );
+ }
+ }
+ if( typelib_TypeClass_INTERFACE_METHOD == pType->eTypeClass )
+ {
+ pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pType;
+ TYPELIB_DANGER_GET( &pReturnType , pMethodType->pReturnTypeRef );
+ bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
+ nArgCount = pMethodType->nParams;
+ ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) * nArgCount );
+ pbIsIn = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
+ pbIsOut = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
+ pbConversionNeeded = ( sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
+
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ ppArgType[i] = 0;
+ TYPELIB_DANGER_GET( & (ppArgType[i]) , pMethodType->pParams[i].pTypeRef );
+ pbIsIn[i] = pMethodType->pParams[i].bIn;
+ pbIsOut[i] = pMethodType->pParams[i].bOut;
+ pbConversionNeeded[i] = remote_relatesToInterface( ppArgType[i] );
+ }
+ }
+
+ // create Mapping
+
+ void *pUnoReturn = 0;
+ void **ppUnoArgs = 0;
+
+ if( pReturnType )
+ {
+ if( bConversionNeededForReturn )
+ {
+ pUnoReturn = alloca( pReturnType->nSize );
+ }
+ else
+ {
+ pUnoReturn = pReturn;
+ }
+ }
+
+ ppUnoArgs = (void **) alloca( nArgCount * sizeof( void * ) );
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ if( pbConversionNeeded[i] )
+ {
+ ppUnoArgs[i] = alloca( ppArgType[i]->nSize );
+ if( pbIsIn[i] )
+ {
+ uno_copyAndConvertData(
+ ppUnoArgs[i],
+ ppArgs[i],
+ ppArgType[i],
+ p->m_mapRemote2Uno.get()
+ );
+ }
+ }
+ else
+ {
+ ppUnoArgs[i] = ppArgs[i];
+ }
+ }
+
+ // do the call
+ uno_Any any;
+ uno_Any *pAny = &any;
+
+ p->m_pUnoI->pDispatcher( p->m_pUnoI,
+ pType,
+ pUnoReturn,
+ ppUnoArgs,
+ &pAny);
+
+ if( ! pAny )
+ {
+ // ------------------
+ // No Exception
+ // ------------------
+
+ // Map return value
+ if( pReturnType && bConversionNeededForReturn )
+ {
+ uno_copyAndConvertData(
+ pReturn ,
+ pUnoReturn,
+ pReturnType,
+ p->m_mapUno2Remote.get() );
+ uno_destructData( pUnoReturn , pReturnType, 0 );
+ }
+
+ // map arguments
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ if( pbConversionNeeded[i] )
+ {
+ if( pbIsIn[i] ) {
+ if( pbIsOut[i] ) {
+ uno_destructData(
+ ppArgs[i] ,
+ ppArgType[i] ,
+ remote_release );
+ uno_copyAndConvertData( ppArgs[i] ,
+ ppUnoArgs[i],
+ ppArgType[i],
+ p->m_mapUno2Remote.get() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( ppArgs[i] ,
+ ppUnoArgs[i],
+ ppArgType[i],
+ p->m_mapUno2Remote.get() );
+ }
+ uno_destructData( ppUnoArgs[i],
+ ppArgType[i],
+ 0 );
+ }
+ }
+ *ppException = 0;
+ }
+ else
+ {
+ // -----------------------
+ // an exception occured
+ // -----------------------
+ typelib_TypeDescription *pAnyType = 0;
+ getCppuType( (Any*) 0 ).getDescription( &pAnyType );
+ uno_copyAndConvertData( *ppException ,
+ pAny ,
+ pAnyType,
+ p->m_mapUno2Remote.get() );
+ uno_destructData( pAny , pAnyType , 0 );
+ typelib_typedescription_release( pAnyType );
+
+ // destruct uno in parameters ( out parameters have not been constructed )
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ if( pbConversionNeeded[i] && pbIsIn[i] )
+ {
+ uno_destructData( ppUnoArgs[i],
+ ppArgType[i],
+ 0 );
+ }
+ }
+ }
+
+ //--------------------------
+ // release all acquired types
+ //--------------------------
+ if( pReturnType )
+ {
+ TYPELIB_DANGER_RELEASE( pReturnType );
+ }
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ TYPELIB_DANGER_RELEASE( ppArgType[ i] );
+ }
+}
+
+}
+
+namespace bridges_remote {
+
+void acquireUno2RemoteStub( remote_Interface *pThis )
+{
+ Uno2RemoteStub *p = ( Uno2RemoteStub * ) pThis;
+ if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
+ {
+
+ p->m_pEnvRemote->pExtEnv->registerProxyInterface(
+ p->m_pEnvRemote->pExtEnv,
+ (void**)&pThis,
+ freeUno2RemoteStub,
+ p->m_sOid.pData,
+ p->m_pType );
+
+ OSL_ASSERT( (remote_Interface*) p == pThis );
+ }
+}
+
+void freeUno2RemoteStub(uno_ExtEnvironment *, void * stub) {
+ delete static_cast< Uno2RemoteStub * >(stub);
+}
+
+Uno2RemoteStub::Uno2RemoteStub( uno_Interface *pUnoI,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pType,
+ uno_Environment *pEnvUno,
+ uno_Environment *pEnvRemote ) :
+ m_sOid( pOid ),
+ m_pType( pType ),
+ m_pUnoI( pUnoI ),
+ m_nRef( 1 ),
+ m_pEnvUno( pEnvUno ),
+ m_pEnvRemote( pEnvRemote ),
+ m_mapRemote2Uno( pEnvRemote, pEnvUno ),
+ m_mapUno2Remote( pEnvUno, pEnvRemote )
+{
+ typelib_typedescription_acquire( (typelib_TypeDescription * )m_pType );
+ m_pEnvUno->acquire( m_pEnvUno );
+ m_pEnvRemote->acquire( m_pEnvRemote );
+
+ acquire = acquireUno2RemoteStub;
+ release = thisRelease;
+ pDispatcher = thisDispatch;
+
+ m_pEnvUno->pExtEnv->registerInterface( m_pEnvUno->pExtEnv,
+ (void **)&m_pUnoI,
+ m_sOid.pData,
+ m_pType );
+ m_pUnoI->acquire( m_pUnoI );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+Uno2RemoteStub::~Uno2RemoteStub()
+{
+ m_pEnvUno->pExtEnv->revokeInterface( m_pEnvUno->pExtEnv , m_pUnoI );
+
+ typelib_typedescription_release( (typelib_TypeDescription * )m_pType );
+ m_pUnoI->release( m_pUnoI );
+ m_pEnvUno->release( m_pEnvUno );
+ m_pEnvRemote->release( m_pEnvRemote );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+} // end namespace bridges_remote
diff --git a/bridges/source/remote/urp/makefile.mk b/bridges/source/remote/urp/makefile.mk
new file mode 100644
index 000000000000..ca550f3a1a3b
--- /dev/null
+++ b/bridges/source/remote/urp/makefile.mk
@@ -0,0 +1,82 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.21 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=urp_uno
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/urp_environment.obj \
+ $(SLO)$/urp_marshal.obj \
+ $(SLO)$/urp_unmarshal.obj \
+ $(SLO)$/urp_dispatch.obj \
+ $(SLO)$/urp_job.obj \
+ $(SLO)$/urp_reader.obj \
+ $(SLO)$/urp_writer.obj \
+ $(SLO)$/urp_log.obj \
+ $(SLO)$/urp_bridgeimpl.obj \
+ $(SLO)$/urp_propertyobject.obj \
+ $(SLO)$/urp_threadid.obj
+
+.IF "$(COM)"=="GCC"
+NOOPTFILES= \
+ $(SLO)$/urp_reader.obj
+.ENDIF # "$(COM)"=="GCC"
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1STDLIBS=\
+ $(SALLIB)\
+ $(CPPULIB)
+
+SHL1LIBS=\
+ $(SLB)$/$(TARGET).lib \
+ $(SLB)$/bridges_remote_static.lib
+
+DEF1NAME= $(SHL1TARGET)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/remote/urp/urp_bridgeimpl.cxx b/bridges/source/remote/urp/urp_bridgeimpl.cxx
new file mode 100644
index 000000000000..7ff2f6874861
--- /dev/null
+++ b/bridges/source/remote/urp/urp_bridgeimpl.cxx
@@ -0,0 +1,253 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_bridgeimpl.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <osl/thread.h>
+#include <bridges/remote/helper.hxx>
+
+#include <algorithm>
+
+#include "urp_bridgeimpl.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+namespace bridges_urp
+{
+
+template < class t >
+inline t mymin( const t & val1, const t & val2 )
+{
+ return val1 < val2 ? val1 : val2;
+}
+
+/***********
+ * urp_BridgeImpl
+ ***********/
+urp_BridgeImpl::urp_BridgeImpl( sal_Int32 nCacheSize , sal_uInt32 nInitialMarshalerSize ) :
+ m_blockMarshaler( this , nInitialMarshalerSize , ::bridges_remote::remote_retrieveOidFromProxy),
+ m_nMarshaledMessages( 0 ),
+ m_oidCacheOut( (sal_uInt16)nCacheSize ),
+ m_tidCacheOut( (sal_uInt16)nCacheSize ),
+ m_typeCacheOut( (sal_uInt16)nCacheSize )
+{
+ m_pOidIn = new OUString[ nCacheSize ];
+ m_pTidIn = new ByteSequence[ nCacheSize ];
+ m_pTypeIn = new Type[ nCacheSize ];
+ m_nRemoteThreads = 0;
+}
+
+urp_BridgeImpl::~urp_BridgeImpl()
+{
+ delete [] m_pOidIn;
+ delete [] m_pTidIn;
+ delete [] m_pTypeIn;
+}
+
+
+void urp_BridgeImpl::applyProtocolChanges( const Properties &props )
+{
+ if( m_properties.nTypeCacheSize != props.nTypeCacheSize )
+ {
+ if( props.nTypeCacheSize == 0 )
+ {
+ delete [] m_pTypeIn;
+ m_pTypeIn = 0;
+ }
+ else
+ {
+ Type *pNew = new Type[props.nTypeCacheSize];
+ sal_Int32 i;
+ sal_Int32 iMin = mymin( m_properties.nTypeCacheSize , props.nTypeCacheSize );
+ for( i = 0; i < iMin ; i ++ )
+ {
+ pNew[i] = m_pTypeIn[i];
+ }
+ delete [] m_pTypeIn;
+ m_pTypeIn = pNew;
+ }
+ OSL_ASSERT( props.nTypeCacheSize <= 0xffff );
+ m_properties.nTypeCacheSize = props.nTypeCacheSize;
+ m_typeCacheOut.resize( (sal_uInt16)props.nTypeCacheSize );
+ }
+
+ if( m_properties.nOidCacheSize != props.nOidCacheSize )
+ {
+ if( 0 == props.nOidCacheSize )
+ {
+ delete [] m_pOidIn;
+ m_pOidIn = 0;
+ }
+ else
+ {
+ OUString *pNew = new OUString[props.nOidCacheSize];
+ sal_Int32 i;
+ sal_Int32 iMin = mymin( m_properties.nOidCacheSize , props.nOidCacheSize );
+ for( i = 0; i < iMin ; i ++ )
+ {
+ pNew[i] = m_pOidIn[i];
+ }
+ delete [] m_pOidIn;
+ m_pOidIn = pNew;
+ }
+ OSL_ASSERT( props.nOidCacheSize <= 0xffff );
+ m_oidCacheOut.resize( (sal_uInt16)props.nOidCacheSize );
+ m_properties.nOidCacheSize = props.nOidCacheSize;
+ }
+
+ if( m_properties.nTidCacheSize != props.nTidCacheSize )
+ {
+ if( 0 == props.nTidCacheSize )
+ {
+ delete [] m_pTidIn;
+ m_pTidIn = 0;
+ }
+ else
+ {
+ ByteSequence *pNew = new ByteSequence[props.nTidCacheSize];
+ sal_Int32 i;
+ sal_Int32 iMin = mymin( m_properties.nTidCacheSize , props.nTidCacheSize );
+ for( i = 0; i < iMin ; i ++ )
+ {
+ pNew[i] = m_pTidIn[i];
+ }
+ delete [] m_pTidIn;
+ m_pTidIn = pNew;
+ }
+ OSL_ASSERT( props.nTidCacheSize <= 0xffff );
+ m_tidCacheOut.resize( (sal_uInt16)props.nTidCacheSize );
+ m_properties.nTidCacheSize = props.nTidCacheSize;
+ }
+
+ if( m_properties.sVersion != props.sVersion )
+ {
+ m_properties.sVersion = props.sVersion;
+ }
+
+ if( m_properties.nFlushBlockSize != props.nFlushBlockSize )
+ {
+ m_properties.nFlushBlockSize = props.nFlushBlockSize;
+ }
+
+ if( m_properties.nOnewayTimeoutMUSEC != props.nOnewayTimeoutMUSEC )
+ {
+ m_properties.nOnewayTimeoutMUSEC = props.nOnewayTimeoutMUSEC;
+ }
+
+ if( props.bClearCache )
+ {
+ if( m_properties.nTypeCacheSize )
+ {
+ delete [] m_pTypeIn;
+ m_pTypeIn = new Type[m_properties.nTypeCacheSize];
+ m_typeCacheOut.clear();
+ }
+ m_lastInType = Type();
+ m_lastOutType = Type();
+
+ if( m_properties.nOidCacheSize )
+ {
+ delete [] m_pOidIn;
+ m_pOidIn = new OUString[ m_properties.nOidCacheSize];
+ m_oidCacheOut.clear();
+ }
+ m_lastOutOid = OUString();
+ m_lastInOid = OUString();
+
+ if( m_properties.nTidCacheSize )
+ {
+ delete [] m_pTidIn;
+ m_pTidIn = new ByteSequence[m_properties.nTidCacheSize];
+ m_tidCacheOut.clear();
+ }
+ m_lastInTid = ByteSequence();
+ m_lastOutTid = ByteSequence();
+ }
+
+ if( m_properties.bNegotiate != props.bNegotiate )
+ {
+ m_properties.bNegotiate = props.bNegotiate;
+ }
+
+ if( m_properties.bForceSynchronous != props.bForceSynchronous )
+ {
+ m_properties.bForceSynchronous = props.bForceSynchronous;
+ }
+
+ m_properties.bCurrentContext = props.bCurrentContext;
+}
+
+void urp_BridgeImpl::addError( char const *pError )
+{
+ OUString message = OUString( RTL_CONSTASCII_USTRINGPARAM( "(tid=" ) );
+ message += OUString::valueOf( (sal_Int32 ) osl_getThreadIdentifier( 0 ) );
+ message += OUString::createFromAscii( ") " );
+ message += OUString::createFromAscii( pError );
+ MutexGuard guard( m_errorListMutex );
+ m_lstErrors.push_back( message );
+}
+
+void urp_BridgeImpl::addError( const OUString & error )
+{
+ OUString message = OUString( RTL_CONSTASCII_USTRINGPARAM( "(tid=" ) );
+ message += OUString::valueOf( (sal_Int32 ) osl_getThreadIdentifier( 0 ) );
+ message += OUString::createFromAscii( ") " );
+ message += error;
+ MutexGuard guard( m_errorListMutex );
+ m_lstErrors.push_back( message );
+}
+
+void urp_BridgeImpl::dumpErrors( FILE * f)
+{
+ MutexGuard guard( m_errorListMutex );
+ for( ::std::list< OUString >::iterator ii = m_lstErrors.begin() ;
+ ii != m_lstErrors.end() ;
+ ++ii )
+ {
+ OString o = OUStringToOString( *ii , RTL_TEXTENCODING_UTF8 );
+ fprintf( f, "%s\n" , o.getStr() );
+ }
+}
+
+OUString urp_BridgeImpl::getErrorsAsString( )
+{
+ MutexGuard guard( m_errorListMutex );
+ OUString ret;
+ for( ::std::list< OUString >::iterator ii = m_lstErrors.begin() ;
+ ii != m_lstErrors.end() ;
+ ++ii )
+ {
+ ret += *ii;
+ }
+ return ret;
+}
+
+}
diff --git a/bridges/source/remote/urp/urp_bridgeimpl.hxx b/bridges/source/remote/urp/urp_bridgeimpl.hxx
new file mode 100644
index 000000000000..d483ee834a5e
--- /dev/null
+++ b/bridges/source/remote/urp/urp_bridgeimpl.hxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_bridgeimpl.hxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _URP_BRIDGEIMPL_HXX_
+#define _URP_BRIDGEIMPL_HXX_
+
+#include <stdio.h>
+#include <osl/mutex.hxx>
+#include <osl/conditn.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/byteseq.hxx>
+
+#ifndef _UNO_THREADPOOL_H_
+#include <uno/threadpool.h>
+#endif
+#include <bridges/remote/bridgeimpl.hxx>
+
+#ifndef _URP_CACHE_HXX_
+#include "urp_cache.hxx"
+#endif
+#include "urp_marshal_decl.hxx"
+
+#ifndef _URP_REPLYCONTAINER_HXX_
+#include "urp_replycontainer.hxx"
+#endif
+#include "urp_property.hxx"
+
+
+namespace bridges_urp
+{
+
+class PropertyObject;
+
+struct equalOUString
+{
+ sal_Int32 operator() ( const ::rtl::OUString &s1, const ::rtl::OUString &s2 ) const
+ {
+ return s1 == s2;
+ }
+};
+
+struct equalType
+{
+ sal_Int32 operator() ( const ::com::sun::star::uno::Type &t1,
+ const ::com::sun::star::uno::Type &t2 ) const
+ {
+ return t1 == t2;
+ }
+};
+
+class OWriterThread;
+class OReaderThread;
+
+struct urp_BridgeImpl :
+ public remote_BridgeImpl
+{
+ urp_BridgeImpl( sal_Int32 nCacheSize , sal_uInt32 nInitialMarshalerSize );
+ ~urp_BridgeImpl();
+
+ void applyProtocolChanges( const Properties & );
+
+ void startBlockBridge();
+ void stopBlockBridge();
+ void addError( char const *pError );
+ void addError( const ::rtl::OUString &anError );
+ void dumpErrors( FILE *f );
+ ::rtl::OUString getErrorsAsString();
+
+ ::osl::Mutex m_marshalingMutex;
+ ::osl::Mutex m_disposingMutex;
+ ::osl::Mutex m_errorListMutex;
+ Marshal m_blockMarshaler;
+ sal_Int32 m_nMarshaledMessages;
+
+ // Caches for vars, that go from local process to the remote process
+ Cache < ::rtl::OUString , equalOUString > m_oidCacheOut;
+ Cache < ::rtl::ByteSequence , EqualThreadId > m_tidCacheOut;
+ Cache < ::com::sun::star::uno::Type , equalType > m_typeCacheOut;
+
+ ::com::sun::star::uno::Type m_lastOutType;
+ ::rtl::ByteSequence m_lastOutTid;
+ ::rtl::OUString m_lastOutOid;
+
+ // Caches for vars, that come from the remote process to the local process
+ ::rtl::OUString *m_pOidIn;
+ ::rtl::ByteSequence *m_pTidIn;
+ ::com::sun::star::uno::Type *m_pTypeIn;
+
+ ::com::sun::star::uno::Type m_lastInType;
+ ::rtl::ByteSequence m_lastInTid;
+ ::rtl::OUString m_lastInOid;
+
+ urp_ClientJobContainer m_clientJobContainer;
+
+ OWriterThread *m_pWriter;
+ OReaderThread *m_pReader;
+ ::rtl::OString m_sLogFileName;
+ FILE *m_pLogFile;
+ ::osl::Condition m_initialized;
+ ::osl::Condition m_cndWaitForThreads;
+
+ struct Properties m_properties;
+ class PropertyObject *m_pPropertyObject;
+ ::std::list< ::rtl::OUString > m_lstErrors;
+ uno_ThreadPool m_hThreadPool;
+};
+
+
+}
+#endif
diff --git a/bridges/source/remote/urp/urp_cache.h b/bridges/source/remote/urp/urp_cache.h
new file mode 100644
index 000000000000..ea77a77843ca
--- /dev/null
+++ b/bridges/source/remote/urp/urp_cache.h
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_cache.h,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+namespace bridges_urp
+{
+ template < class t , class tequals >
+ class Cache
+ {
+ public:
+ inline Cache ( sal_uInt16 nMaxEntries );
+ inline ~Cache();
+
+ // puts the value t into the cache. Returns then entry,
+ // that is used for this value.
+ inline sal_uInt16 put( const t & );
+
+ // lookup, if there is an entry for this value
+ // returns 0xffff, when value cannot be found in the list
+ inline sal_uInt16 seek( const t & );
+
+ // resizes the cache, conserving overlapping values
+ inline void resize( sal_uInt16 nNewMaxEntries );
+
+ // empties the cache
+ inline void clear();
+ private:
+ t *m_pCache;
+ ::std::list< sal_uInt16 > m_lstLeastRecentlyUsed;
+ sal_uInt16 m_nMaxEntries;
+ sal_uInt16 m_nEntries;
+ };
+}
diff --git a/bridges/source/remote/urp/urp_cache.hxx b/bridges/source/remote/urp/urp_cache.hxx
new file mode 100644
index 000000000000..5702fb387dc5
--- /dev/null
+++ b/bridges/source/remote/urp/urp_cache.hxx
@@ -0,0 +1,163 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_cache.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <stdio.h>
+#include <list>
+#include <algorithm>
+#include <rtl/ustring.hxx>
+
+#include "urp_threadid.hxx"
+#include "urp_cache.h"
+
+namespace bridges_urp
+{
+
+ template < class t , class tequals >
+ inline Cache< t , tequals >::Cache( sal_uInt16 nMaxEntries ) :
+ m_pCache( new t[nMaxEntries] ),
+ m_nMaxEntries( nMaxEntries ),
+ m_nEntries( 0 )
+ {
+
+ }
+
+ template < class t , class tequals >
+ inline Cache< t , tequals >::~Cache( )
+ {
+ delete [] m_pCache;
+ }
+
+
+ template < class t , class tequals >
+ inline sal_uInt16 Cache< t , tequals >::put( const t & value )
+ {
+ if( ! m_nMaxEntries )
+ {
+ return 0xffff;
+ }
+ sal_uInt16 nEntry = 0xffff;
+ if( m_nEntries < m_nMaxEntries )
+ {
+ // cache has still empty places
+ m_pCache[m_nEntries] = value;
+ nEntry = m_nEntries;
+ m_nEntries ++;
+
+ // add it to the cache
+ m_lstLeastRecentlyUsed.push_front( nEntry );
+ }
+ else
+ {
+ // cache is full, remove an element and insert the new one
+ nEntry = m_lstLeastRecentlyUsed.back();
+ m_lstLeastRecentlyUsed.pop_back();
+ m_lstLeastRecentlyUsed.push_front( nEntry );
+
+ m_pCache[nEntry] = value;
+ }
+ return nEntry;
+ }
+
+ template < class t , class tequals >
+ inline sal_uInt16 Cache< t , tequals >::seek( const t & value )
+ {
+ for( ::std::list< sal_uInt16 >::iterator ii = m_lstLeastRecentlyUsed.begin() ;
+ ii != m_lstLeastRecentlyUsed.end() ;
+ ++ ii )
+ {
+ if( value == m_pCache[*ii] )
+ {
+ sal_uInt16 nEntry = *ii;
+ m_lstLeastRecentlyUsed.erase( ii );
+ m_lstLeastRecentlyUsed.push_front( nEntry );
+ return nEntry;
+ }
+ }
+ return 0xffff;
+ }
+
+ // helper predicate for element removal
+ template < class t >
+ struct PredicateOverMax
+ {
+ t m_;
+ inline PredicateOverMax( const t &value ) : m_(value)
+ {}
+ sal_Int32 operator () ( const t &value ) const
+ { return value >= m_; }
+ };
+
+ template < class t, class tequals >
+ inline void Cache < t , tequals >::resize( sal_uInt16 nNewMaxEntries )
+ {
+ if( 0 == nNewMaxEntries )
+ {
+ m_lstLeastRecentlyUsed.clear();
+ delete [] m_pCache;
+ m_pCache = 0;
+ m_nMaxEntries = 0;
+ }
+ else
+ {
+ // allocate
+ t *pNew = new t[nNewMaxEntries];
+ sal_Int32 nMin = nNewMaxEntries < m_nMaxEntries ? nNewMaxEntries : m_nMaxEntries;
+
+ // copy
+ for( sal_Int32 i = 0; i < nMin ; i ++ )
+ {
+ pNew[i] = m_pCache[i];
+ }
+ // delete
+ delete [] m_pCache;
+
+ // assign
+ m_pCache = pNew;
+
+ // remove overlapping lru cache entries
+ ::std::remove_if(m_lstLeastRecentlyUsed.begin(),
+ m_lstLeastRecentlyUsed.end(),
+ PredicateOverMax< sal_Int32 > ( nMin ) );
+ }
+ m_nMaxEntries = nNewMaxEntries;
+ m_nEntries = m_nEntries < m_nMaxEntries ?
+ m_nEntries : m_nMaxEntries;
+ }
+
+ template < class t, class tequals >
+ inline void Cache < t, tequals >:: clear()
+ {
+ for( sal_Int32 i = 0; i < m_nMaxEntries ; i ++ )
+ {
+ m_pCache[i] = t();
+ }
+ m_lstLeastRecentlyUsed.clear();
+ m_nEntries = 0;
+ }
+}
diff --git a/bridges/source/remote/urp/urp_dispatch.cxx b/bridges/source/remote/urp/urp_dispatch.cxx
new file mode 100644
index 000000000000..c5ba6a93140d
--- /dev/null
+++ b/bridges/source/remote/urp/urp_dispatch.cxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_dispatch.cxx,v $
+ * $Revision: 1.17.20.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <sal/alloca.h>
+#include <osl/mutex.hxx>
+#include <osl/diagnose.h>
+
+#include <rtl/alloc.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <uno/mapping.hxx>
+#include <uno/threadpool.h>
+
+#include <bridges/remote/remote.h>
+#include <bridges/remote/stub.hxx>
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/remote.hxx>
+
+#include "urp_bridgeimpl.hxx"
+#include "urp_marshal.hxx"
+#include "urp_dispatch.hxx"
+#include "urp_job.hxx"
+#include "urp_writer.hxx"
+#include "urp_log.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+
+namespace bridges_urp
+{
+
+void SAL_CALL urp_sendCloseConnection( uno_Environment *pEnvRemote )
+{
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = (urp_BridgeImpl*) ( pContext->m_pBridgeImpl );
+
+ {
+ MutexGuard guard( pImpl->m_marshalingMutex );
+
+ // send immediately
+ if( ! pImpl->m_blockMarshaler.empty() )
+ {
+ pImpl->m_pWriter->touch( sal_True );
+ }
+
+ pImpl->m_pWriter->sendEmptyMessage();
+ }
+}
+extern "C" void SAL_CALL urp_sendRequest(
+ uno_Environment *pEnvRemote,
+ typelib_TypeDescription const * pMemberType,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException )
+{
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = (urp_BridgeImpl*) ( pContext->m_pBridgeImpl );
+ pImpl->m_initialized.wait();
+ urp_sendRequest_internal(
+ pEnvRemote, pMemberType, pOid, pInterfaceType, pReturn, ppArgs,
+ ppException );
+}
+void SAL_CALL urp_sendRequest_internal(
+ uno_Environment *pEnvRemote,
+ typelib_TypeDescription const * pMemberType,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException )
+{
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = (urp_BridgeImpl*) ( pContext->m_pBridgeImpl );
+
+ ClientJob job(
+ pEnvRemote, pContext, pImpl, pOid, pMemberType, pInterfaceType, pReturn,
+ ppArgs, ppException);
+
+ if( job.pack() && ! job.isOneway() )
+ {
+ job.wait();
+ }
+}
+
+}
+
+
diff --git a/bridges/source/remote/urp/urp_dispatch.hxx b/bridges/source/remote/urp/urp_dispatch.hxx
new file mode 100644
index 000000000000..dd529f97bffb
--- /dev/null
+++ b/bridges/source/remote/urp/urp_dispatch.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_dispatch.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <rtl/ustring.hxx>
+
+#include <typelib/typedescription.h>
+
+#include <uno/any2.h>
+
+
+typedef struct _uno_Environment uno_Environment;
+struct remote_Interface;
+
+
+
+namespace bridges_urp {
+
+ const sal_uInt8 HDRFLAG_LONGHEADER = 0x80;
+ const sal_uInt8 HDRFLAG_REQUEST = 0x40;
+ const sal_uInt8 HDRFLAG_NEWTYPE = 0x20;
+ const sal_uInt8 HDRFLAG_NEWOID = 0x10;
+ const sal_uInt8 HDRFLAG_NEWTID = 0x08;
+ const sal_uInt8 HDRFLAG_LONGMETHODID = 0x04;
+ const sal_uInt8 HDRFLAG_IGNORECACHE = 0x02;
+ const sal_uInt8 HDRFLAG_MOREFLAGS = 0x01;
+ const sal_uInt8 HDRFLAG_MUSTREPLY = 0x80;
+ const sal_uInt8 HDRFLAG_SYNCHRONOUS = 0x40;
+
+ const sal_uInt8 HDRFLAG_EXCEPTION = 0x20;
+
+ void SAL_CALL urp_sendCloseConnection( uno_Environment *pEnvRemote );
+
+ extern "C" void SAL_CALL urp_sendRequest(
+ uno_Environment *pEnvRemote,
+ typelib_TypeDescription const * pMemberType,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException
+ );
+
+ void SAL_CALL urp_sendRequest_internal(
+ uno_Environment *pEnvRemote,
+ typelib_TypeDescription const * pMemberType,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException
+ );
+
+}
+
diff --git a/bridges/source/remote/urp/urp_environment.cxx b/bridges/source/remote/urp/urp_environment.cxx
new file mode 100644
index 000000000000..1afab0633fd4
--- /dev/null
+++ b/bridges/source/remote/urp/urp_environment.cxx
@@ -0,0 +1,554 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_environment.cxx,v $
+ * $Revision: 1.21.20.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+
+#include <osl/interlck.h>
+#include <osl/diagnose.h>
+#include <osl/conditn.h>
+#include <osl/mutex.hxx>
+#include <osl/process.h>
+
+#include <rtl/alloc.h>
+#include <rtl/uuid.h>
+#include <rtl/unload.h>
+
+#include <uno/environment.h>
+#include <uno/lbnames.h>
+#include <uno/mapping.hxx>
+#include <uno/threadpool.h>
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/stub.hxx>
+#include <bridges/remote/context.h>
+#include <bridges/remote/mapping.hxx>
+#include <bridges/remote/counter.hxx>
+#include <bridges/remote/bridgeimpl.hxx>
+#include <bridges/remote/helper.hxx>
+
+#include "urp_bridgeimpl.hxx"
+#include "urp_writer.hxx"
+#include "urp_reader.hxx"
+#include "urp_dispatch.hxx"
+#include "urp_log.hxx"
+#include "urp_propertyobject.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+
+namespace bridges_urp
+{
+rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+// static void dumpProperties( struct Properties *p )
+// {
+// fprintf( stderr , "FlushBlockSize : %d\n" , p->nFlushBlockSize );
+// fprintf( stderr , "OnewayTimeoutMUSEC : %d\n" , p->nOnewayTimeoutMUSEC );
+// fprintf( stderr , "OidCacheSize : %d\n" , p->nOidCacheSize );
+// fprintf( stderr , "TypeCacheSize : %d\n" , p->nTypeCacheSize );
+// fprintf( stderr , "TidCacheSize : %d\n" , p->nTidCacheSize );
+// OString o = OUStringToOString( p->sSupportedVersions , RTL_TEXTENCODING_ASCII_US );
+// fprintf( stderr , "SupportedVersions : %s\n" , o.pData->buffer );
+// o = OUStringToOString( p->sVersion , RTL_TEXTENCODING_ASCII_US );
+// fprintf( stderr , "Version : %s\n" , o.pData->buffer );
+// fprintf( stderr , "SupportsMultipleSynchronous : %d\n" , p->bSupportsMultipleSynchronous );
+// fprintf( stderr , "SupportsMustReply : %d\n" , p->bSupportsMustReply );
+// fprintf( stderr , "SupportsSynchronous : %d\n" , p->bSupportsSynchronous );
+// }
+
+// PropertySetterThread
+//------------------------------------
+class PropertySetterThread : public ::osl::Thread
+{
+ urp_BridgeImpl *m_pImpl;
+ ::rtl::OUString m_sProps;
+ uno_Environment *m_pEnvRemote;
+public:
+ PropertySetterThread( uno_Environment *pEnvRemote,
+ urp_BridgeImpl *pImpl,
+ const ::rtl::OUString & props )
+ : m_pImpl( pImpl )
+ , m_sProps( props )
+ , m_pEnvRemote( pEnvRemote )
+ {
+ if (m_sProps.getLength() > 0) {
+ m_sProps += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(","));
+ }
+ m_sProps += rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("CurrentContext="));
+ // hold the environment in case all references are released before this
+ // thread terminates
+ m_pEnvRemote->acquire( pEnvRemote );
+ }
+ ~PropertySetterThread()
+ {
+ m_pEnvRemote->release( m_pEnvRemote );
+ }
+
+ virtual void SAL_CALL run()
+ {
+ for (;;)
+ {
+ switch ( m_pImpl->m_pPropertyObject->localRequestChange( ) )
+ {
+ case 1:
+ sal_Bool bExceptionThrown;
+ m_pImpl->m_pPropertyObject->localCommitChange( m_sProps , &bExceptionThrown );
+ OSL_ENSURE( !bExceptionThrown, "properties were not set\n" );
+ goto done;
+ case 0:
+ OSL_TRACE( "urp-bridge : remote-counterpart won the changing-the-protocol-race\n" );
+ goto done;
+ }
+ }
+ done:
+ m_pImpl->m_initialized.set();
+ }
+ virtual void SAL_CALL onTerminated()
+ {
+ delete this;
+ }
+};
+//------------------------------------
+
+
+void test_cache()
+{
+ OUString a = OUString( RTL_CONSTASCII_USTRINGPARAM( "a" ) );
+ OUString b = OUString( RTL_CONSTASCII_USTRINGPARAM( "b" ) );
+ OUString c = OUString( RTL_CONSTASCII_USTRINGPARAM( "c" ) );
+ Cache < OUString , equalOUString > cache ( 2 );
+
+ sal_Int32 n = cache.put( a );
+ if (cache.seek( a ) != n)
+ {
+ OSL_ASSERT( false );
+ }
+ OSL_ASSERT( 0 == n );
+
+ n = cache.put( b );
+ OSL_ASSERT( 1 == n );
+
+ cache.put( c );
+
+ OSL_ASSERT( 0xffff == cache.seek( a ) );
+ OSL_ASSERT( 1 == cache.seek( b ) );
+ OSL_ASSERT( 0 == cache.seek( c ) );
+
+ OSL_ASSERT( 1 == cache.put( a ) );
+ OSL_ASSERT( 0xffff == cache.seek( b) );
+ OSL_ASSERT( 1 == cache.seek( a ) );
+ OSL_ASSERT( 0 == cache.seek( c ) );
+}
+
+/*******************
+ * Are we within thread, that calls destructors of static objects ?
+ *******************/
+sal_Bool g_bStaticDestructorsCalled = sal_False;
+struct StaticSingleton
+{
+ ~StaticSingleton()
+ {
+ ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
+ g_bStaticDestructorsCalled = sal_True;
+ }
+};
+StaticSingleton singleton;
+
+#if OSL_DEBUG_LEVEL > 1
+static MyCounter thisCounter( "Remote Environment" );
+#endif
+
+void SAL_CALL allThreadsAreGone( uno_Environment * pEnvRemote )
+{
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = ( urp_BridgeImpl *) pContext->m_pBridgeImpl;
+
+ // if the current thread is not the writer thread, the writer thread
+ // object is not destroyed up to now, though it may already have run out.
+ // In both cases, it must be safe to cal pImpl->m_pWriter->getIdentifier()
+ OSL_ASSERT( pImpl->m_pWriter );
+ if( pImpl->m_pWriter->getIdentifier() == osl_getThreadIdentifier(0) )
+ {
+ // This is the writer thread. It has done some release calls,
+ // and is now the last one, that was active. Because the writer
+ // thread holds the environment weakly, there may also be a thread within
+ // the dispose of the bridge ( because the enviroment may have a refcount == 0 ).
+ // However, this thread MUST wait for the writer thread, so it is perfectly ok,
+ // not to set m_cndWaitForThreads. ( The check for m_nRemoteThreads is done
+ // after the join of the writer thread ).
+ }
+ else
+ {
+ pImpl->m_cndWaitForThreads.set();
+ }
+
+}
+
+void SAL_CALL releaseStubs( uno_Environment *pEnvRemote )
+{
+
+ ((remote_Context * ) pEnvRemote->pContext )->m_pBridgeImpl->m_bReleaseStubsCalled = sal_True;
+
+ remote_Interface **ppInterfaces = 0;
+ sal_Int32 nCount;
+ pEnvRemote->pExtEnv->getRegisteredInterfaces( pEnvRemote->pExtEnv,
+ (void***)&ppInterfaces,
+ &nCount,
+ rtl_allocateMemory );
+
+ sal_Int32 i;
+ for( i = 0 ; i < nCount ; i ++ )
+ {
+ if( ppInterfaces[i]->acquire == bridges_remote::acquireUno2RemoteStub )
+ {
+ // these are freed by the environment, so no release necessary
+ pEnvRemote->pExtEnv->revokeInterface( pEnvRemote->pExtEnv, ppInterfaces[i] );
+ }
+ else
+ {
+ ppInterfaces[i]->release( ppInterfaces[i] );
+ }
+ }
+
+ rtl_freeMemory( (void*) ppInterfaces );
+}
+
+} // end namespace bridges_urp
+
+using namespace bridges_urp;
+
+extern "C" {
+
+static void SAL_CALL RemoteEnvironment_thisDispose( uno_Environment *pEnvRemote )
+{
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = ( urp_BridgeImpl *) pContext->m_pBridgeImpl;
+
+ ::osl::ClearableMutexGuard guard( pImpl->m_disposingMutex );
+ if( pContext->m_pBridgeImpl->m_bDisposed &&
+ ( ! pImpl->m_pReader ||
+ osl_getThreadIdentifier(0) ==
+ (oslThreadIdentifier) pImpl->m_pReader->getIdentifier() ) )
+ {
+ return;
+ }
+ // in case, that the static destructors already have been called, no
+ // tiding up is done.
+ bool tidyUp;
+ {
+ ::osl::MutexGuard guard2( ::osl::Mutex::getGlobalMutex() );
+ tidyUp = ! g_bStaticDestructorsCalled &&
+ ! pContext->m_pBridgeImpl->m_bDisposed;
+ }
+ if( tidyUp )
+ {
+ // TODO : not threadsafe
+ // synchronization with dispatch methods needed !
+
+ pImpl->m_bDisposed = sal_True;
+
+
+ // close the connection
+ uno_threadpool_dispose( pImpl->m_hThreadPool );
+ pImpl->m_pWriter->abortThread();
+ pContext->m_pConnection->close( pContext->m_pConnection );
+
+ if( osl_getThreadIdentifier(0) ==
+ (oslThreadIdentifier) pImpl->m_pReader->getIdentifier() )
+ {
+ // This is the reader thread. Let the thread destroy itself
+ // the reader thread object must also release the connection at this stage !
+ pImpl->m_pReader->destroyYourself();
+ pImpl->m_pReader = 0;
+ }
+ else
+ {
+ // wait for the reader thread
+ // the reader thread object must also release the connection,
+ // when terminating !!!!
+ pImpl->m_pReader->join();
+ }
+
+ // wait for the writer thread
+ pImpl->m_pWriter->join();
+
+ // now let the context go !
+ pContext->dispose( pContext );
+
+ if( 0 != pImpl->m_nRemoteThreads )
+ {
+ // Wait for all threads
+ guard.clear();
+ pImpl->m_cndWaitForThreads.wait();
+ OSL_ASSERT( ! pImpl->m_nRemoteThreads );
+ }
+ else
+ {
+ guard.clear();
+ }
+#ifdef BRIDGES_URP_PROT
+ if( pImpl->m_pLogFile )
+ {
+ fclose( pImpl->m_pLogFile );
+ pImpl->m_pLogFile = 0;
+ }
+#endif
+#if OSL_DEBUG_LEVEL > 1
+ pImpl->dumpErrors( stderr );
+#endif
+
+ // destroy the threads
+ delete pImpl->m_pWriter;
+ pImpl->m_pWriter = 0;
+
+ if( pImpl->m_pReader != 0 )
+ {
+ // This is not the reader thread, so the thread object is deleted
+ delete pImpl->m_pReader;
+ pImpl->m_pReader = 0;
+ }
+
+ bool bReleaseStubs = false;
+ {
+ ::osl::MutexGuard guard2( ::osl::Mutex::getGlobalMutex() );
+ bReleaseStubs = !g_bStaticDestructorsCalled;
+ }
+ if( bReleaseStubs )
+ {
+ releaseStubs( pEnvRemote );
+ }
+ }
+}
+
+static void SAL_CALL RemoteEnvironment_thisDisposing(
+ uno_Environment *pEnvRemote )
+{
+ remote_Context *pContext = (remote_Context * )pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = ((urp_BridgeImpl*) pContext->m_pBridgeImpl);
+
+ {
+ ::osl::ClearableMutexGuard guard( pImpl->m_disposingMutex );
+ if( ! pImpl->m_bDisposed )
+ {
+ guard.clear();
+ urp_sendCloseConnection( pEnvRemote );
+ RemoteEnvironment_thisDispose( pEnvRemote );
+ }
+ }
+ pImpl->m_pPropertyObject->thisRelease();
+ pImpl->m_pPropertyObject = 0;
+
+ uno_threadpool_destroy( pImpl->m_hThreadPool );
+
+ delete pImpl;
+ pContext->aBase.release( (uno_Context * ) pContext );
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+static void SAL_CALL RemoteEnvironment_thisComputeObjectIdentifier(
+ uno_ExtEnvironment *, rtl_uString **, void *)
+{
+ OSL_ENSURE( 0, "RemoteEnvironment_thisComputeObjectIdentifier should never be called" );
+}
+
+static void SAL_CALL RemoteEnvironment_thisAcquireInterface(
+ uno_ExtEnvironment *, void *pInterface )
+{
+ ((remote_Interface *)pInterface)->acquire( ( remote_Interface *) pInterface );
+}
+
+static void SAL_CALL RemoteEnvironment_thisReleaseInterface(
+ uno_ExtEnvironment *, void *pInterface )
+{
+ ((remote_Interface *)pInterface)->release( ( remote_Interface *) pInterface );
+}
+
+//##################################################################################################
+void SAL_CALL uno_initEnvironment( uno_Environment * pEnvRemote )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ // set C-virtual methods
+ pEnvRemote->environmentDisposing = RemoteEnvironment_thisDisposing;
+ pEnvRemote->pExtEnv->computeObjectIdentifier = RemoteEnvironment_thisComputeObjectIdentifier;
+ pEnvRemote->pExtEnv->acquireInterface = RemoteEnvironment_thisAcquireInterface;
+ pEnvRemote->pExtEnv->releaseInterface = RemoteEnvironment_thisReleaseInterface;
+ pEnvRemote->dispose = RemoteEnvironment_thisDispose;
+
+ remote_Context *pContext = ( remote_Context * ) pEnvRemote->pContext;
+ pContext->aBase.acquire( ( uno_Context * ) pContext );
+ pContext->getRemoteInstance = ::bridges_remote::remote_sendQueryInterface;
+
+ // Initialize impl struct urp_BridgeImpl
+ urp_BridgeImpl *pImpl = new ::bridges_urp::urp_BridgeImpl( 256, 8192 );
+ pContext->m_pBridgeImpl = pImpl;
+
+ // Initialize threadpool
+ pImpl->m_hThreadPool = uno_threadpool_create();
+
+ // take the bridgepointer as id
+ pImpl->m_properties.seqBridgeID = ByteSequence( (sal_Int8*)&pEnvRemote , sizeof( pEnvRemote ) );
+
+ pImpl->m_allThreadsAreGone = allThreadsAreGone;
+ pImpl->m_sendRequest = urp_sendRequest;
+ pImpl->m_nRemoteThreads = 0;
+ pImpl->m_bDisposed = sal_False;
+ pImpl->m_bReleaseStubsCalled = sal_False;
+
+ pImpl->m_pPropertyObject = new PropertyObject( &(pImpl->m_properties ), pEnvRemote, pImpl );
+ pImpl->m_pPropertyObject->thisAcquire();
+
+ OUString sProtocolProperties;
+ if( pContext->m_pProtocol->length > 3 )
+ {
+ sProtocolProperties = OUString( pContext->m_pProtocol ).copy( 4, pContext->m_pProtocol->length-4);
+ }
+ if( sProtocolProperties.getLength() )
+ {
+ struct Properties props = pImpl->m_properties;
+ assignFromStringToStruct( sProtocolProperties , &props );
+ if( ! props.bNegotiate )
+ {
+ // no negotiation takes place, the creator of the bridge knows the parameter
+ // of the other side !
+ pImpl->applyProtocolChanges( props );
+ sProtocolProperties = OUString();
+ }
+ }
+
+#ifdef BRIDGES_URP_PROT
+ char *p = getenv( "PROT_REMOTE" );
+ pImpl->m_pLogFile = 0;
+ if( p )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ static int counter;
+ oslProcessInfo data;
+ data.Size = sizeof( data );
+ osl_getProcessInfo( 0 , osl_Process_HEAPUSAGE | osl_Process_IDENTIFIER , &data );
+ OString s(p);
+ s += "_pid";
+ s += OString::valueOf( (sal_Int32) data.Ident );
+ s += "_";
+ s += OString::valueOf( (sal_Int32) counter );
+ pImpl->m_sLogFileName = s;
+ // clear the file
+ FILE *f = fopen( s.getStr() , "w" );
+ OSL_ASSERT( f );
+ if( getenv( "PROT_REMOTE_FAST") )
+ {
+ pImpl->m_pLogFile = f;
+ }
+ else
+ {
+ fclose( f );
+ }
+ counter++;
+ }
+#endif
+
+ // start reader and writer threads
+ pImpl->m_pWriter = new ::bridges_urp::OWriterThread( pContext->m_pConnection , pImpl,
+ pEnvRemote);
+ pImpl->m_pWriter->create();
+
+ pImpl->m_pReader = new ::bridges_urp::OReaderThread( pContext->m_pConnection ,
+ pEnvRemote,
+ pImpl->m_pWriter );
+ pImpl->m_pReader->create();
+
+ PropertySetterThread *pPropsSetterThread =
+ new PropertySetterThread( pEnvRemote, pImpl , sProtocolProperties );
+ pPropsSetterThread->create();
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+
+//##################################################################################################
+void SAL_CALL uno_ext_getMapping(
+ uno_Mapping ** ppMapping,
+ uno_Environment * pFrom,
+ uno_Environment * pTo )
+{
+ OSL_ASSERT( ppMapping && pFrom && pTo );
+ if (ppMapping && pFrom && pTo)
+ {
+ if (*ppMapping)
+ ((*ppMapping)->release)( *ppMapping );
+ bridges_remote::RemoteMapping * pMapping = 0;
+
+ ::rtl::OUString sFromName = pFrom->pTypeName;
+ ::rtl::OUString sToName = pTo->pTypeName;
+ ::rtl::OUString sUno = OUString::createFromAscii( UNO_LB_UNO );
+ ::rtl::OUString sRemote = OUString::createFromAscii( "urp" );
+ if ( sFromName.equalsIgnoreAsciiCase( sRemote ) &&
+ sToName.equalsIgnoreAsciiCase( sUno ) )
+ {
+ pMapping = new bridges_remote::RemoteMapping( pTo, /* Uno */
+ pFrom, /*remote*/
+ bridges_remote::remoteToUno,
+ OUString() );
+ }
+ else if ( sFromName.equalsIgnoreAsciiCase( sUno ) &&
+ sToName.equalsIgnoreAsciiCase( sRemote ) )
+ {
+ pMapping = new bridges_remote::RemoteMapping( pFrom ,
+ pTo ,
+ bridges_remote::unoToRemote,
+ OUString() );
+ }
+
+ *ppMapping = (uno_Mapping * )pMapping;
+ OUString dummy;
+ uno_registerMapping( ppMapping ,
+ bridges_remote::freeRemoteMapping,
+ pFrom ,
+ pTo ,
+ dummy.pData );
+ }
+}
+
+sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
+{
+ return g_moduleCount.canUnload( &g_moduleCount , pTime );
+}
+
+}
diff --git a/bridges/source/remote/urp/urp_job.cxx b/bridges/source/remote/urp/urp_job.cxx
new file mode 100644
index 000000000000..918affdbe689
--- /dev/null
+++ b/bridges/source/remote/urp/urp_job.cxx
@@ -0,0 +1,942 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_job.cxx,v $
+ * $Revision: 1.17 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <string.h>
+#include <stdio.h>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <rtl/alloc.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <uno/current_context.h>
+#include <uno/current_context.hxx>
+#include <uno/threadpool.h>
+
+#include <bridges/cpp_uno/type_misc.hxx>
+#include <bridges/remote/proxy.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/XCurrentContext.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+#include "urp_job.hxx"
+#include "urp_bridgeimpl.hxx"
+#include "urp_writer.hxx"
+#include "urp_dispatch.hxx"
+#include "urp_log.hxx"
+#include "urp_marshal.hxx"
+#include "urp_propertyobject.hxx"
+#include "urp_reader.hxx"
+
+using namespace ::std;
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+
+using namespace bridges_urp;
+
+extern "C" {
+
+static void SAL_CALL doit(void * job) {
+ ServerMultiJob * p = static_cast< ServerMultiJob * >(job);
+ p->execute();
+ delete p;
+}
+
+}
+
+namespace bridges_urp
+{
+ static sal_Bool isDisposedExceptionDescriptionAvail( const Type &type )
+ {
+ static sal_Bool bInit;
+ static sal_Bool bReturn;
+ // we don't care for thread safety here, as both threads must come
+ // to the same result
+ if( ! bInit )
+ {
+ typelib_TypeDescription *pTD = 0;
+ typelib_typedescriptionreference_getDescription( & pTD, type.getTypeLibType() );
+ if( pTD )
+ {
+ bReturn = sal_True;
+ typelib_typedescription_release( pTD );
+ }
+ else
+ {
+ bReturn = sal_False;
+ }
+ bInit = sal_True;
+ }
+ return bReturn;
+ }
+
+ //--------------------------------------------------------------------------------------
+ static void prepareRuntimeExceptionClientSide( uno_Any **ppException , const OUString &s)
+ {
+ com::sun::star::lang::DisposedException exception( s , Reference< XInterface > () );
+ Type type = ::getCppuType( &exception );
+ if( !isDisposedExceptionDescriptionAvail( type ) )
+ {
+ // if it is not available (probably missing type library),
+ // then we are satisfied with throwing a normal runtime exception,
+ // for which cppu provides a static description
+ type = getCppuType( ( RuntimeException * ) 0 );
+ }
+ uno_type_any_construct( *ppException , &exception , type.getTypeLibType() , 0 );
+ }
+
+
+ Job::Job( uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ sal_Sequence *pTid,
+ struct urp_BridgeImpl *pBridgeImpl,
+ Unmarshal *pUnmarshal )
+ : m_pContext( pContext )
+ , m_pUnmarshal( pUnmarshal )
+ , m_pBridgeImpl( pBridgeImpl )
+ , m_pTid( pTid )
+ , m_counter( pEnvRemote )
+ {
+ if ( m_pContext )
+ {
+ m_pContext->aBase.acquire( &m_pContext->aBase );
+ }
+ if( m_pTid )
+ rtl_byte_sequence_acquire( pTid );
+ }
+
+ Job::~Job()
+ {
+ if( m_pTid )
+ rtl_byte_sequence_release( m_pTid );
+ if ( m_pContext )
+ {
+ m_pContext->aBase.release( &m_pContext->aBase );
+ }
+ }
+
+
+
+
+ //--------------------------------------------------------------------------------------
+ sal_Bool ClientJob::extract( )
+ {
+ sal_Bool bReturn = sal_True;
+ //-------------------------------
+ // Handle the reply, unpack data
+ //-------------------------------
+ if( m_bExceptionOccured )
+ {
+ bReturn = m_pUnmarshal->unpackAny( *m_ppException );
+ }
+ else
+ {
+ //---------------------------------
+ // alles ist gut
+ //---------------------------------
+ if( m_pMethodType )
+ {
+ if( m_pMethodType->pReturnTypeRef->eTypeClass != typelib_TypeClass_VOID )
+ {
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType , m_pMethodType->pReturnTypeRef );
+ bReturn = m_pUnmarshal->unpack( m_pReturn , pType ) && bReturn;
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+
+ // out parameters
+ sal_Int32 i;
+ for( i = 0 ; i < m_pMethodType->nParams ; i ++ )
+ {
+ if( m_pMethodType->pParams[i].bOut )
+ {
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType , m_pMethodType->pParams[i].pTypeRef );
+ if( m_pMethodType->pParams[i].bIn )
+ {
+ uno_destructData( m_ppArgs[i] , pType , ::bridges_remote::remote_release );
+ }
+ bReturn = m_pUnmarshal->unpack( m_ppArgs[i] , pType ) && bReturn;
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+ }
+ }
+ else if( m_pAttributeType && m_pReturn )
+ {
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType , m_pAttributeType->pAttributeTypeRef );
+ bReturn = m_pUnmarshal->unpack( m_pReturn , pType ) && bReturn;
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+ else if( m_pAttributeType && m_ppArgs )
+ {
+ // nothing to do
+ }
+ else
+ {
+ OSL_ASSERT( 0 );
+ }
+ }
+ return bReturn;
+ }
+
+ //-------------------------------------------------------------------------------------------
+ void ClientJob::initiate()
+ {
+ uno_threadpool_putJob( m_pBridgeImpl->m_hThreadPool, m_pTid , this, 0, sal_False);
+ }
+
+ //--------------------------------------------------------------------------------------------
+ sal_Bool ClientJob::pack()
+ {
+ sal_Bool bSuccess = sal_True;
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+
+ if( m_pMethodType &&
+ REMOTE_RELEASE_METHOD_INDEX == m_pMethodType->aBase.nPosition &&
+ ! m_pBridgeImpl->m_bDisposed &&
+ m_pBridgeImpl->m_pWriter->getIdentifier() != ::osl::Thread::getCurrentIdentifier() )
+ {
+ // all release calls are delegated to the writer thread to avoid
+ // multiple synchron calls with the same thread id and reentrant
+ // marshaling (in case during destruction of parameters a release is
+ // invoked ).
+ m_pBridgeImpl->m_pWriter->insertReleaseRemoteCall(
+ m_pOid, m_pInterfaceType->aBase.pWeakRef );
+
+ // No waiting, please
+ return sal_False;
+ }
+ else if ( m_pMethodType &&
+ REMOTE_RELEASE_METHOD_INDEX == m_pMethodType->aBase.nPosition &&
+ m_pBridgeImpl->m_bDisposed )
+ {
+ // no exception for release calls !
+ return sal_False;
+ }
+ else if( m_pBridgeImpl->m_bDisposed )
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "URP-Bridge: disposed" ) );
+ buf.append( m_pBridgeImpl->getErrorsAsString() );
+ prepareRuntimeExceptionClientSide( m_ppException , buf.makeStringAndClear() );
+ return sal_False;
+ }
+
+ // build up the flag byte
+ sal_Bool bType = sal_False, bOid = sal_False, bTid = sal_False;
+ sal_uInt8 nFlags = 0;
+ if( m_pBridgeImpl->m_lastOutType.getTypeLibType() != m_pInterfaceType->aBase.pWeakRef &&
+ ! typelib_typedescriptionreference_equals(
+ m_pBridgeImpl->m_lastOutType.getTypeLibType(), m_pInterfaceType->aBase.pWeakRef ) )
+ {
+ //new type
+ nFlags = nFlags | HDRFLAG_NEWTYPE;
+ bType = sal_True;
+ }
+ if( m_pBridgeImpl->m_lastOutOid.pData != m_pOid &&
+ rtl_ustr_compare_WithLength( m_pBridgeImpl->m_lastOutOid.pData->buffer,
+ m_pBridgeImpl->m_lastOutOid.pData->length,
+ m_pOid->buffer,
+ m_pOid->length ) )
+ {
+ //new object id
+ nFlags = nFlags | HDRFLAG_NEWOID;
+ bOid = sal_True;
+ }
+ if( m_pBridgeImpl->m_lastOutTid.getHandle() != m_pTid &&
+ !(m_pBridgeImpl->m_lastOutTid == *(ByteSequence*) &(m_pTid) ) )
+ {
+ // new threadid
+ nFlags = nFlags | HDRFLAG_NEWTID;
+ bTid = sal_True;
+ }
+
+ if( m_bCallingConventionForced )
+ {
+ nFlags = nFlags | HDRFLAG_MOREFLAGS;
+ }
+#ifdef BRIDGES_URP_PROT
+ sal_Int32 nLogStart = m_pBridgeImpl->m_blockMarshaler.getPos();
+#endif
+ // Short request headers can only handle 14-bit method IDs, so
+ // unconditionally use a long header for method IDs that are too large:
+ if( nFlags || m_nMethodIndex >= 0xC000 )
+ {
+ // the flag byte is needed + request
+ nFlags = nFlags | HDRFLAG_LONGHEADER | HDRFLAG_REQUEST; //
+
+ // as long as we do not have customized calls, no MOREFLAGS must be set
+ if( m_nMethodIndex >= 0x100 )
+ {
+ nFlags = nFlags | HDRFLAG_LONGMETHODID;
+ }
+ m_pBridgeImpl->m_blockMarshaler.packInt8( &nFlags );
+
+ if( nFlags & HDRFLAG_MOREFLAGS )
+ {
+ sal_uInt8 nMoreFlags = 0;
+ if( ! m_bOneway )
+ {
+ nMoreFlags = HDRFLAG_SYNCHRONOUS |HDRFLAG_MUSTREPLY;
+ }
+ m_pBridgeImpl->m_blockMarshaler.packInt8( &nMoreFlags );
+ }
+ if( nFlags & HDRFLAG_LONGMETHODID )
+ {
+ sal_uInt16 nMethod = (sal_uInt16 ) m_nMethodIndex;
+ m_pBridgeImpl->m_blockMarshaler.packInt16( &nMethod );
+ }
+ else
+ {
+ sal_uInt8 nMethod = (sal_uInt8) m_nMethodIndex;
+ m_pBridgeImpl->m_blockMarshaler.packInt8( &nMethod );
+ }
+ }
+ else
+ {
+ // no flag byte needed, simply marshal the method index
+ if( m_nMethodIndex >= 64 )
+ {
+ sal_uInt16 nMethod = ( sal_uInt16 ) m_nMethodIndex;
+ nMethod = nMethod | 0x4000;
+ m_pBridgeImpl->m_blockMarshaler.packInt16( &nMethod );
+ }
+ else
+ {
+ sal_uInt8 nMethod = (sal_uInt8 ) m_nMethodIndex;
+ m_pBridgeImpl->m_blockMarshaler.packInt8( &nMethod );
+ }
+ }
+
+ // marshal type,oid,tid
+ if( bType )
+ {
+ m_pBridgeImpl->m_lastOutType = m_pInterfaceType->aBase.pWeakRef;
+ m_pBridgeImpl->m_blockMarshaler.packType( &(m_pBridgeImpl->m_lastOutType) );
+ }
+ if( bOid )
+ {
+ m_pBridgeImpl->m_lastOutOid = *(OUString *)&m_pOid;
+ m_pBridgeImpl->m_blockMarshaler.packOid( m_pBridgeImpl->m_lastOutOid );
+ }
+ if( bTid )
+ {
+ m_pBridgeImpl->m_lastOutTid = *(ByteSequence*)&(m_pTid);
+ m_pBridgeImpl->m_blockMarshaler.packTid( m_pBridgeImpl->m_lastOutTid );
+ }
+
+ if ( m_pBridgeImpl->m_properties.bCurrentContext
+ && m_nMethodIndex != REMOTE_RELEASE_METHOD_INDEX
+ && m_pContext != 0 )
+ {
+ void * pCc = 0;
+ rtl::OUString aEnvName( RTL_CONSTASCII_USTRINGPARAM( "urp" ) );
+ bSuccess = bSuccess && uno_getCurrentContext(
+ &pCc, aEnvName.pData, m_pContext );
+ typelib_TypeDescription * pType = 0;
+ TYPELIB_DANGER_GET(
+ &pType, XCurrentContext::static_type().getTypeLibType() );
+ bSuccess = bSuccess && m_pBridgeImpl->m_blockMarshaler.pack(
+ &pCc, pType );
+ TYPELIB_DANGER_RELEASE( pType );
+ if ( pCc )
+ {
+ remote_Interface * p = static_cast< remote_Interface * >( pCc );
+ p->release( p );
+ }
+ }
+
+ // marshal arguments !
+#ifdef BRIDGES_URP_PROT
+ sal_Int32 nLogHeader = m_pBridgeImpl->m_blockMarshaler.getPos();
+#endif
+ if( m_pMethodType )
+ {
+ sal_Int32 i;
+ for( i = 0 ; i < m_pMethodType->nParams ; i ++ )
+ {
+ if( m_pMethodType->pParams[i].bIn )
+ {
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType , m_pMethodType->pParams[i].pTypeRef );
+ if( pType )
+ {
+ bSuccess =
+ bSuccess && m_pBridgeImpl->m_blockMarshaler.pack( m_ppArgs[i] , pType );
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+ else
+ {
+ bSuccess = sal_False;
+ OUStringBuffer buffer( 128 );
+ buffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "no typedescription available for type" ) );
+ buffer.append( m_pMethodType->pParams[i].pTypeRef->pTypeName );
+ m_pBridgeImpl->addError( buffer.makeStringAndClear() );
+ }
+ }
+ }
+ }
+ else if( m_pAttributeType && m_pReturn )
+ {
+ // nothing to do !
+ }
+ else if( m_pAttributeType && m_ppArgs )
+ {
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType , m_pAttributeType->pAttributeTypeRef );
+ if( pType )
+ {
+ bSuccess = bSuccess && m_pBridgeImpl->m_blockMarshaler.pack( m_ppArgs[0] , pType );
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+ else
+ {
+ bSuccess = sal_False;
+ OUStringBuffer buffer( 128 );
+ buffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "no typedescription available for type" ) );
+ buffer.append( m_pAttributeType->pAttributeTypeRef->pTypeName );
+ m_pBridgeImpl->addError( buffer.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ OSL_ASSERT( 0 );
+ }
+
+#ifdef BRIDGES_URP_PROT
+ urp_logCall( m_pBridgeImpl, m_pBridgeImpl->m_blockMarshaler.getPos() - nLogStart,
+ m_pBridgeImpl->m_blockMarshaler.getPos() - nLogHeader, ! m_bOneway,
+ m_pMethodType ? m_pMethodType->aBase.pMemberName :
+ m_pAttributeType->aBase.pMemberName );
+#endif
+
+ if( bSuccess )
+ {
+ if( ! m_bOneway )
+ {
+ uno_threadpool_attach( m_pBridgeImpl->m_hThreadPool );
+ m_pBridgeImpl->m_clientJobContainer.add( *(ByteSequence*)&(m_pTid), this );
+ }
+
+ m_pBridgeImpl->m_nMarshaledMessages ++;
+ //---------------------------
+ // Inform the writer thread, that there is some work to do
+ //---------------------------
+ m_pBridgeImpl->m_pWriter->touch( ! m_bOneway );
+
+ if( m_bOneway )
+ {
+ *m_ppException = 0;
+ }
+ }
+ else
+ {
+ // Something went wrong during packing, which means, that the caches may not be in sync
+ // anymore. So we have no other choice than to dispose the environment.
+ m_pEnvRemote->dispose( m_pEnvRemote );
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Error during marshaling " ) );
+ if( m_pMethodType )
+ {
+ buf.append( m_pMethodType->aBase.aBase.pTypeName );
+ }
+ else if( m_pAttributeType )
+ {
+ buf.append( m_pAttributeType->aBase.aBase.pTypeName );
+ }
+ buf.appendAscii( "\n" );
+ buf.append( m_pBridgeImpl->getErrorsAsString() );
+ prepareRuntimeExceptionClientSide( m_ppException , buf.makeStringAndClear() );
+ }
+ return bSuccess;
+ // release the guard
+ }
+
+ //------------------------------------------------------------------------------------
+ void ClientJob::wait()
+ {
+ //---------------------------
+ // Wait for the reply
+ //---------------------------
+ void * pDisposeReason = 0;
+
+ uno_threadpool_enter(m_pBridgeImpl->m_hThreadPool, &pDisposeReason );
+
+ if( ! pDisposeReason )
+ {
+ // thread has been disposed !
+ // avoid leak due continous calling on a disposed reference. The
+ // reply may or may not be within the container. If the reader thread
+ // got into problems during unmarshaling the reply for this request,
+ // it won't be in the container anymore, but it is eiterway safe to call
+ // the method
+ ClientJob *pJob =
+ m_pBridgeImpl->m_clientJobContainer.remove( *(ByteSequence*) &m_pTid );
+ if( pJob != this )
+ {
+ // this is not our job, it is probably one of the callstack below, so
+ // push it back
+ m_pBridgeImpl->m_clientJobContainer.add( *(ByteSequence*) &m_pTid , pJob );
+ }
+
+ OUStringBuffer sMessage( 256 );
+ sMessage.appendAscii( RTL_CONSTASCII_STRINGPARAM( "URP_Bridge : disposed\n" ) );
+ sMessage.append( m_pBridgeImpl->getErrorsAsString() );
+ prepareRuntimeExceptionClientSide( m_ppException, sMessage.makeStringAndClear() );
+ m_bExceptionOccured = sal_True;
+ }
+ else
+ {
+ OSL_ASSERT( pDisposeReason == (void*)this );
+ }
+ if( !m_bExceptionOccured )
+ {
+ *m_ppException = 0;
+ }
+ uno_threadpool_detach( m_pBridgeImpl->m_hThreadPool );
+ }
+
+ //------------------------------------------------------------------------------------
+ // ServerMultiJob
+ //------------------------------------------------------------------------------------
+ ServerMultiJob::ServerMultiJob(
+ uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ sal_Sequence *pTid,
+ struct urp_BridgeImpl *pBridgeImpl,
+ Unmarshal *pUnmarshal,
+ sal_Int32 nMaxMessages )
+ : Job( pEnvRemote, pContext, pTid, pBridgeImpl, pUnmarshal )
+ , m_pEnvRemote( pEnvRemote )
+ , m_nCalls( 0 )
+ , m_nMaxMessages( nMaxMessages )
+ , m_nCurrentMemPosition( 0 )
+ {
+ m_pEnvRemote->acquire( m_pEnvRemote );
+ m_nCurrentMemSize = MULTIJOB_STANDARD_MEMORY_SIZE + m_nMaxMessages * (
+ MULTIJOB_PER_CALL_MEMORY_SIZE + sizeof(ServerJobEntry) + sizeof(MemberTypeInfo) );
+ m_pCurrentMem = ( sal_Int8 * ) rtl_allocateMemory( m_nCurrentMemSize );
+ m_aEntries = ( ServerJobEntry * ) getHeap( m_nMaxMessages * sizeof( ServerJobEntry ) );
+ m_aTypeInfo = ( MemberTypeInfo * ) getHeap( m_nMaxMessages * sizeof( MemberTypeInfo ) );
+ }
+
+ ServerMultiJob::~ServerMultiJob()
+ {
+ sal_Int32 i;
+ for( i = 0 ; i < m_nCalls ; i ++ )
+ {
+ struct MemberTypeInfo *const pMTI = &( m_aTypeInfo[i] );
+ struct ServerJobEntry *const pSJE = &( m_aEntries[i] );
+
+ if( pSJE->m_pRemoteI )
+ pSJE->m_pRemoteI->release( pSJE->m_pRemoteI );
+
+ if( pSJE->m_pOid )
+ rtl_uString_release( pSJE->m_pOid );
+
+ if( pSJE->m_pInterfaceTypeRef )
+ typelib_typedescriptionreference_release( pSJE->m_pInterfaceTypeRef );
+
+ if( pMTI->m_pInterfaceType )
+ TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pMTI->m_pInterfaceType );
+
+ for( sal_Int32 iArgs = 0 ; iArgs < pMTI->m_nArgCount ; iArgs ++ )
+ {
+ if( pMTI->m_ppArgType[iArgs] )
+ TYPELIB_DANGER_RELEASE( pMTI->m_ppArgType [iArgs] );
+ }
+ if( pMTI->m_pReturnType )
+ TYPELIB_DANGER_RELEASE( pMTI->m_pReturnType );
+
+ if( pMTI->m_pMethodType )
+ typelib_typedescription_release( (typelib_TypeDescription*)pMTI->m_pMethodType );
+ if( pMTI->m_pAttributeType )
+ typelib_typedescription_release( (typelib_TypeDescription*)pMTI->m_pAttributeType );
+ }
+
+ rtl_freeMemory( m_pCurrentMem );
+ for( list< sal_Int8 *>::iterator ii = m_lstMem.begin() ; ii != m_lstMem.end() ; ++ii )
+ rtl_freeMemory( *ii );
+
+ if( m_pEnvRemote )
+ m_pEnvRemote->release( m_pEnvRemote );
+ }
+
+ //-------------------------------------------------------------------------------------
+ void ServerMultiJob::execute()
+ {
+ Reference< XCurrentContext > xOldCc;
+ bool bHasOldCc = false;
+ for( sal_Int32 i = 0; i < m_nCalls ; i ++ )
+ {
+ struct MemberTypeInfo * const pMTI = &( m_aTypeInfo[i] );
+ struct ServerJobEntry * const pSJE = &( m_aEntries[i] );
+
+ if ( pSJE->m_bHasCurrentContext )
+ {
+ if ( !bHasOldCc )
+ {
+ xOldCc = com::sun::star::uno::getCurrentContext();
+ bHasOldCc = true;
+ }
+ rtl::OUString aEnvName( RTL_CONSTASCII_USTRINGPARAM( "urp" ) );
+ if ( !uno_setCurrentContext(
+ pSJE->m_pCurrentContext, aEnvName.pData, m_pContext ) )
+ {
+ throw RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "fatal: uno_setCurrentContext failed" ) ),
+ Reference< XInterface >() );
+ }
+ if ( pSJE->m_pCurrentContext )
+ {
+ pSJE->m_pCurrentContext->release( pSJE->m_pCurrentContext );
+ }
+ }
+
+ if( ! pSJE->m_pRemoteI )
+ {
+ // -------------------
+ // Initial object ?
+ // ------------------
+ // be robust : Sending a release on a not constructed object
+ // provokes an segfault. Make sure, the call
+ // is not a release call.
+ remote_Context *pRemoteC = ((remote_Context*)m_pEnvRemote->pContext);
+
+ if( ! pMTI->m_bIsReleaseCall && pRemoteC->m_pInstanceProvider )
+ {
+ pSJE->m_pException = &(pSJE->m_exception);
+
+ pRemoteC->m_pInstanceProvider->getInstance(
+ pRemoteC->m_pInstanceProvider,
+ m_pEnvRemote,
+ &(pSJE->m_pRemoteI),
+ pSJE->m_pOid,
+ pMTI->m_pInterfaceType,
+ &(pSJE->m_pException));
+ }
+ else
+ {
+ prepareRuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "urp: No instance provider set")),i);
+ }
+ }
+
+ if( pSJE->m_pException )
+ {
+ // errors during extracting, do nothing
+ }
+ else if( ! pSJE->m_pRemoteI )
+ {
+ // May only occur during the queryInterface call on the initial object !!!
+ // construct the return value
+ uno_type_any_construct( (uno_Any*) pSJE->m_pReturn , 0 , 0 , 0 );
+ }
+ else
+ {
+ pSJE->m_pException = &(pSJE->m_exception );
+
+ if( pMTI->m_bIsReleaseCall )
+ {
+ pSJE->m_pRemoteI->release( pSJE->m_pRemoteI );
+ pSJE->m_pException = 0;
+ }
+ else
+ {
+ pSJE->m_pRemoteI->pDispatcher(
+ pSJE->m_pRemoteI,
+ pMTI->m_pMethodType ? (typelib_TypeDescription*) pMTI->m_pMethodType :
+ (typelib_TypeDescription*) pMTI->m_pAttributeType,
+ pSJE->m_pReturn,
+ pSJE->m_ppArgs,
+ &(pSJE->m_pException) );
+ }
+ }
+ if( pSJE->m_pRemoteI )
+ {
+ /**
+ Do the release here, in case of ForceSynchronous=1, calls
+ originated by the destructor of an UNO object must be sent BEFORE the
+ release returns ( otherwise we don't own the thread anymore ! )
+ */
+ pSJE->m_pRemoteI->release( pSJE->m_pRemoteI );
+ pSJE->m_pRemoteI = 0;
+ }
+
+ // now destruct parameters and marshal replies
+ // Note : when call is synchron => m_nCalls == 1
+ if( pMTI->m_bIsOneway )
+ {
+ // Oneway call, destruct in parameters
+ for( sal_Int32 j = 0 ; j < pMTI->m_pMethodType->nParams ; j ++ )
+ {
+ // usually all parameters must be in parameters, but to be robust ...
+ if( pMTI->m_pbIsIn[j] && !cppu_isSimpleType( pMTI->m_ppArgType[j] ) )
+ {
+ uno_destructData( pSJE->m_ppArgs[j] , pMTI->m_ppArgType[j] , 0 );
+ }
+ }
+
+ if( pSJE->m_pException )
+ {
+ uno_any_destruct( pSJE->m_pException, ::bridges_remote::remote_release );
+ }
+
+ }
+ else
+ {
+ // synchron, get the mutex to marshal reply and send immeadiatly
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+
+ sal_Bool bTid = sal_False;
+ sal_uInt8 nFlags = HDRFLAG_LONGHEADER;
+ ByteSequence tid = m_pTid;
+ if( !( tid == m_pBridgeImpl->m_lastOutTid ) || pSJE->m_bIgnoreCache )
+ {
+ // new threadid
+ nFlags = nFlags | HDRFLAG_NEWTID;
+ bTid = sal_True;
+ }
+
+ if( pSJE->m_pException )
+ {
+ nFlags = nFlags | HDRFLAG_EXCEPTION;
+ }
+#ifdef BRIDGES_URP_PROT
+ sal_Int32 nLogStart = m_pBridgeImpl->m_blockMarshaler.getPos();
+#endif
+ m_pBridgeImpl->m_blockMarshaler.packInt8( &nFlags );
+
+ if( bTid )
+ {
+ if( ! pSJE->m_bIgnoreCache )
+ {
+ m_pBridgeImpl->m_lastOutTid = tid;
+ }
+ m_pBridgeImpl->m_blockMarshaler.packTid( tid , pSJE->m_bIgnoreCache );
+ }
+
+#ifdef BRIDGES_URP_PROT
+ sal_Int32 nLogHeader = m_pBridgeImpl->m_blockMarshaler.getPos();
+#endif
+
+ if( pSJE->m_pException )
+ {
+ //--------------------
+ // an exception was thrown
+ //--------------------
+ m_pBridgeImpl->m_blockMarshaler.packAny( &(pSJE->m_exception) );
+ uno_any_destruct( &(pSJE->m_exception) , ::bridges_remote::remote_release );
+
+ // destroy in parameters
+ for( sal_Int32 j = 0 ; j < pMTI->m_nArgCount ; j ++ )
+ {
+ if( pMTI->m_pbIsIn[j] && ! cppu_isSimpleType( pMTI->m_ppArgType[j] ))
+ {
+ uno_destructData( pSJE->m_ppArgs[j] , pMTI->m_ppArgType[j] ,
+ ::bridges_remote::remote_release );
+ }
+ }
+ }
+ else
+ {
+ //---------------------------
+ // alles ist gut ...
+ //--------------------------
+ if( pMTI->m_pReturnType )
+ {
+ m_pBridgeImpl->m_blockMarshaler.pack(
+ pSJE->m_pReturn, pMTI->m_pReturnType );
+ if( ! cppu_isSimpleType( pMTI->m_pReturnType ) )
+ {
+ uno_destructData( pSJE->m_pReturn , pMTI->m_pReturnType ,
+ ::bridges_remote::remote_release );
+ }
+ }
+ for( sal_Int32 j = 0 ; j < pMTI->m_nArgCount ; j ++ )
+ {
+ if( pMTI->m_pbIsOut[j] )
+ {
+ m_pBridgeImpl->m_blockMarshaler.pack(
+ pSJE->m_ppArgs[j] , pMTI->m_ppArgType[j] );
+ }
+ if( ! cppu_isSimpleType( pMTI->m_ppArgType[j] ) )
+ {
+ uno_destructData( pSJE->m_ppArgs[j], pMTI->m_ppArgType[j] ,
+ ::bridges_remote::remote_release );
+ }
+ }
+ }
+
+#ifdef BRIDGES_URP_PROT
+ {
+ typelib_InterfaceMemberTypeDescription *pMemberType =
+ pMTI->m_pMethodType ?
+ (typelib_InterfaceMemberTypeDescription*)pMTI->m_pMethodType :
+ (typelib_InterfaceMemberTypeDescription*)pMTI->m_pAttributeType;
+
+ urp_logReplying( m_pBridgeImpl ,
+ m_pBridgeImpl->m_blockMarshaler.getPos() - nLogStart,
+ m_pBridgeImpl->m_blockMarshaler.getPos() - nLogHeader,
+ pMemberType->pMemberName );
+ }
+#endif
+
+ m_pBridgeImpl->m_nMarshaledMessages ++;
+ // put it on the wire
+ m_pBridgeImpl->m_pWriter->touch( sal_True );
+ } // MutexGuard marshalingMutex
+ }
+ if ( bHasOldCc )
+ {
+ if ( !com::sun::star::uno::setCurrentContext( xOldCc ) )
+ {
+ throw RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "fatal: com::sun::star::uno::setCurrentContext"
+ " failed" ) ),
+ Reference< XInterface >() );
+ }
+ }
+ }
+
+ //-------------------------------------------------------------------------------------
+ void ServerMultiJob::prepareRuntimeException( const OUString & sMessage , sal_Int32 nCall )
+ {
+ // -------------------------------
+ // Construct the DisposedException
+ // -------------------------------
+ com::sun::star::lang::DisposedException exception( sMessage , Reference< XInterface > () );
+ Type type = getCppuType( &exception );
+ if( !isDisposedExceptionDescriptionAvail( type ) )
+ {
+ // if it is not available (probably missing type library),
+ // then we are satisfied with throwing a normal runtime exception,
+ // for which cppu provides a static description
+ type = getCppuType( ( RuntimeException * ) 0 );
+ }
+
+ m_aEntries[nCall].m_pException = &(m_aEntries[nCall].m_exception);
+ uno_type_any_construct( m_aEntries[nCall].m_pException , &exception , type.getTypeLibType() , 0 );
+ }
+
+ //-------------------------------------------------------------------------------------
+ void ServerMultiJob::initiate()
+ {
+ uno_threadpool_putJob(
+ m_pBridgeImpl->m_hThreadPool,
+ m_pTid,
+ this,
+ doit,
+ m_aTypeInfo[0].m_bIsOneway );
+ }
+
+
+ //-------------------------------------------------------------------------------------
+ sal_Bool ServerMultiJob::extract()
+ {
+ sal_Bool bContinue = sal_True;
+ struct MemberTypeInfo * const pMTI = &(m_aTypeInfo[m_nCalls]);
+ struct ServerJobEntry * const pSJE = &(m_aEntries[m_nCalls]);
+
+ pSJE->m_pException = 0;
+ pSJE->m_ppArgs = 0;
+ pSJE->m_pReturn = 0;
+ pMTI->m_pReturnType = 0;
+
+ if( pMTI->m_nArgCount )
+ {
+ pMTI->m_ppArgType =
+ ( typelib_TypeDescription ** ) getHeap( sizeof(void*) * pMTI->m_nArgCount );
+ pSJE->m_ppArgs = (void**) getHeap( sizeof( void * ) * pMTI->m_nArgCount );
+ pMTI->m_pbIsIn = (sal_Bool *) getHeap( sizeof( sal_Bool ) * pMTI->m_nArgCount );
+ pMTI->m_pbIsOut = (sal_Bool *) getHeap( sizeof( sal_Bool ) * pMTI->m_nArgCount );
+ }
+ if( pMTI->m_pMethodType &&
+ pMTI->m_pMethodType->pReturnTypeRef->eTypeClass != typelib_TypeClass_VOID )
+ {
+ TYPELIB_DANGER_GET( &(pMTI->m_pReturnType), pMTI->m_pMethodType->pReturnTypeRef );
+ }
+ else if( pMTI->m_pAttributeType && ! pMTI->m_nArgCount )
+ {
+ TYPELIB_DANGER_GET( &(pMTI->m_pReturnType) , pMTI->m_pAttributeType->pAttributeTypeRef );
+ }
+
+ // normal method
+ if( pMTI->m_pMethodType )
+ {
+ for( sal_Int32 i = 0 ; i < pMTI->m_nArgCount ; i ++ )
+ {
+ pMTI->m_ppArgType[i] = 0;
+ TYPELIB_DANGER_GET( & ( pMTI->m_ppArgType[i] ) , pMTI->m_pMethodType->pParams[i].pTypeRef);
+ pMTI->m_pbIsIn[i] = pMTI->m_pMethodType->pParams[i].bIn;
+ pMTI->m_pbIsOut[i] = pMTI->m_pMethodType->pParams[i].bOut;
+
+ pSJE->m_ppArgs[i] = getHeap( pMTI->m_ppArgType[i]->nSize );
+ if( pMTI->m_pbIsIn[i] )
+ {
+ // everything needs to be constructed
+ bContinue = m_pUnmarshal->unpack(
+ pSJE->m_ppArgs[i], pMTI->m_ppArgType[i] ) && bContinue;
+ }
+ }
+ }
+ else if( pMTI->m_nArgCount )
+ {
+ // set attribut
+ pMTI->m_ppArgType[0] = 0;
+ pMTI->m_pbIsIn[0] = sal_True;
+ pMTI->m_pbIsOut[0] = sal_False;
+ TYPELIB_DANGER_GET(
+ & ( pMTI->m_ppArgType[0] ) , pMTI->m_pAttributeType->pAttributeTypeRef );
+ pSJE->m_ppArgs[0] = getHeap( pMTI->m_ppArgType[0]->nSize );
+ bContinue = m_pUnmarshal->unpack(
+ pSJE->m_ppArgs[0], pMTI->m_ppArgType[0] ) && bContinue;
+ }
+
+ if( pMTI->m_pReturnType )
+ {
+ pSJE->m_pReturn = getHeap( pMTI->m_pReturnType->nSize );
+ }
+
+ m_nCalls ++;
+ return bContinue;
+ }
+}
+
+
diff --git a/bridges/source/remote/urp/urp_job.hxx b/bridges/source/remote/urp/urp_job.hxx
new file mode 100644
index 000000000000..4b769ec27f2a
--- /dev/null
+++ b/bridges/source/remote/urp/urp_job.hxx
@@ -0,0 +1,381 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_job.hxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _URP_JOB_HXX_
+#define _URP_JOB_HXX_
+#include <list>
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+#include <uno/environment.h>
+#include <uno/threadpool.h>
+#include "urp_threadid.hxx"
+#include "urp_unmarshal.hxx"
+#include "urp_bridgeimpl.hxx"
+
+
+namespace bridges_urp
+{
+const sal_Int32 MULTIJOB_STANDARD_MEMORY_SIZE = 1024;
+const sal_Int32 MULTIJOB_PER_CALL_MEMORY_SIZE = 96;
+
+class Unmarshal;
+struct urp_BridgeImpl;
+
+template < class t >
+inline t mymax( const t &t1 , const t &t2 )
+{
+ return t1 > t2 ? t1 : t2;
+}
+
+class Job
+{
+public:
+ Job( uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ sal_Sequence *pTid,
+ struct urp_BridgeImpl *pBridgeImpl,
+ Unmarshal *pUnmarshal );
+
+ Job( uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ struct urp_BridgeImpl *pBridgeImpl,
+ ::bridges_remote::RemoteThreadCounter_HoldEnvWeak value )
+ : m_pContext( pContext )
+ , m_pBridgeImpl( pBridgeImpl )
+ , m_pTid( 0 )
+ , m_counter( pEnvRemote , value )
+ {
+ if ( m_pContext )
+ {
+ m_pContext->aBase.acquire( &m_pContext->aBase );
+ }
+ }
+
+ ~Job();
+
+ inline void setUnmarshal( Unmarshal *p )
+ { m_pUnmarshal = p; }
+
+public:
+ remote_Context *m_pContext;
+ Unmarshal *m_pUnmarshal;
+ struct urp_BridgeImpl *m_pBridgeImpl;
+ sal_Sequence *m_pTid;
+ ::bridges_remote::RemoteThreadCounter m_counter;
+};
+
+class ClientJob : public Job
+{
+public:
+ // pContext is null for bridge-internal UrpProtocolProperties requests
+ inline ClientJob( uno_Environment *pEnvRemote, // weak !
+ remote_Context *pContext,
+ struct urp_BridgeImpl *pBridgeImpl,
+ rtl_uString *pOid, // weak
+ typelib_TypeDescription const * pMemberType, // weak
+ typelib_InterfaceTypeDescription *pInterfaceType, // weak
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException );
+
+ // ~ClientJob
+ // no release for method type and attribute type necessary, because
+ // it was acquired by the caller of urp_sendRequest. The lifetime
+ // of the ClientJob object is always shorter than the urp_sendRequest call.
+ inline ~ClientJob()
+ {
+ if( m_bReleaseForTypeDescriptionNecessary )
+ typelib_typedescription_release( (typelib_TypeDescription*) m_pInterfaceType );
+ uno_releaseIdFromCurrentThread();
+ }
+
+ sal_Bool pack();
+ void wait();
+ sal_Bool extract( );
+ void initiate();
+
+ inline void setBridgePropertyCall()
+ { m_bBridgePropertyCall = sal_True; }
+ inline sal_Bool isBridgePropertyCall()
+ { return m_bBridgePropertyCall; }
+ inline sal_Bool isOneway()
+ { return m_bOneway; }
+public:
+ typelib_InterfaceMethodTypeDescription *m_pMethodType;
+ typelib_InterfaceAttributeTypeDescription *m_pAttributeType;
+ sal_Bool m_bExceptionOccured;
+
+private:
+ void **m_ppArgs;
+ void *m_pReturn;
+ typelib_InterfaceTypeDescription *m_pInterfaceType;
+ sal_Bool m_bReleaseForTypeDescriptionNecessary;
+
+ uno_Any **m_ppException;
+ sal_Bool m_bOneway;
+ sal_Bool m_bBridgePropertyCall;
+ sal_uInt16 m_nMethodIndex;
+ uno_Environment *m_pEnvRemote;
+ rtl_uString *m_pOid;
+ sal_Bool m_bCallingConventionForced;
+};
+
+struct MemberTypeInfo
+{
+ typelib_InterfaceTypeDescription *m_pInterfaceType;
+ typelib_InterfaceMethodTypeDescription *m_pMethodType;
+ typelib_InterfaceAttributeTypeDescription *m_pAttributeType;
+ sal_Int32 m_nArgCount;
+ sal_Bool m_bIsReleaseCall;
+ sal_Bool *m_pbIsIn;
+ sal_Bool *m_pbIsOut;
+ sal_Bool m_bIsOneway;
+ typelib_TypeDescription *m_pReturnType;
+ typelib_TypeDescription **m_ppArgType;
+};
+
+
+struct ServerJobEntry
+{
+ rtl_uString *m_pOid;
+ remote_Interface *m_pRemoteI;
+ typelib_TypeDescriptionReference *m_pInterfaceTypeRef;
+ void **m_ppArgs;
+ void *m_pReturn;
+ uno_Any m_exception;
+ uno_Any *m_pException;
+ remote_Interface *m_pCurrentContext;
+ sal_Bool m_bHasCurrentContext;
+ sal_Bool m_bIgnoreCache;
+};
+
+class ServerMultiJob : public Job
+{
+public:
+ ServerMultiJob( uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ sal_Sequence *pTid,
+ struct urp_BridgeImpl *pBridgeImpl,
+ Unmarshal *pUnmarshal,
+ sal_Int32 nMaxMessages );
+ ~ServerMultiJob();
+public:
+ sal_Bool extract( );
+ void initiate();
+ void execute();
+
+public:
+ // setMethodType or setAttributeType MUST be called before extract
+ inline void setMethodType(
+ typelib_InterfaceMethodTypeDescription *pMethodType,
+ sal_Bool bIsReleaseCall,
+ sal_Bool bIsOneway )
+ {
+ m_aTypeInfo[m_nCalls].m_pMethodType = pMethodType;
+ m_aTypeInfo[m_nCalls].m_pAttributeType = 0;
+ m_aTypeInfo[m_nCalls].m_nArgCount = pMethodType->nParams;
+ m_aTypeInfo[m_nCalls].m_bIsReleaseCall = bIsReleaseCall;
+ m_aTypeInfo[m_nCalls].m_bIsOneway = bIsOneway;
+ }
+
+ inline void setAttributeType(
+ typelib_InterfaceAttributeTypeDescription *pAttributeType, sal_Bool bIsSetter, sal_Bool bIsOneway )
+ {
+ m_aTypeInfo[m_nCalls].m_pAttributeType = pAttributeType;
+ m_aTypeInfo[m_nCalls].m_pMethodType = 0;
+ m_aTypeInfo[m_nCalls].m_nArgCount = bIsSetter ? 1 : 0;
+ m_aTypeInfo[m_nCalls].m_bIsReleaseCall = sal_False;
+ m_aTypeInfo[m_nCalls].m_bIsOneway = bIsOneway;
+ }
+
+ inline void setType( typelib_TypeDescriptionReference *pTypeRef )
+ {
+ m_aEntries[m_nCalls].m_pInterfaceTypeRef = pTypeRef;
+ typelib_typedescriptionreference_acquire( m_aEntries[m_nCalls].m_pInterfaceTypeRef );
+ TYPELIB_DANGER_GET(
+ (typelib_TypeDescription ** )&(m_aTypeInfo[m_nCalls].m_pInterfaceType) ,
+ pTypeRef );
+ }
+ // setOid or setInterface MUST be called before extract
+ inline void setOid( rtl_uString *pOid )
+ {
+ m_aEntries[m_nCalls].m_pOid = pOid;
+ rtl_uString_acquire( m_aEntries[m_nCalls].m_pOid );
+ m_aEntries[m_nCalls].m_pRemoteI = 0;
+ }
+
+ // setOid or setInterface MUST be called
+ inline void setInterface( remote_Interface *pRemoteI )
+ {
+ m_aEntries[m_nCalls].m_pRemoteI = pRemoteI;
+ pRemoteI->acquire( pRemoteI );
+ m_aEntries[m_nCalls].m_pOid = 0;
+ }
+
+ inline void setCurrentContext(
+ bool bHasCurrentContext, remote_Interface *pCurrentContext )
+ {
+ m_aEntries[m_nCalls].m_pCurrentContext = pCurrentContext;
+ m_aEntries[m_nCalls].m_bHasCurrentContext = bHasCurrentContext;
+ }
+
+ inline void setIgnoreCache( sal_Bool bIgnoreCache )
+ {
+ m_aEntries[m_nCalls].m_bIgnoreCache = bIgnoreCache;
+ }
+
+ inline sal_Bool isFull()
+ { return m_nCalls >= m_nMaxMessages; }
+
+ inline sal_Int8 *getHeap( sal_Int32 nSizeToAlloc )
+ {
+ if( nSizeToAlloc + m_nCurrentMemPosition > m_nCurrentMemSize )
+ {
+ m_lstMem.push_back( m_pCurrentMem );
+ m_nCurrentMemSize = mymax( nSizeToAlloc , MULTIJOB_STANDARD_MEMORY_SIZE ) +
+ (m_nMaxMessages -m_nCalls)*MULTIJOB_PER_CALL_MEMORY_SIZE;
+ m_pCurrentMem = (sal_Int8*) rtl_allocateMemory( m_nCurrentMemSize );
+ m_nCurrentMemPosition = 0;
+ }
+ sal_Int8 *pHeap = m_pCurrentMem + m_nCurrentMemPosition;
+ m_nCurrentMemPosition += nSizeToAlloc;
+
+ // care for alignment
+ if( m_nCurrentMemPosition & 0x7 )
+ {
+ m_nCurrentMemPosition = ( ((sal_uInt32)m_nCurrentMemPosition) & ( 0xffffffff - 0x7 )) + 8;
+ }
+ return pHeap;
+ }
+ void prepareRuntimeException( const ::rtl::OUString &sMessage, sal_Int32 nCall );
+
+private:
+ uno_Environment *m_pEnvRemote;
+ sal_Int32 m_nCalls;
+ sal_Int32 m_nMaxMessages;
+
+ ServerJobEntry *m_aEntries;
+ MemberTypeInfo *m_aTypeInfo;
+
+ sal_Int8 *m_pCurrentMem;
+ sal_Int32 m_nCurrentMemSize;
+ sal_Int32 m_nCurrentMemPosition;
+
+ // list of memory pointers, that must be freed
+ ::std::list< sal_Int8 * > m_lstMem;
+};
+
+
+
+//---------------------------------------------------------------------------------------------
+inline ClientJob::ClientJob(
+ uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ struct urp_BridgeImpl *pBridgeImpl,
+ rtl_uString *pOid,
+ typelib_TypeDescription const * pMemberType,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException )
+ : Job(
+ pEnvRemote, pContext, pBridgeImpl, ::bridges_remote::RTC_HOLDENVWEAK )
+ , m_ppArgs( ppArgs )
+ , m_pReturn( pReturn )
+ , m_pInterfaceType( pInterfaceType ) // weak
+ , m_bReleaseForTypeDescriptionNecessary( sal_False )
+ , m_ppException( ppException )
+ , m_bBridgePropertyCall( sal_False )
+ , m_pEnvRemote( pEnvRemote ) // weak
+ , m_pOid( pOid ) // weak
+ , m_bCallingConventionForced( sal_False )
+{
+ uno_getIdOfCurrentThread( &m_pTid );
+
+ if( typelib_TypeClass_INTERFACE_METHOD == pMemberType->eTypeClass )
+ {
+ m_pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pMemberType;
+ m_pAttributeType = 0;
+ }
+ else if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pMemberType->eTypeClass )
+ {
+ m_pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pMemberType;
+ m_pMethodType = 0;
+ }
+ else
+ {
+ OSL_ASSERT( ! "wrong member type" );
+ }
+
+ // calculate method index
+ if( ! m_pInterfaceType->aBase.bComplete )
+ {
+ // must be acquired because typedescription may be exchanged
+ typelib_typedescription_acquire((typelib_TypeDescription*) m_pInterfaceType );
+ m_bReleaseForTypeDescriptionNecessary = sal_True;
+ typelib_typedescription_complete( (typelib_TypeDescription ** ) &m_pInterfaceType );
+ }
+ m_nMethodIndex = (sal_uInt16) m_pInterfaceType->pMapMemberIndexToFunctionIndex[
+ ((typelib_InterfaceMemberTypeDescription*)pMemberType)->nPosition ];
+
+ if( m_pAttributeType && m_ppArgs )
+ {
+ // setter
+ m_nMethodIndex ++;
+ }
+
+ if( typelib_TypeClass_INTERFACE_METHOD == pMemberType->eTypeClass )
+ {
+// if( (( typelib_InterfaceMemberTypeDescription * ) pMemberType)->nPosition
+// == REMOTE_RELEASE_METHOD_INDEX )
+// {
+// m_bOneway = sal_True;
+// }
+// else
+ if( pBridgeImpl->m_properties.bForceSynchronous )
+ {
+ m_bOneway = sal_False;
+ if( (( typelib_InterfaceMethodTypeDescription * ) pMemberType)->bOneWay )
+ {
+ m_bCallingConventionForced = sal_True;
+ }
+ }
+ else
+ {
+ m_bOneway = (( typelib_InterfaceMethodTypeDescription * ) pMemberType)->bOneWay;
+ }
+ }
+ else
+ {
+ m_bOneway = sal_False;
+ }
+}
+
+}
+#endif
diff --git a/bridges/source/remote/urp/urp_log.cxx b/bridges/source/remote/urp/urp_log.cxx
new file mode 100644
index 000000000000..242503fa7221
--- /dev/null
+++ b/bridges/source/remote/urp/urp_log.cxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_log.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <osl/time.h>
+#include "urp_bridgeimpl.hxx"
+#include "urp_log.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+namespace bridges_urp
+{
+#ifdef BRIDGES_URP_PROT
+ Mutex g_logFileMutex;
+
+ class FileAccess
+ {
+ public:
+ FileAccess( urp_BridgeImpl *pBridgeImpl_ ) :
+ pBridgeImpl( pBridgeImpl_ ),
+ guard( g_logFileMutex )
+ {
+ if( pBridgeImpl->m_pLogFile )
+ {
+ f = pBridgeImpl->m_pLogFile;
+ }
+ else
+ {
+ f = fopen( pBridgeImpl->m_sLogFileName.getStr() , "a" );
+ }
+ }
+ ~FileAccess()
+ {
+ if( ! pBridgeImpl->m_pLogFile )
+ {
+ fclose( f );
+ }
+ }
+ FILE *getFile()
+ {
+ return f;
+ }
+ private:
+ urp_BridgeImpl *pBridgeImpl;
+ MutexGuard guard;
+ FILE *f;
+ };
+
+ void urp_logCall( urp_BridgeImpl *pBridgeImpl, sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron ,
+ const ::rtl::OUString &sMethodName )
+ {
+ if( pBridgeImpl->m_sLogFileName.getLength() && getenv( "PROT_REMOTE_ACTIVATE" ) )
+ {
+ OString sOperation = OUStringToOString( sMethodName,RTL_TEXTENCODING_ASCII_US );
+
+ FileAccess access( pBridgeImpl );
+ fprintf( access.getFile() ,
+ "%06u: calling [size=%d(usedata=%d)] [synchron=%d] [name=%s]\n" ,
+ static_cast< unsigned int > (osl_getGlobalTimer()),
+ static_cast< int > (nSize),
+ static_cast< int > (nUseData),
+ bSynchron, sOperation.pData->buffer );
+ }
+ }
+
+ void urp_logServingRequest( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron ,
+ const ::rtl::OUString &sMethodName )
+ {
+ if( pBridgeImpl->m_sLogFileName.getLength() && getenv( "PROT_REMOTE_ACTIVATE" ) )
+ {
+ OString sOperation = OUStringToOString( sMethodName,RTL_TEXTENCODING_ASCII_US );
+
+ FileAccess access( pBridgeImpl );
+ fprintf(
+ access.getFile(),
+ "%06u: serving request [size=%d(usedata=%d)] [synchron=%d] [name=%s]\n",
+ static_cast< unsigned int > (osl_getGlobalTimer()),
+ static_cast< int > (nSize),
+ static_cast< int > (nUseData),
+ bSynchron,
+ sOperation.pData->buffer
+ );
+ }
+ }
+
+ void urp_logGettingReply( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize, sal_Int32 nUseData,
+ const ::rtl::OUString &sMethodName )
+ {
+ if( pBridgeImpl->m_sLogFileName.getLength() && getenv( "PROT_REMOTE_ACTIVATE" ) )
+ {
+ OString sOperation = OUStringToOString( sMethodName,RTL_TEXTENCODING_ASCII_US );
+ FileAccess access( pBridgeImpl );
+ fprintf( access.getFile(),
+ "%06u: getting reply [size=%d(usedata=%d)][name=%s]\n" ,
+ static_cast< unsigned int > (osl_getGlobalTimer()),
+ static_cast< int > (nSize),
+ static_cast< int > (nUseData),
+ sOperation.pData->buffer);
+ }
+ }
+
+ void urp_logReplying( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize , sal_Int32 nUseData,
+ const ::rtl::OUString &sMethodName )
+ {
+ if( pBridgeImpl->m_sLogFileName.getLength() && getenv( "PROT_REMOTE_ACTIVATE" ) )
+ {
+ OString sOperation = OUStringToOString(sMethodName,RTL_TEXTENCODING_ASCII_US);
+
+ FileAccess access( pBridgeImpl );
+ fprintf( access.getFile(),
+ "%06u: replying [size=%d(usedata=%d)] [name=%s]\n",
+ static_cast< unsigned int > (osl_getGlobalTimer()),
+ static_cast< int > (nSize),
+ static_cast< int > (nUseData),
+ sOperation.pData->buffer);
+ }
+ }
+#endif
+}
diff --git a/bridges/source/remote/urp/urp_log.hxx b/bridges/source/remote/urp/urp_log.hxx
new file mode 100644
index 000000000000..c7811faf51e9
--- /dev/null
+++ b/bridges/source/remote/urp/urp_log.hxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_log.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+namespace bridges_urp
+{
+#ifndef PRODUCT
+#define BRIDGES_URP_PROT
+#endif
+
+#ifdef BRIDGES_URP_PROT
+ void urp_logCall( urp_BridgeImpl *pBridgeImpl ,
+ sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron ,
+ const ::rtl::OUString &sMethodName );
+
+ void urp_logServingRequest( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron ,
+ const ::rtl::OUString &sMethodName );
+
+ void urp_logGettingReply( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize, sal_Int32 nUseData,
+ const ::rtl::OUString &sMethodName );
+
+ void urp_logReplying( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize , sal_Int32 nUseData,
+ const ::rtl::OUString &sMethodName );
+#endif
+}
diff --git a/bridges/source/remote/urp/urp_marshal.cxx b/bridges/source/remote/urp/urp_marshal.cxx
new file mode 100644
index 000000000000..3931eda4908f
--- /dev/null
+++ b/bridges/source/remote/urp/urp_marshal.cxx
@@ -0,0 +1,238 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_marshal.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <string.h>
+#include <osl/diagnose.h>
+#include <rtl/alloc.h>
+
+#include <uno/any2.h>
+#include <uno/sequence2.h>
+
+#include "urp_marshal.hxx"
+
+using namespace ::rtl;
+
+using namespace ::com::sun::star::uno;
+
+namespace bridges_urp {
+
+static int g_nDetectLittleEndian = 1;
+char g_bMarshalSystemIsLittleEndian = ((char*)&g_nDetectLittleEndian)[0];
+
+Marshal::Marshal( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nBufferSize,
+ urp_extractOidCallback callback) :
+ m_nBufferSize( nBufferSize ),
+ m_base( (sal_Int8*)rtl_allocateMemory( nBufferSize ) ),
+ m_pos( m_base + 2*sizeof( sal_Int32 ) ),
+ m_pBridgeImpl( pBridgeImpl ),
+ m_callback( callback )
+{}
+
+Marshal::~Marshal( )
+{
+ rtl_freeMemory( m_base );
+}
+
+void Marshal::packOid( const ::rtl::OUString & oid )
+{
+ sal_uInt16 nIndex;
+ if( oid.getLength() )
+ {
+ nIndex = m_pBridgeImpl->m_oidCacheOut.seek( oid );
+ if( 0xffff == nIndex )
+ {
+ nIndex = m_pBridgeImpl->m_oidCacheOut.put( oid );
+ packString( (void*)(&oid.pData) );
+ }
+ else
+ {
+ OUString dummy;
+ packString( &dummy );
+ }
+ }
+ else
+ {
+ // null reference
+ nIndex = 0xffff;
+ OUString dummy;
+ packString( &dummy );
+ }
+ packInt16( &nIndex );
+}
+
+void Marshal::packTid( const ByteSequence & threadId, sal_Bool bIgnoreCache )
+{
+
+ sal_uInt16 nIndex = 0xffff;
+ if( ! bIgnoreCache )
+ {
+ nIndex = m_pBridgeImpl->m_tidCacheOut.seek( threadId );
+ }
+
+ if( 0xffff == nIndex )
+ {
+ if( ! bIgnoreCache )
+ {
+ nIndex = m_pBridgeImpl->m_tidCacheOut.put( threadId );
+ }
+ packByteSequence( (sal_Int8*) threadId.getConstArray() ,threadId.getLength());
+ }
+ else
+ {
+ packByteSequence( 0 , 0 );
+ }
+ packInt16( &nIndex );
+}
+
+
+void Marshal::packType( void *pSource )
+{
+ typelib_TypeDescriptionReference *pRef =
+ *(typelib_TypeDescriptionReference ** ) pSource;
+
+ OSL_ASSERT( pRef );
+
+ sal_uInt8 nTypeClass = ( sal_uInt8 ) pRef->eTypeClass;
+
+ if( nTypeClass <= /* any*/ 14 )
+ {
+ packInt8( (sal_Int8*)&nTypeClass );
+ }
+ else
+ {
+ OUString sTypeName;
+ sal_uInt16 nIndex = 0xffff;
+
+ nIndex = m_pBridgeImpl->m_typeCacheOut.seek( *(Type*)&pRef );
+ if( 0xffff == nIndex )
+ {
+ // put it into the cache
+ nIndex = m_pBridgeImpl->m_typeCacheOut.put( *(Type*)&pRef );
+ sTypeName = pRef->pTypeName;
+ nTypeClass = nTypeClass | 0x80;
+ }
+ packInt8( &nTypeClass );
+ packInt16( &nIndex );
+ if( 0x80 & nTypeClass )
+ {
+ packString( &sTypeName );
+ }
+ }
+}
+
+sal_Bool Marshal::packRecursive( void *pSource , typelib_TypeDescription *pType )
+{
+ sal_Bool bSuccess = sal_True;
+ switch( pType->eTypeClass )
+ {
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_STRUCT:
+ {
+ typelib_CompoundTypeDescription * pCompType = (typelib_CompoundTypeDescription*)pType;
+
+ if (pCompType->pBaseTypeDescription)
+ {
+ bSuccess = pack( pSource , (typelib_TypeDescription*) pCompType->pBaseTypeDescription );
+ }
+
+ // then construct members
+ typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets;
+ sal_Int32 nDescr = pCompType->nMembers;
+
+ for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos )
+ {
+ typelib_TypeDescription * pMemberType = 0;
+ TYPELIB_DANGER_GET( &pMemberType, ppTypeRefs[nPos] );
+ if( pMemberType )
+ {
+ bSuccess = bSuccess && pack( (char*)pSource + pMemberOffsets[nPos] , pMemberType );
+ TYPELIB_DANGER_RELEASE( pMemberType );
+ }
+ else
+ {
+ OUStringBuffer buf( 64 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Couldn't get typedescription for type "));
+ buf.append( ppTypeRefs[nPos]->pTypeName );
+ m_pBridgeImpl->addError( buf.makeStringAndClear() );
+ bSuccess = sal_False;
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ typelib_IndirectTypeDescription *pIndirectType =
+ ( typelib_IndirectTypeDescription* ) pType;
+
+ const sal_Int32 nElements = (*(uno_Sequence **)pSource)->nElements;
+ char * pSourceElements = (char *)(*(uno_Sequence **)pSource)->elements;
+
+ if( typelib_TypeClass_BYTE == pIndirectType->pType->eTypeClass )
+ {
+ // Byte sequences are optimized
+ packByteSequence( (sal_Int8*)pSourceElements , nElements );
+ }
+ else
+ {
+ typelib_TypeDescription *pElementType = 0;
+ TYPELIB_DANGER_GET( &pElementType, pIndirectType->pType );
+ if( pElementType )
+ {
+ const sal_Int32 nElementSize = pElementType->nSize;
+
+ packCompressedSize( nElements );
+ for ( sal_Int32 i = 0 ; i < nElements; i++ )
+ {
+ bSuccess = bSuccess && pack( pSourceElements + (nElementSize*i) , pElementType );
+ }
+ TYPELIB_DANGER_RELEASE( pElementType );
+ }
+ else
+ {
+ bSuccess = sal_False;
+ OUStringBuffer buf( 64 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Couldn't get typedescription for type "));
+ buf.append( pIndirectType->pType->pTypeName );
+ m_pBridgeImpl->addError( buf.makeStringAndClear() );
+ }
+ }
+ break;
+ }
+ default:
+ OSL_ASSERT( 0 );
+ }
+ return bSuccess;
+}
+
+} // end namespace bridges
diff --git a/bridges/source/remote/urp/urp_marshal.hxx b/bridges/source/remote/urp/urp_marshal.hxx
new file mode 100644
index 000000000000..30cfad42cdd9
--- /dev/null
+++ b/bridges/source/remote/urp/urp_marshal.hxx
@@ -0,0 +1,346 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_marshal.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _URP_MARSHAL_HXX_
+#define _URP_MARSHAL_HXX_
+#include <rtl/ustrbuf.hxx>
+#include <rtl/byteseq.hxx>
+#include <com/sun/star/uno/Type.hxx>
+#include "urp_bridgeimpl.hxx"
+#include "urp_marshal_decl.hxx"
+
+#include <string.h>
+
+struct remote_Interface;
+
+namespace bridges_urp
+{
+ // methods for accessing marshaling buffer
+ inline void Marshal::finish( sal_Int32 nMessageCount )
+ {
+ sal_Int32 nSize = getSize() - 2*sizeof( sal_Int32 );
+
+ // save the state
+ sal_Int8 *pos = m_pos;
+ m_pos = m_base;
+ packInt32( &nSize );
+ packInt32( &nMessageCount );
+
+ // reset the state
+ m_pos = pos;
+ }
+
+ inline void Marshal::restart()
+ {
+ m_pos = m_base + 2*sizeof( sal_Int32 );
+ }
+
+ inline sal_Int8 *Marshal::getBuffer()
+ {
+ return m_base;
+ }
+
+ inline sal_Bool Marshal::empty() const
+ {
+ return ( m_pos - m_base ) == 2*sizeof( sal_Int32 );
+ }
+
+ inline sal_Int32 Marshal::getSize()
+ {
+ return ((sal_Int32) (m_pos - m_base));
+ }
+
+ inline void Marshal::ensureAdditionalMem( sal_Int32 nMemToAdd )
+ {
+ sal_Int32 nDiff = m_pos - m_base;
+ if( nDiff + nMemToAdd > m_nBufferSize )
+ {
+ m_nBufferSize = m_nBufferSize * 2 > nDiff + nMemToAdd ?
+ m_nBufferSize* 2 :
+ nDiff + nMemToAdd;
+
+ m_base = ( sal_Int8 * ) rtl_reallocateMemory( m_base , m_nBufferSize );
+ m_pos = m_base + nDiff;
+ }
+ }
+
+ // marshaling methods
+ inline void Marshal::packInt8( void *pSource )
+ {
+ ensureAdditionalMem( 1 );
+ *m_pos = *((sal_Int8*) pSource );
+ m_pos++;
+ }
+
+ inline void Marshal::packInt16( void *pSource )
+ {
+ ensureAdditionalMem( 2 );
+ if( isSystemLittleEndian() )
+ {
+ m_pos[0] = ((unsigned char *)pSource)[1];
+ m_pos[1] = ((unsigned char *)pSource)[0];
+ }
+ else
+ {
+ m_pos[1] = ((unsigned char *)pSource)[1];
+ m_pos[0] = ((unsigned char *)pSource)[0];
+ }
+ m_pos +=2;
+ }
+
+ inline void Marshal::packByteSequence( sal_Int8 *pData , sal_Int32 nLength )
+ {
+ packCompressedSize( nLength );
+
+ ensureAdditionalMem( nLength );
+ memcpy( m_pos , pData , nLength );
+ m_pos += nLength;
+ }
+
+ inline void Marshal::packString( void *pSource )
+ {
+ rtl_uString *p = *( rtl_uString ** ) pSource;
+
+ // to be optimized !
+ // static buffer in marshal
+ ::rtl::OString o = ::rtl::OUStringToOString( p , RTL_TEXTENCODING_UTF8 );
+ sal_Int32 nLength = o.pData->length;
+ packCompressedSize( nLength );
+
+ ensureAdditionalMem( nLength );
+
+ memcpy( m_pos , o.pData->buffer , nLength );
+ m_pos += nLength;
+ }
+
+ inline sal_Bool Marshal::packAny( void *pSource )
+ {
+ sal_Bool bSuccess = sal_True;
+ uno_Any *pAny = (uno_Any * ) pSource;
+
+ // pack the type
+ packType( &( pAny->pType ) );
+ // pack the value
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType, pAny->pType );
+ if( pType )
+ {
+ pack( pAny->pData , pType );
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+ else
+ {
+ rtl::OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("couldn't get typedescription for type " ) );
+ buf.append( pAny->pType->pTypeName );
+ m_pBridgeImpl->addError( buf.makeStringAndClear() );
+ bSuccess = sal_False;
+ }
+ return bSuccess;
+ }
+
+ inline void Marshal::packInt32( void *pSource )
+ {
+ ensureAdditionalMem( 4 );
+ if( isSystemLittleEndian() )
+ {
+ m_pos[0] = ((unsigned char *)pSource)[3];
+ m_pos[1] = ((unsigned char *)pSource)[2];
+ m_pos[2] = ((unsigned char *)pSource)[1];
+ m_pos[3] = ((unsigned char *)pSource)[0];
+ }
+ else {
+ m_pos[3] = ((unsigned char *)pSource)[3];
+ m_pos[2] = ((unsigned char *)pSource)[2];
+ m_pos[1] = ((unsigned char *)pSource)[1];
+ m_pos[0] = ((unsigned char *)pSource)[0];
+ }
+ m_pos +=4;
+ }
+
+ inline void Marshal::packCompressedSize( sal_Int32 nSize )
+ {
+ ensureAdditionalMem( 5 );
+
+ if( nSize < 0xff )
+ {
+ *((sal_uInt8*)m_pos) = (sal_uInt8) nSize;
+ m_pos ++;
+ }
+ else
+ {
+ *((sal_uInt8*)m_pos) = 0xff;
+ m_pos ++;
+ packInt32( &nSize );
+ }
+ }
+
+ inline sal_Bool Marshal::pack( void *pSource , typelib_TypeDescription *pType )
+ {
+ sal_Bool bSuccess = sal_True;
+ switch( pType->eTypeClass )
+ {
+ case typelib_TypeClass_BYTE:
+ {
+ packInt8( pSource );
+ break;
+ }
+ case typelib_TypeClass_BOOLEAN:
+ {
+ ensureAdditionalMem( 1 );
+ *m_pos = ( *((sal_Bool*) pSource ) ) ? 1 : 0;
+ m_pos++;
+ break;
+ }
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ {
+ packInt16( pSource );
+ break;
+ }
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_FLOAT:
+ {
+ packInt32( pSource );
+ break;
+ }
+ case typelib_TypeClass_DOUBLE:
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ {
+ ensureAdditionalMem( 8 );
+ if( isSystemLittleEndian() )
+ {
+ m_pos[0] = ((unsigned char *)pSource)[7];
+ m_pos[1] = ((unsigned char *)pSource)[6];
+ m_pos[2] = ((unsigned char *)pSource)[5];
+ m_pos[3] = ((unsigned char *)pSource)[4];
+ m_pos[4] = ((unsigned char *)pSource)[3];
+ m_pos[5] = ((unsigned char *)pSource)[2];
+ m_pos[6] = ((unsigned char *)pSource)[1];
+ m_pos[7] = ((unsigned char *)pSource)[0];
+ }
+ else
+ {
+ m_pos[7] = ((unsigned char *)pSource)[7];
+ m_pos[6] = ((unsigned char *)pSource)[6];
+ m_pos[5] = ((unsigned char *)pSource)[5];
+ m_pos[4] = ((unsigned char *)pSource)[4];
+ m_pos[3] = ((unsigned char *)pSource)[3];
+ m_pos[2] = ((unsigned char *)pSource)[2];
+ m_pos[1] = ((unsigned char *)pSource)[1];
+ m_pos[0] = ((unsigned char *)pSource)[0];
+ }
+ m_pos += 8;
+ break;
+ }
+
+ case typelib_TypeClass_STRING:
+ {
+ packString( pSource );
+ break;
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ packType( pSource );
+ break;
+ }
+ case typelib_TypeClass_ANY:
+ {
+ bSuccess = packAny( pSource );
+ break;
+ }
+ case typelib_TypeClass_TYPEDEF:
+ {
+ bSuccess = sal_False;
+ m_pBridgeImpl->addError( "can't handle typedef typedescriptions" );
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ remote_Interface *pRemoteI = *( remote_Interface ** )pSource;
+
+ ::rtl::OUString sOid;
+ sal_uInt16 nIndex = 0xffff;
+ if( pRemoteI )
+ {
+ m_callback( pRemoteI , &(sOid.pData) );
+
+ nIndex = m_pBridgeImpl->m_oidCacheOut.seek( sOid );
+ if( 0xffff == nIndex )
+ {
+ nIndex = m_pBridgeImpl->m_oidCacheOut.put( sOid );
+ }
+ else
+ {
+ // cached !
+ sOid = ::rtl::OUString();
+ }
+ }
+ packString( &sOid );
+ packInt16( &nIndex );
+ break;
+ }
+ case typelib_TypeClass_VOID:
+ {
+ // do nothing
+ break;
+ }
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_SEQUENCE:
+ {
+ bSuccess = packRecursive( pSource, pType );
+ break;
+ }
+ default:
+ {
+ bSuccess = sal_False;
+ rtl::OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "can't handle values with typeclass " ) );
+ buf.append( (sal_Int32 ) pType->eTypeClass , 10 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " (" ) );
+ buf.append( pType->pTypeName );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
+ m_pBridgeImpl->addError( buf.makeStringAndClear() );
+ break;
+ }
+ }
+ return bSuccess;
+ }
+}
+
+
+
+#endif
+
diff --git a/bridges/source/remote/urp/urp_marshal_decl.hxx b/bridges/source/remote/urp/urp_marshal_decl.hxx
new file mode 100644
index 000000000000..a5d5e943fd65
--- /dev/null
+++ b/bridges/source/remote/urp/urp_marshal_decl.hxx
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_marshal_decl.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _URP_MARSHAL_DECL_HXX_
+#define _URP_MARSHAL_DECL_HXX_
+
+#include <rtl/ustring.hxx>
+#include <rtl/byteseq.hxx>
+
+#include <com/sun/star/uno/Type.hxx>
+
+namespace bridges_urp
+{
+ struct urp_BridgeImpl;
+
+ typedef void
+ ( SAL_CALL * urp_extractOidCallback )( remote_Interface *pRemoteI, rtl_uString **ppOid );
+
+ extern char g_bMarshalSystemIsLittleEndian;
+ class Marshal
+ {
+ public:
+ Marshal( /* cache access */ struct urp_BridgeImpl *,
+ sal_Int32 m_nBufferSize,
+ urp_extractOidCallback callback = 0
+ );
+ ~Marshal( );
+
+ inline sal_Bool pack( void *pSource , typelib_TypeDescription *pType );
+
+ sal_Bool packRecursive( void *pSource, typelib_TypeDescription *pType );
+
+ void packTid( const ::rtl::ByteSequence &id, sal_Bool bIgnoreCache = sal_False );
+ void packOid( const ::rtl::OUString &oid );
+ void packType( void *pSource );
+
+ inline void packCompressedSize( sal_Int32 nSize );
+ inline void packInt8( void *pSource );
+ inline void packInt16( void *pSource );
+ inline void packInt32( void *pSource );
+ inline void packString( void *pSource );
+ inline sal_Bool packAny( void *pSource );
+ inline void packByteSequence( sal_Int8 *pBuffer , sal_Int32 nSize );
+
+ // can be called during marshaling, but not between
+ // finish and restart
+ // returns true, when nothing has been marshaled
+ inline sal_Bool empty() const;
+
+ // stops marshaling, inserts size in front of the buffer
+ // getStart and getSize can now be called
+ inline void finish( sal_Int32 nMessageCount );
+
+ // must be called after finish. After calling restart,
+ // a new marshalling session is started invalidating
+ // the previous bufer
+ inline void restart();
+
+ // is only valid, after finish has been called.
+ // valid until destructed.
+ inline sal_Int8 *getBuffer();
+
+ // is only valid, after finish has been called.
+ // valid until destructed.
+ inline sal_Int32 getSize();
+
+ inline sal_Int32 getPos()
+ { return m_pos - m_base; }
+
+ inline sal_Bool isSystemLittleEndian()
+ { return g_bMarshalSystemIsLittleEndian; }
+
+ private:
+ inline void ensureAdditionalMem( sal_Int32 nMemToAdd );
+ sal_Int32 m_nBufferSize;
+ sal_Int8 *m_base;
+ sal_Int8 *m_pos;
+ struct urp_BridgeImpl *m_pBridgeImpl;
+ urp_extractOidCallback m_callback;
+ };
+}
+#endif
diff --git a/bridges/source/remote/urp/urp_property.hxx b/bridges/source/remote/urp/urp_property.hxx
new file mode 100644
index 000000000000..0b3f1ea560da
--- /dev/null
+++ b/bridges/source/remote/urp/urp_property.hxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_property.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _URP_PROPERTY_HXX_
+#define _URP_PROPERTY_HXX_
+#ifndef _BRIDGES_REMOTE_REMOTE_H_
+#include <bridges/remote/remote.h>
+#endif
+#include <rtl/ustring.hxx>
+#include <rtl/byteseq.hxx>
+
+namespace bridges_urp
+{
+ struct Properties
+ {
+ ::rtl::ByteSequence seqBridgeID;
+ sal_Int32 nTypeCacheSize;
+ sal_Int32 nOidCacheSize;
+ sal_Int32 nTidCacheSize;
+ ::rtl::OUString sSupportedVersions;
+ ::rtl::OUString sVersion;
+ sal_Int32 nFlushBlockSize;
+ sal_Int32 nOnewayTimeoutMUSEC;
+ sal_Bool bSupportsMustReply;
+ sal_Bool bSupportsSynchronous;
+ sal_Bool bSupportsMultipleSynchronous;
+ sal_Bool bClearCache;
+ sal_Bool bNegotiate;
+ sal_Bool bForceSynchronous;
+ sal_Bool bCurrentContext;
+
+ inline Properties()
+ : nTypeCacheSize( 256 )
+ , nOidCacheSize( 256 )
+ , nTidCacheSize( 256 )
+ , sSupportedVersions( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1.0" ) ) )
+ , sVersion( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1.0" )))
+ , nFlushBlockSize( 4*1024 )
+ , nOnewayTimeoutMUSEC( 10000 )
+ , bSupportsMustReply( sal_False )
+ , bSupportsSynchronous( sal_False )
+ , bSupportsMultipleSynchronous( sal_False )
+ , bClearCache( sal_False )
+ , bNegotiate( sal_True )
+ , bForceSynchronous( sal_True )
+ , bCurrentContext( sal_False )
+ {}
+
+ inline Properties & SAL_CALL operator = ( const Properties &props )
+ {
+ seqBridgeID = props.seqBridgeID;
+ nTypeCacheSize = props.nTypeCacheSize;
+ nOidCacheSize = props.nOidCacheSize;
+ nTidCacheSize = props.nTidCacheSize;
+ sSupportedVersions = props.sSupportedVersions;
+ sVersion = props.sVersion;
+ nFlushBlockSize = props.nFlushBlockSize;
+ nOnewayTimeoutMUSEC = props.nOnewayTimeoutMUSEC;
+ bSupportsMustReply = props.bSupportsMustReply;
+ bSupportsSynchronous = props.bSupportsSynchronous;
+ bSupportsMultipleSynchronous = props.bSupportsMultipleSynchronous;
+ bClearCache = props.bClearCache;
+ bNegotiate = props.bNegotiate;
+ bForceSynchronous = props.bForceSynchronous;
+ bCurrentContext = props.bCurrentContext;
+ return *this;
+ }
+ };
+} // end namespace bridges_urp
+#endif
diff --git a/bridges/source/remote/urp/urp_propertyobject.cxx b/bridges/source/remote/urp/urp_propertyobject.cxx
new file mode 100644
index 000000000000..fa5fd4252490
--- /dev/null
+++ b/bridges/source/remote/urp/urp_propertyobject.cxx
@@ -0,0 +1,796 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_propertyobject.cxx,v $
+ * $Revision: 1.11.20.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <stdlib.h>
+#include <osl/diagnose.h>
+
+#include <rtl/random.h>
+
+#include <uno/data.h>
+
+#include "com/sun/star/bridge/InvalidProtocolChangeException.hpp"
+#include <com/sun/star/bridge/XProtocolProperties.hpp>
+
+#include "urp_propertyobject.hxx"
+#include "urp_dispatch.hxx"
+#include "urp_bridgeimpl.hxx"
+#include "urp_job.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::bridge;
+using namespace ::com::sun::star::uno;
+
+using namespace bridges_urp;
+
+extern "C" {
+
+static void SAL_CALL staticAcquire( remote_Interface *pRemoteI )
+{
+ PropertyObject *pProperties = (PropertyObject *) pRemoteI;
+ pProperties->thisAcquire();
+}
+
+static void SAL_CALL staticRelease( remote_Interface *pRemoteI )
+{
+ PropertyObject *pProperties = (PropertyObject *) pRemoteI;
+ pProperties->thisRelease();
+}
+
+static void SAL_CALL staticDispatch(
+ remote_Interface * pRemoteI, typelib_TypeDescription const * pMemberType,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ PropertyObject *pProperties = (PropertyObject *) pRemoteI;
+ pProperties->thisDispatch( pMemberType, pReturn, pArgs, ppException );
+}
+
+}
+
+namespace bridges_urp
+{
+// some nice constants ....
+static const sal_Int32 METHOD_QUERY_INTERFACE = 0;
+static const sal_Int32 METHOD_GET_PROPERTIES = 3;
+static const sal_Int32 METHOD_REQUEST_CHANGE = 4;
+static const sal_Int32 METHOD_COMMIT_CHANGE = 5;
+
+static const sal_Int32 PROPERTY_BRIDGEID = 0;
+static const sal_Int32 PROPERTY_TYPECACHESIZE = 1;
+static const sal_Int32 PROPERTY_OIDCACHESIZE = 2;
+static const sal_Int32 PROPERTY_TIDCACHESIZE = 3;
+static const sal_Int32 PROPERTY_SUPPORTEDVERSIONS = 4;
+static const sal_Int32 PROPERTY_VERSION =5;
+static const sal_Int32 PROPERTY_FLUSHBLOCKSIZE = 6;
+static const sal_Int32 PROPERTY_ONEWAYTIMEOUT_MUSEC = 7;
+static const sal_Int32 PROPERTY_SUPPORTSMUSTREPLY = 8;
+static const sal_Int32 PROPERTY_SUPPERTSSYNCHRONOUS = 9;
+static const sal_Int32 PROPERTY_SUPPORTSMULTIPLESYNCHRONOUS = 10;
+static const sal_Int32 PROPERTY_CLEARCACHE = 11;
+static const sal_Int32 PROPERTY_NEGOTIATE = 12;
+static const sal_Int32 PROPERTY_FORCESYNCHRONOUS = 13;
+static const sal_Int32 PROPERTY_CURRENTCONTEXT = 14;
+
+static const sal_Int32 MAX_PROPERTIES = PROPERTY_CURRENTCONTEXT +1;
+
+const sal_Char *g_aPropertyName[] =
+{
+ "BridgeId",
+ "TypeCacheSize",
+ "OidCacheSize",
+ "TidCacheSize",
+ "SupportedVersion",
+ "Version",
+ "FlushBlockSize",
+ "OnewayTimeoutMUSEC",
+ "SupportsMustReply",
+ "SupportsSynchronous",
+ "SupportsMultipleSynchronous",
+ "ClearCache",
+ "Negotiate",
+ "ForceSynchronous",
+ "CurrentContext"
+};
+
+// nice little helper functions for conversion
+template< class t >
+void assignToIdl( ProtocolProperty *pIdl, sal_Int32 nIndex, const t &value )
+{
+ pIdl->Name = OUString::createFromAscii( g_aPropertyName[nIndex] );
+ ( *(::com::sun::star::uno::Any *)&(pIdl->Value) ) <<= value;
+}
+
+template< class t >
+void assignFromIdl( t * p, const ProtocolProperty & property )
+{
+ property.Value >>=*p;
+}
+
+static sal_Int32 getIndexFromIdl( const ProtocolProperty & property )
+{
+ sal_Int32 nResult = -1;
+ for( sal_Int32 i = 0 ; i < MAX_PROPERTIES ; i ++ )
+ {
+ if( 0 == property.Name.compareToAscii( g_aPropertyName[i] ) )
+ {
+ nResult = i;
+ break;
+ }
+ }
+ return nResult;
+}
+
+static sal_Int32 getIndexFromString( const OUString & property )
+{
+ sal_Int32 nResult = -1;
+ for( sal_Int32 i = 0 ; i < MAX_PROPERTIES ; i ++ )
+ {
+ if( 0 == property.compareToAscii( g_aPropertyName[i] ) )
+ {
+ nResult = i;
+ break;
+ }
+ }
+ return nResult;
+}
+
+static sal_Bool assignFromIdlToStruct( Properties *pProps, const ProtocolProperty &idl )
+{
+ sal_Bool bReturn = sal_True;
+
+ sal_Int32 nIndex = getIndexFromIdl( idl );
+ if( nIndex >= 0 )
+ {
+ switch( nIndex )
+ {
+ case PROPERTY_SUPPORTSMULTIPLESYNCHRONOUS:
+ assignFromIdl( &(pProps->bSupportsMultipleSynchronous) , idl );
+ break;
+ case PROPERTY_SUPPERTSSYNCHRONOUS:
+ assignFromIdl( &(pProps->bSupportsMustReply) , idl );
+ break;
+ case PROPERTY_SUPPORTSMUSTREPLY:
+ assignFromIdl( &(pProps->bSupportsSynchronous) , idl );
+ break;
+ case PROPERTY_ONEWAYTIMEOUT_MUSEC:
+ assignFromIdl( &(pProps->nOnewayTimeoutMUSEC) , idl );
+ break;
+ case PROPERTY_BRIDGEID:
+ assignFromIdl( (Sequence< sal_Int8 > * )&(pProps->seqBridgeID), idl );
+ break;
+ case PROPERTY_TYPECACHESIZE:
+ assignFromIdl( &(pProps->nTypeCacheSize) , idl );
+ break;
+ case PROPERTY_OIDCACHESIZE:
+ assignFromIdl( &(pProps->nOidCacheSize) , idl );
+ break;
+ case PROPERTY_TIDCACHESIZE:
+ assignFromIdl( &(pProps->nTidCacheSize), idl );
+ break;
+ case PROPERTY_SUPPORTEDVERSIONS:
+ assignFromIdl( &(pProps->sSupportedVersions) , idl );
+ break;
+ case PROPERTY_VERSION:
+ assignFromIdl( &(pProps->sVersion) , idl );
+ break;
+ case PROPERTY_FLUSHBLOCKSIZE:
+ assignFromIdl( &(pProps->nFlushBlockSize) ,idl );
+ break;
+ case PROPERTY_CLEARCACHE:
+ assignFromIdl( &(pProps->bClearCache) ,idl );
+ break;
+ case PROPERTY_NEGOTIATE:
+ assignFromIdl( &(pProps->bNegotiate) ,idl );
+ break;
+ case PROPERTY_FORCESYNCHRONOUS:
+ assignFromIdl( &(pProps->bForceSynchronous) ,idl );
+ break;
+ case PROPERTY_CURRENTCONTEXT:
+ pProps->bCurrentContext = true;
+ break;
+ default:
+ bReturn = sal_False;
+ }
+ }
+ else
+ {
+ bReturn = sal_False;
+ }
+ return bReturn;
+}
+
+static void extractTokens(
+ const ::rtl::OUString &sProps , ::std::list< OUString > &lst )
+{
+ sal_Int32 nNext = 0;
+ while ( sal_True )
+ {
+ sal_Int32 nStart = nNext;
+ nNext = sProps.indexOf( ',' , nNext );
+ if( -1 == nNext )
+ {
+ lst.push_back( sProps.copy( nStart, sProps.getLength() - nStart ) );
+ break;
+ }
+ lst.push_back( sProps.copy( nStart , nNext - nStart ) );
+ nNext ++;
+ }
+}
+
+
+static void assignFromStringToPropSeq( const OUString &sProps, uno_Sequence **ppPropertySeq)
+{
+ ::std::list< OUString > lst;
+ extractTokens( sProps , lst );
+
+ typelib_TypeDescription *pSequenceType = 0;
+ getCppuType( (Sequence< ProtocolProperty > *)0).getDescription( &pSequenceType );
+ uno_Sequence *pSeq = 0;
+ uno_sequence_construct( &pSeq , pSequenceType , 0, lst.size() , 0 );
+ ProtocolProperty *pElements = (ProtocolProperty * ) pSeq->elements;
+
+ sal_Int32 i = 0;
+ for( ::std::list< OUString >::iterator ii = lst.begin() ; ii != lst.end() ; ++ ii, i++ )
+ {
+ sal_Int32 nAssign = (*ii).indexOf( '=' );
+ if( -1 == nAssign )
+ {
+ OString o = OUStringToOString( *ii, RTL_TEXTENCODING_ASCII_US );
+ OSL_ENSURE( !"wrong protocol propertyt format, ignored", o.getStr() );
+ }
+ OUString sPropName = (*ii).copy( 0, nAssign );
+ OUString sValue = (*ii).copy( nAssign +1, (*ii).getLength() - nAssign -1 );
+
+ sal_Int32 nIndex = getIndexFromString( sPropName );
+ if( -1 == nIndex )
+ {
+ OString o = OUStringToOString( sPropName , RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE( !"unknown protocol property, ignored", o.getStr() );
+ }
+ switch( nIndex )
+ {
+ // voids
+ case PROPERTY_CURRENTCONTEXT:
+ pElements[i].Name = OUString::createFromAscii(
+ g_aPropertyName[nIndex] );
+ break;
+ // bools
+ case PROPERTY_CLEARCACHE:
+ case PROPERTY_NEGOTIATE:
+ case PROPERTY_FORCESYNCHRONOUS:
+ {
+ sal_Bool bClearCache = (sal_Bool ) sValue.toInt32();
+ assignToIdl( &(pElements[i]) , nIndex , bClearCache );
+ break;
+ }
+ // ints
+ case PROPERTY_TYPECACHESIZE:
+ case PROPERTY_OIDCACHESIZE:
+ case PROPERTY_TIDCACHESIZE:
+ case PROPERTY_FLUSHBLOCKSIZE:
+ case PROPERTY_ONEWAYTIMEOUT_MUSEC:
+ {
+ sal_Int32 nValue = sValue.toInt32();
+ assignToIdl( &(pElements[i]) , nIndex , nValue );
+ break;
+ }
+
+ // strings
+ case PROPERTY_VERSION:
+ assignToIdl( &(pElements[i]) , nIndex , sValue );
+ break;
+ default:
+ OString o = OUStringToOString( sPropName, RTL_TEXTENCODING_ASCII_US );
+ OSL_ENSURE( !"readonly protocol property, ignored" , o.getStr() );
+ }
+ }
+ *ppPropertySeq = pSeq;
+ typelib_typedescription_release( pSequenceType );
+}
+
+static void assignFromPropSeqToStruct( uno_Sequence *pSeq , struct Properties *pProps )
+{
+ sal_Int32 i;
+ ProtocolProperty *pElements = (ProtocolProperty *)pSeq->elements;
+ for( i = 0 ; i < pSeq->nElements ; i ++ )
+ {
+ assignFromIdlToStruct( pProps , pElements[i] );
+ }
+}
+
+void assignFromStringToStruct( const OUString & sProps , struct Properties *pProps )
+{
+ uno_Sequence *pSeq = 0;
+ assignFromStringToPropSeq( sProps , &pSeq );
+ assignFromPropSeqToStruct( pSeq , pProps );
+ uno_type_destructData( &pSeq, getCppuType( (Sequence< ProtocolProperty > *)0).getTypeLibType(),0);
+}
+
+
+//----------------------------------------------------------------------------------------------
+// PropertyObject implementation
+PropertyObject::PropertyObject(
+ struct Properties *pLocalSetting , uno_Environment *pEnvRemote, urp_BridgeImpl *pImpl )
+ : m_commitChangeCondition( osl_createCondition() )
+ , m_nRefCount( 0 )
+ , m_pBridgeImpl( pImpl )
+ , m_pLocalSetting( pLocalSetting )
+ , m_pEnvRemote( pEnvRemote )
+ , m_bRequestChangeHasBeenCalled( sal_False )
+ , m_bServerWaitingForCommit( sal_False )
+ , m_bApplyProperties( sal_False )
+{
+ acquire = staticAcquire;
+ release = staticRelease;
+ pDispatcher = staticDispatch;
+}
+
+PropertyObject::~PropertyObject()
+{
+ osl_destroyCondition( m_commitChangeCondition );
+}
+
+void SAL_CALL PropertyObject::thisDispatch(
+ typelib_TypeDescription const * pMemberType, void * pReturn, void * ppArgs[],
+ uno_Any ** ppException )
+{
+ OSL_ASSERT( pMemberType->eTypeClass == typelib_TypeClass_INTERFACE_METHOD );
+
+ typelib_InterfaceMethodTypeDescription *pMethodType =
+ ( typelib_InterfaceMethodTypeDescription * ) pMemberType;
+
+ switch( pMethodType->aBase.nPosition )
+ {
+ case METHOD_QUERY_INTERFACE:
+ OSL_ENSURE( 0 , "not implemented yet !" );
+ break;
+ case METHOD_GET_PROPERTIES:
+ {
+ implGetProperties( (uno_Sequence **) pReturn );
+ *ppException = 0;
+ break;
+ }
+ case METHOD_COMMIT_CHANGE:
+ {
+ implCommitChange( *(uno_Sequence ** ) ppArgs[0] , ppException );
+ break;
+ }
+ case METHOD_REQUEST_CHANGE:
+ {
+ *(sal_Int32 *) pReturn = implRequestChange( *(sal_Int32 *)ppArgs[0], ppException );
+ break;
+ }
+ default:
+ OSL_ENSURE( 0 , "unkown method !" );
+ }
+}
+
+void SAL_CALL PropertyObject::localGetPropertiesFromRemote( struct Properties *pR )
+{
+ OUString oid = OUString::createFromAscii( g_NameOfUrpProtocolPropertiesObject );
+
+ typelib_TypeDescription *pInterfaceType = 0;
+ getCppuType( (Reference< XProtocolProperties > *) 0 ).getDescription( &pInterfaceType );
+
+ if( !pInterfaceType->bComplete )
+ {
+ typelib_typedescription_complete( &pInterfaceType );
+ }
+
+ typelib_TypeDescription *pMethodType = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pMethodType,
+ ((typelib_InterfaceTypeDescription*) pInterfaceType)->ppAllMembers[METHOD_GET_PROPERTIES] );
+
+
+ uno_Sequence *pResult = 0;
+ uno_Any exception;
+ uno_Any *pException = &exception;
+ urp_sendRequest( m_pEnvRemote,
+ pMethodType,
+ oid.pData,
+ (typelib_InterfaceTypeDescription*) pInterfaceType,
+ &pResult,
+ 0,
+ &pException );
+
+ if( pException )
+ {
+ OSL_ENSURE( 0 , "remote urp-bridge doesn't support property-object" );
+ uno_any_destruct( pException , 0 );
+ return;
+ }
+
+ ProtocolProperty *pP = (ProtocolProperty * ) pResult->elements;
+ for( sal_Int32 i = 0; i < pResult->nElements ; i ++ )
+ {
+ if( ! assignFromIdlToStruct( pR , pP[i] ) )
+ {
+ OSL_ENSURE( 0 , "unknown property !!!!" );
+ }
+ }
+
+ typelib_typedescription_release( pInterfaceType );
+ typelib_typedescription_release( pMethodType );
+}
+
+
+// implementation for call from remote
+void SAL_CALL PropertyObject::implGetProperties( uno_Sequence **ppReturnValue )
+{
+ typelib_TypeDescription *pElementType= 0;
+ getCppuType( (Sequence< ProtocolProperty > *)0).getDescription( &pElementType );
+
+ OSL_ENSURE( pElementType , "Couldn't get property type" );
+
+ *ppReturnValue = 0;
+ uno_sequence_construct( ppReturnValue , pElementType , 0, MAX_PROPERTIES , 0 );
+ ProtocolProperty *pElements = (ProtocolProperty * ) ( *ppReturnValue )->elements;
+ Properties *pP = m_pLocalSetting;
+
+ assignToIdl( &(pElements[PROPERTY_BRIDGEID]),PROPERTY_BRIDGEID, *(Sequence< sal_Int8 > *)&(pP->seqBridgeID) );
+ assignToIdl( &(pElements[PROPERTY_TYPECACHESIZE]),PROPERTY_TYPECACHESIZE,pP->nTypeCacheSize );
+ assignToIdl( &(pElements[PROPERTY_OIDCACHESIZE]),PROPERTY_OIDCACHESIZE, pP->nOidCacheSize );
+ assignToIdl( &(pElements[PROPERTY_TIDCACHESIZE]),PROPERTY_TIDCACHESIZE, pP->nTidCacheSize );
+ assignToIdl( &(pElements[PROPERTY_SUPPORTEDVERSIONS]),PROPERTY_SUPPORTEDVERSIONS, pP->sSupportedVersions );
+ assignToIdl( &(pElements[PROPERTY_VERSION]),PROPERTY_VERSION, pP->sVersion );
+ assignToIdl( &(pElements[PROPERTY_FLUSHBLOCKSIZE]), PROPERTY_FLUSHBLOCKSIZE,pP->nFlushBlockSize );
+ assignToIdl( &(pElements[PROPERTY_ONEWAYTIMEOUT_MUSEC]), PROPERTY_ONEWAYTIMEOUT_MUSEC, pP->nOnewayTimeoutMUSEC );
+ assignToIdl( &(pElements[PROPERTY_SUPPORTSMUSTREPLY]), PROPERTY_SUPPORTSMUSTREPLY, pP->bSupportsMustReply );
+ assignToIdl( &(pElements[PROPERTY_SUPPERTSSYNCHRONOUS]), PROPERTY_SUPPERTSSYNCHRONOUS, pP->bSupportsSynchronous );
+ assignToIdl( &(pElements[PROPERTY_SUPPORTSMULTIPLESYNCHRONOUS]), PROPERTY_SUPPORTSMULTIPLESYNCHRONOUS, pP->bSupportsMultipleSynchronous );
+ assignToIdl( &(pElements[PROPERTY_CLEARCACHE]), PROPERTY_CLEARCACHE, pP->bClearCache );
+
+ typelib_typedescription_release( pElementType );
+}
+
+//----------------------------------------------------------------------------------------------
+sal_Int32 SAL_CALL PropertyObject::localRequestChange( )
+{
+ sal_Int32 nResult = 0;
+ sal_Bool bCall = sal_True;
+
+ // disallow marshaling NOW !
+ ClearableMutexGuard marshalingGuard( m_pBridgeImpl->m_marshalingMutex );
+ {
+ MutexGuard guard( m_mutex );
+ if( m_bRequestChangeHasBeenCalled || m_bServerWaitingForCommit )
+ {
+ // another transaction is already underway
+ // try again later !
+ bCall = sal_False;
+ }
+ m_bRequestChangeHasBeenCalled = sal_True;
+
+ if( bCall )
+ {
+ // calulate random number
+ rtlRandomPool pool = rtl_random_createPool ();
+ rtl_random_getBytes( pool , &m_nRandomNumberOfRequest, sizeof( m_nRandomNumberOfRequest ) );
+ rtl_random_destroyPool( pool );
+ }
+ }
+
+ if( bCall )
+ {
+ OUString oid = OUString::createFromAscii( g_NameOfUrpProtocolPropertiesObject );
+
+ // gather types for calling
+ typelib_TypeDescription *pInterfaceType = 0;
+ getCppuType( (Reference< XProtocolProperties > *) 0 ).getDescription( &pInterfaceType );
+
+ if( !pInterfaceType->bComplete )
+ {
+ typelib_typedescription_complete( &pInterfaceType );
+ }
+
+ typelib_TypeDescription *pMethodType = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pMethodType,
+ ((typelib_InterfaceTypeDescription*) pInterfaceType)->ppAllMembers[METHOD_REQUEST_CHANGE] );
+
+ void *pArg1 = &m_nRandomNumberOfRequest;
+ void **ppArgs = &pArg1;
+
+ uno_Any exception;
+ uno_Any *pException = &exception;
+
+ ClientJob job( m_pEnvRemote,
+ 0,
+ m_pBridgeImpl,
+ oid.pData,
+ pMethodType,
+ (typelib_InterfaceTypeDescription*) pInterfaceType,
+ &nResult,
+ ppArgs,
+ &pException );
+
+ // put the call on the line !
+ sal_Bool bSuccess = job.pack();
+
+ // now allow writing on wire again.
+ // NOTE : this has been locked, because it is inevitable to set m_bRequestChangeHasBeenCalled
+ // and call requestChange in an atomar operation. Otherwise, implRequestChange may be called
+ // inbetween and reply, before the request is put on the wire. This certainly would
+ // be confusing for the remote counterpart !
+ marshalingGuard.clear();
+
+ // wait for the reply ...
+ if( bSuccess )
+ {
+ job.wait();
+
+ if( pException )
+ {
+ // the object is unknown on the other side.
+ uno_any_destruct( pException , 0 );
+ nResult = 0;
+ }
+ }
+ else
+ {
+ nResult = 0;
+ }
+ typelib_typedescription_release( pInterfaceType );
+ typelib_typedescription_release( pMethodType );
+ }
+
+ {
+ MutexGuard guard( m_mutex );
+ m_bRequestChangeHasBeenCalled = sal_False;
+ m_bServerWaitingForCommit = ( 0 == nResult );
+ }
+ return nResult;
+}
+
+// implementation for call from remote
+sal_Int32 SAL_CALL PropertyObject::implRequestChange( sal_Int32 nRandomNumber, uno_Any **ppException )
+{
+ sal_Int32 nResult = 0;
+ MutexGuard guard( m_mutex );
+ if( m_bRequestChangeHasBeenCalled )
+ {
+ // this side has also called requestChange, now negotiate, which side is allowed
+ // to commit the change !
+ if( m_nRandomNumberOfRequest > nRandomNumber )
+ {
+ // this side may commit !!!!
+ nResult = 0;
+ }
+ else if( m_nRandomNumberOfRequest == nRandomNumber )
+ {
+ // sorry, try again !
+ nResult = -1;
+ }
+ else if( m_nRandomNumberOfRequest < nRandomNumber )
+ {
+ // the other side may commit !
+ nResult = 1;
+ // m_bServerWaitingForCommit will be set by localRequestChange
+ }
+ }
+ else
+ {
+ // This side has NOT called requestChange, so the other side may commit
+ nResult = 1;
+ m_bServerWaitingForCommit = sal_True;
+ }
+
+ *ppException = 0;
+ return nResult;
+}
+
+
+
+void SAL_CALL PropertyObject::localCommitChange( const ::rtl::OUString &sProps , sal_Bool *pbExceptionThrown )
+{
+ // lock the bridge NOW !
+ // NOTE: it is not allowed for other threads to call, when a commit change is underway.
+ // The remote counterpart cannot if the call following the commit already uses
+ // the new properties or not.
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+
+ OUString oid = OUString::createFromAscii( g_NameOfUrpProtocolPropertiesObject );
+
+ osl_resetCondition( m_commitChangeCondition );
+
+ Properties props = *m_pLocalSetting;
+
+ typelib_TypeDescription *pInterfaceType = 0;
+ getCppuType( (Reference< XProtocolProperties > *) 0 ).getDescription( &pInterfaceType );
+
+ if( !pInterfaceType->bComplete )
+ {
+ typelib_typedescription_complete( &pInterfaceType );
+ }
+
+ typelib_TypeDescription *pMethodType = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pMethodType,
+ ((typelib_InterfaceTypeDescription*) pInterfaceType)->ppAllMembers[METHOD_COMMIT_CHANGE] );
+
+// typelib_TypeDescription *pSequenceType= 0;
+
+
+ // extract name/value pairs
+ uno_Sequence *pSeq = 0;
+ assignFromStringToPropSeq( sProps, &pSeq );
+ assignFromPropSeqToStruct( pSeq , &props );
+// ::std::list< OUString > lst;
+// extractTokens( sProps , lst );
+
+// getCppuType( (Sequence< ProtocolProperty > *)0).getDescription( &pSequenceType );
+// uno_sequence_construct( &pSeq , pSequenceType , 0, lst.size() , 0 );
+// ProtocolProperty *pElements = (ProtocolProperty * ) pSeq->elements;
+
+// sal_Int32 i = 0;
+// for( ::std::list< OUString >::iterator ii = lst.begin() ; ii != lst.end() ; ++ ii, i++ )
+// {
+// sal_Int32 nAssign = (*ii).indexOf( '=' );
+// if( -1 == nAssign )
+// {
+// OString o = OUStringToOString( *ii, RTL_TEXTENCODING_ASCII_US );
+// OSL_ENSURE( !"wrong protocol propertyt format, ignored", o.getStr() );
+// }
+// OUString sPropName = (*ii).copy( 0, nAssign );
+// OUString sValue = (*ii).copy( nAssign +1, (*ii).getLength() - nAssign -1 );
+
+// sal_Int32 nIndex = getIndexFromString( sPropName );
+// if( -1 == nIndex )
+// {
+// OString o = OUStringToOString( sPropName , RTL_TEXTENCODING_ASCII_US);
+// OSL_ENSURE( !"unknown protocol property, ignored", o.getStr() );
+// }
+// switch( nIndex )
+// {
+// // bools
+// case PROPERTY_CLEARCACHE:
+// {
+// sal_Bool bClearCache = (sal_Bool ) sValue.toInt32();
+// assignToIdl( &(pElements[i]) , nIndex , bClearCache );
+// break;
+// }
+// // ints
+// case PROPERTY_TYPECACHESIZE:
+// case PROPERTY_OIDCACHESIZE:
+// case PROPERTY_TIDCACHESIZE:
+// case PROPERTY_FLUSHBLOCKSIZE:
+// case PROPERTY_ONEWAYTIMEOUT_MUSEC:
+// {
+// sal_Int32 nValue = sValue.toInt32();
+// assignToIdl( &(pElements[i]) , nIndex , nValue );
+// break;
+// }
+
+// // strings
+// case PROPERTY_VERSION:
+// assignToIdl( &(pElements[i]) , nIndex , sValue );
+// break;
+// default:
+// OString o = OUStringToOString( sPropName, RTL_TEXTENCODING_ASCII_US );
+// OSL_ENSURE( !"readonly protocol property, ignored" , o.getStr() );
+// }
+// assignFromIdlToStruct( &props, pElements[i] );
+// }
+
+ void *pArg1 = &pSeq;
+ uno_Any exception;
+ uno_Any *pException = &exception;
+
+ ClientJob job( m_pEnvRemote,
+ 0,
+ m_pBridgeImpl,
+ oid.pData,
+ pMethodType,
+ (typelib_InterfaceTypeDescription*) pInterfaceType,
+ 0,
+ &pArg1,
+ &pException );
+ job.setBridgePropertyCall();
+ if( job.pack() )
+ {
+ job.wait();
+ }
+ else
+ {
+ OSL_ASSERT( pException != NULL );
+ }
+
+ ::uno_type_destructData(
+ &pSeq, getCppuType( (Sequence< ProtocolProperty > *)0).getTypeLibType(), 0 );
+
+ *pbExceptionThrown = pException ? sal_True : sal_False;
+
+ if( pException )
+ {
+ OString o = OUStringToOString( ((com::sun::star::uno::Exception*)pException->pData)->Message,
+ RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE( !"exception thrown during calling on PropertyObject",o.getStr() );
+ uno_any_destruct( pException , 0 );
+ }
+ else
+ {
+ m_pBridgeImpl->applyProtocolChanges( props );
+ m_bServerWaitingForCommit = sal_False;
+ m_bApplyProperties = sal_False;
+ }
+
+ // let the reader thread go ...
+ osl_setCondition( m_commitChangeCondition );
+
+ typelib_typedescription_release( pMethodType );
+ typelib_typedescription_release( pInterfaceType );
+}
+
+void SAL_CALL PropertyObject::implCommitChange( uno_Sequence *pSequence, uno_Any **ppException )
+{
+ MutexGuard guard( m_mutex );
+ m_propsToBeApplied = *m_pLocalSetting;
+
+ ProtocolProperty *pP = (ProtocolProperty * ) pSequence->elements;
+ for( sal_Int32 i = 0; i < pSequence->nElements ; i ++ )
+ {
+ if( ! assignFromIdlToStruct( &m_propsToBeApplied , pP[i] ) )
+ {
+ InvalidProtocolChangeException exception;
+ Type type = getCppuType( &exception );
+ exception.Message = OUString::createFromAscii( "urp: unknown Property " );
+ exception.Message += pP[i].Name;
+ exception.invalidProperty = pP[i];
+ exception.reason = 1;
+
+ uno_type_any_construct( *ppException, &exception, type.getTypeLibType() , 0 );
+
+ m_bApplyProperties = sal_False;
+ m_bServerWaitingForCommit = sal_False;
+ return;
+ }
+ }
+
+ m_bApplyProperties = sal_True;
+ *ppException = 0;
+}
+
+Properties SAL_CALL PropertyObject::getCommitedChanges()
+{
+ MutexGuard guard( m_mutex );
+ OSL_ASSERT( m_bApplyProperties );
+ m_bApplyProperties = sal_False;
+ m_bServerWaitingForCommit = sal_False;
+ return m_propsToBeApplied;
+}
+
+void SAL_CALL PropertyObject::waitUntilChangesAreCommitted()
+{
+ osl_waitCondition( m_commitChangeCondition , 0 );
+}
+}
diff --git a/bridges/source/remote/urp/urp_propertyobject.hxx b/bridges/source/remote/urp/urp_propertyobject.hxx
new file mode 100644
index 000000000000..e6412b0c4ad1
--- /dev/null
+++ b/bridges/source/remote/urp/urp_propertyobject.hxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_propertyobject.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <stdio.h>
+#include <osl/interlck.h>
+#include <osl/mutex.hxx>
+
+#ifndef _OSL_CONDITN_H_
+#include <osl/conditn.h>
+#endif
+#include <rtl/string.hxx>
+#include <uno/sequence2.h>
+
+#ifndef _BRIDGES_REMOTE_REMOTE_H_
+#include <bridges/remote/remote.h>
+#endif
+#include "urp_property.hxx"
+
+namespace bridges_urp {
+
+struct urp_BridgeImpl;
+const sal_Char g_NameOfUrpProtocolPropertiesObject[] = "UrpProtocolProperties";
+
+// helper functions
+void assignFromStringToStruct( const ::rtl::OUString & sProps , struct Properties *pProps );
+
+class PropertyObject : public remote_Interface
+{
+private:
+ ::osl::Mutex m_mutex;
+ oslCondition m_commitChangeCondition;
+ oslInterlockedCount m_nRefCount;
+ urp_BridgeImpl *m_pBridgeImpl;
+ struct Properties *m_pLocalSetting;
+ struct Properties m_propsToBeApplied;
+
+ uno_Environment *m_pEnvRemote;
+ sal_Int32 m_nRandomNumberOfRequest;
+ sal_Bool m_bRequestChangeHasBeenCalled;
+ sal_Bool m_bServerWaitingForCommit;
+ sal_Bool m_bApplyProperties;
+
+public:
+ PropertyObject(
+ struct Properties *pLocalSetting , uno_Environment *pEnvRemote, urp_BridgeImpl *pImpl );
+ ~PropertyObject();
+
+ void SAL_CALL thisAcquire( )
+ {
+ osl_incrementInterlockedCount( &m_nRefCount );
+ }
+
+ void SAL_CALL thisRelease()
+ {
+ if( ! osl_decrementInterlockedCount( &m_nRefCount ) )
+ {
+ delete this;
+ }
+ }
+
+ void SAL_CALL thisDispatch( typelib_TypeDescription const * pMemberType,
+ void * pReturn,
+ void * pArgs[],
+ uno_Any ** ppException );
+
+public: // local
+ sal_Int32 SAL_CALL localRequestChange( );
+ void SAL_CALL localCommitChange( const ::rtl::OUString &properties, sal_Bool *pbExceptionThrown );
+ void SAL_CALL localGetPropertiesFromRemote( struct Properties * );
+
+ // returns 0, if nothing was commited.
+ inline sal_Bool SAL_CALL changesHaveBeenCommited()
+ { return m_bApplyProperties; }
+ Properties SAL_CALL getCommitedChanges();
+
+ void SAL_CALL waitUntilChangesAreCommitted();
+
+protected:
+ // these methods are called by thisDispatch
+ void SAL_CALL implGetProperties( uno_Sequence **ppReturnValue );
+ sal_Int32 SAL_CALL implRequestChange( sal_Int32 nRandomNumber, uno_Any **ppException );
+ void SAL_CALL implCommitChange( uno_Sequence *seqOfProperties, uno_Any **ppException );
+};
+
+}
diff --git a/bridges/source/remote/urp/urp_reader.cxx b/bridges/source/remote/urp/urp_reader.cxx
new file mode 100644
index 000000000000..dd9ff0af80ec
--- /dev/null
+++ b/bridges/source/remote/urp/urp_reader.cxx
@@ -0,0 +1,835 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_reader.cxx,v $
+ * $Revision: 1.18.20.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <string.h>
+
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <bridges/remote/connection.h>
+#include <bridges/remote/counter.hxx>
+#include <bridges/remote/context.h>
+#include <bridges/remote/helper.hxx>
+
+#include <com/sun/star/uno/XCurrentContext.hpp>
+#include <uno/environment.h>
+
+#include "urp_reader.hxx"
+#include "urp_writer.hxx"
+#include "urp_dispatch.hxx"
+#include "urp_job.hxx"
+#include "urp_bridgeimpl.hxx"
+#include "urp_log.hxx"
+#include "urp_propertyobject.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+
+#if OSL_DEBUG_LEVEL > 1
+static MyCounter thisCounter( "DEBUG : ReaderThread" );
+#endif
+
+namespace bridges_urp
+{
+
+ /**
+ * This callback is used to ensure, that the release call is sent for the correct type.
+ *
+ ***/
+ void SAL_CALL urp_releaseRemoteCallback (
+ remote_Interface *, rtl_uString *pOid,
+ typelib_TypeDescriptionReference *pTypeRef, uno_Environment *pEnvRemote )
+ {
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = (urp_BridgeImpl*) ( pContext->m_pBridgeImpl );
+
+ pImpl->m_pWriter->insertReleaseRemoteCall( pOid , pTypeRef );
+ }
+
+
+ struct MessageFlags
+ {
+ sal_uInt16 nMethodId;
+ sal_Bool bRequest;
+ sal_Bool bType;
+ sal_Bool bOid;
+ sal_Bool bTid;
+ sal_Bool bException;
+ sal_Bool bMustReply;
+ sal_Bool bSynchronous;
+ sal_Bool bMoreFlags;
+ sal_Bool bIgnoreCache;
+ sal_Bool bBridgePropertyCall;
+ ///--------------------------
+ inline MessageFlags()
+ {
+ bTid = sal_False;
+ bOid = sal_False;
+ bType = sal_False;
+ bException = sal_False;
+ bMoreFlags = sal_False;
+ bIgnoreCache = sal_False;
+ bBridgePropertyCall = sal_False;
+ }
+ //---------------------------
+ }; // end struct MessageFlags
+
+inline sal_Bool OReaderThread::getMemberTypeDescription(
+ typelib_InterfaceAttributeTypeDescription **ppAttributeType,
+ typelib_InterfaceMethodTypeDescription **ppMethodType,
+ sal_Bool *pbIsSetter,
+ sal_uInt16 nMethodId ,
+ typelib_TypeDescriptionReference * pITypeRef )
+{
+ if( pITypeRef->eTypeClass != typelib_TypeClass_INTERFACE )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "interface type is not of typeclass interface (" );
+ sMessage.append( (sal_Int32) pITypeRef->eTypeClass );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+ OSL_ENSURE( 0 , "type is not an interface" );
+ return sal_False;
+ }
+
+ typelib_InterfaceTypeDescription *pInterfaceType = 0;
+ TYPELIB_DANGER_GET(
+ (typelib_TypeDescription **)&pInterfaceType , pITypeRef );
+ if( ! pInterfaceType )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "No typedescription can be retrieved for type " );
+ sMessage.append( OUString( pITypeRef->pTypeName ) );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+ OSL_ENSURE( 0 , "urp: unknown type " );
+ return sal_False;
+ }
+
+ if( ! pInterfaceType->aBase.bComplete )
+ {
+ typelib_typedescription_complete( (typelib_TypeDescription **) &pInterfaceType );
+ }
+
+ if ( nMethodId >= pInterfaceType->nMapFunctionIndexToMemberIndex )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "vtable out of range for type " );
+ sMessage.append( OUString( pITypeRef->pTypeName ) );
+ sMessage.appendAscii( " (" );
+ sMessage.append( (sal_Int32) nMethodId );
+ sMessage.appendAscii( " )" );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+
+ OSL_ENSURE( 0 , "vtable index out of range" );
+ return sal_False;
+ }
+
+ sal_Int32 nMemberIndex = pInterfaceType->pMapFunctionIndexToMemberIndex[ nMethodId ];
+
+ if( !( pInterfaceType->nAllMembers > nMemberIndex && nMemberIndex >= 0 ) )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "vtable out of range for type " );
+ sMessage.append( OUString( pITypeRef->pTypeName ) );
+ sMessage.appendAscii( " (" );
+ sMessage.append( (sal_Int32) nMethodId );
+ sMessage.appendAscii( " )" );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+
+ OSL_ENSURE( 0 , "vtable index out of range" );
+ return sal_False;
+ }
+
+ typelib_InterfaceMemberTypeDescription *pMemberType = 0;
+ typelib_typedescriptionreference_getDescription(
+ (typelib_TypeDescription **) &pMemberType,pInterfaceType->ppAllMembers[nMemberIndex]);
+
+ if(! pMemberType )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "unknown method type description for type" );
+ sMessage.append( OUString( pITypeRef->pTypeName ) );
+ sMessage.appendAscii( " (" );
+ sMessage.append( (sal_Int32) nMethodId );
+ sMessage.appendAscii( " )" );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+
+ OSL_ENSURE( 0 , "unknown method type description" );
+ return sal_False;
+ }
+
+ if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pMemberType->aBase.eTypeClass )
+ {
+ // Note: pMapMemberIndexToFunctionIndex always contains the function
+ // index of the attribute getter! setter function index is getter index
+ // + 1.
+ *ppAttributeType = (typelib_InterfaceAttributeTypeDescription *) pMemberType;
+ *pbIsSetter = ! (
+ pInterfaceType->pMapMemberIndexToFunctionIndex[nMemberIndex] == nMethodId );
+ }
+ else
+ {
+ *ppMethodType = (typelib_InterfaceMethodTypeDescription *) pMemberType;
+ }
+
+ TYPELIB_DANGER_RELEASE( (typelib_TypeDescription * )pInterfaceType );
+ return sal_True;
+}
+
+OReaderThread::OReaderThread( remote_Connection *pConnection,
+ uno_Environment *pEnvRemote,
+ OWriterThread * pWriterThread ) :
+ m_pConnection( pConnection ),
+ m_pEnvRemote( pEnvRemote ),
+ m_pWriterThread( pWriterThread ),
+ m_bDestroyMyself( sal_False ),
+ m_bContinue( sal_True ),
+ m_pBridgeImpl((struct urp_BridgeImpl*)
+ ((remote_Context *)pEnvRemote->pContext)->m_pBridgeImpl ),
+ m_unmarshal( m_pBridgeImpl, m_pEnvRemote, ::bridges_remote::remote_createStub )
+{
+ m_pEnvRemote->acquireWeak( m_pEnvRemote );
+ m_pConnection->acquire( m_pConnection );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+
+OReaderThread::~OReaderThread( )
+{
+ m_pEnvRemote->releaseWeak( m_pEnvRemote );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+// may only be called in the callstack of this thread !!!!!
+// run() -> dispose() -> destroyYourself()
+void OReaderThread::destroyYourself()
+{
+ m_bDestroyMyself = sal_True;
+ m_pConnection->release( m_pConnection );
+ m_pConnection = 0;
+ m_bContinue = sal_False;
+}
+
+void OReaderThread::onTerminated()
+{
+ if( m_bDestroyMyself )
+ {
+ delete this;
+ }
+}
+
+
+void OReaderThread::disposeEnvironment()
+{
+ struct remote_Context *pContext =
+ ( struct remote_Context * ) m_pEnvRemote->pContext;
+ m_bContinue = sal_False;
+ if( ! pContext->m_pBridgeImpl->m_bDisposed )
+ {
+ uno_Environment *pEnvRemote = 0;
+ m_pEnvRemote->harden( &pEnvRemote , m_pEnvRemote );
+ if( pEnvRemote )
+ {
+ pEnvRemote->dispose( m_pEnvRemote );
+ pEnvRemote->release( m_pEnvRemote );
+ }
+ else
+ {
+ // environment has been disposed eitherway !
+ }
+ }
+}
+
+inline sal_Bool OReaderThread::readBlock( sal_Int32 *pnMessageCount )
+{
+ m_unmarshal.setSize( 8 );
+ if( 8 != m_pConnection->read( m_pConnection , m_unmarshal.getBuffer(), 8 ) )
+ {
+ OUString s( RTL_CONSTASCII_USTRINGPARAM( "Unexpected connection closure" ) );
+ m_pBridgeImpl->addError( s );
+ return sal_False;
+ }
+
+ sal_Int32 nSize;
+ m_unmarshal.unpackInt32( &nSize );
+ m_unmarshal.unpackInt32( pnMessageCount );
+
+ if( nSize < 0 )
+ {
+ // buffer too big
+ // no exception can be thrown, because there is no thread id, which could be
+ // used. -> terminate !
+ OUStringBuffer s;
+ s.appendAscii( "Packet-size too big (" );
+ s.append( (sal_Int64) (sal_uInt32 ) nSize );
+ s.append( sal_Unicode( ')' ) );
+ m_pBridgeImpl->addError( s.makeStringAndClear() );
+ OSL_ENSURE( 0 , "urp bridge: Packet-size too big" );
+ return sal_False;
+ }
+
+ if( 0 == nSize )
+ {
+ // normal termination !
+ return sal_False;
+ }
+
+ // allocate the necessary memory
+ if( ! m_unmarshal.setSize( nSize ) )
+ {
+ OUStringBuffer s;
+ s.appendAscii( "Packet-size too big, couln't allocate necessary memory (" );
+ s.append( (sal_Int64) (sal_uInt32 ) nSize );
+ s.append( sal_Unicode( ')' ) );
+ m_pBridgeImpl->addError( s.makeStringAndClear() );
+ OSL_ENSURE( 0 , "urp bridge: messages size too large, terminating connection" );
+ return sal_False;
+ }
+
+ sal_Int32 nRead = m_pConnection->read( m_pConnection , m_unmarshal.getBuffer() , nSize );
+
+ if( nSize != nRead )
+ {
+ OUStringBuffer s;
+ s.appendAscii( "Unexpected connection closure, inconsistent packet (" );
+ s.append( (sal_Int64) (sal_uInt32 ) nSize );
+ s.appendAscii( " asked, " );
+ s.append( (sal_Int64) (sal_uInt32 ) nRead );
+ s.appendAscii( " got )" );
+ m_pBridgeImpl->addError( s.makeStringAndClear() );
+ // couldn't get the asked amount of bytes, quit
+ // should only occur, when the environment has already been disposed
+ OSL_ENSURE( m_pBridgeImpl->m_bDisposed , "urp bridge: inconsistent packet, terminating connection." );
+ return sal_False;
+ }
+ return sal_True;
+}
+
+inline sal_Bool OReaderThread::readFlags( struct MessageFlags *pFlags )
+{
+ sal_uInt8 nBitField;
+ if( ! m_unmarshal.unpackInt8( &nBitField ) )
+ {
+ m_pBridgeImpl->addError( "Unexpected end of message header (1)" );
+ return sal_False;
+ }
+
+ if( HDRFLAG_LONGHEADER & nBitField )
+ {
+ // this is a long header, interpret the byte as bitfield
+ pFlags->bTid = (HDRFLAG_NEWTID & nBitField );
+ pFlags->bRequest = (HDRFLAG_REQUEST & nBitField);
+
+ if( pFlags->bRequest )
+ {
+ // request
+ pFlags->bType = ( HDRFLAG_NEWTYPE & nBitField );
+ pFlags->bOid = ( HDRFLAG_NEWOID & nBitField );
+ pFlags->bIgnoreCache = ( HDRFLAG_IGNORECACHE & nBitField );
+ pFlags->bMoreFlags = ( HDRFLAG_MOREFLAGS & nBitField );
+
+ if( pFlags->bMoreFlags )
+ {
+ // another byte with flags
+ sal_Int8 moreFlags;
+ if( ! m_unmarshal.unpackInt8( &moreFlags ) )
+ {
+ m_pBridgeImpl->addError( "Unexpected end of message header (2)" );
+ return sal_False;
+ }
+ pFlags->bSynchronous = ( HDRFLAG_SYNCHRONOUS & moreFlags );
+ pFlags->bMustReply = ( HDRFLAG_MUSTREPLY & moreFlags );
+ OSL_ENSURE( pFlags->bSynchronous && pFlags->bMustReply ||
+ ! pFlags->bSynchronous && !pFlags->bMustReply,
+ "urp-bridge : customized calls currently not supported !");
+ }
+
+ if( HDRFLAG_LONGMETHODID & nBitField )
+ {
+ // methodid as unsigned short
+ if( ! m_unmarshal.unpackInt16( &(pFlags->nMethodId )) )
+ {
+ m_pBridgeImpl->addError( "Unexpected end of message header (3)" );
+ return sal_False;
+ }
+ }
+ else
+ {
+ sal_uInt8 id;
+ if( ! m_unmarshal.unpackInt8( &id ) )
+ {
+ m_pBridgeImpl->addError( "Unexpected end of message header (4)" );
+ return sal_False;
+ }
+ pFlags->nMethodId = (sal_uInt16) id;
+ }
+ }
+ else
+ {
+ // reply
+ pFlags->bRequest = sal_False;
+ pFlags->bException = ( HDRFLAG_EXCEPTION & nBitField );
+ }
+ }
+ else
+ {
+ // short request
+ pFlags->bRequest = sal_True;
+ if( 0x40 & nBitField )
+ {
+ sal_uInt8 lower;
+ if( ! m_unmarshal.unpackInt8( &lower ) )
+ {
+ m_pBridgeImpl->addError( "Unexpected end of message header (5)" );
+ return sal_False;
+ }
+ pFlags->nMethodId = ( nBitField & 0x3f ) << 8 | lower;
+ }
+ else
+ {
+ pFlags->nMethodId = ( nBitField & 0x3f );
+ }
+ }
+ return sal_True;
+}
+
+void OReaderThread::run()
+{
+ // This vars are needed to hold oid,tid and type information, which should not be cached.
+ Type lastTypeNoCache;
+ OUString lastOidNoCache;
+ ByteSequence lastTidNoCache;
+
+ while( m_bContinue )
+ {
+ sal_Int32 nMessageCount;
+ if( ! readBlock( &nMessageCount ) )
+ {
+ disposeEnvironment();
+ break;
+ }
+
+ uno_Environment *pEnvRemote = 0;
+ m_pEnvRemote->harden( &pEnvRemote , m_pEnvRemote );
+ if( !pEnvRemote )
+ {
+ // environment has been disposed already, quit here
+ break;
+ }
+ ServerMultiJob *pMultiJob = 0;
+ remote_Interface *pLastRemoteI = 0;
+ while( ! m_unmarshal.finished() )
+ {
+#ifdef BRIDGES_URP_PROT
+ sal_uInt32 nLogStart = m_unmarshal.getPos();
+ sal_Bool bIsOneWay = sal_False;
+ OUString sMemberName;
+#endif
+ MessageFlags flags;
+
+ if( ! readFlags( &flags ) )
+ {
+ m_pBridgeImpl->addError( "incomplete message, skipping block" );
+ OSL_ENSURE ( 0 , "urp-bridge : incomplete message, skipping block" );
+ break;
+ }
+
+ // use these ** to access the ids fast ( avoid acquire/release calls )
+ sal_Sequence **ppLastTid = flags.bIgnoreCache ?
+ (sal_Sequence **) &lastTidNoCache :
+ (sal_Sequence **) &(m_pBridgeImpl->m_lastInTid);
+ rtl_uString **ppLastOid = flags.bIgnoreCache ?
+ (rtl_uString ** ) &lastOidNoCache :
+ (rtl_uString ** ) &(m_pBridgeImpl->m_lastInOid);
+ typelib_TypeDescriptionReference **ppLastType =
+ flags.bIgnoreCache ?
+ (typelib_TypeDescriptionReference ** ) &lastTypeNoCache :
+ (typelib_TypeDescriptionReference ** ) &(m_pBridgeImpl->m_lastInType);
+
+ // get new type
+ if( flags.bType )
+ {
+ typelib_TypeDescriptionReference *pTypeRef = 0;
+ if( m_unmarshal.unpackType( &pTypeRef ) )
+ {
+ // release the old type
+ typelib_typedescriptionreference_release( *ppLastType );
+ // set the new type
+ *ppLastType = pTypeRef;
+
+ // no release on pTypeRef necessary (will be released by type dtor)
+ }
+ else
+ {
+ typelib_typedescriptionreference_release( pTypeRef );
+ m_pBridgeImpl->addError( "error during unpacking (maybe cached) interface type" );
+ OSL_ENSURE( 0 , "urp-bridge : error during unpacking interface type, terminating connection" );
+ disposeEnvironment();
+ break;
+ }
+ if( m_pBridgeImpl->m_lastInType.getTypeClass() != TypeClass_INTERFACE )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "interface type is not of typeclass interface (" );
+ sMessage.append( (sal_Int32) m_pBridgeImpl->m_lastInType.getTypeClass() );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+ OSL_ENSURE( 0 , "urp-bridge : not an interface type" );
+ disposeEnvironment();
+ break;
+ }
+ }
+ if( flags.bOid )
+ {
+ rtl_uString *pOid = 0;
+ if( m_unmarshal.unpackOid( &pOid ) )
+ {
+ rtl_uString_release( *ppLastOid );
+ *ppLastOid = pOid;
+ }
+ else
+ {
+ rtl_uString_release( pOid );
+ m_pBridgeImpl->addError( "error during unpacking (maybe cached) oid" );
+ OSL_ENSURE( 0 , "urp-bridge : error during unpacking cached data, terminating connection" );
+ disposeEnvironment();
+ break;
+ }
+ }
+
+ if( flags.bTid )
+ {
+ sal_Sequence *pSeq = 0;
+ if( m_unmarshal.unpackTid( &pSeq ) )
+ {
+ rtl_byte_sequence_release( *ppLastTid );
+ *ppLastTid = pSeq;
+ }
+ else
+ {
+ rtl_byte_sequence_release( pSeq );
+
+ m_pBridgeImpl->addError( "error during unpacking (maybe cached) tid" );
+ OSL_ENSURE( 0 , "urp-bridge : error during unpacking cached data, terminating connection" );
+ disposeEnvironment();
+ break;
+ }
+ }
+
+ // do the job
+ if( flags.bRequest )
+ {
+ bool bHasCc = m_pBridgeImpl->m_properties.bCurrentContext
+ && flags.nMethodId != REMOTE_RELEASE_METHOD_INDEX
+ && !rtl::OUString( *ppLastOid ).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ g_NameOfUrpProtocolPropertiesObject ) );
+ remote_Interface * pCc = 0;
+ if ( bHasCc )
+ {
+ typelib_TypeDescription * pType = 0;
+ TYPELIB_DANGER_GET(
+ &pType,
+ XCurrentContext::static_type().getTypeLibType() );
+ bool ok = m_unmarshal.unpack( &pCc, pType );
+ TYPELIB_DANGER_RELEASE( pType );
+ if ( !ok )
+ {
+ OSL_ENSURE(
+ false,
+ ("urp_bridge: error while unpacking current"
+ " context") );
+ disposeEnvironment();
+ break;
+ }
+ }
+
+ //--------------------------
+ // handle request
+ //--------------------------
+ // get the membertypedescription
+ typelib_InterfaceMethodTypeDescription *pMethodType = 0;
+ typelib_InterfaceAttributeTypeDescription *pAttributeType = 0;
+ sal_Bool bIsSetter = sal_False;
+
+ if( getMemberTypeDescription(
+ &pAttributeType, &pMethodType, &bIsSetter,
+ flags.nMethodId, *ppLastType ) )
+ {
+ if( ! pLastRemoteI || flags.bOid || flags.bType )
+ {
+ // a new interface must be retrieved
+
+ // retrieve the interface NOW from the environment
+ // (avoid race conditions : oneway followed by release )
+ typelib_InterfaceTypeDescription *pInterfaceType = 0;
+
+ TYPELIB_DANGER_GET(
+ (typelib_TypeDescription ** ) &pInterfaceType ,
+ *ppLastType );
+ if( !pInterfaceType )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "Couldn't retrieve type description for type " );
+ sMessage.append( OUString( (*ppLastType)->pTypeName ) );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+ delete pMultiJob;
+ pMultiJob = 0;
+ disposeEnvironment();
+ pLastRemoteI = 0; // stubs are released during dispose eitherway
+ break;
+ }
+ pEnvRemote->pExtEnv->getRegisteredInterface(
+ pEnvRemote->pExtEnv, ( void ** ) &pLastRemoteI,
+ *ppLastOid, pInterfaceType );
+ TYPELIB_DANGER_RELEASE( (typelib_TypeDescription * )pInterfaceType );
+
+ if( !pLastRemoteI &&
+ REMOTE_RELEASE_METHOD_INDEX != flags.nMethodId &&
+ 0 == rtl_ustr_ascii_compare_WithLength(
+ (*ppLastOid)->buffer, (*ppLastOid)->length, g_NameOfUrpProtocolPropertiesObject ) )
+ {
+ // check for bridge internal propertyobject
+ pLastRemoteI = m_pBridgeImpl->m_pPropertyObject;
+ pLastRemoteI->acquire( pLastRemoteI );
+ flags.bBridgePropertyCall = sal_True;
+ }
+
+ // NOTE : Instance provider is called in the executing thread
+ // Otherwise, instance provider may block the bridge
+ }
+
+ sal_Bool bCallIsOneway = sal_False;
+ if( flags.bMoreFlags )
+ {
+ // flags override the default !
+ bCallIsOneway = ! flags.bSynchronous;
+ }
+ else if( pMethodType && pMethodType->bOneWay )
+ {
+ bCallIsOneway = sal_True;
+ }
+
+ if( pMultiJob && ! flags.bTid && bCallIsOneway && ! pMultiJob->isFull())
+ {
+ // add to the existing multijob, nothing to do here
+ }
+ else
+ {
+ // create a new multijob
+ if( pMultiJob )
+ {
+ // there exists an old one, start it first.
+ pMultiJob->initiate();
+ }
+
+ pMultiJob = new ServerMultiJob(
+ pEnvRemote,
+ static_cast< remote_Context * >(
+ pEnvRemote->pContext ),
+ *ppLastTid, m_pBridgeImpl, &m_unmarshal,
+ nMessageCount );
+ }
+
+ pMultiJob->setCurrentContext( bHasCc, pCc );
+ pMultiJob->setIgnoreCache( flags.bIgnoreCache );
+ pMultiJob->setType( *ppLastType );
+ if( pMethodType )
+ {
+ pMultiJob->setMethodType( pMethodType ,
+ REMOTE_RELEASE_METHOD_INDEX == flags.nMethodId,
+ bCallIsOneway );
+ }
+ else if( pAttributeType )
+ {
+ pMultiJob->setAttributeType( pAttributeType, bIsSetter, bCallIsOneway );
+ }
+ else
+ {
+ OSL_ASSERT( 0 );
+ }
+
+ if( pLastRemoteI )
+ pMultiJob->setInterface( pLastRemoteI );
+ else
+ pMultiJob->setOid( *ppLastOid );
+ } /* getMemberTypeDescription */
+ else
+ {
+ delete pMultiJob;
+ pMultiJob = 0;
+ pLastRemoteI = 0; // stubs are released during dispose eitherway
+ disposeEnvironment();
+ break;
+ }
+#ifdef BRIDGES_URP_PROT
+ bIsOneWay = pMethodType && pMethodType->bOneWay;
+ sMemberName = pMethodType ?
+ pMethodType->aBase.pMemberName :
+ pAttributeType->aBase.pMemberName;
+ sal_uInt32 nLogHeader = m_unmarshal.getPos();
+#endif
+ if( ! pMultiJob->extract( ) )
+ {
+ // severe error during extracting, dispose
+ delete pMultiJob;
+ pMultiJob = 0;
+ pLastRemoteI = 0; // stubs are released during dispose eitherway
+ disposeEnvironment();
+ break;
+ }
+
+#ifdef BRIDGES_URP_PROT
+ urp_logServingRequest(
+ m_pBridgeImpl, m_unmarshal.getPos() - nLogStart,
+ m_unmarshal.getPos() - nLogHeader,
+ !bIsOneWay,
+ sMemberName );
+#endif
+ if ( flags.bBridgePropertyCall )
+ {
+ // call to the bridge internal object.
+ // these calls MUST be executed within the dispatcher thread in order
+ // to synchronize properly with protocol changes
+ // NOTE : Threadid is not preserved for this call.
+
+ // lock the marshaling NOW !
+ {
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+
+ pMultiJob->execute();
+
+ if( m_pBridgeImpl->m_pPropertyObject->changesHaveBeenCommited() )
+ {
+ Properties props;
+ props = m_pBridgeImpl->m_pPropertyObject->getCommitedChanges();
+
+ // This call modified the protocol, apply the changes NOW !
+ m_pBridgeImpl->applyProtocolChanges( props );
+ }
+ }
+ delete pMultiJob;
+ pMultiJob = 0;
+ }
+ }
+ else
+ {
+ //--------------------------
+ // handle reply
+ //--------------------------
+ if( pMultiJob )
+ {
+ pMultiJob->initiate();
+ pMultiJob = 0;
+ }
+ if( pLastRemoteI )
+ {
+ pLastRemoteI->release( pLastRemoteI );
+ pLastRemoteI = 0;
+ }
+ ClientJob *pClientJob =
+ m_pBridgeImpl->m_clientJobContainer.remove( *( ByteSequence * )ppLastTid );
+
+ // Bridge MUST be already disposed, otherwise we got a wrong threadid
+ // from remote !
+ OSL_ASSERT( pClientJob || m_pBridgeImpl->m_bDisposed );
+ if( ! pClientJob )
+ {
+ OUStringBuffer error( 128 );
+ error.appendAscii( "ThreadID " );
+ OString o = byteSequence2HumanReadableString( *(ByteSequence* )ppLastTid );
+ error.appendAscii( o.getStr(), o.getLength() );
+ error.appendAscii( " unknown, so couldn't unmarshal reply" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ pLastRemoteI = 0;
+ disposeEnvironment();
+ break;
+ }
+
+ pClientJob->m_bExceptionOccured = flags.bException;
+
+ pClientJob->setUnmarshal( &m_unmarshal );
+#ifdef BRIDGES_URP_PROT
+ sMemberName = pClientJob->m_pMethodType ?
+ pClientJob->m_pMethodType->aBase.pMemberName :
+ pClientJob->m_pAttributeType->aBase.pMemberName;
+ sal_uInt32 nLogHeader = m_unmarshal.getPos();
+#endif
+ if( ! pClientJob->extract( ) )
+ {
+ // severe error during extracting, dispose
+ pLastRemoteI = 0; // stubs are released during dispose eitherway
+ disposeEnvironment();
+ break;
+ }
+#ifdef BRIDGES_URP_PROT
+ urp_logGettingReply(
+ m_pBridgeImpl, m_unmarshal.getPos() - nLogStart,
+ m_unmarshal.getPos() - nLogHeader, sMemberName );
+#endif
+ sal_Bool bBridgePropertyCallAndWaitingForReply =
+ pClientJob->isBridgePropertyCall();
+
+ pClientJob->initiate();
+
+ if( bBridgePropertyCallAndWaitingForReply )
+ {
+ // NOTE : This must be the reply for commit change. The new properties
+ // are now applied by the clientJob thread, but the reader thread
+ // must wait for it, because the next message on the wire already
+ // uses the new protocol settings.
+ // waiting for the commit change reply
+ m_pBridgeImpl->m_pPropertyObject->waitUntilChangesAreCommitted();
+ }
+ }
+ } // end while( !m_unmarshal.finished() )
+
+ if( pLastRemoteI )
+ pLastRemoteI->release( pLastRemoteI );
+
+ if( pMultiJob )
+ pMultiJob->initiate();
+
+ if( pEnvRemote )
+ pEnvRemote->release( pEnvRemote );
+ }
+
+ if( m_pConnection )
+ {
+ m_pConnection->release( m_pConnection );
+ m_pConnection = 0;
+ }
+}
+}
diff --git a/bridges/source/remote/urp/urp_reader.hxx b/bridges/source/remote/urp/urp_reader.hxx
new file mode 100644
index 000000000000..9cb36e629c07
--- /dev/null
+++ b/bridges/source/remote/urp/urp_reader.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_reader.hxx,v $
+ * $Revision: 1.7.20.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <osl/thread.hxx>
+
+#include "urp_unmarshal.hxx"
+
+struct remote_Connection;
+typedef struct _uno_Environment uno_Environment;
+
+namespace bridges_urp
+{
+
+class OWriterThread;
+struct MessageFlags;
+
+class OReaderThread :
+ public ::osl::Thread
+{
+public:
+ OReaderThread( remote_Connection *pConnection ,
+ uno_Environment *pEnvRemote,
+ OWriterThread *pWriterThread );
+ ~OReaderThread();
+
+ // may only be called in the callstack of this thread !!!!!
+ // run() -> disposeEnvironment() -> dispose() -> destroyYourself()
+ void destroyYourself();
+
+private:
+ virtual void SAL_CALL run();
+ virtual void SAL_CALL onTerminated();
+
+ inline sal_Bool readBlock( sal_Int32 *pnMessageCount );
+ inline sal_Bool readFlags( struct MessageFlags *pFlags );
+
+ void disposeEnvironment();
+
+ inline sal_Bool getMemberTypeDescription(
+ typelib_InterfaceAttributeTypeDescription **ppAttributeType,
+ typelib_InterfaceMethodTypeDescription **ppMethodType,
+ sal_Bool *pbIsSetter,
+ sal_uInt16 nMethodId ,
+ typelib_TypeDescriptionReference *pITypeRef);
+
+ remote_Connection *m_pConnection;
+ uno_Environment *m_pEnvRemote;
+ OWriterThread *m_pWriterThread;
+ sal_Bool m_bDestroyMyself;
+ sal_Bool m_bContinue;
+ urp_BridgeImpl *m_pBridgeImpl;
+ Unmarshal m_unmarshal;
+};
+
+}
diff --git a/bridges/source/remote/urp/urp_replycontainer.hxx b/bridges/source/remote/urp/urp_replycontainer.hxx
new file mode 100644
index 000000000000..bcf0394853a4
--- /dev/null
+++ b/bridges/source/remote/urp/urp_replycontainer.hxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_replycontainer.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <hash_map>
+#include <list>
+
+#include <osl/mutex.hxx>
+#include <osl/diagnose.h>
+
+#include "urp_threadid.hxx"
+
+namespace bridges_urp
+{
+ class ClientJob;
+ typedef ::std::hash_map< ::rtl::ByteSequence ,
+ ::std::list < ClientJob * > ,
+ HashThreadId ,
+ EqualThreadId > Id2ClientJobStackMap;
+
+ class urp_ClientJobContainer
+ {
+ public:
+ void add( const ::rtl::ByteSequence &id , ClientJob *p )
+ {
+ ::osl::MutexGuard guard( m_mutex );
+ m_map[id].push_back( p );
+ }
+
+ ClientJob *remove( const ::rtl::ByteSequence & id )
+ {
+ ::osl::MutexGuard guard( m_mutex );
+ Id2ClientJobStackMap::iterator ii = m_map.find( id );
+
+ ClientJob *p = 0;
+ if( ii != m_map.end() )
+ {
+ p = (*ii).second.back();
+ (*ii).second.pop_back();
+ if( (*ii).second.empty() )
+ {
+ m_map.erase( ii );
+ }
+ }
+
+ return p;
+ }
+
+ private:
+ ::osl::Mutex m_mutex;
+ Id2ClientJobStackMap m_map;
+ };
+}
diff --git a/bridges/source/remote/urp/urp_threadid.cxx b/bridges/source/remote/urp/urp_threadid.cxx
new file mode 100644
index 000000000000..19ede890568c
--- /dev/null
+++ b/bridges/source/remote/urp/urp_threadid.cxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_threadid.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include "urp_threadid.hxx"
+
+#include <rtl/strbuf.hxx>
+
+using namespace rtl;
+
+namespace bridges_urp
+{
+ rtl::OString byteSequence2HumanReadableString( const rtl::ByteSequence &a )
+ {
+ const sal_uInt8 *p = (const sal_uInt8 * ) a.getConstArray();
+ sal_Int32 nLength = a.getLength();
+ OStringBuffer buf( a.getLength() * 2 + 2 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM( "0x" ) );
+ for( sal_Int32 i = 0 ; i < nLength ; i ++ )
+ buf.append( (sal_Int32) p[i] , 16 );
+ return buf.makeStringAndClear();
+ }
+}
diff --git a/bridges/source/remote/urp/urp_threadid.hxx b/bridges/source/remote/urp/urp_threadid.hxx
new file mode 100644
index 000000000000..2fe259b3e89b
--- /dev/null
+++ b/bridges/source/remote/urp/urp_threadid.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_threadid.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _URP_THREADID_HXX_
+#define _URP_THREADID_HXX_
+
+#include <sal/types.h>
+#include <rtl/byteseq.hxx>
+#include <rtl/string.hxx>
+
+namespace bridges_urp
+{
+
+ struct EqualThreadId
+ {
+ sal_Int32 operator () ( const ::rtl::ByteSequence &a , const ::rtl::ByteSequence &b ) const
+ {
+ return a == b;
+ }
+ };
+
+ struct HashThreadId
+ {
+ sal_Int32 operator () ( const ::rtl::ByteSequence &a ) const
+ {
+ if( a.getLength() >= 4 )
+ {
+ return *(sal_Int32*) a.getConstArray();
+ }
+ return 0;
+ }
+ };
+
+ rtl::OString byteSequence2HumanReadableString( const rtl::ByteSequence &a );
+}
+#endif
diff --git a/bridges/source/remote/urp/urp_unmarshal.cxx b/bridges/source/remote/urp/urp_unmarshal.cxx
new file mode 100644
index 000000000000..798a5ff79ec5
--- /dev/null
+++ b/bridges/source/remote/urp/urp_unmarshal.cxx
@@ -0,0 +1,710 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_unmarshal.cxx,v $
+ * $Revision: 1.16 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <string.h>
+
+#include <osl/diagnose.h>
+
+#include <rtl/alloc.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <uno/data.h>
+#include <uno/any2.h>
+#include <uno/sequence2.h>
+
+#include <com/sun/star/uno/Any.hxx>
+
+#include "urp_unmarshal.hxx"
+#include "urp_bridgeimpl.hxx"
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace bridges_urp
+{
+static int g_nDetectLittleEndian = 1;
+char g_bSystemIsLittleEndian = ((char*)&g_nDetectLittleEndian)[0];
+
+
+Unmarshal::Unmarshal( struct urp_BridgeImpl *pBridgeImpl,
+ uno_Environment *pEnvRemote,
+ remote_createStubFunc callback ) :
+ m_nBufferSize( 4096 ),
+ m_base( (sal_Int8*) rtl_allocateMemory( m_nBufferSize ) ),
+ m_pos( m_base ),
+ m_nLength( 0 ),
+ m_callback( callback ),
+ m_pEnvRemote( pEnvRemote ),
+ m_pBridgeImpl( pBridgeImpl )
+{
+}
+
+Unmarshal::~Unmarshal()
+{
+ rtl_freeMemory( m_base );
+}
+
+// special unpacks
+sal_Bool Unmarshal::unpackTid( sal_Sequence **ppThreadId )
+{
+ sal_Int32 nSize;
+ sal_Bool bReturn = unpackCompressedSize( &nSize );
+ if( bReturn )
+ {
+ if( nSize )
+ {
+ rtl_byte_sequence_constructFromArray( ppThreadId , m_pos , nSize );
+ m_pos += nSize;
+ sal_uInt16 nIndex;
+ bReturn = unpackInt16( &nIndex );
+ if( nIndex < m_pBridgeImpl->m_properties.nTidCacheSize )
+ {
+ m_pBridgeImpl->m_pTidIn[nIndex] = *(ByteSequence * )ppThreadId;
+ }
+ else if( 0xffff != nIndex )
+ {
+ bReturn = sal_False;
+ rtl_byte_sequence_construct( ppThreadId , 0 );
+
+ OUStringBuffer error( 128 );
+ error.appendAscii( "cache index for tid " );
+ OString o = byteSequence2HumanReadableString( *(ByteSequence * ) ppThreadId );
+ error.appendAscii( o.getStr(), o.getLength() );
+ error.appendAscii( "out of range(0x");
+ error.append( (sal_Int32) nIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ sal_uInt16 nIndex;
+ bReturn = unpackInt16( &nIndex );
+ if( nIndex < m_pBridgeImpl->m_properties.nTidCacheSize )
+ {
+ *ppThreadId = m_pBridgeImpl->m_pTidIn[nIndex].getHandle();
+ rtl_byte_sequence_acquire( *ppThreadId );
+ }
+ else
+ {
+ bReturn = sal_False;
+ rtl_byte_sequence_construct( ppThreadId , 0 );
+ OUStringBuffer error(128);
+ error.appendAscii( "cache index for tids out of range(0x" );
+ error.append( (sal_Int32) nIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ }
+ else
+ {
+ m_pBridgeImpl->addError( "couldn't unpack thread id because of previous errors" );
+ }
+ return bReturn;
+}
+
+sal_Bool Unmarshal::unpackOid( rtl_uString **ppOid )
+{
+ sal_Bool bReturn = sal_True;
+ sal_uInt16 nCacheIndex = 0;
+
+ bReturn = bReturn && unpackString( ppOid );
+ bReturn = bReturn && unpackInt16( &nCacheIndex );
+
+ if( bReturn &&
+ ! ( 0xffff == nCacheIndex && 0 == (*ppOid)->length ) /* null reference */ )
+ {
+ if( (*ppOid)->length )
+ {
+ // new unknown reference
+ if( 0xffff != nCacheIndex )
+ {
+ // oid should be cached ?
+ if( nCacheIndex < m_pBridgeImpl->m_properties.nOidCacheSize )
+ {
+ m_pBridgeImpl->m_pOidIn[nCacheIndex] = *ppOid;
+ }
+ else
+ {
+ OUStringBuffer error( 128 );
+ error.appendAscii( "new oid provided (" );
+ error.append( *ppOid );
+ error.appendAscii( "), but new cache index is out of range(0x");
+ error.append( (sal_Int32) nCacheIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+
+ bReturn = sal_False;
+ rtl_uString_new( ppOid );
+ }
+ }
+ }
+ else
+ {
+ // reference in cache !
+ if( nCacheIndex < m_pBridgeImpl->m_properties.nOidCacheSize )
+ {
+ rtl_uString_assign( ppOid , m_pBridgeImpl->m_pOidIn[nCacheIndex].pData );
+ }
+ else
+ {
+ bReturn = sal_False;
+ rtl_uString_new( ppOid );
+
+ OUStringBuffer error( 128 );
+ error.appendAscii( "cache index for oids out of range(0x");
+ error.append( (sal_Int32) nCacheIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ }
+
+ return bReturn;
+}
+
+sal_Bool Unmarshal::unpack( void *pDestination ,
+ typelib_TypeDescription *pTypeDescr )
+{
+ // Note: We implement unpack functionality without recursions in order
+ // to avoid stack overflows caused by rotten URP blocks.
+
+ m_aItemsToUnpack.push( UnpackItem( pDestination, pTypeDescr ) );
+
+ sal_Bool bReturn = sal_True;
+ do
+ {
+ void * pDest = m_aItemsToUnpack.top().pDest;
+ typelib_TypeDescription * pType = m_aItemsToUnpack.top().pType;
+ m_aItemsToUnpack.pop();
+
+ switch( pType->eTypeClass )
+ {
+ case typelib_TypeClass_VOID:
+ // do nothing
+ break;
+ case typelib_TypeClass_BYTE:
+ {
+ bReturn = unpackInt8( pDest );
+ break;
+ }
+ case typelib_TypeClass_BOOLEAN:
+ {
+ bReturn = ! checkOverflow( 1 );
+ if( bReturn )
+ {
+ *((sal_Bool*)pDest) = (sal_Bool ) ( *m_pos);
+ m_pos ++;
+ }
+ else
+ {
+ *((sal_Bool*)pDest) = 0;
+ }
+ break;
+ }
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ {
+ unpackInt16( pDest );
+ break;
+ }
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ {
+ bReturn = unpackInt32( pDest );
+ break;
+ }
+ case typelib_TypeClass_DOUBLE:
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ {
+ sal_Int8 * p = static_cast< sal_Int8 * >(pDest);
+ bReturn = ! checkOverflow( 8 );
+ if( bReturn )
+ {
+ if( isSystemLittleEndian() )
+ {
+ p[7] = m_pos[0];
+ p[6] = m_pos[1];
+ p[5] = m_pos[2];
+ p[4] = m_pos[3];
+ p[3] = m_pos[4];
+ p[2] = m_pos[5];
+ p[1] = m_pos[6];
+ p[0] = m_pos[7];
+ }
+ else
+ {
+ p[0] = m_pos[0];
+ p[1] = m_pos[1];
+ p[2] = m_pos[2];
+ p[3] = m_pos[3];
+ p[4] = m_pos[4];
+ p[5] = m_pos[5];
+ p[6] = m_pos[6];
+ p[7] = m_pos[7];
+ }
+ m_pos += 8;
+ }
+ else
+ {
+ // Do not trigger alignment errors:
+ p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = 0;
+ }
+ break;
+ }
+ case typelib_TypeClass_STRING:
+ {
+ unpackString( pDest );
+ break;
+ }
+ case typelib_TypeClass_ANY:
+ {
+ uno_Any *pAny = ( uno_Any * )pDest;
+
+ pAny->pType = 0;
+ // Type is acquired with typelib_typedescription_acquire
+
+ bReturn = unpackType( &(pAny->pType) );
+
+ typelib_TypeDescription *pDataType = 0;
+ if( bReturn && pAny->pType )
+ {
+ typelib_typedescriptionreference_getDescription( &pDataType , pAny->pType );
+
+ if( pDataType )
+ {
+ switch (pDataType->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (sizeof(void *) < sizeof(sal_Int64))
+ {
+ pAny->pData = rtl_allocateMemory( sizeof(sal_Int64) );
+ }
+ else
+ {
+ pAny->pData = &pAny->pReserved;
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (sizeof(void *) < sizeof(float))
+ {
+ pAny->pData = rtl_allocateMemory( sizeof(float) );
+ }
+ else
+ {
+ pAny->pData = &pAny->pReserved;
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (sizeof(void *) < sizeof(double))
+ {
+ pAny->pData = rtl_allocateMemory( sizeof(double) );
+ }
+ else
+ {
+ pAny->pData = &pAny->pReserved;
+ }
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_UNION:
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_ARRAY:
+ pAny->pData = rtl_allocateMemory( pDataType->nSize );
+ break;
+ case typelib_TypeClass_ANY:
+ {
+ m_pBridgeImpl->addError(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "can't unmarshal any: any in any not supported!" ) ) );
+
+ pAny->pData = 0;
+ Type type; // void
+ pAny->pType = type.getTypeLibType();
+ typelib_typedescriptionreference_acquire( pAny->pType );
+
+ bReturn = sal_False;
+ break;
+ }
+ default:
+ pAny->pData = &pAny->pReserved;
+ }
+
+ if ( bReturn )
+ {
+ m_aItemsToUnpack.push(
+ UnpackItem( pAny->pData, pDataType ) );
+ }
+ }
+ else
+ {
+ OUStringBuffer error;
+ error.appendAscii( "can't unmarshal any because typedescription for " );
+ error.append( pAny->pType->pTypeName );
+ error.appendAscii( " is missing" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+
+ if( pDataType )
+ {
+ typelib_typedescription_release( pDataType );
+ }
+ else
+ {
+ pAny->pData = 0;
+ Type type; // void
+ pAny->pType = type.getTypeLibType();
+ typelib_typedescriptionreference_acquire( pAny->pType );
+
+ bReturn = sal_False;
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ *(remote_Interface**)pDest = 0;
+
+ rtl_uString *pString = 0;
+ bReturn = unpackOid( &pString ) && bReturn;
+
+ if( bReturn && pString && pString->length )
+ {
+ m_callback( (remote_Interface**) pDest ,
+ pString,
+ pType->pWeakRef ,
+ m_pEnvRemote,
+ urp_releaseRemoteCallback );
+ }
+ if( pString )
+ {
+ rtl_uString_release( pString );
+ }
+ break;
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ bReturn = unpackType( pDest );
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_CompoundTypeDescription * pCompType =
+ (typelib_CompoundTypeDescription *)pType;
+
+ // direct members
+ typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets;
+ sal_Int32 nDescr = pCompType->nMembers;
+
+ // at least assume 1 byte per member
+ bReturn = bReturn && ! checkOverflow( nDescr * 1 );
+ for ( sal_Int32 nPos = nDescr; nPos; --nPos )
+ {
+ typelib_TypeDescription * pMemberType = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pMemberType, ppTypeRefs[ nPos - 1 ] );
+
+ m_aItemsToUnpack.push(
+ UnpackItem( (char*)pDest + pMemberOffsets[ nPos - 1 ],
+ pMemberType,
+ true /* construct even in error case */ ) );
+
+ m_aTypesToRelease.push_back( pMemberType );
+ }
+
+ // parent
+ if (pCompType->pBaseTypeDescription)
+ {
+ m_aItemsToUnpack.push(
+ UnpackItem( pDest,
+ (typelib_TypeDescription *)
+ pCompType->pBaseTypeDescription ) );
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ sal_Int32 nLen;
+ bReturn = unpackCompressedSize( &nLen );
+
+ // urp protocol does not allow to use the elementsize as a guess, if enough data
+ // is available. However, at least one byte per member must be within the message
+ bReturn = bReturn && ! checkOverflow( 1 * nLen );
+ uno_Sequence *pSequence = 0;
+ if( nLen && bReturn )
+ {
+ typelib_TypeDescriptionReference * pETRef =
+ ((typelib_IndirectTypeDescription *)pType)->pType;
+
+ typelib_TypeDescription * pET = 0;
+ typelib_typedescriptionreference_getDescription( &pET , pETRef );
+
+ if( pET )
+ {
+ sal_Int32 nElementSize = pET->nSize;
+
+ pSequence = (uno_Sequence *)rtl_allocateMemory(
+ SAL_SEQUENCE_HEADER_SIZE + nElementSize * nLen );
+ pSequence->nRefCount = 1;
+ pSequence->nElements = nLen;
+
+ if( typelib_TypeClass_BYTE == pET->eTypeClass )
+ {
+ memcpy( pSequence->elements , m_pos , nLen );
+ m_pos += nLen;
+ }
+ else
+ {
+ for ( sal_Int32 i = nLen; i; --i )
+ {
+ m_aItemsToUnpack.push(
+ UnpackItem(
+ ((char*)pSequence->elements)
+ + (i - 1) * nElementSize,
+ pET ) );
+ }
+ }
+ m_aTypesToRelease.push_back( pET );
+ }
+ else
+ {
+ bReturn = sal_False;
+ uno_constructData( &pSequence , pType );
+ OUStringBuffer error;
+ error.appendAscii( "can't unmarshal sequence, because there is no typedescription for element type " );
+ error.append( pETRef->pTypeName );
+ error.appendAscii( " available" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ uno_constructData( &pSequence , pType );
+ }
+
+ *((uno_Sequence **)pDest) = pSequence;
+ break;
+ }
+ case typelib_TypeClass_UNION:
+ case typelib_TypeClass_ARRAY:
+ case typelib_TypeClass_SERVICE:
+ case typelib_TypeClass_MODULE:
+ case typelib_TypeClass_INTERFACE_METHOD:
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ case typelib_TypeClass_UNKNOWN:
+ default:
+ {
+ ::rtl::OUStringBuffer buffer( 128 );
+ buffer.appendAscii( RTL_CONSTASCII_STRINGPARAM("Unsupported typeclass during unmarshaling ("));
+ buffer.append( ( sal_Int32 ) pType->eTypeClass , 10 );
+ buffer.appendAscii( ")" );
+ m_pBridgeImpl->addError( buffer.makeStringAndClear() );
+ bReturn = sal_False;
+ }
+ }
+
+ if ( !bReturn )
+ {
+ // construct default data for every remaining item.
+ while ( !m_aItemsToUnpack.empty() )
+ {
+ const UnpackItem & rItem = m_aItemsToUnpack.top();
+
+ if ( rItem.bMustBeConstructed )
+ uno_constructData( rItem.pDest , rItem.pType );
+
+ m_aItemsToUnpack.pop();
+ }
+ }
+ }
+ while ( !m_aItemsToUnpack.empty() );
+
+ // release pending type descriptions
+ TypeDescVector::const_iterator it = m_aTypesToRelease.begin();
+ const TypeDescVector::const_iterator end = m_aTypesToRelease.end();
+ while ( it != end )
+ {
+ typelib_typedescription_release( *it );
+ it++;
+ }
+ m_aTypesToRelease.clear();
+
+ return bReturn;
+}
+
+sal_Bool Unmarshal::unpackType( void *pDest )
+{
+ *(typelib_TypeDescriptionReference **) pDest = 0;
+
+ sal_uInt8 nTypeClass;
+ sal_Bool bReturn = unpackInt8( &nTypeClass );
+
+ typelib_TypeDescriptionReference *pTypeRef = 0;
+ if( bReturn )
+ {
+ if( nTypeClass <= 14 /* any */ )
+ {
+ pTypeRef = * typelib_static_type_getByTypeClass((typelib_TypeClass )nTypeClass);
+ typelib_typedescriptionreference_acquire( pTypeRef );
+ }
+ else
+ {
+ sal_uInt16 nCacheIndex = 0;
+ bReturn = bReturn && unpackInt16( &nCacheIndex );
+
+ if( bReturn )
+ {
+ if( nTypeClass & 0x80 )
+ {
+ // new type
+ rtl_uString *pString = 0;
+ bReturn = bReturn && unpackString( &pString );
+ if( bReturn )
+ {
+ typelib_TypeDescription *pType = 0;
+ typelib_typedescription_getByName( &pType, pString );
+ if( pType )
+ {
+ // type is known in this process
+ if( (typelib_TypeClass )(nTypeClass & 0x7f) == pType->eTypeClass )
+ {
+ //typename and typeclass match, this is as it should be
+ pTypeRef = pType->pWeakRef;
+ typelib_typedescriptionreference_acquire( pTypeRef );
+ }
+ else
+ {
+ // typename and typeclass do not match, dispose the bridge
+ // as there must be inconsistent type base between both processes
+ // or trash comes over the wire ...
+ bReturn = sal_False;
+ OUStringBuffer error( 128 );
+ error.appendAscii( "it is tried to introduce type " );
+ error.append( pString );
+ error.appendAscii( "with typeclass " );
+ error.append( (sal_Int32)( nTypeClass & 0x7f ) , 10 );
+ error.appendAscii( " , which does not match with typeclass " );
+ error.append( (sal_Int32) pType->eTypeClass ,10 );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ typelib_typedescription_release( pType );
+ pType = 0;
+ }
+ else
+ {
+ // a type by this name is not known in the process.
+ if( (nTypeClass & 0x7f) < typelib_TypeClass_UNKNOWN )
+ {
+ // typeclass is within a valid range, introduce the new
+ // type.
+ typelib_typedescriptionreference_new(
+ &pTypeRef, (typelib_TypeClass )(nTypeClass & 0x7f), pString );
+ }
+ else
+ {
+ // typeclass is out of range !
+ bReturn = sal_False;
+ OUStringBuffer error( 128 );
+ error.appendAscii( "it is tried to introduce type " );
+ error.append( pString );
+ error.appendAscii( "with an out of range typeclass " );
+ error.append( (sal_Int32)( nTypeClass & 0x7f ) , 10 );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+
+ if( bReturn && nCacheIndex != 0xffff )
+ {
+ if( nCacheIndex < m_pBridgeImpl->m_properties.nTypeCacheSize )
+ {
+ m_pBridgeImpl->m_pTypeIn[nCacheIndex] = *( Type * )&pTypeRef;
+ }
+ else
+ {
+ bReturn = sal_False;
+ OUStringBuffer error( 128 );
+ error.appendAscii( "cache index for type " );
+ error.append( pString );
+ error.appendAscii( "out of range(0x" );
+ error.append( (sal_Int32) nCacheIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ }
+ if( pString )
+ {
+ rtl_uString_release( pString );
+ }
+ }
+ else
+ {
+ if( nCacheIndex < m_pBridgeImpl->m_properties.nTypeCacheSize )
+ {
+ pTypeRef = m_pBridgeImpl->m_pTypeIn[nCacheIndex].getTypeLibType();
+ typelib_typedescriptionreference_acquire( pTypeRef );
+ }
+ else
+ {
+ bReturn = sal_False;
+ OUStringBuffer error;
+ error.appendAscii( "cache index for types out of range(0x" );
+ error.append( (sal_Int32) nCacheIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ }
+ }
+ }
+ if( ! pTypeRef )
+ {
+ pTypeRef = * typelib_static_type_getByTypeClass(typelib_TypeClass_VOID);
+ typelib_typedescriptionreference_acquire( pTypeRef );
+ }
+ // pTypeRef is already acquired
+ *(typelib_TypeDescriptionReference**)pDest = pTypeRef;
+ return bReturn;
+}
+
+}
+
diff --git a/bridges/source/remote/urp/urp_unmarshal.hxx b/bridges/source/remote/urp/urp_unmarshal.hxx
new file mode 100644
index 000000000000..f8590c20d89d
--- /dev/null
+++ b/bridges/source/remote/urp/urp_unmarshal.hxx
@@ -0,0 +1,283 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_unmarshal.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _URP_UNMARSHAL_HXX_
+#define _URP_UNMARSHAL_HXX_
+
+#include <stack>
+#include <vector>
+#include <rtl/byteseq.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <bridges/remote/context.h>
+
+#ifndef _BRIDGES_REMOTE_HELPER_HXX_
+#include <bridges/remote/helper.hxx>
+#endif
+#include <com/sun/star/uno/Type.hxx>
+#include "urp_bridgeimpl.hxx"
+
+typedef struct _uno_Environment uno_Environment;
+struct remote_Interface;
+
+namespace bridges_urp
+{
+
+extern char g_bSystemIsLittleEndian;
+class ThreadId;
+struct urp_BridgeImpl;
+void SAL_CALL urp_releaseRemoteCallback(
+ remote_Interface *pRemoteI,rtl_uString *pOid,
+ typelib_TypeDescriptionReference *pTypeRef,
+ uno_Environment *pEnvRemote );
+
+struct UnpackItem
+{
+ void * pDest;
+ typelib_TypeDescription * pType;
+ bool bMustBeConstructed;
+
+ UnpackItem()
+ : pDest( 0 ), pType( 0 ), bMustBeConstructed( false ) {}
+ UnpackItem( void * d, typelib_TypeDescription * t, bool b = false )
+ : pDest( d ), pType( t ), bMustBeConstructed( b ) {}
+};
+
+typedef std::stack< UnpackItem > UnpackItemStack;
+typedef std::vector< typelib_TypeDescription * > TypeDescVector;
+
+class Unmarshal
+{
+public:
+ Unmarshal(
+ struct urp_BridgeImpl *,
+ uno_Environment *pEnvRemote,
+ remote_createStubFunc callback );
+ ~Unmarshal();
+
+ inline sal_Bool finished()
+ { return m_base + m_nLength == m_pos; }
+ inline sal_uInt32 getPos()
+ { return (sal_uInt32 ) (m_pos - m_base); }
+
+ inline sal_Bool setSize( sal_Int32 nSize );
+
+ sal_Bool unpack( void *pDest, typelib_TypeDescription *pType );
+ inline sal_Bool unpackCompressedSize( sal_Int32 *pData );
+ inline sal_Bool unpackInt8( void *pDest );
+ inline sal_Bool unpackString( void *pDest );
+ inline sal_Bool unpackInt16( void *pDest );
+ inline sal_Bool unpackInt32( void *pDest );
+ sal_Bool unpackType( void *pDest );
+
+ inline sal_Bool unpackAny( void *pDest );
+ sal_Bool unpackOid( rtl_uString **ppOid );
+ sal_Bool unpackTid( sal_Sequence **ppThreadId );
+
+ sal_Int8 *getBuffer()
+ { return m_base; }
+ inline sal_Bool isSystemLittleEndian()
+ { return g_bSystemIsLittleEndian; }
+
+private:
+ inline sal_Bool checkOverflow( sal_Int32 nNextMem );
+
+ UnpackItemStack m_aItemsToUnpack;
+ TypeDescVector m_aTypesToRelease;
+
+ sal_Int32 m_nBufferSize;
+ sal_Int8 *m_base;
+ sal_Int8 *m_pos;
+ sal_Int32 m_nLength;
+
+ remote_createStubFunc m_callback;
+ uno_Environment *m_pEnvRemote;
+ urp_BridgeImpl *m_pBridgeImpl;
+};
+
+inline sal_Bool Unmarshal::setSize( sal_Int32 nSize )
+{
+ if( nSize > m_nBufferSize )
+ {
+ // adjust buffer size and length.
+ sal_Int8 * base =
+ (sal_Int8*)rtl_reallocateMemory (m_base, sal_Size(nSize));
+ if (base != 0)
+ {
+ m_base = base;
+ m_nLength = m_nBufferSize = nSize;
+ }
+ }
+ else
+ {
+ // adjust buffer length, only.
+ m_nLength = nSize;
+ }
+
+ // reset buffer position, and leave.
+ m_pos = m_base;
+ return (m_nLength == nSize);
+}
+
+inline sal_Bool Unmarshal::checkOverflow( sal_Int32 nNextMem )
+{
+ sal_Bool bOverflow = nNextMem < 0 ||
+ (((sal_Int32)( m_pos - m_base )) + nNextMem ) > m_nLength;
+ if( bOverflow )
+ m_pBridgeImpl->addError( "message too short" );
+ return bOverflow;
+}
+
+
+inline sal_Bool Unmarshal::unpackInt8( void *pDest )
+{
+ sal_Bool bReturn = ! checkOverflow( 1 );
+ if( bReturn )
+ {
+ *((sal_Int8*)pDest ) = *m_pos;
+ m_pos++;
+ }
+ else
+ {
+ *((sal_Int8*)pDest ) = 0;
+ }
+ return bReturn;
+}
+
+inline sal_Bool Unmarshal::unpackInt32( void *pDest )
+{
+ sal_uInt32 *p = ( sal_uInt32 * ) pDest;
+ sal_Bool bReturn = ! checkOverflow(4);
+ if( bReturn )
+ {
+ if( isSystemLittleEndian() )
+ {
+ ((sal_Int8*) p )[3] = m_pos[0];
+ ((sal_Int8*) p )[2] = m_pos[1];
+ ((sal_Int8*) p )[1] = m_pos[2];
+ ((sal_Int8*) p )[0] = m_pos[3];
+ }
+ else
+ {
+ ((sal_Int8*) p )[3] = m_pos[3];
+ ((sal_Int8*) p )[2] = m_pos[2];
+ ((sal_Int8*) p )[1] = m_pos[1];
+ ((sal_Int8*) p )[0] = m_pos[0];
+ }
+ m_pos += 4;
+ }
+ else
+ {
+ *p = 0;
+ }
+ return bReturn;
+}
+
+inline sal_Bool Unmarshal::unpackInt16( void *pDest )
+{
+ sal_uInt16 *p = ( sal_uInt16 * ) pDest;
+
+ sal_Bool bReturn = ! checkOverflow( 2 );
+ if( bReturn )
+ {
+ if( isSystemLittleEndian() )
+ {
+ ((sal_Int8*) p )[1] = m_pos[0];
+ ((sal_Int8*) p )[0] = m_pos[1];
+ }
+ else
+ {
+ ((sal_Int8*) p )[1] = m_pos[1];
+ ((sal_Int8*) p )[0] = m_pos[0];
+ }
+ m_pos ++;
+ m_pos ++;
+ }
+ else
+ {
+ *p = 0;
+ }
+ return bReturn;
+}
+
+inline sal_Bool Unmarshal::unpackString( void *pDest )
+{
+ sal_Int32 nLength;
+ sal_Bool bReturn = unpackCompressedSize( &nLength );
+
+ bReturn = bReturn && ! checkOverflow( nLength );
+ if( bReturn )
+ {
+ *(rtl_uString **) pDest = 0;
+ rtl_string2UString( (rtl_uString**) pDest, (const sal_Char * )m_pos , nLength,
+ RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS );
+ m_pos += nLength;
+ }
+ else
+ {
+ *(rtl_uString ** ) pDest = 0;
+ rtl_uString_new( (rtl_uString **) pDest );
+ }
+ return bReturn;
+}
+
+inline sal_Bool Unmarshal::unpackCompressedSize( sal_Int32 *pData )
+{
+ sal_uInt8 n8Size;
+ sal_Bool bReturn = unpackInt8( &n8Size );
+ if( bReturn )
+ {
+ if( n8Size == 0xff )
+ {
+ unpackInt32( pData );
+ }
+ else
+ {
+ *pData = (sal_Int32 ) n8Size;
+ }
+ }
+ return bReturn;
+}
+
+inline sal_Bool Unmarshal::unpackAny( void *pDest )
+{
+ typelib_TypeDescriptionReference *pTypeRef =
+ * typelib_static_type_getByTypeClass( typelib_TypeClass_ANY );
+
+ typelib_TypeDescription * pTD = 0;
+ typelib_typedescriptionreference_getDescription( &pTD, pTypeRef );
+
+ sal_Bool bReturn = unpack( pDest, pTD );
+
+ typelib_typedescription_release( pTD );
+
+ return bReturn;
+}
+
+}
+#endif
diff --git a/bridges/source/remote/urp/urp_writer.cxx b/bridges/source/remote/urp/urp_writer.cxx
new file mode 100644
index 000000000000..248be6c37098
--- /dev/null
+++ b/bridges/source/remote/urp/urp_writer.cxx
@@ -0,0 +1,272 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_writer.cxx,v $
+ * $Revision: 1.17.20.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <stdio.h>
+#include <osl/time.h>
+
+#include <osl/mutex.hxx>
+#include <osl/conditn.h>
+
+#include <typelib/typedescription.h>
+
+#include <bridges/remote/connection.h>
+#include <bridges/remote/remote.hxx>
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <bridges/remote/counter.hxx>
+
+#include "urp_writer.hxx"
+#include "urp_bridgeimpl.hxx"
+#include "urp_marshal.hxx"
+#include "urp_dispatch.hxx"
+
+#if OSL_DEBUG_LEVEL > 1
+static MyCounter thisCounter( "DEBUG : WriterThread" );
+#endif
+
+using namespace ::osl;
+
+namespace bridges_urp {
+
+OWriterThread::OWriterThread( remote_Connection *pConnection, urp_BridgeImpl *pBridgeImpl,
+ uno_Environment *pEnvRemote) :
+ m_bAbort( sal_False ),
+ m_bInBlockingWait( sal_False ),
+ m_bEnterBlockingWait( sal_False ),
+ m_pConnection( pConnection ),
+ m_pBridgeImpl( pBridgeImpl ),
+ m_pEnvRemote( pEnvRemote )
+
+{
+ m_oslCondition = osl_createCondition();
+ osl_resetCondition( m_oslCondition );
+ m_pConnection->acquire( m_pConnection );
+
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+OWriterThread::~OWriterThread()
+{
+ osl_destroyCondition( m_oslCondition );
+ m_pConnection->release( m_pConnection );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+
+// touch is called with locked m_marshalingMutex
+void OWriterThread::touch( sal_Bool bImmediately )
+{
+ if( bImmediately || m_pBridgeImpl->m_blockMarshaler.getPos() > m_pBridgeImpl->m_properties.nFlushBlockSize )
+ {
+ write();
+ }
+ else
+ {
+ // wake the writer thread up
+ if( m_bInBlockingWait )
+ {
+ m_bInBlockingWait = sal_False;
+ osl_setCondition( m_oslCondition );
+ }
+ else
+ {
+ // ensure, that the writing thread does not enter blocking mode
+ m_bEnterBlockingWait = sal_False;
+ }
+ }
+}
+
+
+void OWriterThread::abortThread()
+{
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+
+ m_bAbort = sal_True;
+ m_bEnterBlockingWait = sal_False;
+ if( m_bInBlockingWait )
+ {
+ m_bInBlockingWait = sal_False;
+ osl_setCondition( m_oslCondition );
+ }
+}
+
+
+// must be called with locked marshaling mutex
+void OWriterThread::write()
+{
+ if( ! m_pBridgeImpl->m_blockMarshaler.empty() && ! m_bAbort )
+ {
+ m_pBridgeImpl->m_blockMarshaler.finish( m_pBridgeImpl->m_nMarshaledMessages);
+ m_pBridgeImpl->m_nMarshaledMessages = 0;
+
+ sal_Int32 nLength = m_pBridgeImpl->m_blockMarshaler.getSize();
+ sal_Int8 *pBuf = m_pBridgeImpl->m_blockMarshaler.getBuffer();
+
+ if( nLength != m_pConnection->write( m_pConnection, pBuf, nLength ))
+ {
+ m_pBridgeImpl->m_blockMarshaler.restart();
+ return;
+ }
+ m_pConnection->flush( m_pConnection );
+ m_pBridgeImpl->m_blockMarshaler.restart();
+ }
+}
+
+void OWriterThread::sendEmptyMessage()
+{
+ // must be called with locked marshaling mutex
+ sal_Int32 a[2] = {0,0};
+ m_pConnection->write( m_pConnection , (sal_Int8*) a , sizeof( sal_Int32) *2 );
+}
+
+void OWriterThread::insertReleaseRemoteCall(
+ rtl_uString *pOid,typelib_TypeDescriptionReference *pTypeRef)
+{
+ {
+ ::osl::MutexGuard guard( m_releaseCallMutex );
+
+ struct RemoteReleaseCall call;
+ call.sOid = pOid;
+ call.typeInterface = pTypeRef;
+ m_lstReleaseCalls.push_back( call );
+ }
+ {
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+ if( m_bInBlockingWait )
+ {
+ m_bInBlockingWait = sal_False;
+ osl_setCondition( m_oslCondition );
+ }
+ else
+ {
+ // ensure, that the writing thread does not enter blocking mode
+ m_bEnterBlockingWait = sal_False;
+ }
+ }
+}
+
+/* The release calls for doubled interfaces
+ *
+ *
+ ***/
+void OWriterThread::executeReleaseRemoteCalls()
+{
+ ::std::list< struct RemoteReleaseCall > lstReleaseCalls;
+ {
+ ::osl::MutexGuard guard( m_releaseCallMutex );
+ lstReleaseCalls.swap( m_lstReleaseCalls );
+ }
+
+ for( ::std::list< struct RemoteReleaseCall >::iterator ii = lstReleaseCalls.begin();
+ ii != lstReleaseCalls.end();
+ ++ ii )
+ {
+ struct RemoteReleaseCall &call = (*ii) ;
+
+ typelib_TypeDescription *pInterfaceTypeDesc = 0;
+ typelib_TypeDescription *pReleaseMethod = 0;
+
+ call.typeInterface.getDescription( &pInterfaceTypeDesc );
+ if( ! pInterfaceTypeDesc->bComplete )
+ {
+ typelib_typedescription_complete( &pInterfaceTypeDesc );
+ }
+
+ uno_Any any;
+ uno_Any *pAny = &any;
+
+ typelib_typedescriptionreference_getDescription(
+ &pReleaseMethod ,
+ ((typelib_InterfaceTypeDescription*)pInterfaceTypeDesc)->ppAllMembers[REMOTE_RELEASE_METHOD_INDEX] );
+
+ urp_sendRequest_internal(
+ m_pEnvRemote , pReleaseMethod, call.sOid.pData,
+ (typelib_InterfaceTypeDescription*) pInterfaceTypeDesc, 0, 0,
+ &pAny );
+
+ typelib_typedescription_release( pReleaseMethod );
+ typelib_typedescription_release( pInterfaceTypeDesc );
+ }
+}
+
+
+void OWriterThread::run()
+{
+ while( ! m_bAbort )
+ {
+ sal_Bool bWait;
+ {
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+ bWait = m_bEnterBlockingWait;
+ if( bWait )
+ {
+ osl_resetCondition( m_oslCondition );
+ m_bInBlockingWait = sal_True;
+ }
+ m_bEnterBlockingWait = sal_True;
+ }
+
+ // wait for some notification
+ if( bWait )
+ osl_waitCondition( m_oslCondition , 0 );
+ // (m_bInBlockingWait = sal_False was set by the activating thread)
+
+ if( m_bAbort )
+ break;
+
+ // Wait for the timeout
+ TimeValue value = { 0 , 1000 * m_pBridgeImpl->m_properties.nOnewayTimeoutMUSEC };
+ osl_resetCondition( m_oslCondition );
+ osl_waitCondition( m_oslCondition , &value );
+
+ // check if there are some release calls to be sent ....
+ executeReleaseRemoteCalls();
+
+ {
+ // write to the socket
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+ if( ! m_pBridgeImpl->m_blockMarshaler.empty() )
+ {
+ write();
+ }
+ }
+ }
+}
+
+
+}
+
diff --git a/bridges/source/remote/urp/urp_writer.hxx b/bridges/source/remote/urp/urp_writer.hxx
new file mode 100644
index 000000000000..f5cafe261280
--- /dev/null
+++ b/bridges/source/remote/urp/urp_writer.hxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp_writer.hxx,v $
+ * $Revision: 1.7.20.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <list>
+
+#include <osl/conditn.h>
+#include <osl/mutex.hxx>
+
+#include <rtl/ustring.hxx>
+
+#include <osl/thread.hxx>
+
+#include <com/sun/star/uno/Type.hxx>
+
+struct remote_Connection;
+
+namespace bridges_urp
+{
+ struct RemoteReleaseCall
+ {
+ ::rtl::OUString sOid;
+ ::com::sun::star::uno::Type typeInterface;
+ };
+
+ struct urp_BridgeImpl;
+ class OWriterThread :
+ public ::osl::Thread
+ {
+ public:
+ OWriterThread( remote_Connection *pConnection,
+ urp_BridgeImpl *m_pBridgeImpl,
+ uno_Environment *pEnvRemote);
+ ~OWriterThread( );
+
+ virtual void SAL_CALL run();
+
+ void touch( sal_Bool bImmediately );
+ void sendEmptyMessage();
+
+ void abortThread();
+
+ void SAL_CALL insertReleaseRemoteCall (
+ rtl_uString *pOid,typelib_TypeDescriptionReference *pTypeRef);
+ void SAL_CALL executeReleaseRemoteCalls();
+
+ private:
+ void write();
+ oslCondition m_oslCondition;
+ sal_Bool m_bAbort;
+ sal_Bool m_bInBlockingWait;
+ sal_Bool m_bEnterBlockingWait;
+ remote_Connection *m_pConnection;
+ urp_BridgeImpl *m_pBridgeImpl;
+ uno_Environment *m_pEnvRemote; // this is held weak only
+
+ ::osl::Mutex m_releaseCallMutex;
+ ::std::list< struct RemoteReleaseCall > m_lstReleaseCalls;
+ };
+}
+