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
...
@@ -135,10 +135,9 @@ bridge_noopt_objects := except
bridge_asm_objects := call
bridge_asm_objects := call
else ifeq ($(OS)$(COM),WNTGCC)
else ifeq ($(OS)$(COM),WNTGCC)
bridges_SELECTED_BRIDGE := mingw_x86-64
bridges_SELECTED_BRIDGE := mingw_x86-64
#bridge_asm_objects := call
bridge_asm_objects := call
bridge_noopt_objects := uno2cpp
bridge_noncallexception_noopt_objects := callvirtualmethod
bridge_exception_objects := callvirtualmethod cpp2uno dllinit except smallstruct
bridge_exception_objects := abi cpp2uno except uno2cpp
#bridge_exception_objects := cpp2uno dllinit except smallstruct
endif
endif
else ifeq ($(OS)$(CPU),SOLARISI)
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 @@
...
@@ -17,29 +17,45 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
* 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
);
#include <typelib/typedescription.hxx>
void
dso_exit
(
void
);
namespace
x86_64
extern
"C"
BOOL
WINAPI
DllMain
(
HMODULE
hModule
,
DWORD
dwReason
,
LPVOID
lpvReserved
)
{
{
switch
(
dwReason
)
{
case
DLL_PROCESS_ATTACH
:
DisableThreadLibraryCalls
(
hModule
);
dso_init
();
/* 6 general purpose registers are used for parameter passing */
break
;
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
:
}
// namespace x86_64
if
(
!
lpvReserved
)
dso_exit
();
break
;
}
return
TRUE
;
#endif // _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* 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 @@
...
@@ -16,264 +16,100 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
* 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
movq %rdi, -112(%rbp) # Save GP registers
_privateSnippetExecutorGeneral:
movq %rsi, -104(%rbp)
.LFBg:
movq %rdx, -96(%rbp)
movl %esp,%ecx
movq %rcx, -88(%rbp)
pushl %ebp # proper stack frame needed for exception handling
movq %r8 , -80(%rbp)
.LCFIg0:
movq %r9 , -72(%rbp)
movl %esp,%ebp
.LCFIg1:
movsd %xmm0, -64(%rbp) # Save FP registers
subl $0x4,%esp # 32bit returnValue
movsd %xmm1, -56(%rbp)
pushl %esp # 32bit &returnValue
movsd %xmm2, -48(%rbp)
pushl %ecx # 32bit pCallStack
movsd %xmm3, -40(%rbp)
pushl %edx # 32bit nVtableOffset
movsd %xmm4, -32(%rbp)
pushl %eax # 32bit nFunctionIndex
movsd %xmm5, -24(%rbp)
call _cpp_vtable_call
movsd %xmm6, -16(%rbp)
movl 16(%esp),%eax # 32bit returnValue
movsd %xmm7, -8(%rbp)
leave
ret
.LFEg:
.long .-_privateSnippetExecutorGeneral
.globl _privateSnippetExecutorVoid
leaq -144(%rbp), %r9 # 6th param: sal_uInt64 * pRegisterReturn
_privateSnippetExecutorVoid:
leaq 16(%rbp), %r8 # 5rd param: void ** ovrflw
.LFBv:
leaq -64(%rbp), %rcx # 4th param: void ** fpreg
movl %esp,%ecx
leaq -112(%rbp), %rdx # 3rd param: void ** gpreg
pushl %ebp # proper stack frame needed for exception handling
movl -148(%rbp), %esi # 2nd param: sal_int32 nVtableOffset
.LCFIv0:
movl -152(%rbp), %edi # 1st param: sal_int32 nFunctionIndex
movl %esp,%ebp
.LCFIv1:
call cpp_vtable_call
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
cmp $10, %rax # typelib_TypeClass_FLOAT
_privateSnippetExecutorHyper:
je .Lfloat
.LFBh:
cmp $11, %rax # typelib_TypeClass_DOUBLE
movl %esp,%ecx
je .Lfloat
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
movq -144(%rbp), %rax # Return value (int case)
_privateSnippetExecutorFloat:
movq -136(%rbp), %rdx # Return value (int case)
.LFBf:
movq -144(%rbp), %xmm0 # Return value (int case)
movl %esp,%ecx
movq -136(%rbp), %xmm1 # Return value (int case)
pushl %ebp # proper stack frame needed for exception handling
jmp .Lfinish
.LCFIf0:
.Lfloat:
movl %esp,%ebp
movlpd -144(%rbp), %xmm0 # Return value (float/double case)
.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
.Lfinish:
_privateSnippetExecutorDouble:
leave
.LFBd:
ret
movl %esp,%ecx
.LFE3:
pushl %ebp # proper stack frame needed for exception handling
.long .-privateSnippetExecutor
.LCFId0:
# see http://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
movl %esp,%ebp
# for details of the .eh_frame, the "Common Information Entry" and "Frame Description Entry" formats
.LCFId1:
# and http://mentorembedded.github.io/cxx-abi/exceptions.pdf for more info
subl $0x8,%esp # 64bit returnValue
.section .eh_frame,"a"
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:
.Lframe1:
.long .LECIE1-.LSCIE1 # length
.long .LECIE1-.LSCIE1
.LSCIE1:
.LSCIE1:
.long 0 # CIE_ID
.long 0x0
.byte 1 # version
.byte 0x1
.string "zR" # augmentation
.string "zR"
.uleb128 1 # code_alignment_factor
.uleb128 0x1
.sleb128 -4 # data_alignment_factor
.sleb128 -8
.byte 8 # return_address_register
.byte 0x10
.uleb128 1 # augmentation size 1:
.uleb128 0x1
.byte 0x1B # FDE Encoding (pcrel sdata4)
.byte 0x1b
# initial_instructions:
.byte 0xc
.byte 0x0C # DW_CFA_def_cfa %esp, 4
.uleb128 0x7
.uleb128 4
.uleb128 0x8
.uleb128 4
.byte 0x90
.byte 0x88 # DW_CFA_offset ret, 1
.uleb128 0x1
.uleb128 1
.align 8
.align 4
.LECIE1:
.LECIE1:
.LSFDEg:
.LSFDE1:
.long .LEFDEg-.LASFDEg # length
.long .LEFDE1-.LASFDE1
.LASFDEg:
.LASFDE1:
.long .LASFDEg-.Lframe1 # CIE_pointer
.long .LASFDE1-.Lframe1
.long .LFBg-. # initial_location
.long .LFB3-.
.long .LFEg-.LFBg # address_range
.long .LFE3-.LFB3
.uleb128 0 # augmentation size 0
.uleb128 0x0
# instructions:
.byte 0x4
.byte 0x04 # DW_CFA_advance_loc4
.long .LCFI0-.LFB3
.long .LCFIg0-.LFBg
.byte 0xe
.byte 0x0E # DW_CFA_def_cfa_offset 8
.uleb128 0x10
.uleb128 8
.byte 0x86
.byte 0x85 # DW_CFA_offset %ebp, 2
.uleb128 0x2
.uleb128 2
.byte 0x4
.byte 0x04 # DW_CFA_advance_loc4
.long .LCFI1-.LCFI0
.long .LCFIg1-.LCFIg0
.byte 0xd
.byte 0x0D # DW_CFA_def_cfa_register %ebp
.uleb128 0x6
.uleb128 5
.align 8
.align 4
.LEFDE1:
.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:
bridges/source/cpp_uno/mingw_x86-64/callvirtualmethod.cxx
Dosyayı görüntüle @
211544a5
...
@@ -19,120 +19,147 @@
...
@@ -19,120 +19,147 @@
#include "sal/config.h"
#include "sal/config.h"
#include <cstring>
#include "cppu/macros.hxx"
#include "cppu/macros.hxx"
#include "osl/diagnose.h"
#include "sal/types.h"
#include "sal/types.h"
#include "typelib/typeclass.h"
#include "typelib/typeclass.h"
#include "typelib/typedescription.h"
#include "typelib/typedescription.h"
#include "abi.hxx"
#include "callvirtualmethod.hxx"
#include "callvirtualmethod.hxx"
#include "share.hxx"
#include "smallstruct.hxx"
// The call instruction within the asm block of callVirtualMethod may throw
// exceptions. At least GCC 4.7.0 with -O0 would create (unnecessary)
// For some reason, callVirtualMethod needs to be in a source file of its own,
// .gcc_exception_table call-site table entries around all other calls in this
// so that stack unwinding upon a thrown exception from within the asm block
// function that can throw, leading to std::terminate if the asm call throws an
// call works, at least with GCC 4.7.0 and --enable-dbgutil.
// exception and the unwinding C++ personality routine finds the unexpected hole
// in the .gcc_exception_table. Therefore, make sure this function explicitly
// The call instruction within the asm section of callVirtualMethod may throw
// only calls nothrow-functions (so GCC 4.7.0 with -O0 happens to not create a
// exceptions. So that the compiler handles this correctly, it is important
// .gcc_exception_table section at all for this function). For some reason,
// that (a) callVirtualMethod might call dummy_can_throw_anything (although this
// this also needs to be in a source file of its own.
// 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
// Also, this file should be compiled with -fnon-call-exceptions, and ideally
// caught which are thrown from the instruction calling callVirtualMethod). [It
// there would be a way to tell the compiler that the asm block contains calls
// is unclear how much of this comment is still relevent -- see the above
// to functions that can potentially throw; see the mail thread starting at
// comment.]
// <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
CPPU_CURRENT_NAMESPACE
::
callVirtualMethod
(
void
*
pAdjustedThisPtr
,
sal_Int32
nVtableIndex
,
void
*
pRegisterReturn
,
void
*
pThis
,
sal_uInt32
nVtableIndex
,
void
*
pRegisterReturn
,
typelib_TypeDescription
const
*
returnType
,
sal_Int32
*
pStackLongs
,
typelib_TypeDescriptionReference
*
pReturnTypeRef
,
bool
bSimpleReturn
,
sal_Int32
nStackLongs
)
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
// Should not happen, but...
// reference parameters are pointers
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!"
);
// Get pointer to method
OSL_ENSURE
(
(
sizeof
(
void
*
)
==
4
)
&&
(
sizeof
(
sal_Int32
)
==
4
),
"### unexpected size of int!"
);
sal_uInt64
pMethod
=
*
((
sal_uInt64
*
)
pThis
);
OSL_ENSURE
(
nStackLongs
&&
pStackLongs
,
"### no stack in callVirtualMethod !"
);
pMethod
+=
8
*
nVtableIndex
;
pMethod
=
*
((
sal_uInt64
*
)
pMethod
);
// never called
// Load parameters to stack, if necessary
if
(
!
pAdjustedThisPtr
)
CPPU_CURRENT_NAMESPACE
::
dummy_can_throw_anything
(
"xxx"
);
// address something
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
(
asm
volatile
(
"mov %%esp, %6
\n\t
"
// copy values
// Fill the xmm registers
"mov %0, %%eax
\n\t
"
"movq %6, %%rax
\n\t
"
"mov %%eax, %%edx
\n\t
"
"dec %%edx
\n\t
"
"movsd (%%rax), %%xmm0
\n\t
"
"shl $2, %%edx
\n\t
"
"movsd 8(%%rax), %%xmm1
\n\t
"
"add %1, %%edx
\n
"
"movsd 16(%%rax), %%xmm2
\n\t
"
"Lcopy:
\n\t
"
"movsd 24(%%rax), %%xmm3
\n\t
"
"pushl 0(%%edx)
\n\t
"
"movsd 32(%%rax), %%xmm4
\n\t
"
"sub $4, %%edx
\n\t
"
"movsd 40(%%rax), %%xmm5
\n\t
"
"dec %%eax
\n\t
"
"movsd 48(%%rax), %%xmm6
\n\t
"
"jne Lcopy
\n\t
"
"movsd 56(%%rax), %%xmm7
\n\t
"
// do the actual call
"mov %2, %%edx
\n\t
"
// Fill the general purpose registers
"mov 0(%%edx), %%edx
\n\t
"
"movq %5, %%rax
\n\t
"
"mov %3, %%eax
\n\t
"
"shl $2, %%eax
\n\t
"
"movq (%%rax), %%rdi
\n\t
"
"add %%eax, %%edx
\n\t
"
"movq 8(%%rax), %%rsi
\n\t
"
"mov 0(%%edx), %%edx
\n\t
"
"movq 16(%%rax), %%rdx
\n\t
"
"call *%%edx
\n\t
"
"movq 24(%%rax), %%rcx
\n\t
"
// save return registers
"movq 32(%%rax), %%r8
\n\t
"
"mov %%eax, %4
\n\t
"
"movq 40(%%rax), %%r9
\n\t
"
"mov %%edx, %5
\n\t
"
// cleanup stack
// Perform the call
"mov %6, %%esp
\n\t
"
"movq %4, %%r11
\n\t
"
:
"movq %7, %%rax
\n\t
"
:
"m"
(
nStackLongs
),
"m"
(
pStackLongs
),
"m"
(
pAdjustedThisPtr
),
"call *%%r11
\n\t
"
"m"
(
nVtableIndex
),
"m"
(
eax
),
"m"
(
edx
),
"m"
(
stackptr
)
:
"eax"
,
"ecx"
,
"edx"
);
// Fill the return values
switch
(
returnType
->
eTypeClass
)
"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
:
case
typelib_TypeClass_HYPER
:
break
;
case
typelib_TypeClass_UNSIGNED_HYPER
:
case
typelib_TypeClass_HYPER
:
*
reinterpret_cast
<
sal_uInt64
*>
(
pRegisterReturn
)
=
rax
;
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
;
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 @@
...
@@ -17,8 +17,8 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
*/
#ifndef 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_
MINGW_INTEL
_CALLVIRTUALMETHOD_HXX
#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_
GCC3_LINUX_X86_64
_CALLVIRTUALMETHOD_HXX
#include "sal/config.h"
#include "sal/config.h"
...
@@ -29,9 +29,10 @@
...
@@ -29,9 +29,10 @@
namespace
CPPU_CURRENT_NAMESPACE
{
namespace
CPPU_CURRENT_NAMESPACE
{
void
callVirtualMethod
(
void
callVirtualMethod
(
void
*
pAdjustedThisPtr
,
sal_Int32
nVtableIndex
,
void
*
pRegisterReturn
,
void
*
pThis
,
sal_uInt32
nVtableIndex
,
void
*
pRegisterReturn
,
typelib_TypeDescription
const
*
returnType
,
sal_Int32
*
pStackLongs
,
typelib_TypeDescriptionReference
*
pReturnTypeRef
,
bool
bSimpleReturn
,
sal_Int32
nStackLongs
);
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 @@
...
@@ -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/genfunc.hxx>
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/RuntimeException.hpp"
#include <uno/data.h>
#include <uno/data.h>
#include <typelib/typedescription.hxx>
#include <typelib/typedescription.hxx>
#include <sal/alloca.h>
#include "bridges/cpp_uno/shared/bridge.hxx"
#include "bridges/cpp_uno/shared/bridge.hxx"
#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
#include "bridges/cpp_uno/shared/types.hxx"
#include "bridges/cpp_uno/shared/types.hxx"
#include "bridges/cpp_uno/shared/vtablefactory.hxx"
#include "bridges/cpp_uno/shared/vtablefactory.hxx"
#include "abi.hxx"
#include "share.hxx"
#include "share.hxx"
#include "smallstruct.hxx"
using
namespace
::
osl
;
using
namespace
::
rtl
;
using
namespace
::
com
::
sun
::
star
::
uno
;
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
,
bridges
::
cpp_uno
::
shared
::
CppInterfaceProxy
*
pThis
,
const
typelib_TypeDescription
*
pMemberTypeDescr
,
const
typelib_TypeDescription
*
pMemberTypeDescr
,
typelib_TypeDescriptionReference
*
pReturnTypeRef
,
// 0 indicates void return
typelib_TypeDescriptionReference
*
pReturnTypeRef
,
// 0 indicates void return
sal_Int32
nParams
,
typelib_MethodParameter
*
pParams
,
sal_Int32
nParams
,
typelib_MethodParameter
*
pParams
,
void
**
pCallStack
,
void
**
gpreg
,
void
**
fpreg
,
void
**
ovrflw
,
void
*
pReturnValue
)
sal_uInt64
*
pRegisterReturn
/* space for register return */
)
{
{
// pCallStack: ret, [return ptr], this, params
unsigned
int
nr_gpr
=
0
;
//number of gpr registers used
char
*
pCppStack
=
(
char
*
)(
pCallStack
+
1
);
unsigned
int
nr_fpr
=
0
;
//number of fpr registers used
// return
// return
typelib_TypeDescription
*
pReturnTypeDescr
=
0
;
typelib_TypeDescription
*
pReturnTypeDescr
=
0
;
...
@@ -57,33 +75,26 @@ void cpp2uno_call(
...
@@ -57,33 +75,26 @@ void cpp2uno_call(
void
*
pUnoReturn
=
0
;
void
*
pUnoReturn
=
0
;
void
*
pCppReturn
=
0
;
// complex return ptr: if != 0 && != pUnoReturn, reconversion need
void
*
pCppReturn
=
0
;
// complex return ptr: if != 0 && != pUnoReturn, reconversion need
if
(
pReturnTypeDescr
)
if
(
pReturnTypeDescr
)
{
{
if
(
bridges
::
cpp_uno
::
shared
::
isSimpleType
(
pReturnTypeDescr
))
if
(
x86_64
::
return_in_hidden_param
(
pReturnTypeRef
)
)
{
pUnoReturn
=
pReturnValue
;
// direct way for simple types
}
else
// complex return via ptr (pCppReturn)
{
{
if
(
!
bridges
::
cpp_uno
::
shared
::
isSmallStruct
(
pReturnTypeDescr
))
{
pCppReturn
=
*
gpreg
++
;
pCppReturn
=
*
(
void
**
)
pCppStack
;
nr_gpr
++
;
pCppStack
+=
sizeof
(
void
*
);
}
else
{
pCppReturn
=
pReturnValue
;
}
pUnoReturn
=
(
bridges
::
cpp_uno
::
shared
::
relatesToInterfaceType
(
pUnoReturn
=
(
bridges
::
cpp_uno
::
shared
::
relatesToInterfaceType
(
pReturnTypeDescr
)
pReturnTypeDescr
)
?
alloca
(
pReturnTypeDescr
->
nSize
)
?
alloca
(
pReturnTypeDescr
->
nSize
)
:
pCppReturn
);
// direct way
:
pCppReturn
);
// direct way
}
}
else
pUnoReturn
=
pRegisterReturn
;
// direct way for simple types
}
}
// pop this
// pop this
pCppStack
+=
sizeof
(
void
*
);
gpreg
++
;
nr_gpr
++
;
// stack space
// stack space
OSL_ENSURE
(
sizeof
(
void
*
)
==
sizeof
(
sal_Int32
),
"### unexpected size!"
);
// parameters
// parameters
void
**
pUnoArgs
=
(
void
**
)
alloca
(
4
*
sizeof
(
void
*
)
*
nParams
);
void
**
pUnoArgs
=
(
void
**
)
alloca
(
4
*
sizeof
(
void
*
)
*
nParams
);
void
**
pCppArgs
=
pUnoArgs
+
nParams
;
void
**
pCppArgs
=
pUnoArgs
+
nParams
;
...
@@ -92,36 +103,57 @@ void cpp2uno_call(
...
@@ -92,36 +103,57 @@ void cpp2uno_call(
// type descriptions for reconversions
// type descriptions for reconversions
typelib_TypeDescription
**
ppTempParamTypeDescr
=
(
typelib_TypeDescription
**
)(
pUnoArgs
+
(
3
*
nParams
));
typelib_TypeDescription
**
ppTempParamTypeDescr
=
(
typelib_TypeDescription
**
)(
pUnoArgs
+
(
3
*
nParams
));
sal_Int32
nTempIndizes
=
0
;
sal_Int32
nTempIndizes
=
0
;
for
(
sal_Int32
nPos
=
0
;
nPos
<
nParams
;
++
nPos
)
for
(
sal_Int32
nPos
=
0
;
nPos
<
nParams
;
++
nPos
)
{
{
const
typelib_MethodParameter
&
rParam
=
pParams
[
nPos
];
const
typelib_MethodParameter
&
rParam
=
pParams
[
nPos
];
typelib_TypeDescription
*
pParamTypeDescr
=
0
;
TYPELIB_DANGER_GET
(
&
pParamTypeDescr
,
rParam
.
pTypeRef
);
if
(
!
rParam
.
bOut
int
nUsedGPR
=
0
;
&&
bridges
::
cpp_uno
::
shared
::
isSimpleType
(
pParamTypeDescr
))
int
nUsedSSE
=
0
;
// value
#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
;
// Simple types must fit exactly one register on x86_64
pUnoArgs
[
nPos
]
=
pCppStack
;
OSL_ASSERT
(
bFitsRegisters
&&
(
(
nUsedSSE
==
1
&&
nUsedGPR
==
0
)
||
(
nUsedSSE
==
0
&&
nUsedGPR
==
1
)
)
);
switch
(
pParamTypeDescr
->
eTypeClass
)
if
(
nUsedSSE
==
1
)
{
{
case
typelib_TypeClass_HYPER
:
if
(
nr_fpr
<
x86_64
::
MAX_SSE_REGS
)
case
typelib_TypeClass_UNSIGNED_HYPER
:
{
case
typelib_TypeClass_DOUBLE
:
pCppArgs
[
nPos
]
=
pUnoArgs
[
nPos
]
=
fpreg
++
;
pCppStack
+=
sizeof
(
sal_Int32
);
// extra long
nr_fpr
++
;
break
;
}
default
:
else
break
;
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
if
(
!
rParam
.
bIn
)
// is pure out
{
{
...
@@ -131,12 +163,10 @@ void cpp2uno_call(
...
@@ -131,12 +163,10 @@ void cpp2uno_call(
// will be released at reconversion
// will be released at reconversion
ppTempParamTypeDescr
[
nTempIndizes
++
]
=
pParamTypeDescr
;
ppTempParamTypeDescr
[
nTempIndizes
++
]
=
pParamTypeDescr
;
}
}
// is in/inout
else
if
(
bridges
::
cpp_uno
::
shared
::
relatesToInterfaceType
(
pParamTypeDescr
)
)
// is in/inout
else
if
(
bridges
::
cpp_uno
::
shared
::
relatesToInterfaceType
(
pParamTypeDescr
))
{
{
uno_copyAndConvertData
(
pUnoArgs
[
nPos
]
=
alloca
(
pParamTypeDescr
->
nSize
),
uno_copyAndConvertData
(
pUnoArgs
[
nPos
]
=
alloca
(
pParamTypeDescr
->
nSize
),
*
(
void
**
)
pCppStack
,
pParamTypeDescr
,
pCppStack
,
pParamTypeDescr
,
pThis
->
getBridge
()
->
getCpp2Uno
()
);
pThis
->
getBridge
()
->
getCpp2Uno
()
);
pTempIndizes
[
nTempIndizes
]
=
nPos
;
// has to be reconverted
pTempIndizes
[
nTempIndizes
]
=
nPos
;
// has to be reconverted
// will be released at reconversion
// will be released at reconversion
...
@@ -144,12 +174,11 @@ void cpp2uno_call(
...
@@ -144,12 +174,11 @@ void cpp2uno_call(
}
}
else
// direct way
else
// direct way
{
{
pUnoArgs
[
nPos
]
=
*
(
void
**
)
pCppStack
;
pUnoArgs
[
nPos
]
=
pCppStack
;
// no longer needed
// no longer needed
TYPELIB_DANGER_RELEASE
(
pParamTypeDescr
);
TYPELIB_DANGER_RELEASE
(
pParamTypeDescr
);
}
}
}
}
pCppStack
+=
sizeof
(
sal_Int32
);
// standard parameter length
}
}
// ExceptionHolder
// ExceptionHolder
...
@@ -157,11 +186,10 @@ void cpp2uno_call(
...
@@ -157,11 +186,10 @@ void cpp2uno_call(
uno_Any
*
pUnoExc
=
&
aUnoExc
;
uno_Any
*
pUnoExc
=
&
aUnoExc
;
// invoke uno dispatch call
// invoke uno dispatch call
(
*
pThis
->
getUnoI
()
->
pDispatcher
)(
(
*
pThis
->
getUnoI
()
->
pDispatcher
)(
pThis
->
getUnoI
(),
pMemberTypeDescr
,
pUnoReturn
,
pUnoArgs
,
&
pUnoExc
);
pThis
->
getUnoI
(),
pMemberTypeDescr
,
pUnoReturn
,
pUnoArgs
,
&
pUnoExc
);
// in case an exception occurred...
// in case an exception occurred...
if
(
pUnoExc
)
if
(
pUnoExc
)
{
{
// destruct temporary in/inout params
// destruct temporary in/inout params
for
(
;
nTempIndizes
--
;
)
for
(
;
nTempIndizes
--
;
)
...
@@ -175,9 +203,9 @@ void cpp2uno_call(
...
@@ -175,9 +203,9 @@ void cpp2uno_call(
if
(
pReturnTypeDescr
)
if
(
pReturnTypeDescr
)
TYPELIB_DANGER_RELEASE
(
pReturnTypeDescr
);
TYPELIB_DANGER_RELEASE
(
pReturnTypeDescr
);
CPPU_CURRENT_NAMESPACE
::
raiseException
(
CPPU_CURRENT_NAMESPACE
::
raiseException
(
&
aUnoExc
,
pThis
->
getBridge
()
->
getUno2Cpp
()
);
// has to destruct the any
&
aUnoExc
,
pThis
->
getBridge
()
->
getUno2Cpp
()
);
// is here for dummy
// has to destruct the any
return
typelib_TypeClass_VOID
;
}
}
else
// else no exception occurred...
else
// else no exception occurred...
{
{
...
@@ -187,7 +215,7 @@ void cpp2uno_call(
...
@@ -187,7 +215,7 @@ void cpp2uno_call(
sal_Int32
nIndex
=
pTempIndizes
[
nTempIndizes
];
sal_Int32
nIndex
=
pTempIndizes
[
nTempIndizes
];
typelib_TypeDescription
*
pParamTypeDescr
=
ppTempParamTypeDescr
[
nTempIndizes
];
typelib_TypeDescription
*
pParamTypeDescr
=
ppTempParamTypeDescr
[
nTempIndizes
];
if
(
pParams
[
nIndex
].
bOut
)
// inout/out
if
(
pParams
[
nIndex
].
bOut
)
// inout/out
{
{
// convert and assign
// convert and assign
uno_destructData
(
pCppArgs
[
nIndex
],
pParamTypeDescr
,
cpp_release
);
uno_destructData
(
pCppArgs
[
nIndex
],
pParamTypeDescr
,
cpp_release
);
...
@@ -200,237 +228,209 @@ void cpp2uno_call(
...
@@ -200,237 +228,209 @@ void cpp2uno_call(
TYPELIB_DANGER_RELEASE
(
pParamTypeDescr
);
TYPELIB_DANGER_RELEASE
(
pParamTypeDescr
);
}
}
// return
// 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
,
uno_copyAndConvertData
(
pCppReturn
,
pUnoReturn
,
pReturnTypeDescr
,
pThis
->
getBridge
()
->
getUno2Cpp
()
);
pThis
->
getBridge
()
->
getUno2Cpp
()
);
// destroy temp uno return
// destroy temp uno return
uno_destructData
(
pUnoReturn
,
pReturnTypeDescr
,
0
);
uno_destructData
(
pUnoReturn
,
pReturnTypeDescr
,
0
);
}
}
if
(
pReturnValue
!=
pCppReturn
)
// complex return ptr is set to return reg
// complex return ptr is set to eax
*
(
void
**
)
pRegisterReturn
=
pCppReturn
;
*
static_cast
<
void
**
>
(
pReturnValue
)
=
pCppReturn
;
}
}
if
(
pReturnTypeDescr
)
if
(
pReturnTypeDescr
)
{
{
typelib_TypeClass
eRet
=
(
typelib_TypeClass
)
pReturnTypeDescr
->
eTypeClass
;
TYPELIB_DANGER_RELEASE
(
pReturnTypeDescr
);
TYPELIB_DANGER_RELEASE
(
pReturnTypeDescr
);
return
eRet
;
}
}
else
return
typelib_TypeClass_VOID
;
}
}
}
}
//==================================================================================================
//==================================================================================================
extern
"C"
void
cpp_vtable_call
(
extern
"C"
typelib_TypeClass
cpp_vtable_call
(
int
nFunctionIndex
,
int
nVtableOffset
,
void
**
pCallStack
,
sal_Int32
nFunctionIndex
,
sal_Int32
nVtableOffset
,
void
*
pReturnValue
)
void
**
gpreg
,
void
**
fpreg
,
void
**
ovrflw
,
sal_uInt64
*
pRegisterReturn
/* space for register return */
)
{
{
OSL_ENSURE
(
sizeof
(
sal_Int32
)
==
sizeof
(
void
*
),
"### unexpected!"
);
// gpreg: [ret *], this, [other gpr params]
// fpreg: [fpr params]
//
pCallStack: ret adr, [ret *], this, params
//
ovrflw: [gpr or fpr params (properly aligned)]
void
*
pThis
;
void
*
pThis
;
if
(
nFunctionIndex
&
0x80000000
)
if
(
nFunctionIndex
&
0x80000000
)
{
{
nFunctionIndex
&=
0x7fffffff
;
nFunctionIndex
&=
0x7fffffff
;
pThis
=
pCallStack
[
2
];
pThis
=
gpreg
[
1
];
}
}
else
else
{
{
pThis
=
pCallStack
[
1
];
pThis
=
gpreg
[
0
];
}
}
pThis
=
static_cast
<
char
*
>
(
pThis
)
-
nVtableOffset
;
pThis
=
static_cast
<
char
*>
(
pThis
)
-
nVtableOffset
;
bridges
::
cpp_uno
::
shared
::
CppInterfaceProxy
*
pCppI
=
bridges
::
cpp_uno
::
shared
::
CppInterfaceProxy
::
castInterfaceToProxy
(
bridges
::
cpp_uno
::
shared
::
CppInterfaceProxy
*
pCppI
=
pThis
);
bridges
::
cpp_uno
::
shared
::
CppInterfaceProxy
::
castInterfaceToProxy
(
pThis
);
typelib_InterfaceTypeDescription
*
pTypeDescr
=
pCppI
->
getTypeDescr
();
typelib_InterfaceTypeDescription
*
pTypeDescr
=
pCppI
->
getTypeDescr
();
OSL_ENSURE
(
nFunctionIndex
<
pTypeDescr
->
nMapFunctionIndexToMemberIndex
,
"### illegal vtable index!"
);
OSL_ENSURE
(
nFunctionIndex
<
pTypeDescr
->
nMapFunctionIndexToMemberIndex
,
"### illegal vtable index!
\n
"
);
if
(
nFunctionIndex
>=
pTypeDescr
->
nMapFunctionIndexToMemberIndex
)
if
(
nFunctionIndex
>=
pTypeDescr
->
nMapFunctionIndexToMemberIndex
)
{
{
throw
RuntimeException
(
throw
RuntimeException
(
OUString
(
"illegal vtable index!"
),
OUString
(
"illegal vtable index!"
),
reinterpret_cast
<
XInterface
*>
(
pCppI
)
);
(
XInterface
*
)
pThis
);
}
}
// determine called method
// determine called method
sal_Int32
nMemberPos
=
pTypeDescr
->
pMapFunctionIndexToMemberIndex
[
nFunctionIndex
];
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
]
);
TypeDescription
aMemberDescr
(
pTypeDescr
->
ppAllMembers
[
nMemberPos
]
);
switch
(
aMemberDescr
.
get
()
->
eTypeClass
)
typelib_TypeClass
eRet
;
{
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
case
typelib_TypeClass_INTERFACE_ATTRIBUTE
:
switch
(
nFunctionIndex
)
{
{
case
1
:
// acquire()
typelib_TypeDescriptionReference
*
pAttrTypeRef
=
pCppI
->
acquireProxy
();
// non virtual call!
reinterpret_cast
<
typelib_InterfaceAttributeTypeDescription
*>
(
aMemberDescr
.
get
()
)
->
pAttributeTypeRef
;
break
;
case
2
:
// release()
if
(
pTypeDescr
->
pMapMemberIndexToFunctionIndex
[
nMemberPos
]
==
nFunctionIndex
)
pCppI
->
releaseProxy
();
// non virtual call!
{
// 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
;
break
;
case
0
:
// queryInterface() opt
}
case
typelib_TypeClass_INTERFACE_METHOD
:
{
{
typelib_TypeDescription
*
pTD
=
0
;
// is METHOD
TYPELIB_DANGER_GET
(
&
pTD
,
reinterpret_cast
<
Type
*
>
(
pCallStack
[
3
]
)
->
getTypeLibType
()
);
switch
(
nFunctionIndex
)
if
(
pTD
)
{
{
XInterface
*
pInterface
=
0
;
case
1
:
// acquire()
(
*
pCppI
->
getBridge
()
->
getCppEnv
()
->
getRegisteredInterface
)(
pCppI
->
acquireProxy
();
// non virtual call!
pCppI
->
getBridge
()
->
getCppEnv
(),
eRet
=
typelib_TypeClass_VOID
;
(
void
**
)
&
pInterface
,
pCppI
->
getOid
().
pData
,
break
;
(
typelib_InterfaceTypeDescription
*
)
pTD
);
case
2
:
// release()
pCppI
->
releaseProxy
();
// non virtual call!
if
(
pInterface
)
eRet
=
typelib_TypeClass_VOID
;
{
::
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
;
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
:
default
:
cpp2uno_call
(
{
pCppI
,
aMemberDescr
.
get
(),
throw
RuntimeException
(
OUString
(
"no member description found!"
),
((
typelib_InterfaceMethodTypeDescription
*
)
aMemberDescr
.
get
())
->
pReturnTypeRef
,
reinterpret_cast
<
XInterface
*>
(
pCppI
)
);
((
typelib_InterfaceMethodTypeDescription
*
)
aMemberDescr
.
get
())
->
nParams
,
((
typelib_InterfaceMethodTypeDescription
*
)
aMemberDescr
.
get
())
->
pParams
,
pCallStack
,
pReturnValue
);
}
}
break
;
}
default
:
{
throw
RuntimeException
(
OUString
(
"no member description found!"
),
(
XInterface
*
)
pThis
);
}
}
}
return
eRet
;
}
}
//==================================================================================================
//==================================================================================================
extern
"C"
void
privateSnippetExecutorGeneral
();
extern
"C"
void
privateSnippetExecutor
(
...
);
extern
"C"
void
privateSnippetExecutorVoid
();
extern
"C"
void
privateSnippetExecutorHyper
();
const
int
codeSnippetSize
=
24
;
extern
"C"
void
privateSnippetExecutorFloat
();
extern
"C"
void
privateSnippetExecutorDouble
();
// Generate a trampoline that redirects method calls to
extern
"C"
void
privateSnippetExecutorClass
();
// privateSnippetExecutor().
extern
"C"
typedef
void
(
*
PrivateSnippetExecutor
)();
//
// privateSnippetExecutor() saves all the registers that are used for
int
const
codeSnippetSize
=
16
;
// parameter passing on x86_64, and calls the cpp_vtable_call().
// When it returns, privateSnippetExecutor() sets the return value.
unsigned
char
*
codeSnippet
(
//
unsigned
char
*
code
,
sal_Int32
functionIndex
,
sal_Int32
vtableOffset
,
// Note: The code snippet we build here must not create a stack frame,
typelib_TypeDescriptionReference
*
returnType
)
// 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
;
sal_uInt64
nOffsetAndIndex
=
(
(
(
sal_uInt64
)
nVtableOffset
)
<<
32
)
|
(
(
sal_uInt64
)
nFunctionIndex
);
if
(
returnType
)
TYPELIB_DANGER_GET
(
&
returnTypeDescr
,
returnType
);
if
(
bHasHiddenParam
)
nOffsetAndIndex
|=
0x80000000
;
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
;
}
// 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
;
};
struct
bridges
::
cpp_uno
::
shared
::
VtableFactory
::
Slot
{
void
*
fn
;
};
bridges
::
cpp_uno
::
shared
::
VtableFactory
::
Slot
*
bridges
::
cpp_uno
::
shared
::
VtableFactory
::
Slot
*
...
@@ -439,12 +439,14 @@ bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
...
@@ -439,12 +439,14 @@ bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
return
static_cast
<
Slot
*
>
(
block
)
+
2
;
return
static_cast
<
Slot
*
>
(
block
)
+
2
;
}
}
//==================================================================================================
sal_Size
bridges
::
cpp_uno
::
shared
::
VtableFactory
::
getBlockSize
(
sal_Size
bridges
::
cpp_uno
::
shared
::
VtableFactory
::
getBlockSize
(
sal_Int32
slotCount
)
sal_Int32
slotCount
)
{
{
return
(
slotCount
+
2
)
*
sizeof
(
Slot
)
+
slotCount
*
codeSnippetSize
;
return
(
slotCount
+
2
)
*
sizeof
(
Slot
)
+
slotCount
*
codeSnippetSize
;
}
}
//==================================================================================================
bridges
::
cpp_uno
::
shared
::
VtableFactory
::
Slot
*
bridges
::
cpp_uno
::
shared
::
VtableFactory
::
Slot
*
bridges
::
cpp_uno
::
shared
::
VtableFactory
::
initializeBlock
(
bridges
::
cpp_uno
::
shared
::
VtableFactory
::
initializeBlock
(
void
*
block
,
sal_Int32
slotCount
)
void
*
block
,
sal_Int32
slotCount
)
...
@@ -455,56 +457,59 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
...
@@ -455,56 +457,59 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
return
slots
+
slotCount
;
return
slots
+
slotCount
;
}
}
//==================================================================================================
unsigned
char
*
bridges
::
cpp_uno
::
shared
::
VtableFactory
::
addLocalFunctions
(
unsigned
char
*
bridges
::
cpp_uno
::
shared
::
VtableFactory
::
addLocalFunctions
(
Slot
**
slots
,
unsigned
char
*
code
,
Slot
**
slots
,
unsigned
char
*
code
,
typelib_InterfaceTypeDescription
const
*
type
,
typelib_InterfaceTypeDescription
const
*
type
,
sal_Int32
functionOffset
,
sal_Int32
nFunctionOffset
,
sal_Int32
functionCount
,
sal_Int32
nVtableOffset
)
sal_Int32
functionCount
,
sal_Int32
vtableOffset
)
{
{
(
*
slots
)
-=
functionCount
;
(
*
slots
)
-=
functionCount
;
Slot
*
s
=
*
slots
;
Slot
*
s
=
*
slots
;
for
(
sal_Int32
i
=
0
;
i
<
type
->
nMembers
;
++
i
)
{
for
(
sal_Int32
nPos
=
0
;
nPos
<
type
->
nMembers
;
++
nPos
)
typelib_TypeDescription
*
member
=
0
;
{
TYPELIB_DANGER_GET
(
&
member
,
type
->
ppMembers
[
i
]);
typelib_TypeDescription
*
pTD
=
0
;
OSL_ASSERT
(
member
!=
0
);
switch
(
member
->
eTypeClass
)
{
TYPELIB_DANGER_GET
(
&
pTD
,
type
->
ppMembers
[
nPos
]
);
case
typelib_TypeClass_INTERFACE_ATTRIBUTE
:
OSL_ASSERT
(
pTD
);
// Getter:
if
(
typelib_TypeClass_INTERFACE_ATTRIBUTE
==
pTD
->
eTypeClass
)
{
typelib_InterfaceAttributeTypeDescription
*
pAttrTD
=
reinterpret_cast
<
typelib_InterfaceAttributeTypeDescription
*>
(
pTD
);
// get method
(
s
++
)
->
fn
=
code
;
(
s
++
)
->
fn
=
code
;
code
=
codeSnippet
(
code
=
codeSnippet
(
code
,
nFunctionOffset
++
,
nVtableOffset
,
code
,
functionOffset
++
,
vtableOffset
,
x86_64
::
return_in_hidden_param
(
pAttrTD
->
pAttributeTypeRef
)
);
reinterpret_cast
<
typelib_InterfaceAttributeTypeDescription
*
>
(
member
)
->
pAttributeTypeRef
);
if
(
!
pAttrTD
->
bReadOnly
)
// Setter:
if
(
!
reinterpret_cast
<
typelib_InterfaceAttributeTypeDescription
*
>
(
member
)
->
bReadOnly
)
{
{
// set method
(
s
++
)
->
fn
=
code
;
(
s
++
)
->
fn
=
code
;
code
=
codeSnippet
(
code
=
codeSnippet
(
code
,
nFunctionOffset
++
,
nVtableOffset
,
false
);
code
,
functionOffset
++
,
vtableOffset
,
NULL
);
}
}
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
;
(
s
++
)
->
fn
=
code
;
code
=
codeSnippet
(
code
=
codeSnippet
(
code
,
nFunctionOffset
++
,
nVtableOffset
,
code
,
functionOffset
++
,
vtableOffset
,
x86_64
::
return_in_hidden_param
(
pMethodTD
->
pReturnTypeRef
)
);
reinterpret_cast
<
typelib_InterfaceMethodTypeDescription
*
>
(
member
)
->
pReturnTypeRef
);
break
;
default
:
OSL_ASSERT
(
false
);
break
;
}
}
TYPELIB_DANGER_RELEASE
(
member
);
else
OSL_ASSERT
(
false
);
TYPELIB_DANGER_RELEASE
(
pTD
);
}
}
return
code
;
return
code
;
}
}
//==================================================================================================
void
bridges
::
cpp_uno
::
shared
::
VtableFactory
::
flushCode
(
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: */
/* 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 @@
...
@@ -17,26 +17,80 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
* 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/genfunc.hxx>
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/RuntimeException.hpp"
#include <uno/data.h>
#include <uno/data.h>
#include <sal/alloca.h>
#include <sal/alloca.h>
#include
"bridges/cpp_uno/shared/bridge.hxx"
#include
<bridges/cpp_uno/shared/bridge.hxx>
#include
"bridges/cpp_uno/shared/types.hxx"
#include
<bridges/cpp_uno/shared/types.hxx>
#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
#include "bridges/cpp_uno/shared/vtables.hxx"
#include "bridges/cpp_uno/shared/vtables.hxx"
#include "abi.hxx"
#include "callvirtualmethod.hxx"
#include "callvirtualmethod.hxx"
#include "share.hxx"
#include "share.hxx"
#include "smallstruct.hxx"
using
namespace
::
rtl
;
using
namespace
::
rtl
;
using
namespace
::
com
::
sun
::
star
::
uno
;
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
(
static
void
cpp_call
(
bridges
::
cpp_uno
::
shared
::
UnoInterfaceProxy
*
pThis
,
bridges
::
cpp_uno
::
shared
::
UnoInterfaceProxy
*
pThis
,
...
@@ -45,66 +99,53 @@ static void cpp_call(
...
@@ -45,66 +99,53 @@ static void cpp_call(
sal_Int32
nParams
,
typelib_MethodParameter
*
pParams
,
sal_Int32
nParams
,
typelib_MethodParameter
*
pParams
,
void
*
pUnoReturn
,
void
*
pUnoArgs
[],
uno_Any
**
ppUnoExc
)
void
*
pUnoReturn
,
void
*
pUnoArgs
[],
uno_Any
**
ppUnoExc
)
{
{
// max space for: [complex ret ptr], values|ptr ...
// Maxium space for [complex ret ptr], values | ptr ...
char
*
pCppStack
=
// (but will be used less - some of the values will be in pGPR and pFPR)
#ifdef BROKEN_ALLOCA
sal_uInt64
*
pStack
=
(
sal_uInt64
*
)
__builtin_alloca
(
(
nParams
+
3
)
*
sizeof
(
sal_uInt64
)
);
(
char
*
)
malloc
(
sizeof
(
sal_Int32
)
+
((
nParams
+
2
)
*
sizeof
(
sal_Int64
))
);
sal_uInt64
*
pStackStart
=
pStack
;
#else
(
char
*
)
alloca
(
sizeof
(
sal_Int32
)
+
((
nParams
+
2
)
*
sizeof
(
sal_Int64
))
);
sal_uInt64
pGPR
[
x86_64
::
MAX_GPR_REGS
];
#endif
sal_uInt32
nGPR
=
0
;
char
*
pCppStackStart
=
pCppStack
;
// return
double
pFPR
[
x86_64
::
MAX_SSE_REGS
];
sal_uInt32
nFPR
=
0
;
// Return
typelib_TypeDescription
*
pReturnTypeDescr
=
0
;
typelib_TypeDescription
*
pReturnTypeDescr
=
0
;
TYPELIB_DANGER_GET
(
&
pReturnTypeDescr
,
pReturnTypeRef
);
TYPELIB_DANGER_GET
(
&
pReturnTypeDescr
,
pReturnTypeRef
);
OSL_ENSURE
(
pReturnTypeDescr
,
"### expected return type description!"
);
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
pCppReturn
=
pUnoReturn
;
// direct way for simple types
}
else
else
{
{
// complex return via ptr
// complex return via ptr
pCppReturn
pCppReturn
=
bridges
::
cpp_uno
::
shared
::
relatesToInterfaceType
(
pReturnTypeDescr
)
?
=
(
bridges
::
cpp_uno
::
shared
::
relatesToInterfaceType
(
__builtin_alloca
(
pReturnTypeDescr
->
nSize
)
:
pUnoReturn
;
pReturnTypeDescr
)
INSERT_INT64
(
&
pCppReturn
,
nGPR
,
pGPR
,
pStack
);
#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
())
// Push "this" pointer
+
aVtableSlot
.
offset
;
void
*
pAdjustedThisPtr
=
reinterpret_cast
<
void
**
>
(
pThis
->
getCppI
()
)
+
aVtableSlot
.
offset
;
*
(
void
**
)
pCppStack
=
pAdjustedThisPtr
;
INSERT_INT64
(
&
pAdjustedThisPtr
,
nGPR
,
pGPR
,
pStack
);
pCppStack
+=
sizeof
(
void
*
);
// Args
// stack space
void
**
pCppArgs
=
(
void
**
)
alloca
(
3
*
sizeof
(
void
*
)
*
nParams
);
OSL_ENSURE
(
sizeof
(
void
*
)
==
sizeof
(
sal_Int32
),
"### unexpected size!"
);
// Indizes of values this have to be converted (interface conversion cpp<=>uno)
// 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
);
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
));
typelib_TypeDescription
**
ppTempParamTypeDescr
=
(
typelib_TypeDescription
**
)(
pCppArgs
+
(
2
*
nParams
));
sal_Int32
nTempIndizes
=
0
;
sal_Int32
nTempIndizes
=
0
;
for
(
sal_Int32
nPos
=
0
;
nPos
<
nParams
;
++
nPos
)
for
(
sal_Int32
nPos
=
0
;
nPos
<
nParams
;
++
nPos
)
{
{
...
@@ -112,22 +153,39 @@ static void cpp_call(
...
@@ -112,22 +153,39 @@ static void cpp_call(
typelib_TypeDescription
*
pParamTypeDescr
=
0
;
typelib_TypeDescription
*
pParamTypeDescr
=
0
;
TYPELIB_DANGER_GET
(
&
pParamTypeDescr
,
rParam
.
pTypeRef
);
TYPELIB_DANGER_GET
(
&
pParamTypeDescr
,
rParam
.
pTypeRef
);
if
(
!
rParam
.
bOut
if
(
!
rParam
.
bOut
&&
bridges
::
cpp_uno
::
shared
::
isSimpleType
(
pParamTypeDescr
))
&&
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
()
);
pThis
->
getBridge
()
->
getUno2Cpp
()
);
switch
(
pParamTypeDescr
->
eTypeClass
)
switch
(
pParamTypeDescr
->
eTypeClass
)
{
{
case
typelib_TypeClass_HYPER
:
case
typelib_TypeClass_HYPER
:
case
typelib_TypeClass_UNSIGNED_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
:
case
typelib_TypeClass_DOUBLE
:
pCppStack
+=
sizeof
(
sal_Int32
);
// extra long
INSERT_FLOAT_DOUBLE
(
pCppArgs
[
nPos
],
nFPR
,
pFPR
,
pStack
);
break
;
break
;
default
:
default
:
break
;
break
;
}
}
// no longer needed
// no longer needed
TYPELIB_DANGER_RELEASE
(
pParamTypeDescr
);
TYPELIB_DANGER_RELEASE
(
pParamTypeDescr
);
}
}
...
@@ -137,28 +195,18 @@ static void cpp_call(
...
@@ -137,28 +195,18 @@ static void cpp_call(
{
{
// cpp out is constructed mem, uno out is not!
// cpp out is constructed mem, uno out is not!
uno_constructData
(
uno_constructData
(
#ifdef BROKEN_ALLOCA
pCppArgs
[
nPos
]
=
alloca
(
pParamTypeDescr
->
nSize
),
*
(
void
**
)
pCppStack
=
pCppArgs
[
nPos
]
=
malloc
(
pParamTypeDescr
->
nSize
),
#else
*
(
void
**
)
pCppStack
=
pCppArgs
[
nPos
]
=
alloca
(
pParamTypeDescr
->
nSize
),
#endif
pParamTypeDescr
);
pParamTypeDescr
);
pTempIndizes
[
nTempIndizes
]
=
nPos
;
// default constructed for cpp call
pTempIndizes
[
nTempIndizes
]
=
nPos
;
// default constructed for cpp call
// will be released at reconversion
// will be released at reconversion
ppTempParamTypeDescr
[
nTempIndizes
++
]
=
pParamTypeDescr
;
ppTempParamTypeDescr
[
nTempIndizes
++
]
=
pParamTypeDescr
;
}
}
// is in/inout
// is in/inout
else
if
(
bridges
::
cpp_uno
::
shared
::
relatesToInterfaceType
(
else
if
(
bridges
::
cpp_uno
::
shared
::
relatesToInterfaceType
(
pParamTypeDescr
))
pParamTypeDescr
))
{
{
uno_copyAndConvertData
(
uno_copyAndConvertData
(
#ifdef BROKEN_ALLOCA
pCppArgs
[
nPos
]
=
alloca
(
pParamTypeDescr
->
nSize
),
*
(
void
**
)
pCppStack
=
pCppArgs
[
nPos
]
=
malloc
(
pParamTypeDescr
->
nSize
),
pUnoArgs
[
nPos
],
pParamTypeDescr
,
pThis
->
getBridge
()
->
getUno2Cpp
()
);
#else
*
(
void
**
)
pCppStack
=
pCppArgs
[
nPos
]
=
alloca
(
pParamTypeDescr
->
nSize
),
#endif
pUnoArgs
[
nPos
],
pParamTypeDescr
,
pThis
->
getBridge
()
->
getUno2Cpp
()
);
pTempIndizes
[
nTempIndizes
]
=
nPos
;
// has to be reconverted
pTempIndizes
[
nTempIndizes
]
=
nPos
;
// has to be reconverted
// will be released at reconversion
// will be released at reconversion
...
@@ -166,22 +214,40 @@ static void cpp_call(
...
@@ -166,22 +214,40 @@ static void cpp_call(
}
}
else
// direct way
else
// direct way
{
{
*
(
void
**
)
pCppStack
=
pCppArgs
[
nPos
]
=
pUnoArgs
[
nPos
];
pCppArgs
[
nPos
]
=
pUnoArgs
[
nPos
];
// no longer needed
// no longer needed
TYPELIB_DANGER_RELEASE
(
pParamTypeDescr
);
TYPELIB_DANGER_RELEASE
(
pParamTypeDescr
);
}
}
INSERT_INT64
(
&
(
pCppArgs
[
nPos
]),
nGPR
,
pGPR
,
pStack
);
}
}
pCppStack
+=
sizeof
(
sal_Int32
);
// standard parameter length
}
}
try
try
{
{
OSL_ENSURE
(
!
(
(
pCppStack
-
pCppStackStart
)
&
3
),
"UNALIGNED STACK !!! (Please DO panic)"
);
try
{
CPPU_CURRENT_NAMESPACE
::
callVirtualMethod
(
CPPU_CURRENT_NAMESPACE
::
callVirtualMethod
(
pAdjustedThisPtr
,
aVtableSlot
.
index
,
pAdjustedThisPtr
,
aVtableSlot
.
index
,
pCppReturn
,
pReturnTypeDescr
,
pCppReturn
,
pReturnTypeRef
,
bSimpleReturn
,
(
sal_Int32
*
)
pCppStackStart
,
(
pCppStack
-
pCppStackStart
)
/
sizeof
(
sal_Int32
)
);
pStackStart
,
(
pStack
-
pStackStart
),
// NO exception occurred...
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
;
*
ppUnoExc
=
0
;
// reconvert temporary params
// reconvert temporary params
...
@@ -206,9 +272,6 @@ static void cpp_call(
...
@@ -206,9 +272,6 @@ static void cpp_call(
}
}
// destroy temp cpp param => cpp: every param was constructed
// destroy temp cpp param => cpp: every param was constructed
uno_destructData
(
pCppArgs
[
nIndex
],
pParamTypeDescr
,
cpp_release
);
uno_destructData
(
pCppArgs
[
nIndex
],
pParamTypeDescr
,
cpp_release
);
#ifdef BROKEN_ALLOCA
free
(
pCppArgs
[
nIndex
]
);
#endif
TYPELIB_DANGER_RELEASE
(
pParamTypeDescr
);
TYPELIB_DANGER_RELEASE
(
pParamTypeDescr
);
}
}
...
@@ -232,26 +295,14 @@ static void cpp_call(
...
@@ -232,26 +295,14 @@ static void cpp_call(
// destroy temp cpp param => cpp: every param was constructed
// destroy temp cpp param => cpp: every param was constructed
uno_destructData
(
pCppArgs
[
nIndex
],
ppTempParamTypeDescr
[
nTempIndizes
],
cpp_release
);
uno_destructData
(
pCppArgs
[
nIndex
],
ppTempParamTypeDescr
[
nTempIndizes
],
cpp_release
);
TYPELIB_DANGER_RELEASE
(
ppTempParamTypeDescr
[
nTempIndizes
]
);
TYPELIB_DANGER_RELEASE
(
ppTempParamTypeDescr
[
nTempIndizes
]
);
#ifdef BROKEN_ALLOCA
free
(
pCppArgs
[
nIndex
]
);
#endif
}
}
// return type
// return type
if
(
pReturnTypeDescr
)
if
(
pReturnTypeDescr
)
TYPELIB_DANGER_RELEASE
(
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
{
namespace
bridges
{
namespace
cpp_uno
{
namespace
shared
{
...
@@ -262,16 +313,25 @@ void unoInterfaceProxyDispatch(
...
@@ -262,16 +313,25 @@ void unoInterfaceProxyDispatch(
// is my surrogate
// is my surrogate
bridges
::
cpp_uno
::
shared
::
UnoInterfaceProxy
*
pThis
bridges
::
cpp_uno
::
shared
::
UnoInterfaceProxy
*
pThis
=
static_cast
<
bridges
::
cpp_uno
::
shared
::
UnoInterfaceProxy
*
>
(
pUnoI
);
=
static_cast
<
bridges
::
cpp_uno
::
shared
::
UnoInterfaceProxy
*
>
(
pUnoI
);
#if OSL_DEBUG_LEVEL > 0
typelib_InterfaceTypeDescription
*
pTypeDescr
=
pThis
->
pTypeDescr
;
#endif
switch
(
pMemberDescr
->
eTypeClass
)
switch
(
pMemberDescr
->
eTypeClass
)
{
{
case
typelib_TypeClass_INTERFACE_ATTRIBUTE
:
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
(
VtableSlot
aVtableSlot
(
getVtableSlot
(
getVtableSlot
(
reinterpret_cast
<
reinterpret_cast
<
typelib_InterfaceAttributeTypeDescription
const
*
>
(
typelib_InterfaceAttributeTypeDescription
const
*
>
(
pMemberDescr
)));
pMemberDescr
)));
if
(
pReturn
)
if
(
pReturn
)
{
{
// dependent dispatch
// dependent dispatch
...
@@ -298,7 +358,7 @@ void unoInterfaceProxyDispatch(
...
@@ -298,7 +358,7 @@ void unoInterfaceProxyDispatch(
// dependent dispatch
// dependent dispatch
aVtableSlot
.
index
+=
1
;
// get, then set method
aVtableSlot
.
index
+=
1
;
// get, then set method
cpp_call
(
cpp_call
(
pThis
,
aVtableSlot
,
pThis
,
aVtableSlot
,
// get, then set method
pReturnTypeRef
,
pReturnTypeRef
,
1
,
&
aParam
,
1
,
&
aParam
,
pReturn
,
pArgs
,
ppException
);
pReturn
,
pArgs
,
ppException
);
...
@@ -310,11 +370,17 @@ void unoInterfaceProxyDispatch(
...
@@ -310,11 +370,17 @@ void unoInterfaceProxyDispatch(
}
}
case
typelib_TypeClass_INTERFACE_METHOD
:
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
(
VtableSlot
aVtableSlot
(
getVtableSlot
(
getVtableSlot
(
reinterpret_cast
<
reinterpret_cast
<
typelib_InterfaceMethodTypeDescription
const
*
>
(
typelib_InterfaceMethodTypeDescription
const
*
>
(
pMemberDescr
)));
pMemberDescr
)));
switch
(
aVtableSlot
.
index
)
switch
(
aVtableSlot
.
index
)
{
{
// standard calls
// standard calls
...
@@ -333,8 +399,8 @@ void unoInterfaceProxyDispatch(
...
@@ -333,8 +399,8 @@ void unoInterfaceProxyDispatch(
if
(
pTD
)
if
(
pTD
)
{
{
uno_Interface
*
pInterface
=
0
;
uno_Interface
*
pInterface
=
0
;
(
*
pThis
->
pBridge
->
getUnoEnv
()
->
getRegisteredInterface
)(
(
*
pThis
->
getBridge
()
->
getUnoEnv
()
->
getRegisteredInterface
)(
pThis
->
pBridge
->
getUnoEnv
(),
pThis
->
getBridge
()
->
getUnoEnv
(),
(
void
**
)
&
pInterface
,
pThis
->
oid
.
pData
,
(
typelib_InterfaceTypeDescription
*
)
pTD
);
(
void
**
)
&
pInterface
,
pThis
->
oid
.
pData
,
(
typelib_InterfaceTypeDescription
*
)
pTD
);
if
(
pInterface
)
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