xref: /AOO41X/main/bridges/source/cpp_uno/shared/vtablefactory.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_bridges.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #if defined OS2
32*cdf0e10cSrcweir #define INCL_DOS
33*cdf0e10cSrcweir #define INCL_DOSMISC
34*cdf0e10cSrcweir #endif
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir #include "bridges/cpp_uno/shared/vtablefactory.hxx"
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir #include "guardedarray.hxx"
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir #include "bridges/cpp_uno/shared/vtables.hxx"
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #include "osl/thread.h"
43*cdf0e10cSrcweir #include "osl/security.hxx"
44*cdf0e10cSrcweir #include "osl/file.hxx"
45*cdf0e10cSrcweir #include "osl/diagnose.h"
46*cdf0e10cSrcweir #include "osl/mutex.hxx"
47*cdf0e10cSrcweir #include "rtl/alloc.h"
48*cdf0e10cSrcweir #include "rtl/ustring.hxx"
49*cdf0e10cSrcweir #include "sal/types.h"
50*cdf0e10cSrcweir #include "typelib/typedescription.hxx"
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir #include <hash_map>
53*cdf0e10cSrcweir #include <new>
54*cdf0e10cSrcweir #include <vector>
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir #if defined SAL_UNX
57*cdf0e10cSrcweir #include <unistd.h>
58*cdf0e10cSrcweir #include <string.h>
59*cdf0e10cSrcweir #include <sys/mman.h>
60*cdf0e10cSrcweir #elif defined SAL_W32
61*cdf0e10cSrcweir #define WIN32_LEAN_AND_MEAN
62*cdf0e10cSrcweir #ifdef _MSC_VER
63*cdf0e10cSrcweir #pragma warning(push,1) // disable warnings within system headers
64*cdf0e10cSrcweir #endif
65*cdf0e10cSrcweir #include <windows.h>
66*cdf0e10cSrcweir #ifdef _MSC_VER
67*cdf0e10cSrcweir #pragma warning(pop)
68*cdf0e10cSrcweir #endif
69*cdf0e10cSrcweir #elif defined SAL_OS2
70*cdf0e10cSrcweir #define INCL_DOS
71*cdf0e10cSrcweir #define INCL_DOSMISC
72*cdf0e10cSrcweir #include <os2.h>
73*cdf0e10cSrcweir #else
74*cdf0e10cSrcweir #error Unsupported platform
75*cdf0e10cSrcweir #endif
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir using bridges::cpp_uno::shared::VtableFactory;
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir namespace {
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir extern "C" void * SAL_CALL allocExec(rtl_arena_type *, sal_Size * size) {
82*cdf0e10cSrcweir     sal_Size pagesize;
83*cdf0e10cSrcweir #if defined SAL_UNX
84*cdf0e10cSrcweir #if defined FREEBSD || defined NETBSD
85*cdf0e10cSrcweir     pagesize = getpagesize();
86*cdf0e10cSrcweir #else
87*cdf0e10cSrcweir     pagesize = sysconf(_SC_PAGESIZE);
88*cdf0e10cSrcweir #endif
89*cdf0e10cSrcweir #elif defined SAL_W32
90*cdf0e10cSrcweir     SYSTEM_INFO info;
91*cdf0e10cSrcweir     GetSystemInfo(&info);
92*cdf0e10cSrcweir     pagesize = info.dwPageSize;
93*cdf0e10cSrcweir #elif defined(SAL_OS2)
94*cdf0e10cSrcweir 	ULONG ulPageSize;
95*cdf0e10cSrcweir 	DosQuerySysInfo(QSV_PAGE_SIZE, QSV_PAGE_SIZE, &ulPageSize, sizeof(ULONG));
96*cdf0e10cSrcweir 	pagesize = (sal_Size)ulPageSize;
97*cdf0e10cSrcweir #else
98*cdf0e10cSrcweir #error Unsupported platform
99*cdf0e10cSrcweir #endif
100*cdf0e10cSrcweir     sal_Size n = (*size + (pagesize - 1)) & ~(pagesize - 1);
101*cdf0e10cSrcweir     void * p;
102*cdf0e10cSrcweir #if defined SAL_UNX
103*cdf0e10cSrcweir     p = mmap(
104*cdf0e10cSrcweir         0, n, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1,
105*cdf0e10cSrcweir         0);
106*cdf0e10cSrcweir     if (p == MAP_FAILED) {
107*cdf0e10cSrcweir         p = 0;
108*cdf0e10cSrcweir     }
109*cdf0e10cSrcweir 	else if (mprotect (static_cast<char*>(p), n, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
110*cdf0e10cSrcweir 	{
111*cdf0e10cSrcweir 		munmap (static_cast<char*>(p), n);
112*cdf0e10cSrcweir 		p = 0;
113*cdf0e10cSrcweir 	}
114*cdf0e10cSrcweir #elif defined SAL_W32
115*cdf0e10cSrcweir     p = VirtualAlloc(0, n, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
116*cdf0e10cSrcweir #elif defined(SAL_OS2)
117*cdf0e10cSrcweir     p = 0;
118*cdf0e10cSrcweir     DosAllocMem( &p, n, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_ANY);
119*cdf0e10cSrcweir #endif
120*cdf0e10cSrcweir     if (p != 0) {
121*cdf0e10cSrcweir         *size = n;
122*cdf0e10cSrcweir     }
123*cdf0e10cSrcweir     return p;
124*cdf0e10cSrcweir }
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir extern "C" void SAL_CALL freeExec(
127*cdf0e10cSrcweir     rtl_arena_type *, void * address, sal_Size size)
128*cdf0e10cSrcweir {
129*cdf0e10cSrcweir #if defined SAL_UNX
130*cdf0e10cSrcweir     munmap(static_cast< char * >(address), size);
131*cdf0e10cSrcweir #elif defined SAL_W32
132*cdf0e10cSrcweir     (void) size; // unused
133*cdf0e10cSrcweir     VirtualFree(address, 0, MEM_RELEASE);
134*cdf0e10cSrcweir #elif defined(SAL_OS2)
135*cdf0e10cSrcweir 	(void) DosFreeMem( address);
136*cdf0e10cSrcweir #endif
137*cdf0e10cSrcweir }
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir }
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir class VtableFactory::GuardedBlocks: public std::vector< Block > {
142*cdf0e10cSrcweir public:
143*cdf0e10cSrcweir     GuardedBlocks(VtableFactory const & factory):
144*cdf0e10cSrcweir         m_factory(factory), m_guarded(true) {}
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir     ~GuardedBlocks();
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir     void unguard() { m_guarded = false; }
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir private:
151*cdf0e10cSrcweir     GuardedBlocks(GuardedBlocks &); // not implemented
152*cdf0e10cSrcweir     void operator =(GuardedBlocks); // not implemented
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir     VtableFactory const & m_factory;
155*cdf0e10cSrcweir     bool m_guarded;
156*cdf0e10cSrcweir };
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir VtableFactory::GuardedBlocks::~GuardedBlocks() {
159*cdf0e10cSrcweir     if (m_guarded) {
160*cdf0e10cSrcweir         for (iterator i(begin()); i != end(); ++i) {
161*cdf0e10cSrcweir             m_factory.freeBlock(*i);
162*cdf0e10cSrcweir         }
163*cdf0e10cSrcweir     }
164*cdf0e10cSrcweir }
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir class VtableFactory::BaseOffset {
167*cdf0e10cSrcweir public:
168*cdf0e10cSrcweir     BaseOffset(typelib_InterfaceTypeDescription * type) { calculate(type, 0); }
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir     sal_Int32 getFunctionOffset(rtl::OUString const & name) const
171*cdf0e10cSrcweir     { return m_map.find(name)->second; }
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir private:
174*cdf0e10cSrcweir     sal_Int32 calculate(
175*cdf0e10cSrcweir         typelib_InterfaceTypeDescription * type, sal_Int32 offset);
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir     typedef std::hash_map< rtl::OUString, sal_Int32, rtl::OUStringHash > Map;
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir     Map m_map;
180*cdf0e10cSrcweir };
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir sal_Int32 VtableFactory::BaseOffset::calculate(
183*cdf0e10cSrcweir     typelib_InterfaceTypeDescription * type, sal_Int32 offset)
184*cdf0e10cSrcweir {
185*cdf0e10cSrcweir     rtl::OUString name(type->aBase.pTypeName);
186*cdf0e10cSrcweir     if (m_map.find(name) == m_map.end()) {
187*cdf0e10cSrcweir         for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
188*cdf0e10cSrcweir             offset = calculate(type->ppBaseTypes[i], offset);
189*cdf0e10cSrcweir         }
190*cdf0e10cSrcweir         m_map.insert(Map::value_type(name, offset));
191*cdf0e10cSrcweir         typelib_typedescription_complete(
192*cdf0e10cSrcweir             reinterpret_cast< typelib_TypeDescription ** >(&type));
193*cdf0e10cSrcweir         offset += bridges::cpp_uno::shared::getLocalFunctions(type);
194*cdf0e10cSrcweir     }
195*cdf0e10cSrcweir     return offset;
196*cdf0e10cSrcweir }
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir VtableFactory::VtableFactory(): m_arena(
199*cdf0e10cSrcweir     rtl_arena_create(
200*cdf0e10cSrcweir         "bridges::cpp_uno::shared::VtableFactory",
201*cdf0e10cSrcweir         sizeof (void *), // to satisfy alignment requirements
202*cdf0e10cSrcweir         0, reinterpret_cast< rtl_arena_type * >(-1), allocExec, freeExec, 0))
203*cdf0e10cSrcweir {
204*cdf0e10cSrcweir     if (m_arena == 0) {
205*cdf0e10cSrcweir         throw std::bad_alloc();
206*cdf0e10cSrcweir     }
207*cdf0e10cSrcweir }
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir VtableFactory::~VtableFactory() {
210*cdf0e10cSrcweir     {
211*cdf0e10cSrcweir         osl::MutexGuard guard(m_mutex);
212*cdf0e10cSrcweir         for (Map::iterator i(m_map.begin()); i != m_map.end(); ++i) {
213*cdf0e10cSrcweir             for (sal_Int32 j = 0; j < i->second.count; ++j) {
214*cdf0e10cSrcweir                 freeBlock(i->second.blocks[j]);
215*cdf0e10cSrcweir             }
216*cdf0e10cSrcweir             delete[] i->second.blocks;
217*cdf0e10cSrcweir         }
218*cdf0e10cSrcweir     }
219*cdf0e10cSrcweir     rtl_arena_destroy(m_arena);
220*cdf0e10cSrcweir }
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir VtableFactory::Vtables VtableFactory::getVtables(
223*cdf0e10cSrcweir     typelib_InterfaceTypeDescription * type)
224*cdf0e10cSrcweir {
225*cdf0e10cSrcweir     rtl::OUString name(type->aBase.pTypeName);
226*cdf0e10cSrcweir     osl::MutexGuard guard(m_mutex);
227*cdf0e10cSrcweir     Map::iterator i(m_map.find(name));
228*cdf0e10cSrcweir     if (i == m_map.end()) {
229*cdf0e10cSrcweir         GuardedBlocks blocks(*this);
230*cdf0e10cSrcweir         createVtables(blocks, BaseOffset(type), type, true);
231*cdf0e10cSrcweir         Vtables vtables;
232*cdf0e10cSrcweir         OSL_ASSERT(blocks.size() <= SAL_MAX_INT32);
233*cdf0e10cSrcweir         vtables.count = static_cast< sal_Int32 >(blocks.size());
234*cdf0e10cSrcweir         bridges::cpp_uno::shared::GuardedArray< Block > guardedBlocks(
235*cdf0e10cSrcweir             new Block[vtables.count]);
236*cdf0e10cSrcweir         vtables.blocks = guardedBlocks.get();
237*cdf0e10cSrcweir         for (sal_Int32 j = 0; j < vtables.count; ++j) {
238*cdf0e10cSrcweir             vtables.blocks[j] = blocks[j];
239*cdf0e10cSrcweir         }
240*cdf0e10cSrcweir         i = m_map.insert(Map::value_type(name, vtables)).first;
241*cdf0e10cSrcweir         guardedBlocks.release();
242*cdf0e10cSrcweir         blocks.unguard();
243*cdf0e10cSrcweir     }
244*cdf0e10cSrcweir     return i->second;
245*cdf0e10cSrcweir }
246*cdf0e10cSrcweir 
247*cdf0e10cSrcweir #ifdef USE_DOUBLE_MMAP
248*cdf0e10cSrcweir bool VtableFactory::createBlock(Block &block, sal_Int32 slotCount) const
249*cdf0e10cSrcweir {
250*cdf0e10cSrcweir     sal_Size size = getBlockSize(slotCount);
251*cdf0e10cSrcweir     sal_Size pagesize = sysconf(_SC_PAGESIZE);
252*cdf0e10cSrcweir     block.size = (size + (pagesize - 1)) & ~(pagesize - 1);
253*cdf0e10cSrcweir     block.start = block.exec = NULL;
254*cdf0e10cSrcweir     block.fd = -1;
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir     osl::Security aSecurity;
257*cdf0e10cSrcweir     rtl::OUString strDirectory;
258*cdf0e10cSrcweir     rtl::OUString strURLDirectory;
259*cdf0e10cSrcweir     if (aSecurity.getHomeDir(strURLDirectory))
260*cdf0e10cSrcweir         osl::File::getSystemPathFromFileURL(strURLDirectory, strDirectory);
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir     for (int i = strDirectory.getLength() == 0 ? 1 : 0; i < 2; ++i)
263*cdf0e10cSrcweir     {
264*cdf0e10cSrcweir         if (!strDirectory.getLength())
265*cdf0e10cSrcweir             strDirectory = rtl::OUString::createFromAscii("/tmp");
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir         strDirectory += rtl::OUString::createFromAscii("/.execoooXXXXXX");
268*cdf0e10cSrcweir         rtl::OString aTmpName = rtl::OUStringToOString(strDirectory, osl_getThreadTextEncoding());
269*cdf0e10cSrcweir         char *tmpfname = new char[aTmpName.getLength()+1];
270*cdf0e10cSrcweir         strncpy(tmpfname, aTmpName.getStr(), aTmpName.getLength()+1);
271*cdf0e10cSrcweir         if ((block.fd = mkstemp(tmpfname)) == -1)
272*cdf0e10cSrcweir             perror("creation of executable memory area failed");
273*cdf0e10cSrcweir         if (block.fd == -1)
274*cdf0e10cSrcweir         {
275*cdf0e10cSrcweir             delete[] tmpfname;
276*cdf0e10cSrcweir             break;
277*cdf0e10cSrcweir         }
278*cdf0e10cSrcweir         unlink(tmpfname);
279*cdf0e10cSrcweir         delete[] tmpfname;
280*cdf0e10cSrcweir         if (ftruncate(block.fd, block.size) == -1)
281*cdf0e10cSrcweir         {
282*cdf0e10cSrcweir             perror("truncation of executable memory area failed");
283*cdf0e10cSrcweir             close(block.fd);
284*cdf0e10cSrcweir             block.fd = -1;
285*cdf0e10cSrcweir             break;
286*cdf0e10cSrcweir         }
287*cdf0e10cSrcweir         block.start = mmap(NULL, block.size, PROT_READ | PROT_WRITE, MAP_SHARED, block.fd, 0);
288*cdf0e10cSrcweir         if (block.start== MAP_FAILED) {
289*cdf0e10cSrcweir             block.start = 0;
290*cdf0e10cSrcweir         }
291*cdf0e10cSrcweir         block.exec = mmap(NULL, block.size, PROT_READ | PROT_EXEC, MAP_SHARED, block.fd, 0);
292*cdf0e10cSrcweir         if (block.exec == MAP_FAILED) {
293*cdf0e10cSrcweir            block.exec = 0;
294*cdf0e10cSrcweir         }
295*cdf0e10cSrcweir 
296*cdf0e10cSrcweir         //All good
297*cdf0e10cSrcweir         if (block.start && block.exec && block.fd != -1)
298*cdf0e10cSrcweir             break;
299*cdf0e10cSrcweir 
300*cdf0e10cSrcweir         freeBlock(block);
301*cdf0e10cSrcweir 
302*cdf0e10cSrcweir         strDirectory = rtl::OUString();
303*cdf0e10cSrcweir     }
304*cdf0e10cSrcweir     if (!block.start || !block.exec || block.fd == -1)
305*cdf0e10cSrcweir     {
306*cdf0e10cSrcweir        //Fall back to non-doublemmaped allocation
307*cdf0e10cSrcweir        block.fd = -1;
308*cdf0e10cSrcweir        block.start = block.exec = rtl_arena_alloc(m_arena, &block.size);
309*cdf0e10cSrcweir     }
310*cdf0e10cSrcweir     return (block.start != 0 && block.exec != 0);
311*cdf0e10cSrcweir }
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir void VtableFactory::freeBlock(Block const & block) const {
314*cdf0e10cSrcweir     //if the double-map failed we were allocated on the arena
315*cdf0e10cSrcweir     if (block.fd == -1 && block.start == block.exec && block.start != NULL)
316*cdf0e10cSrcweir         rtl_arena_free(m_arena, block.start, block.size);
317*cdf0e10cSrcweir     else
318*cdf0e10cSrcweir     {
319*cdf0e10cSrcweir         if (block.start) munmap(block.start, block.size);
320*cdf0e10cSrcweir         if (block.exec) munmap(block.exec, block.size);
321*cdf0e10cSrcweir         if (block.fd != -1) close(block.fd);
322*cdf0e10cSrcweir     }
323*cdf0e10cSrcweir }
324*cdf0e10cSrcweir #else
325*cdf0e10cSrcweir bool VtableFactory::createBlock(Block &block, sal_Int32 slotCount) const
326*cdf0e10cSrcweir {
327*cdf0e10cSrcweir     block.size = getBlockSize(slotCount);
328*cdf0e10cSrcweir     block.start = rtl_arena_alloc(m_arena, &block.size);
329*cdf0e10cSrcweir     return block.start != 0;
330*cdf0e10cSrcweir }
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir void VtableFactory::freeBlock(Block const & block) const {
333*cdf0e10cSrcweir     rtl_arena_free(m_arena, block.start, block.size);
334*cdf0e10cSrcweir }
335*cdf0e10cSrcweir #endif
336*cdf0e10cSrcweir 
337*cdf0e10cSrcweir void VtableFactory::createVtables(
338*cdf0e10cSrcweir     GuardedBlocks & blocks, BaseOffset const & baseOffset,
339*cdf0e10cSrcweir     typelib_InterfaceTypeDescription * type, bool includePrimary) const
340*cdf0e10cSrcweir {
341*cdf0e10cSrcweir     if (includePrimary) {
342*cdf0e10cSrcweir         sal_Int32 slotCount
343*cdf0e10cSrcweir             = bridges::cpp_uno::shared::getPrimaryFunctions(type);
344*cdf0e10cSrcweir         Block block;
345*cdf0e10cSrcweir         if (!createBlock(block, slotCount)) {
346*cdf0e10cSrcweir             throw std::bad_alloc();
347*cdf0e10cSrcweir         }
348*cdf0e10cSrcweir         try {
349*cdf0e10cSrcweir             Slot * slots = initializeBlock(block.start, slotCount);
350*cdf0e10cSrcweir             unsigned char * codeBegin =
351*cdf0e10cSrcweir                 reinterpret_cast< unsigned char * >(slots);
352*cdf0e10cSrcweir             unsigned char * code = codeBegin;
353*cdf0e10cSrcweir             sal_Int32 vtableOffset = blocks.size() * sizeof (Slot *);
354*cdf0e10cSrcweir             for (typelib_InterfaceTypeDescription const * type2 = type;
355*cdf0e10cSrcweir                  type2 != 0; type2 = type2->pBaseTypeDescription)
356*cdf0e10cSrcweir             {
357*cdf0e10cSrcweir                 code = addLocalFunctions(
358*cdf0e10cSrcweir                     &slots, code,
359*cdf0e10cSrcweir #ifdef USE_DOUBLE_MMAP
360*cdf0e10cSrcweir                     sal_IntPtr(block.exec) - sal_IntPtr(block.start),
361*cdf0e10cSrcweir #endif
362*cdf0e10cSrcweir                     type2,
363*cdf0e10cSrcweir                     baseOffset.getFunctionOffset(type2->aBase.pTypeName),
364*cdf0e10cSrcweir                     bridges::cpp_uno::shared::getLocalFunctions(type2),
365*cdf0e10cSrcweir                     vtableOffset);
366*cdf0e10cSrcweir             }
367*cdf0e10cSrcweir             flushCode(codeBegin, code);
368*cdf0e10cSrcweir #ifdef USE_DOUBLE_MMAP
369*cdf0e10cSrcweir 	    //Finished generating block, swap writable pointer with executable
370*cdf0e10cSrcweir 	    //pointer
371*cdf0e10cSrcweir             ::std::swap(block.start, block.exec);
372*cdf0e10cSrcweir #endif
373*cdf0e10cSrcweir             blocks.push_back(block);
374*cdf0e10cSrcweir         } catch (...) {
375*cdf0e10cSrcweir             freeBlock(block);
376*cdf0e10cSrcweir             throw;
377*cdf0e10cSrcweir         }
378*cdf0e10cSrcweir     }
379*cdf0e10cSrcweir     for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
380*cdf0e10cSrcweir         createVtables(blocks, baseOffset, type->ppBaseTypes[i], i != 0);
381*cdf0e10cSrcweir     }
382*cdf0e10cSrcweir }
383