Итак, я учусь проектировать компилятор с использованием ANTLR4 & LLVMSharp. Попытка добавить 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));
Редактировать: Решение найдено, вы должны запустить проект C # в целевом процессоре x64, даже если он нацелен на x86. Видимо, отладчик отключается в противном случае. Не думайте, что на самом деле в самом коде есть что-то неправильное, просто неуправляемая функция, похоже, не обрабатывается отладчиком в таких ситуациях.