[interp] properly pass 64bit integers to native code on 32bit arches
authorBernhard Urban <bernhard.urban@xamarin.com>
Wed, 17 May 2017 11:40:58 +0000 (13:40 +0200)
committerBernhard Urban <bernhard.urban@xamarin.com>
Wed, 17 May 2017 15:36:43 +0000 (17:36 +0200)
mono/mini/interp/interp-internals.h
mono/mini/interp/interp.c

index 692925187816f4a93216e88ced07b2036277fbfc..cc4cd237c677f3be75f9b93162979168aef28f7d 100644 (file)
@@ -39,6 +39,10 @@ typedef struct {
        union {
                gint32 i;
                gint64 l;
+               struct {
+                       gint32 lo;
+                       gint32 hi;
+               } pair;
                double f;
                /* native size integer and pointer types */
                gpointer p;
index cd652abc91a0986e3f2c2c0d171bf471422120e3..7b26797c9b3dd555038b3cbf3b958696cf81153d 100644 (file)
@@ -750,7 +750,12 @@ static InterpMethodArguments* build_args_from_sig (MonoMethodSignature *sig, Mon
                        break;
 #if SIZEOF_VOID_P == 4
                case MONO_TYPE_I8:
-                       g_assert (0);
+#ifdef TARGET_ARM
+                       /* pairs begin at even registers */
+                       if (margs->ilen & 1)
+                               margs->ilen++;
+#endif
+                       margs->ilen += 2;
                        break;
 #endif
                case MONO_TYPE_R4:
@@ -820,9 +825,22 @@ static InterpMethodArguments* build_args_from_sig (MonoMethodSignature *sig, Mon
                        int_i++;
                        break;
 #if SIZEOF_VOID_P == 4
-               case MONO_TYPE_I8:
-                       g_assert (0);
+               case MONO_TYPE_I8: {
+                       stackval *sarg = &frame->stack_args [i];
+#ifdef TARGET_ARM
+                       /* pairs begin at even registers */
+                       if (int_i & 1)
+                               int_i++;
+#endif
+                       margs->iargs [int_i] = (gpointer) sarg->data.pair.lo;
+                       int_i++;
+                       margs->iargs [int_i] = (gpointer) sarg->data.pair.hi;
+#if DEBUG_INTERP
+                       g_print ("build_args_from_sig: margs->iargs [%d/%d]: 0x%016llx, hi=0x%08x lo=0x%08x (frame @ %d)\n", int_i - 1, int_i, *((guint64 *) &margs->iargs [int_i - 1]), sarg->data.pair.hi, sarg->data.pair.lo, i);
+#endif
+                       int_i++;
                        break;
+               }
 #endif
                case MONO_TYPE_R4:
                case MONO_TYPE_R8: