{
MonoError error;
MonoInst *ins, **sp, **stack_start;
- MonoBasicBlock *tblock = NULL, *init_localsbb = NULL;
+ MonoBasicBlock *tblock = NULL;
+ MonoBasicBlock *init_localsbb = NULL, *init_localsbb2 = NULL;
MonoSimpleBasicBlock *bb = NULL, *original_bb = NULL;
MonoMethod *cmethod, *method_definition;
MonoInst **arg_array;
init_localsbb->next_bb = cfg->cbb;
link_bblock (cfg, start_bblock, init_localsbb);
link_bblock (cfg, init_localsbb, cfg->cbb);
-
+ init_localsbb2 = init_localsbb;
cfg->cbb = init_localsbb;
if (cfg->gsharedvt && cfg->method == method) {
if (next_bb)
MONO_START_BB (cfg, next_bb);
+ /*
+ * Parts of the initlocals code needs to come after this, since it might call methods like memset.
+ */
+ init_localsbb2 = cfg->cbb;
+ NEW_BBLOCK (cfg, next_bb);
+ MONO_START_BB (cfg, next_bb);
+
ip += 2;
break;
}
cfg->cbb = init_localsbb;
cfg->ip = NULL;
for (i = 0; i < header->num_locals; ++i) {
+ /*
+ * Vtype initialization might need to be done after CEE_JIT_ATTACH, since it can make calls to memset (),
+ * which need the trampoline code to work.
+ */
+ if (MONO_TYPE_ISSTRUCT (header->locals [i]))
+ cfg->cbb = init_localsbb2;
+ else
+ cfg->cbb = init_localsbb;
emit_init_local (cfg, i, header->locals [i], init_locals);
}
}
#endif
}
+typedef struct {
+ char arr [4 * 1024];
+} LargeStruct;
+
+typedef int (STDCALL *LargeStructDelegate) (LargeStruct *s);
+
+static void
+call_managed_large_vt (gpointer arg)
+{
+ LargeStructDelegate del = (LargeStructDelegate)arg;
+ LargeStruct s;
+
+ call_managed_res = del (&s);
+}
+
+LIBTEST_API int STDCALL
+mono_test_marshal_thread_attach_large_vt (SimpleDelegate del)
+{
+#ifdef WIN32
+ return 43;
+#else
+ int res;
+ pthread_t t;
+
+ res = pthread_create (&t, NULL, (gpointer (*)(gpointer))call_managed_large_vt, del);
+ g_assert (res == 0);
+ pthread_join (t, NULL);
+
+ return call_managed_res;
+#endif
+}
+
typedef int (STDCALL *Callback) (void);
static Callback callback;
return res;
}
+ public struct LargeStruct {
+ public Int16 s;
+ public Int16 v;
+ public UInt32 p;
+ public UInt32 e;
+ public Int32 l;
+ public Int32 ll;
+ public UInt16 h;
+ public Int16 r;
+ public Int16 pp;
+ public Int32 hh;
+ public Int32 bn;
+ public Int32 dn;
+ public Int32 dr;
+ public Int32 sh;
+ public Int32 ra;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
+ public Int32[] angle;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
+ public Int32[] width;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
+ public Int32[] edge;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3 * 1024)]
+ public byte[] echo;
+ }
+
+ public delegate int LargeStructDelegate (ref LargeStruct s);
+
+ [DllImport ("libtest", EntryPoint="mono_test_marshal_thread_attach_large_vt")]
+ public static extern int mono_test_marshal_thread_attach_large_vt (LargeStructDelegate d);
+
+ public static int test_43_thread_attach_large_vt () {
+ int res = mono_test_marshal_thread_attach_large_vt (delegate (ref LargeStruct s) {
+ return 43;
+ });
+ return res;
+ }
+
class Worker {
volatile bool stop = false;
public void Stop () {