Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
211544a5
Kaydet (Commit)
211544a5
authored
Haz 04, 2013
tarafından
Fridrich Štrba
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Compiling but not working mingw_x86-64 bridges
Change-Id: I5ea6edf367dd18e60a86d12c523b7732a8ac44d4
üst
b9dc42fc
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1031 additions
and
851 deletions
+1031
-851
Library_cpp_uno.mk
bridges/Library_cpp_uno.mk
+3
-4
abi.cxx
bridges/source/cpp_uno/mingw_x86-64/abi.cxx
+330
-0
abi.hxx
bridges/source/cpp_uno/mingw_x86-64/abi.hxx
+33
-17
call.s
bridges/source/cpp_uno/mingw_x86-64/call.s
+89
-253
callvirtualmethod.cxx
bridges/source/cpp_uno/mingw_x86-64/callvirtualmethod.cxx
+127
-100
callvirtualmethod.hxx
bridges/source/cpp_uno/mingw_x86-64/callvirtualmethod.hxx
+6
-5
cpp2uno.cxx
bridges/source/cpp_uno/mingw_x86-64/cpp2uno.cxx
+279
-274
smallstruct.cxx
bridges/source/cpp_uno/mingw_x86-64/smallstruct.cxx
+0
-71
smallstruct.hxx
bridges/source/cpp_uno/mingw_x86-64/smallstruct.hxx
+0
-29
uno2cpp.cxx
bridges/source/cpp_uno/mingw_x86-64/uno2cpp.cxx
+164
-98
No files found.
bridges/Library_cpp_uno.mk
Dosyayı görüntüle @
211544a5
...
...
@@ -135,10 +135,9 @@ bridge_noopt_objects := except
bridge_asm_objects := call
else ifeq ($(OS)$(COM),WNTGCC)
bridges_SELECTED_BRIDGE := mingw_x86-64
#bridge_asm_objects := call
bridge_noopt_objects := uno2cpp
bridge_exception_objects := callvirtualmethod cpp2uno dllinit except smallstruct
#bridge_exception_objects := cpp2uno dllinit except smallstruct
bridge_asm_objects := call
bridge_noncallexception_noopt_objects := callvirtualmethod
bridge_exception_objects := abi cpp2uno except uno2cpp
endif
else ifeq ($(OS)$(CPU),SOLARISI)
...
...
bridges/source/cpp_uno/mingw_x86-64/abi.cxx
0 → 100644
Dosyayı görüntüle @
211544a5
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
// 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 "sal/config.h"
#include "abi.hxx"
using
namespace
x86_64
;
/* 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
/* 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
)
throw
()
{
/* 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
byteOffset
)
throw
()
{
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
(
(
byteOffset
%
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
(
(
byteOffset
%
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
offset
=
byteOffset
+
pStruct
->
pMemberOffsets
[
nMember
];
int
num
=
classify_argument
(
pTypeInStruct
,
subclasses
,
offset
);
if
(
num
==
0
)
{
TYPELIB_DANGER_RELEASE
(
pTypeDescr
);
return
0
;
}
for
(
int
i
=
0
;
i
<
num
;
i
++
)
{
int
pos
=
offset
/
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"
,
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
)
throw
()
{
enum
x86_64_reg_class
classes
[
MAX_CLASSES
];
int
n
;
n
=
classify_argument
(
pTypeRef
,
classes
,
0
);
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"
,
classes
[
n
]
);
#endif
OSL_ASSERT
(
0
);
}
return
true
;
}
bool
x86_64
::
return_in_hidden_param
(
typelib_TypeDescriptionReference
*
pTypeRef
)
throw
()
{
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
)
throw
()
{
enum
x86_64_reg_class
classes
[
MAX_CLASSES
];
int
n
;
n
=
classify_argument
(
pTypeRef
,
classes
,
0
);
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
;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bridges/source/cpp_uno/mingw_x86-64/
dllinit.c
xx
→
bridges/source/cpp_uno/mingw_x86-64/
abi.h
xx
Dosyayı görüntüle @
211544a5
...
...
@@ -17,29 +17,45 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <windows.h>
#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)
void
dso_init
(
void
);
void
dso_exit
(
void
);
#include <typelib/typedescription.hxx>
extern
"C"
BOOL
WINAPI
DllMain
(
HMODULE
hModule
,
DWORD
dwReason
,
LPVOID
lpvReserved
)
namespace
x86_64
{
switch
(
dwReason
)
{
case
DLL_PROCESS_ATTACH
:
DisableThreadLibraryCalls
(
hModule
);
dso_init
();
break
;
/* 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
)
throw
();
/** 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
)
throw
();
void
fill_struct
(
typelib_TypeDescriptionReference
*
pTypeRef
,
const
sal_uInt64
*
pGPR
,
const
double
*
pSSE
,
void
*
pStruct
)
throw
();
case
DLL_PROCESS_DETACH
:
if
(
!
lpvReserved
)
dso_exit
();
break
;
}
}
// namespace x86_64
return
TRUE
;
}
#endif // _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bridges/source/cpp_uno/mingw_x86-64/call.s
Dosyayı görüntüle @
211544a5
...
...
@@ -16,264 +16,100 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
.text
.text
.align 2
.globl privateSnippetExecutor
privateSnippetExecutor:
.LFB3:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
subq $160, %rsp
.LCFI2:
movq %r10, -152(%rbp) # Save (nVtableOffset << 32) + nFunctionIndex
.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
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)
.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
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
.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
cmp $10, %rax # typelib_TypeClass_FLOAT
je .Lfloat
cmp $11, %rax # typelib_TypeClass_DOUBLE
je .Lfloat
.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
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)
.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"
.Lfinish:
leave
ret
.LFE3:
.long .-privateSnippetExecutor
# see http://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
# for details of the .eh_frame, the "Common Information Entry" and "Frame Description Entry" formats
# and http://mentorembedded.github.io/cxx-abi/exceptions.pdf for more info
.section .eh_frame,"a"
.Lframe1:
.long .LECIE1-.LSCIE1 # length
.long .LECIE1-.LSCIE1
.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
.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:
.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:
.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:
bridges/source/cpp_uno/mingw_x86-64/callvirtualmethod.cxx
Dosyayı görüntüle @
211544a5
...
...
@@ -19,120 +19,147 @@
#include "sal/config.h"
#include <cstring>
#include "cppu/macros.hxx"
#include "osl/diagnose.h"
#include "sal/types.h"
#include "typelib/typeclass.h"
#include "typelib/typedescription.h"
#include "abi.hxx"
#include "callvirtualmethod.hxx"
#include "share.hxx"
#include "smallstruct.hxx"
// For some reason, callVirtualMethod needs to be in a source file of its own,
// so that stack unwinding upon a thrown exception from within the asm block
// call works, at least with GCC 4.7.0 and --enable-dbgutil.
// The call instruction within the asm section of callVirtualMethod may throw
// exceptions. So that the compiler handles this correctly, it is important
// that (a) callVirtualMethod might call dummy_can_throw_anything (although this
// never happens at runtime), which in turn can throw exceptions, and (b)
// callVirtualMethod is not inlined at its call site (so that any exceptions are
// caught which are thrown from the instruction calling callVirtualMethod). [It
// is unclear how much of this comment is still relevent -- see the above
// comment.]
// The call instruction within the asm block of callVirtualMethod may throw
// exceptions. At least GCC 4.7.0 with -O0 would create (unnecessary)
// .gcc_exception_table call-site table entries around all other calls in this
// function that can throw, leading to std::terminate if the asm call throws an
// exception and the unwinding C++ personality routine finds the unexpected hole
// in the .gcc_exception_table. Therefore, make sure this function explicitly
// only calls nothrow-functions (so GCC 4.7.0 with -O0 happens to not create a
// .gcc_exception_table section at all for this function). For some reason,
// this also needs to be in a source file of its own.
//
// Also, this file should be compiled with -fnon-call-exceptions, and ideally
// there would be a way to tell the compiler that the asm block contains calls
// to functions that can potentially throw; see the mail thread starting at
// <http://gcc.gnu.org/ml/gcc/2012-03/msg00454.html> "C++: Letting compiler know
// asm block can call function that can throw?"
void
CPPU_CURRENT_NAMESPACE
::
callVirtualMethod
(
void
*
pAdjustedThisPtr
,
sal_Int32
nVtableIndex
,
void
*
pRegisterReturn
,
typelib_TypeDescription
const
*
returnType
,
sal_Int32
*
pStackLongs
,
sal_Int32
nStackLongs
)
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
)
{
// parameter list is mixed list of * and values
// reference parameters are pointers
// 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
;
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 !"
);
// Get pointer to method
sal_uInt64
pMethod
=
*
((
sal_uInt64
*
)
pThis
);
pMethod
+=
8
*
nVtableIndex
;
pMethod
=
*
((
sal_uInt64
*
)
pMethod
);
// never called
if
(
!
pAdjustedThisPtr
)
CPPU_CURRENT_NAMESPACE
::
dummy_can_throw_anything
(
"xxx"
);
// address something
// Load parameters to stack, if necessary
sal_uInt64
*
pCallStack
=
NULL
;
if
(
nStack
)
{
// 16-bytes aligned
sal_uInt32
nStackBytes
=
(
(
nStack
+
1
)
>>
1
)
*
16
;
pCallStack
=
(
sal_uInt64
*
)
__builtin_alloca
(
nStackBytes
);
std
::
memcpy
(
pCallStack
,
pStack
,
nStackBytes
);
}
// Return values
sal_uInt64
rax
;
sal_uInt64
rdx
;
double
xmm0
;
double
xmm1
;
volatile
long
edx
=
0
,
eax
=
0
;
// for register returns
void
*
stackptr
;
asm
volatile
(
"mov %%esp, %6
\n\t
"
// copy values
"mov %0, %%eax
\n\t
"
"mov %%eax, %%edx
\n\t
"
"dec %%edx
\n\t
"
"shl $2, %%edx
\n\t
"
"add %1, %%edx
\n
"
"Lcopy:
\n\t
"
"pushl 0(%%edx)
\n\t
"
"sub $4, %%edx
\n\t
"
"dec %%eax
\n\t
"
"jne Lcopy
\n\t
"
// do the actual call
"mov %2, %%edx
\n\t
"
"mov 0(%%edx), %%edx
\n\t
"
"mov %3, %%eax
\n\t
"
"shl $2, %%eax
\n\t
"
"add %%eax, %%edx
\n\t
"
"mov 0(%%edx), %%edx
\n\t
"
"call *%%edx
\n\t
"
// save return registers
"mov %%eax, %4
\n\t
"
"mov %%edx, %5
\n\t
"
// cleanup stack
"mov %6, %%esp
\n\t
"
:
:
"m"
(
nStackLongs
),
"m"
(
pStackLongs
),
"m"
(
pAdjustedThisPtr
),
"m"
(
nVtableIndex
),
"m"
(
eax
),
"m"
(
edx
),
"m"
(
stackptr
)
:
"eax"
,
"ecx"
,
"edx"
);
switch
(
returnType
->
eTypeClass
)
// Fill the xmm registers
"movq %6, %%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 %5, %%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 %4, %%r11
\n\t
"
"movq %7, %%rax
\n\t
"
"call *%%r11
\n\t
"
// Fill the return values
"movq %%rax, %0
\n\t
"
"movq %%rdx, %1
\n\t
"
"movsd %%xmm0, %2
\n\t
"
"movsd %%xmm1, %3
\n\t
"
:
"=m"
(
rax
),
"=m"
(
rdx
),
"=m"
(
xmm0
),
"=m"
(
xmm1
)
:
"m"
(
pMethod
),
"m"
(
pGPR
),
"m"
(
pFPR
),
"m"
(
nFPR
),
"m"
(
pCallStack
)
// dummy input to prevent the compiler from optimizing the alloca out
:
"rax"
,
"rdi"
,
"rsi"
,
"rdx"
,
"rcx"
,
"r8"
,
"r9"
,
"r10"
,
"r11"
,
"xmm0"
,
"xmm1"
,
"xmm2"
,
"xmm3"
,
"xmm4"
,
"xmm5"
,
"xmm6"
,
"xmm7"
,
"xmm8"
,
"xmm9"
,
"xmm10"
,
"xmm11"
,
"xmm12"
,
"xmm13"
,
"xmm14"
,
"xmm15"
);
switch
(
pReturnTypeRef
->
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
:
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
;
}
}
}
...
...
bridges/source/cpp_uno/mingw_x86-64/callvirtualmethod.hxx
Dosyayı görüntüle @
211544a5
...
...
@@ -17,8 +17,8 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_
MINGW_INTEL
_CALLVIRTUALMETHOD_HXX
#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_
MINGW_INTEL
_CALLVIRTUALMETHOD_HXX
#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_
GCC3_LINUX_X86_64
_CALLVIRTUALMETHOD_HXX
#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_
GCC3_LINUX_X86_64
_CALLVIRTUALMETHOD_HXX
#include "sal/config.h"
...
...
@@ -29,9 +29,10 @@
namespace
CPPU_CURRENT_NAMESPACE
{
void
callVirtualMethod
(
void
*
pAdjustedThisPtr
,
sal_Int32
nVtableIndex
,
void
*
pRegisterReturn
,
typelib_TypeDescription
const
*
returnType
,
sal_Int32
*
pStackLongs
,
sal_Int32
nStackLongs
);
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
);
}
...
...
bridges/source/cpp_uno/mingw_x86-64/cpp2uno.cxx
Dosyayı görüntüle @
211544a5
...
...
@@ -18,36 +18,54 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <boost/unordered_map.hpp>
#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 <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 "abi.hxx"
#include "share.hxx"
#include "smallstruct.hxx"
using
namespace
::
osl
;
using
namespace
::
rtl
;
using
namespace
::
com
::
sun
::
star
::
uno
;
namespace
{
//==================================================================================================
void
cpp2uno_call
(
// Perform the UNO call
//
// We must convert the parameters 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
**
pCallStack
,
void
*
pReturnValue
)
void
**
gpreg
,
void
**
fpreg
,
void
**
ovrflw
,
sal_uInt64
*
pRegisterReturn
/* space for register return */
)
{
// pCallStack: ret, [return ptr], this, params
char
*
pCppStack
=
(
char
*
)(
pCallStack
+
1
);
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
;
...
...
@@ -57,33 +75,26 @@ void cpp2uno_call(
void
*
pUnoReturn
=
0
;
void
*
pCppReturn
=
0
;
// complex return ptr: if != 0 && != pUnoReturn, reconversion need
if
(
pReturnTypeDescr
)
if
(
pReturnTypeDescr
)
{
if
(
bridges
::
cpp_uno
::
shared
::
isSimpleType
(
pReturnTypeDescr
))
{
pUnoReturn
=
pReturnValue
;
// direct way for simple types
}
else
// complex return via ptr (pCppReturn)
if
(
x86_64
::
return_in_hidden_param
(
pReturnTypeRef
)
)
{
if
(
!
bridges
::
cpp_uno
::
shared
::
isSmallStruct
(
pReturnTypeDescr
))
{
pCppReturn
=
*
(
void
**
)
pCppStack
;
pCppStack
+=
sizeof
(
void
*
);
}
else
{
pCppReturn
=
pReturnValue
;
}
pCppReturn
=
*
gpreg
++
;
nr_gpr
++
;
pUnoReturn
=
(
bridges
::
cpp_uno
::
shared
::
relatesToInterfaceType
(
pReturnTypeDescr
)
?
alloca
(
pReturnTypeDescr
->
nSize
)
:
pCppReturn
);
// direct way
pUnoReturn
=
(
bridges
::
cpp_uno
::
shared
::
relatesToInterfaceType
(
pReturnTypeDescr
)
?
alloca
(
pReturnTypeDescr
->
nSize
)
:
pCppReturn
);
// direct way
}
else
pUnoReturn
=
pRegisterReturn
;
// direct way for simple types
}
// pop this
pCppStack
+=
sizeof
(
void
*
);
gpreg
++
;
nr_gpr
++
;
// stack space
OSL_ENSURE
(
sizeof
(
void
*
)
==
sizeof
(
sal_Int32
),
"### unexpected size!"
);
// parameters
void
**
pUnoArgs
=
(
void
**
)
alloca
(
4
*
sizeof
(
void
*
)
*
nParams
);
void
**
pCppArgs
=
pUnoArgs
+
nParams
;
...
...
@@ -92,36 +103,57 @@ void cpp2uno_call(
// type descriptions for reconversions
typelib_TypeDescription
**
ppTempParamTypeDescr
=
(
typelib_TypeDescription
**
)(
pUnoArgs
+
(
3
*
nParams
));
sal_Int32
nTempIndizes
=
0
;
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
int
nUsedGPR
=
0
;
int
nUsedSSE
=
0
;
#if OSL_DEBUG_LEVEL > 0
bool
bFitsRegisters
=
#endif
x86_64
::
examine_argument
(
rParam
.
pTypeRef
,
false
,
nUsedGPR
,
nUsedSSE
);
if
(
!
rParam
.
bOut
&&
bridges
::
cpp_uno
::
shared
::
isSimpleType
(
rParam
.
pTypeRef
)
)
// value
{
pCppArgs
[
nPos
]
=
pCppStack
;
pUnoArgs
[
nPos
]
=
pCppStack
;
switch
(
pParamTypeDescr
->
eTypeClass
)
// Simple types must fit exactly one register on x86_64
OSL_ASSERT
(
bFitsRegisters
&&
(
(
nUsedSSE
==
1
&&
nUsedGPR
==
0
)
||
(
nUsedSSE
==
0
&&
nUsedGPR
==
1
)
)
);
if
(
nUsedSSE
==
1
)
{
case
typelib_TypeClass_HYPER
:
case
typelib_TypeClass_UNSIGNED_HYPER
:
case
typelib_TypeClass_DOUBLE
:
pCppStack
+=
sizeof
(
sal_Int32
);
// extra long
break
;
default
:
break
;
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
//
ptr to complex value
| ref
else
//
struct <= 16 bytes || ptr to complex value |
| ref
{
pCppArgs
[
nPos
]
=
*
(
void
**
)
pCppStack
;
typelib_TypeDescription
*
pParamTypeDescr
=
0
;
TYPELIB_DANGER_GET
(
&
pParamTypeDescr
,
rParam
.
pTypeRef
);
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
{
...
...
@@ -131,12 +163,10 @@ void cpp2uno_call(
// will be released at reconversion
ppTempParamTypeDescr
[
nTempIndizes
++
]
=
pParamTypeDescr
;
}
// is in/inout
else
if
(
bridges
::
cpp_uno
::
shared
::
relatesToInterfaceType
(
pParamTypeDescr
))
else
if
(
bridges
::
cpp_uno
::
shared
::
relatesToInterfaceType
(
pParamTypeDescr
)
)
// is in/inout
{
uno_copyAndConvertData
(
pUnoArgs
[
nPos
]
=
alloca
(
pParamTypeDescr
->
nSize
),
*
(
void
**
)
pCppStack
,
pParamTypeDescr
,
pCppStack
,
pParamTypeDescr
,
pThis
->
getBridge
()
->
getCpp2Uno
()
);
pTempIndizes
[
nTempIndizes
]
=
nPos
;
// has to be reconverted
// will be released at reconversion
...
...
@@ -144,12 +174,11 @@ void cpp2uno_call(
}
else
// direct way
{
pUnoArgs
[
nPos
]
=
*
(
void
**
)
pCppStack
;
pUnoArgs
[
nPos
]
=
pCppStack
;
// no longer needed
TYPELIB_DANGER_RELEASE
(
pParamTypeDescr
);
}
}
pCppStack
+=
sizeof
(
sal_Int32
);
// standard parameter length
}
// ExceptionHolder
...
...
@@ -157,11 +186,10 @@ void cpp2uno_call(
uno_Any
*
pUnoExc
=
&
aUnoExc
;
// invoke uno dispatch call
(
*
pThis
->
getUnoI
()
->
pDispatcher
)(
pThis
->
getUnoI
(),
pMemberTypeDescr
,
pUnoReturn
,
pUnoArgs
,
&
pUnoExc
);
(
*
pThis
->
getUnoI
()
->
pDispatcher
)(
pThis
->
getUnoI
(),
pMemberTypeDescr
,
pUnoReturn
,
pUnoArgs
,
&
pUnoExc
);
// in case an exception occurred...
if
(
pUnoExc
)
if
(
pUnoExc
)
{
// destruct temporary in/inout params
for
(
;
nTempIndizes
--
;
)
...
...
@@ -175,9 +203,9 @@ void cpp2uno_call(
if
(
pReturnTypeDescr
)
TYPELIB_DANGER_RELEASE
(
pReturnTypeDescr
);
CPPU_CURRENT_NAMESPACE
::
raiseException
(
&
aUnoExc
,
pThis
->
getBridge
()
->
getUno2Cpp
()
);
// has to destruct the any
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 occurred...
{
...
...
@@ -187,7 +215,7 @@ void cpp2uno_call(
sal_Int32
nIndex
=
pTempIndizes
[
nTempIndizes
];
typelib_TypeDescription
*
pParamTypeDescr
=
ppTempParamTypeDescr
[
nTempIndizes
];
if
(
pParams
[
nIndex
].
bOut
)
// inout/out
if
(
pParams
[
nIndex
].
bOut
)
// inout/out
{
// convert and assign
uno_destructData
(
pCppArgs
[
nIndex
],
pParamTypeDescr
,
cpp_release
);
...
...
@@ -200,237 +228,209 @@ void cpp2uno_call(
TYPELIB_DANGER_RELEASE
(
pParamTypeDescr
);
}
// return
if
(
pCppReturn
)
// has complex return
if
(
pCppReturn
)
// has complex return
{
if
(
pUnoReturn
!=
pCppReturn
)
// needs reconversion
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
;
// complex return ptr is set to return reg
*
(
void
**
)
pRegisterReturn
=
pCppReturn
;
}
if
(
pReturnTypeDescr
)
if
(
pReturnTypeDescr
)
{
typelib_TypeClass
eRet
=
(
typelib_TypeClass
)
pReturnTypeDescr
->
eTypeClass
;
TYPELIB_DANGER_RELEASE
(
pReturnTypeDescr
);
return
eRet
;
}
else
return
typelib_TypeClass_VOID
;
}
}
//==================================================================================================
extern
"C"
void
cpp_vtable_call
(
int
nFunctionIndex
,
int
nVtableOffset
,
void
**
pCallStack
,
void
*
pReturnValue
)
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 */
)
{
OSL_ENSURE
(
sizeof
(
sal_Int32
)
==
sizeof
(
void
*
),
"### unexpected!"
);
//
pCallStack: ret adr, [ret *], this, params
// gpreg: [ret *], this, [other gpr params]
// fpreg: [fpr params]
//
ovrflw: [gpr or fpr params (properly aligned)]
void
*
pThis
;
if
(
nFunctionIndex
&
0x80000000
)
if
(
nFunctionIndex
&
0x80000000
)
{
nFunctionIndex
&=
0x7fffffff
;
pThis
=
pCallStack
[
2
];
pThis
=
gpreg
[
1
];
}
else
{
pThis
=
pCallStack
[
1
];
pThis
=
gpreg
[
0
];
}
pThis
=
static_cast
<
char
*
>
(
pThis
)
-
nVtableOffset
;
bridges
::
cpp_uno
::
shared
::
CppInterfaceProxy
*
pCppI
=
bridges
::
cpp_uno
::
shared
::
CppInterfaceProxy
::
castInterfaceToProxy
(
pThis
);
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
)
OSL_ENSURE
(
nFunctionIndex
<
pTypeDescr
->
nMapFunctionIndexToMemberIndex
,
"### illegal vtable index!
\n
"
);
if
(
nFunctionIndex
>=
pTypeDescr
->
nMapFunctionIndexToMemberIndex
)
{
throw
RuntimeException
(
OUString
(
"illegal vtable index!"
),
(
XInterface
*
)
pThis
);
throw
RuntimeException
(
OUString
(
"illegal vtable index!"
),
reinterpret_cast
<
XInterface
*>
(
pCppI
)
);
}
// determine called method
sal_Int32
nMemberPos
=
pTypeDescr
->
pMapFunctionIndexToMemberIndex
[
nFunctionIndex
];
OSL_ENSURE
(
nMemberPos
<
pTypeDescr
->
nAllMembers
,
"### illegal member index!"
);
OSL_ENSURE
(
nMemberPos
<
pTypeDescr
->
nAllMembers
,
"### illegal member index!
\n
"
);
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
:
typelib_TypeClass
eRet
;
switch
(
aMemberDescr
.
get
()
->
eTypeClass
)
{
// is METHOD
switch
(
nFunctionIndex
)
case
typelib_TypeClass_INTERFACE_ATTRIBUTE
:
{
case
1
:
// acquire()
pCppI
->
acquireProxy
();
// non virtual call!
break
;
case
2
:
// release()
pCppI
->
releaseProxy
();
// non virtual call!
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
0
:
// queryInterface() opt
}
case
typelib_TypeClass_INTERFACE_METHOD
:
{
typelib_TypeDescription
*
pTD
=
0
;
TYPELIB_DANGER_GET
(
&
pTD
,
reinterpret_cast
<
Type
*
>
(
pCallStack
[
3
]
)
->
getTypeLibType
()
);
if
(
pTD
)
// is METHOD
switch
(
nFunctionIndex
)
{
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
];
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
);
}
TYPELIB_DANGER_RELEASE
(
pTD
);
}
}
// else perform queryInterface()
break
;
}
default
:
cpp2uno_call
(
pCppI
,
aMemberDescr
.
get
(),
((
typelib_InterfaceMethodTypeDescription
*
)
aMemberDescr
.
get
())
->
pReturnTypeRef
,
((
typelib_InterfaceMethodTypeDescription
*
)
aMemberDescr
.
get
())
->
nParams
,
((
typelib_InterfaceMethodTypeDescription
*
)
aMemberDescr
.
get
())
->
pParams
,
pCallStack
,
pReturnValue
);
{
throw
RuntimeException
(
OUString
(
"no member description found!"
),
reinterpret_cast
<
XInterface
*>
(
pCppI
)
);
}
break
;
}
default
:
{
throw
RuntimeException
(
OUString
(
"no member description found!"
),
(
XInterface
*
)
pThis
);
}
}
return
eRet
;
}
//==================================================================================================
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
)
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
(())
{
typelib_TypeDescription
*
returnTypeDescr
=
0
;
if
(
returnType
)
TYPELIB_DANGER_GET
(
&
returnTypeDescr
,
returnType
);
typelib_TypeClass
returnTypeClass
=
returnType
?
returnType
->
eTypeClass
:
typelib_TypeClass_VOID
;
if
(
!
bridges
::
cpp_uno
::
shared
::
isSimpleType
(
returnTypeClass
)
&&
!
bridges
::
cpp_uno
::
shared
::
isSmallStruct
(
returnTypeDescr
))
{
functionIndex
|=
0x80000000
;
}
PrivateSnippetExecutor
exec
=
privateSnippetExecutorGeneral
;
switch
(
returnTypeClass
)
{
case
typelib_TypeClass_VOID
:
exec
=
privateSnippetExecutorVoid
;
break
;
case
typelib_TypeClass_HYPER
:
case
typelib_TypeClass_UNSIGNED_HYPER
:
exec
=
privateSnippetExecutorHyper
;
break
;
case
typelib_TypeClass_FLOAT
:
exec
=
privateSnippetExecutorFloat
;
break
;
case
typelib_TypeClass_DOUBLE
:
exec
=
privateSnippetExecutorDouble
;
break
;
case
typelib_TypeClass_STRUCT
:
if
(
bridges
::
cpp_uno
::
shared
::
isSmallStruct
(
returnTypeDescr
))
{
if
(
returnType
->
pType
->
nSize
<=
4
)
{
exec
=
privateSnippetExecutorGeneral
;
}
else
if
(
returnType
->
pType
->
nSize
<=
8
)
{
exec
=
privateSnippetExecutorHyper
;
}
}
else
{
exec
=
privateSnippetExecutorClass
;
}
break
;
case
typelib_TypeClass_STRING
:
case
typelib_TypeClass_TYPE
:
case
typelib_TypeClass_ANY
:
case
typelib_TypeClass_SEQUENCE
:
case
typelib_TypeClass_INTERFACE
:
exec
=
privateSnippetExecutorClass
;
break
;
default:
exec
=
privateSnippetExecutorGeneral
;
break
;
}
if
(
returnType
)
TYPELIB_DANGER_RELEASE
(
returnTypeDescr
);
unsigned
char
*
p
=
code
;
OSL_ASSERT
(
sizeof
(
sal_Int32
)
==
4
);
// mov function_index, %eax:
*
p
++
=
0xB8
;
*
reinterpret_cast
<
sal_Int32
*
>
(
p
)
=
functionIndex
;
p
+=
sizeof
(
sal_Int32
);
// mov vtable_offset, %edx:
*
p
++
=
0xBA
;
*
reinterpret_cast
<
sal_Int32
*
>
(
p
)
=
vtableOffset
;
p
+=
sizeof
(
sal_Int32
);
// jmp privateSnippetExecutor:
*
p
++
=
0xE9
;
*
reinterpret_cast
<
sal_Int32
*
>
(
p
)
=
((
unsigned
char
*
)
exec
)
-
p
-
sizeof
(
sal_Int32
);
p
+=
sizeof
(
sal_Int32
);
OSL_ASSERT
(
p
-
code
<=
codeSnippetSize
);
return
code
+
codeSnippetSize
;
}
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
;
#if OSL_DEBUG_LEVEL > 1
fprintf
(
stderr
,
"==> codeSnippet, functionIndex=%d%s, vtableOffset=%d
\n
"
,
nFunctionIndex
,
(
bHasHiddenParam
?
"|0x80000000"
:
""
),
nVtableOffset
);
#endif
return
code
+
codeSnippetSize
;
}
//==================================================================================================
struct
bridges
::
cpp_uno
::
shared
::
VtableFactory
::
Slot
{
void
*
fn
;
};
bridges
::
cpp_uno
::
shared
::
VtableFactory
::
Slot
*
...
...
@@ -439,12 +439,14 @@ 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
)
...
...
@@ -455,56 +457,59 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
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
)
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
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:
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
,
functionOffset
++
,
vtableOffset
,
reinterpret_cast
<
typelib_InterfaceAttributeTypeDescription
*
>
(
member
)
->
pAttributeTypeRef
);
// Setter:
if
(
!
reinterpret_cast
<
typelib_InterfaceAttributeTypeDescription
*
>
(
member
)
->
bReadOnly
)
code
=
codeSnippet
(
code
,
nFunctionOffset
++
,
nVtableOffset
,
x86_64
::
return_in_hidden_param
(
pAttrTD
->
pAttributeTypeRef
)
);
if
(
!
pAttrTD
->
bReadOnly
)
{
// set method
(
s
++
)
->
fn
=
code
;
code
=
codeSnippet
(
code
,
functionOffset
++
,
vtableOffset
,
NULL
);
code
=
codeSnippet
(
code
,
nFunctionOffset
++
,
nVtableOffset
,
false
);
}
break
;
}
else
if
(
typelib_TypeClass_INTERFACE_METHOD
==
pTD
->
eTypeClass
)
{
typelib_InterfaceMethodTypeDescription
*
pMethodTD
=
reinterpret_cast
<
typelib_InterfaceMethodTypeDescription
*>
(
pTD
);
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
;
code
=
codeSnippet
(
code
,
nFunctionOffset
++
,
nVtableOffset
,
x86_64
::
return_in_hidden_param
(
pMethodTD
->
pReturnTypeRef
)
);
}
TYPELIB_DANGER_RELEASE
(
member
);
else
OSL_ASSERT
(
false
);
TYPELIB_DANGER_RELEASE
(
pTD
);
}
return
code
;
}
//==================================================================================================
void
bridges
::
cpp_uno
::
shared
::
VtableFactory
::
flushCode
(
unsigned
char
const
*
,
unsigned
char
const
*
)
SAL_UNUSED_PARAMETER
unsigned
char
const
*
,
SAL_UNUSED_PARAMETER
unsigned
char
const
*
)
{}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bridges/source/cpp_uno/mingw_x86-64/smallstruct.cxx
deleted
100644 → 0
Dosyayı görüntüle @
b9dc42fc
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "bridges/cpp_uno/shared/types.hxx"
#include "typelib/typeclass.h"
#include "typelib/typedescription.h"
namespace
bridges
{
namespace
cpp_uno
{
namespace
shared
{
namespace
{
bool
isSimpleStruct
(
typelib_TypeDescription
const
*
type
)
{
switch
(
type
->
eTypeClass
)
{
case
typelib_TypeClass_STRUCT
:
{
typelib_CompoundTypeDescription
const
*
p
=
reinterpret_cast
<
typelib_CompoundTypeDescription
const
*
>
(
type
);
for
(
sal_Int32
i
=
0
;
i
<
p
->
nMembers
;
++
i
)
{
switch
(
p
->
ppTypeRefs
[
i
]
->
eTypeClass
)
{
case
typelib_TypeClass_STRUCT
:
{
typelib_TypeDescription
*
t
=
0
;
TYPELIB_DANGER_GET
(
&
t
,
p
->
ppTypeRefs
[
i
]);
bool
b
=
isSimpleStruct
(
t
);
TYPELIB_DANGER_RELEASE
(
t
);
if
(
!
b
)
{
return
false
;
}
}
break
;
default
:
if
(
!
isSimpleType
(
p
->
ppTypeRefs
[
i
]
->
eTypeClass
))
return
false
;
break
;
}
}
}
return
true
;
default
:
return
false
;
}
}
}
bool
isSmallStruct
(
typelib_TypeDescription
const
*
type
)
{
return
(
type
->
nSize
<=
8
&&
isSimpleStruct
(
type
));
}
}
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bridges/source/cpp_uno/mingw_x86-64/smallstruct.hxx
deleted
100644 → 0
Dosyayı görüntüle @
b9dc42fc
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "typelib/typeclass.h"
#include "typelib/typedescription.h"
namespace
bridges
{
namespace
cpp_uno
{
namespace
shared
{
bool
isSmallStruct
(
typelib_TypeDescription
const
*
type
);
}
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bridges/source/cpp_uno/mingw_x86-64/uno2cpp.cxx
Dosyayı görüntüle @
211544a5
...
...
@@ -17,26 +17,80 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <exception>
#include <typeinfo>
#include "rtl/alloc.h"
#include "rtl/ustrbuf.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/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 "callvirtualmethod.hxx"
#include "share.hxx"
#include "smallstruct.hxx"
using
namespace
::
rtl
;
using
namespace
::
com
::
sun
::
star
::
uno
;
namespace
{
// 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 );
//==================================================================================================
namespace
{
void
appendCString
(
OUStringBuffer
&
buffer
,
char
const
*
text
)
{
if
(
text
!=
0
)
{
buffer
.
append
(
OStringToOUString
(
OString
(
text
),
RTL_TEXTENCODING_ISO_8859_1
));
// use 8859-1 to avoid conversion failure
}
}
}
static
void
cpp_call
(
bridges
::
cpp_uno
::
shared
::
UnoInterfaceProxy
*
pThis
,
...
...
@@ -45,66 +99,53 @@ static void cpp_call(
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
;
// 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
;
// return
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
void
*
pCppReturn
=
0
;
// if != 0 && != pUnoReturn, needs reconversion
(see below)
if
(
pReturnTypeDescr
)
bool
bSimpleReturn
=
true
;
if
(
pReturnTypeDescr
)
{
if
(
bridges
::
cpp_uno
::
shared
::
isSimpleType
(
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
)
#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
*
);
}
pCppReturn
=
bridges
::
cpp_uno
::
shared
::
relatesToInterfaceType
(
pReturnTypeDescr
)
?
__builtin_alloca
(
pReturnTypeDescr
->
nSize
)
:
pUnoReturn
;
INSERT_INT64
(
&
pCppReturn
,
nGPR
,
pGPR
,
pStack
);
}
}
// 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)
// 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
);
//
t
ype descriptions for reconversions
//
T
ype descriptions for reconversions
typelib_TypeDescription
**
ppTempParamTypeDescr
=
(
typelib_TypeDescription
**
)(
pCppArgs
+
(
2
*
nParams
));
sal_Int32
nTempIndizes
=
0
;
sal_Int32
nTempIndizes
=
0
;
for
(
sal_Int32
nPos
=
0
;
nPos
<
nParams
;
++
nPos
)
{
...
...
@@ -112,22 +153,39 @@ static void cpp_call(
typelib_TypeDescription
*
pParamTypeDescr
=
0
;
TYPELIB_DANGER_GET
(
&
pParamTypeDescr
,
rParam
.
pTypeRef
);
if
(
!
rParam
.
bOut
&&
bridges
::
cpp_uno
::
shared
::
isSimpleType
(
pParamTypeDescr
))
if
(
!
rParam
.
bOut
&&
bridges
::
cpp_uno
::
shared
::
isSimpleType
(
pParamTypeDescr
))
{
uno_copyAndConvertData
(
pCppArgs
[
nPos
]
=
pCppStack
,
pUnoArgs
[
nPos
],
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
:
pCppStack
+=
sizeof
(
sal_Int32
);
// extra long
INSERT_FLOAT_DOUBLE
(
pCppArgs
[
nPos
],
nFPR
,
pFPR
,
pStack
);
break
;
default
:
break
;
}
// no longer needed
TYPELIB_DANGER_RELEASE
(
pParamTypeDescr
);
}
...
...
@@ -137,28 +195,18 @@ static void cpp_call(
{
// 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
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
))
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
()
);
pCppArgs
[
nPos
]
=
alloca
(
pParamTypeDescr
->
nSize
),
pUnoArgs
[
nPos
],
pParamTypeDescr
,
pThis
->
getBridge
()
->
getUno2Cpp
()
);
pTempIndizes
[
nTempIndizes
]
=
nPos
;
// has to be reconverted
// will be released at reconversion
...
...
@@ -166,22 +214,40 @@ static void cpp_call(
}
else
// direct way
{
*
(
void
**
)
pCppStack
=
pCppArgs
[
nPos
]
=
pUnoArgs
[
nPos
];
pCppArgs
[
nPos
]
=
pUnoArgs
[
nPos
];
// no longer needed
TYPELIB_DANGER_RELEASE
(
pParamTypeDescr
);
}
INSERT_INT64
(
&
(
pCppArgs
[
nPos
]),
nGPR
,
pGPR
,
pStack
);
}
pCppStack
+=
sizeof
(
sal_Int32
);
// standard parameter length
}
try
{
OSL_ENSURE
(
!
(
(
pCppStack
-
pCppStackStart
)
&
3
),
"UNALIGNED STACK !!! (Please DO panic)"
);
CPPU_CURRENT_NAMESPACE
::
callVirtualMethod
(
pAdjustedThisPtr
,
aVtableSlot
.
index
,
pCppReturn
,
pReturnTypeDescr
,
(
sal_Int32
*
)
pCppStackStart
,
(
pCppStack
-
pCppStackStart
)
/
sizeof
(
sal_Int32
)
);
// NO exception occurred...
try
{
CPPU_CURRENT_NAMESPACE
::
callVirtualMethod
(
pAdjustedThisPtr
,
aVtableSlot
.
index
,
pCppReturn
,
pReturnTypeRef
,
bSimpleReturn
,
pStackStart
,
(
pStack
-
pStackStart
),
pGPR
,
nGPR
,
pFPR
,
nFPR
);
}
catch
(
const
Exception
&
)
{
throw
;
}
catch
(
const
std
::
exception
&
e
)
{
OUStringBuffer
buf
;
buf
.
append
(
"C++ code threw "
);
appendCString
(
buf
,
typeid
(
e
).
name
());
buf
.
append
(
": "
);
appendCString
(
buf
,
e
.
what
());
throw
RuntimeException
(
buf
.
makeStringAndClear
(),
Reference
<
XInterface
>
());
}
catch
(...)
{
throw
RuntimeException
(
OUString
(
"C++ code threw unknown exception"
),
Reference
<
XInterface
>
());
}
*
ppUnoExc
=
0
;
// reconvert temporary params
...
...
@@ -206,9 +272,6 @@ static void cpp_call(
}
// 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
);
}
...
...
@@ -232,26 +295,14 @@ static void cpp_call(
// 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
{
...
...
@@ -262,16 +313,25 @@ void unoInterfaceProxyDispatch(
// 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
<
getVtableSlot
(
reinterpret_cast
<
typelib_InterfaceAttributeTypeDescription
const
*
>
(
pMemberDescr
)));
if
(
pReturn
)
{
// dependent dispatch
...
...
@@ -298,7 +358,7 @@ void unoInterfaceProxyDispatch(
// dependent dispatch
aVtableSlot
.
index
+=
1
;
// get, then set method
cpp_call
(
pThis
,
aVtableSlot
,
pThis
,
aVtableSlot
,
// get, then set method
pReturnTypeRef
,
1
,
&
aParam
,
pReturn
,
pArgs
,
ppException
);
...
...
@@ -310,11 +370,17 @@ void unoInterfaceProxyDispatch(
}
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
<
getVtableSlot
(
reinterpret_cast
<
typelib_InterfaceMethodTypeDescription
const
*
>
(
pMemberDescr
)));
switch
(
aVtableSlot
.
index
)
{
// standard calls
...
...
@@ -333,8 +399,8 @@ void unoInterfaceProxyDispatch(
if
(
pTD
)
{
uno_Interface
*
pInterface
=
0
;
(
*
pThis
->
pBridge
->
getUnoEnv
()
->
getRegisteredInterface
)(
pThis
->
pBridge
->
getUnoEnv
(),
(
*
pThis
->
getBridge
()
->
getUnoEnv
()
->
getRegisteredInterface
)(
pThis
->
getBridge
()
->
getUnoEnv
(),
(
void
**
)
&
pInterface
,
pThis
->
oid
.
pData
,
(
typelib_InterfaceTypeDescription
*
)
pTD
);
if
(
pInterface
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment