LibreOffice Module bridges (master) 1
msvc_win32_intel/cpp2uno.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21#include <malloc.h>
22
23#include <com/sun/star/uno/genfunc.hxx>
24#include <sal/log.hxx>
25#include <uno/data.h>
26#include <typelib/typedescription.hxx>
27
28#include "bridge.hxx"
29#include "cppinterfaceproxy.hxx"
30#include "types.hxx"
31#include "vtablefactory.hxx"
32
33#include <msvc/x86.hxx>
34#include <msvc/cpp2uno.hxx>
35
36using namespace ::com::sun::star;
37
38namespace
39{
40
45static __declspec(naked) void __cdecl cpp_vtable_call()
46{
47__asm
48 {
49 sub esp, 8 // space for immediate return type
50 push esp
51 push edx // vtable offset
52 push eax // function index
53 mov eax, esp
54 add eax, 20
55 push eax // original stack ptr
56
57 call cpp_mediate
58 add esp, 16
59
60 cmp eax, typelib_TypeClass_FLOAT
61 je Lfloat
62 cmp eax, typelib_TypeClass_DOUBLE
63 je Ldouble
64 cmp eax, typelib_TypeClass_HYPER
65 je Lhyper
66 cmp eax, typelib_TypeClass_UNSIGNED_HYPER
67 je Lhyper
68 // rest is eax
69 pop eax
70 add esp, 4
71 ret
72Lhyper:
73 pop eax
74 pop edx
75 ret
76Lfloat:
77 fld dword ptr [esp]
78 add esp, 8
79 ret
80Ldouble:
81 fld qword ptr [esp]
82 add esp, 8
83 ret
84 }
85}
86
87int const codeSnippetSize = 16;
88
89unsigned char * codeSnippet(
90 unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset)
91{
92 unsigned char * p = code;
93 static_assert(sizeof (sal_Int32) == 4, "boo");
94 // mov eax, functionIndex:
95 *p++ = 0xB8;
96 *reinterpret_cast< sal_Int32 * >(p) = functionIndex;
97 p += sizeof (sal_Int32);
98 // mov edx, vtableOffset:
99 *p++ = 0xBA;
100 *reinterpret_cast< sal_Int32 * >(p) = vtableOffset;
101 p += sizeof (sal_Int32);
102 // jmp rel32 cpp_vtable_call:
103 *p++ = 0xE9;
104 *reinterpret_cast< sal_Int32 * >(p)
105 = ((unsigned char *) cpp_vtable_call) - p - sizeof (sal_Int32);
106 p += sizeof (sal_Int32);
107 assert(p - code <= codeSnippetSize);
108 return code + codeSnippetSize;
109}
110
111}
112
114
117{
118 return static_cast< Slot * >(block) + 1;
119}
120
122 sal_Int32 slotCount)
123{
124 return (slotCount + 1) * sizeof (Slot) + slotCount * codeSnippetSize;
125}
126
129 void * block, sal_Int32 slotCount, sal_Int32,
130 typelib_InterfaceTypeDescription *)
131{
132 struct Rtti {
133 sal_Int32 n0, n1, n2;
134 type_info * rtti;
135 Rtti():
136 n0(0), n1(0), n2(0),
137 rtti(RTTInfos::get("com.sun.star.uno.XInterface"))
138 {}
139 };
140 static Rtti rtti;
141
142 Slot * slots = mapBlockToVtable(block);
143 slots[-1].fn = &rtti;
144 return slots + slotCount;
145}
146
148 Slot ** slots, unsigned char * code,
149 typelib_InterfaceTypeDescription const *, sal_Int32 functionOffset,
150 sal_Int32 functionCount, sal_Int32 vtableOffset)
151{
152 (*slots) -= functionCount;
153 Slot * s = *slots;
154 for (sal_Int32 i = 0; i < functionCount; ++i) {
155 (s++)->fn = code;
156 code = codeSnippet(code, functionOffset++, vtableOffset);
157 }
158 return code;
159}
160
162 unsigned char const *,
163 unsigned char const *)
164{
165}
166
167/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static Slot * mapBlockToVtable(void *block)
Given a pointer to a block, turn it into a vtable pointer.
static void flushCode(unsigned char const *begin, unsigned char const *end)
Flush all the generated code snippets of a vtable, on platforms that require it.
static unsigned char * addLocalFunctions(Slot **slots, unsigned char *code, sal_PtrDiff writetoexecdiff, typelib_InterfaceTypeDescription const *type, sal_Int32 functionOffset, sal_Int32 functionCount, sal_Int32 vtableOffset)
Fill the vtable slots corresponding to all local (i.e., not inherited) functions of a given interface...
static Slot * initializeBlock(void *block, sal_Int32 slotCount, sal_Int32 vtableNumber, typelib_InterfaceTypeDescription *type)
Initialize a raw vtable block.
static std::size_t getBlockSize(sal_Int32 slotCount)
Calculate the size of a raw vtable block.
void cpp_vtable_call(sal_Int32 func, sal_Int32 offset, void **pStack)
is called on incoming vtable calls (called by asm snippets)
const int codeSnippetSize
static unsigned char * codeSnippet(unsigned char *code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, bool bHasHiddenParam)
void * p
int n2
int n1
typelib_TypeClass __cdecl cpp_mediate(void **pCallStack, const sal_Int32 nFunctionIndex, const sal_Int32 nVtableOffset, sal_Int64 *const pRegisterReturn)
static __declspec(naked) void copyConstruct()
int i
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
sal_Unicode code