/**************************************************************
 * 
 * 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
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



#ifndef INCLUDED_BRIDGES_CPP_UNO_SHARED_VTABLEFACTORY_HXX
#define INCLUDED_BRIDGES_CPP_UNO_SHARED_VTABLEFACTORY_HXX

#include "osl/mutex.hxx"
#include "rtl/alloc.h"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "typelib/typedescription.hxx"

#include <hash_map>

/*See: http://people.redhat.com/drepper/selinux-mem.html*/
#if defined (LINUX) || defined (FREEBSD)
#define USE_DOUBLE_MMAP
#endif

namespace bridges { namespace cpp_uno { namespace shared {

/** Hand out vtable structures for interface type descriptions.
 */
class VtableFactory {
public:
    // This structure is not defined in the generic part, but instead has to be
    // defined individually for each CPP--UNO bridge:
    /** A vtable slot.
     */
    struct Slot;

    /** A raw vtable block.
     */
    struct Block {
        /** The start of the raw vtable block.

            It points to the start of the allocated memory block, whereas the
            vtable pointer typically points some bytes into the block (e.g.,
            skipping an RTTI pointer, see mapBlockToVtable).  Also, the block
            contains any generated code snippets, after the vtable itself.
         */
        void * start;

#ifdef USE_DOUBLE_MMAP
	/** When seperately mmapping the block for writing and executing
            exec points to the same memory as start, except start is used
            exclusively for writing and exec for executing
         */
        void * exec;

	/** File handle for the underlying anonymous file
         */
        int fd;
#endif

        /** The size of the raw vtable block, in bytes.
         */
        sal_Size size;
    };

    /** The vtable structure corresponding to an interface type.
     */
    struct Vtables {
        /** The number of blocks/vtables.
         */
        sal_Int32 count;

        /** An array of blocks, representing the multiple vtables of a
            (multiple-inheritance) type.

            <p>A block is a raw vtable.  It points to the start of the allocated
            memory block, whereas the vtable pointer typically points some bytes
            into the block (e.g., skipping an RTTI pointer, see
            mapBlockToVtable).  Also, the block contains any generated code
            snippets, after the vtable itself.</p>
         */
        Block * blocks;
    };

    VtableFactory();

    ~VtableFactory();

    /** Given an interface type description, return its corresponding vtable
        structure.
     */
    Vtables getVtables(typelib_InterfaceTypeDescription * type);

    // This function is not defined in the generic part, but instead has to be
    // defined individually for each CPP--UNO bridge:
    /** Given a pointer to a block, turn it into a vtable pointer.
     */
    static Slot * mapBlockToVtable(void * block);

private:
    class GuardedBlocks;
    friend class GuardedBlocks;

    class BaseOffset;

    VtableFactory(VtableFactory &); // not implemented
    void operator =(VtableFactory); // not implemented

    bool createBlock(Block &block, sal_Int32 slotCount) const;

    void freeBlock(Block const & block) const;

    void createVtables(
        GuardedBlocks & blocks, BaseOffset const & baseOffset,
        typelib_InterfaceTypeDescription * type, bool includePrimary) const;

    // This function is not defined in the generic part, but instead has to be
    // defined individually for each CPP--UNO bridge:
    /** Calculate the size of a raw vtable block.

        @param slotCount  the number of virtual function slots the returned
        vtable block shall support (if there are any platform-specific slots,
        like an RTTI pointer, or a pointer to a destructor, they are not covered
        by slotCount)
        @return  the size of the raw vtable block, in bytes
     */
    static sal_Size getBlockSize(sal_Int32 slotCount);

    // This function is not defined in the generic part, but instead has to be
    // defined individually for each CPP--UNO bridge:
    /** Initialize a raw vtable block.

        @param block  the start address of the raw vtable block
        @param slotCount  the number of slots
        @return  a pointer past the last vtable slot
     */
    static Slot * initializeBlock(void * block, sal_Int32 slotCount);

    // This function is not defined in the generic part, but instead has to be
    // defined individually for each CPP--UNO bridge:
    /** Fill the vtable slots corresponding to all local (i.e., not inherited)
        functions of a given interface type (and generate any necessary code
        snippets for them).

        @param slots  on input, points past the vtable slot to be filled with
        the last virtual function local to the given type; on output, points to
        the vtable slot filled with the first virtual function local to the
        given type
        @param code  points to the start of the area where code snippets can be
        generated
        @param writetoexecdiff when the same code area is mmaped twice, once for
        writing for code-generation, and once for code-execution, then this
        records the offset from a writable address to its executable address
        @param type  the interface type description for which to generate vtable
        slots
        @param functionOffset  the function offset of the first vtable slot
        (typically coded into the code snippet for that vtable slot)
        @param functionCount  the number of vtable slots to fill (the number of
        local functions of the given type, passed in so that it need not be
        recomputed)
        @param vtableOffset  the offset of this vtable (needed to adjust the
        this pointer, typically coded into the code snippets for all the filled
        vtable slots)
        @return  a pointer to the remaining code snippet area
     */
    static unsigned char * addLocalFunctions(
        Slot ** slots, unsigned char * code,
#ifdef USE_DOUBLE_MMAP
        sal_PtrDiff writetoexecdiff,
#endif
        typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
        sal_Int32 functionCount, sal_Int32 vtableOffset);

    // This function is not defined in the generic part, but instead has to be
    // defined individually for each CPP--UNO bridge:
    /** Flush all the generated code snippets of a vtable, on platforms that
        require it.

        @param begin  points to the start of the code snippet area
        @param end  points behind the end of the code snippet area
     */
    static void flushCode(
        unsigned char const * begin, unsigned char const * end);

    typedef std::hash_map< rtl::OUString, Vtables, rtl::OUStringHash > Map;

    osl::Mutex m_mutex;
    Map m_map;

    rtl_arena_type * m_arena;
};

} } }

#endif
