因此,使用ANTLR4& amp; LLVMSharp。尝试使用marshal函数添加2个双精度,并且应用程序仅在调试模式下崩溃(可能的堆栈损坏?)IR为以下示例生成。编组整数作为参数时没有问题。
define double @main(double %x, double %y) #0 {
entry:
%tmp = fadd double %x, %y
ret double %tmp
}
错误如下所示。
Managed Debugging Assistant 'FatalExecutionEngineError'
The runtime has encountered a fatal error. The address of the error was at 0x737e17cf, on thread 0x299c. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshalling errors for COM-interop or PInvoke, which may corrupt the stack.
编组代码如下所示
LLVMBool success = new LLVMBool(0);
LLVMModuleRef module = LLVM.ModuleCreateWithName("LLVMSharpIntro");
LLVMTypeRef[] param_types = { LLVM.DoubleType(), LLVM.DoubleType() };
LLVMTypeRef ret_type = LLVM.FunctionType(LLVM.DoubleType(), param_types, false);
LLVMValueRef sum = LLVM.AddFunction(module, "main", ret_type);
LLVMBasicBlockRef entry = LLVM.AppendBasicBlock(sum, "entry");
LLVMBuilderRef builder = LLVM.CreateBuilder();
LLVM.PositionBuilderAtEnd(builder, entry);
LLVMValueRef tmp = LLVM.BuildFAdd(builder, LLVM.GetParam(sum, 0), LLVM.GetParam(sum, 1), "tmp");
LLVM.BuildRet(builder, tmp);
if(LLVM.VerifyModule(module,LLVMVerifierFailureAction.LLVMPrintMessageAction, out var error) != success)
{
Console.WriteLine($"Error: {error}");
}
LLVM.LinkInMCJIT();
LLVM.InitializeX86TargetMC();
LLVM.InitializeX86Target();
LLVM.InitializeX86TargetInfo();
LLVM.InitializeX86AsmParser();
LLVM.InitializeX86AsmPrinter();
LLVMMCJITCompilerOptions options = new LLVMMCJITCompilerOptions { NoFramePointerElim = 1 };
LLVM.InitializeMCJITCompilerOptions(options);
if (LLVM.CreateExecutionEngineForModule(out var engine, module, out error) != success)
{
Console.WriteLine($"Error: {error}");
}
LLVM.DumpModule(module);
var addMethod = Marshal.GetDelegateForFunctionPointer<FloatingPoint>(LLVM.GetPointerToGlobal(engine, sum));
GC.KeepAlive(addMethod);
Console.WriteLine(addMethod(6.0, 2.0));
编辑:找到解决方案,你必须在x64 cpu目标中运行C#项目,即使它是针对x86的。显然,调试器会以其他方式翻转。不要认为代码本身实际上有任何不正确的地方,在这些情况下调试器似乎无法很好地处理非托管函数。