[Mono-dev] [PATCH] Win32 pinvoke3 runtime tests fixes

Bill Holmes billholmes54 at gmail.com
Mon Jul 28 16:36:13 EDT 2008

Hello All,

I am sending an update to this patch since there have been some
discussion since the original posting.

The 2 changes since the previous patch are in mono_arch_emit_epilog.

@@ -4186,6 +4192,11 @@

+	if (MONO_TYPE_ISSTRUCT (mono_method_signature (cfg->method)->ret) &&
(cinfo->ret.storage == ArgOnStack) && (cfg->vret_addr)) {
+		/* When return structs are passed on the stack the address needs to
be stored in eax. */
+		x86_mov_reg_membase (code, X86_EAX, cfg->vret_addr->sreg1,
cfg->vret_addr->inst_offset, sizeof (gpointer));
+	}
 	x86_leave (code);

 	if (CALLCONV_IS_STDCALL (sig)) {

It was brought to my attention on IRC that the address of the return
struct needs to be in the return register for more platforms than just
Win32.   I removed the 'if Win32' preprocessor check so that this
occurs on all platforms.

@@ -4177,6 +4177,12 @@
 			case ArgOnDoubleFpStack:
 				x86_fld_membase (code, cfg->ret->inst_basereg,
cfg->ret->inst_offset + (quad * sizeof (gpointer)), TRUE);
+#ifdef PLATFORM_WIN32
+				/* Structs that contain only a double are stored spanning eax and edx. */
+				/* This is needed for calling methods that were compiled the MSVC
compiler. */
+				x86_mov_reg_membase (code, return_regs[0],
cfg->ret->inst_basereg, cfg->ret->inst_offset, 4);
+				x86_mov_reg_membase (code, return_regs[1],
cfg->ret->inst_basereg, cfg->ret->inst_offset + sizeof (gpointer), 4);
 			case ArgNone:

I found that this is a difference between the way the MSVC and the
Cygwin gcc compiler handle structs with doubles.  MS stores the double
across the 2 return registers while gcc uses the float registers.  I
am suggesting that for Windows we store the value in both locations as
we can not determine which compiler generated the method that we are
attempting to call.

I would also like to put this change into the branch as well.


On Thu, Jul 17, 2008 at 7:14 PM, Bill Holmes <billholmes54 at gmail.com> wrote:
> Hello All,
> I did some investigation on Win32 about why the pinvoke3 runtime test
> was failing.  What I found was a calling convention error in the test,
> and two struct marshaling bugs.
> For the calling convention problem I simply added a __stdcall
> statement in libtest.c to the function pointer declaration that was
> missing it.
> The two calling convention bugs I was able to handle in the epilog.
> See comments in patch for more detail.
> The final problem I found was similar to a problem I observed before
> when working on Winx64.  Zoltan fixed the problem with r104552 so I
> decided to take a chance and try that fix out for x86 and the problem
> went away.
> One last thing to point out is that this test does not even run on
> .NET.  Does this mean that Mono is better than .Net in this case?  ;)
> Unhandled Exception: System.Reflection.TargetInvocationException:
> Exception has been thrown by the target of an invocation. --->
> System.Runtime.InteropServices.MarshalDirectiveException: Method's
> type signature is not PInvoke compatible.
>   at Tests.mono_test_marshal_delegate2(SimpleDelegate2 d)
>   at Tests.test_0_marshal_struct_delegate()
>   --- End of inner exception stack trace ---
>   at System.RuntimeMethodHandle._InvokeMethodFast(Object target,
> Object[] arguments, SignatureStruct& sig, MethodAttributes
> methodAttributes, RuntimeTypeHandletypeOwner)
>   at System.RuntimeMethodHandle.InvokeMethodFast(Object target,
> Object[] arguments, Signature sig, MethodAttributes methodAttributes,
> RuntimeTypeHandle typeOwner)
>   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj,
> BindingFlags invokeAttr, Binder binder, Object[] parameters,
> CultureInfo culture, Boolean skipVisibilityChecks)
>   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj,
> BindingFlags invokeAttr, Binder binder, Object[] parameters,
> CultureInfo culture)
>   at TestDriver.RunTests(Type type, String[] args)
>   at TestDriver.RunTests(Type type)
>   at Tests.Main()
> -bill
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pinvoke3_08_07_28.diff
Type: application/octet-stream
Size: 1955 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20080728/c972c113/attachment.obj 

More information about the Mono-devel-list mailing list