예제 #1
0
        /// <summary>
        /// Defines the global variable that backs a vtable.
        /// </summary>
        /// <param name="Module">The module to declare the global in.</param>
        /// <param name="Type">The type that owns the vtable.</param>
        /// <param name="VTableEntryImpls">
        /// The list of virtual function pointers in the vtable.
        /// </param>
        /// <returns>A vtable global variable.</returns>
        public static LLVMValueRef DefineVTableGlobal(
            LLVMModuleBuilder Module,
            IType Type,
            LLVMValueRef[] VTableEntryImpls)
        {
            var fields = new LLVMValueRef[3];

            fields[0] = ConstInt(Int64Type(), Module.GetTypeId(Type), false);
            fields[1] = ConstInt(Int64Type(), Module.GetTypeIndex(Type), false);
            fields[2] = ConstArray(
                PointerType(Int8Type(), 0),
                VTableEntryImpls);
            var vtableContents = ConstStruct(fields, false);
            var vtable         = Module.DeclareGlobal(
                vtableContents.TypeOf(),
                Type.FullName.ToString() + ".vtable");

            vtable.SetGlobalConstant(true);
            vtable.SetLinkage(LLVMLinkage.LLVMInternalLinkage);
            vtable.SetInitializer(vtableContents);
            return(vtable);
        }
예제 #2
0
        /// <summary>
        /// Defines this stub's body.
        /// </summary>
        /// <param name="Module">The module that defines the stub.</param>
        public void Emit(LLVMModuleBuilder Module)
        {
            var entryBlock = AppendBasicBlock(Function, "entry");

            var defaultBlock = AppendBasicBlock(Function, "unknown_type");
            var builder      = CreateBuilder();

            PositionBuilderAtEnd(builder, defaultBlock);
            BuildUnreachable(builder);
            DisposeBuilder(builder);

            builder = CreateBuilder();
            PositionBuilderAtEnd(builder, entryBlock);
            var switchInstr = BuildSwitch(builder, GetParam(Function, 0), defaultBlock, (uint)impls.Count);

            foreach (var pair in impls)
            {
                switchInstr.AddCase(
                    ConstInt(Int64Type(), (ulong)Module.GetTypeIndex(pair.Key), false),
                    WriteReturnBlock(pair.Key, pair.Value, Module));
            }
            DisposeBuilder(builder);
        }