Skip to content

Instantly share code, notes, and snippets.

@nanase
Created August 14, 2015 20:17
Show Gist options
  • Save nanase/42e480a17f7fdd6dcb23 to your computer and use it in GitHub Desktop.
Save nanase/42e480a17f7fdd6dcb23 to your computer and use it in GitHub Desktop.
LLVMSharpを使って、LLVMからC#のコードを動的に呼び出す。
using System;
using System.Runtime.InteropServices;
using LLVMSharp;
namespace LLVMSharp_Test
{
class Program
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ActType();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void FuncType();
public static void Act()
{
Console.WriteLine("[C#] Hello world! : {0}", 42);
}
private static void InitializeJIT(out LLVMExecutionEngineRef engine, LLVMModuleRef module, out IntPtr error)
{
LLVM.LinkInMCJIT();
LLVM.InitializeX86Target();
LLVM.InitializeX86TargetInfo();
LLVM.InitializeX86TargetMC();
LLVM.InitializeX86AsmPrinter();
if (Environment.OSVersion.Platform == PlatformID.Win32NT) // On Windows, LLVM currently (3.6) does not support PE/COFF
LLVM.SetTarget(module, Marshal.PtrToStringAnsi(LLVM.GetDefaultTargetTriple()) + "-elf");
var options = new LLVMMCJITCompilerOptions();
var optionsSize = (4 * sizeof(int)) + IntPtr.Size; // LLVMMCJITCompilerOptions has 4 ints and a pointer
LLVM.InitializeMCJITCompilerOptions(out options, optionsSize);
LLVM.CreateMCJITCompilerForModule(out engine, module, out options, optionsSize, out error);
}
public static void Main(string[] args)
{
ActType act_ref = Act;
IntPtr act_pointer = Marshal.GetFunctionPointerForDelegate(act_ref);
var False = new LLVMBool(0);
var True = new LLVMBool(1);
var context = LLVM.ContextCreate();
LLVMExecutionEngineRef engine;
IntPtr error;
var module = LLVM.ModuleCreateWithNameInContext("LLVMTest", context);
var builder = LLVM.CreateBuilderInContext(context);
InitializeJIT(out engine, module, out error);
var int32Type = LLVM.Int32TypeInContext(context);
var voidType = LLVM.VoidTypeInContext(context);
var voidFuncType = LLVM.FunctionType(voidType, new LLVMTypeRef[0], False);
var pointerType = LLVM.PointerType(voidFuncType, 0);
LLVMTypeRef[] param_types = { voidType };
var ret_type = LLVM.FunctionType(voidType, out param_types[0], 0, False);
var entry_func = LLVM.AddFunction(module, "func", ret_type);
var entry = LLVM.AppendBasicBlock(entry_func, "entry");
LLVM.PositionBuilderAtEnd(builder, entry);
{
var v1 = LLVM.BuildAlloca(builder, int32Type, "1");
LLVM.SetAlignment(v1, 4);
var func = LLVM.BuildAlloca(builder, pointerType, "func");
LLVM.SetAlignment(func, 8);
LLVM.BuildStore(builder, LLVM.ConstInt(int32Type, 0, False), v1);
var store = LLVM.BuildStore(builder,
LLVM.ConstIntToPtr(LLVM.ConstInt(int32Type, (ulong)act_pointer.ToInt32(), False), pointerType),
func);
LLVM.SetAlignment(store, 8);
var v2 = LLVM.BuildLoad(builder, func, "2");
LLVM.SetAlignment(v2, 8);
LLVMValueRef[] act_func_vals = { LLVM.ConstInt(int32Type, 42, False) };
LLVM.BuildCall(builder, v2, out act_func_vals[0], 0, "");
LLVM.BuildRetVoid(builder);
}
// {
// var passManager = LLVM.CreatePassManager ();
// var pmbuilder = LLVM.PassManagerBuilderCreate ();
// LLVM.PassManagerBuilderSetOptLevel (pmbuilder, 0);
// LLVM.PassManagerBuilderSetSizeLevel (pmbuilder, 0);
// LLVM.PassManagerBuilderSetDisableUnitAtATime (pmbuilder, False);
// LLVM.PassManagerBuilderSetDisableUnrollLoops (pmbuilder, False);
// LLVM.PassManagerBuilderPopulateModulePassManager (pmbuilder, passManager);
// LLVM.RunPassManager (passManager, module);
// LLVM.PassManagerBuilderDispose (pmbuilder);
// }
//
LLVM.VerifyModule(module, LLVMVerifierFailureAction.LLVMAbortProcessAction, out error);
LLVM.DisposeMessage(error);
LLVM.DumpModule(module);
var funcMethod = (FuncType)Marshal.GetDelegateForFunctionPointer(LLVM.GetPointerToGlobal(engine, entry_func), typeof(FuncType));
{
funcMethod();
}
if (LLVM.WriteBitcodeToFile(module, "func.bc") != 0)
Console.WriteLine("error writing bitcode to file, skipping");
LLVM.DisposeBuilder(builder);
LLVM.DisposeExecutionEngine(engine);
Console.ReadLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment