[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 @@
break;
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);
+#endif
break;
case ArgNone:
break;
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.
-bill
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