Closed kaby76 closed 7 years ago
An analysis shows that the code from SharpLLVM may have worked, but was kludgy because it used a function that converted a char to a long pointer on the stack. Consider LLVMVerifyModule(). ` SWIGEXPORT unsigned int SWIGSTDCALL CSharp_VerifyModule(void jarg1, int jarg2, void * jarg3) { unsigned int jresult ; LLVMModuleRef arg1 ; LLVMVerifierFailureAction arg2 ; char arg3 = (char ) 0 ; LLVMBool result;
arg1 = (LLVMModuleRef)jarg1; arg2 = (LLVMVerifierFailureAction)jarg2; arg3 = (char **)jarg3; result = (LLVMBool)LLVMVerifyModule(arg1,arg2,arg3); jresult = result;
if (arg3 != NULL) arg3 = SWIG_csharp_string_callback(*arg3);
return jresult;
}
We see in this code a call to SWIG_csharp_string_callback. Further, over in the C# side, the code looks like this:
[global::System.Runtime.InteropServices.DllImport("SharpLLVM.Native.dll", EntryPoint="CSharp_VerifyModule")]
public static extern bool VerifyModule(System.IntPtr jarg1, int jarg2, [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)]out string jarg3);
and
public unsafe static bool VerifyModule(ModuleRef M, VerifierFailureAction Action, out string OutMessage) {
bool ret = LLVMPINVOKE.VerifyModule(M.Value, (int)Action, out OutMessage);
return ret;
}
`
Instead, following up on the other Swig-generated data types like ModuleRef, I will introduce a "MyString" type that is similar, but not generated.
Fixed in upcoming 4.0.6-alpha release.
Apparently, the definition created by Swig for the wrapper of LLVMVerifyModule is:
public static extern bool VerifyModule(System.IntPtr jarg1, int jarg2, [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)]out string jarg3);
This does not work! Upon return from the Pinvoke call, the heap is corrupted. This is a left over from SharpLang, and I suspect it never worked. This must be fixed. For now, a work around is to edit the generated code to not write to jarg3, but the out string will never be set.