Add a new 'MONO_DEBUGGER_EVENT_TRAMPOLINE' notification for the debugger which also...
[mono.git] / mono / metadata / marshal.c
index fac7cb83b23e6ba1f4928c9ea68dec2a2b2f10f2..ea59d1fdb71593b47c00747bea29f32ce50677ad 100644 (file)
@@ -101,6 +101,9 @@ mono_string_to_lpstr (MonoString *string_obj);
 static MonoStringBuilder *
 mono_string_utf8_to_builder2 (char *text);
 
+static MonoStringBuilder *
+mono_string_utf16_to_builder2 (gunichar2 *text);
+
 static void
 mono_byvalarray_to_array (MonoArray *arr, gpointer native_arr, MonoClass *eltype, guint32 elnum);
 
@@ -116,9 +119,6 @@ mono_delegate_begin_invoke (MonoDelegate *delegate, gpointer *params);
 static MonoObject *
 mono_delegate_end_invoke (MonoDelegate *delegate, gpointer *params);
 
-static MonoObject *
-mono_marshal_xdomain_copy_value (MonoObject *val);
-
 static void
 mono_marshal_xdomain_copy_out_value (MonoObject *src, MonoObject *dst);
 
@@ -227,6 +227,7 @@ mono_marshal_init (void)
                register_icall (mono_string_utf8_to_builder, "mono_string_utf8_to_builder", "void ptr ptr", FALSE);
                register_icall (mono_string_utf8_to_builder2, "mono_string_utf8_to_builder2", "object ptr", FALSE);
                register_icall (mono_string_utf16_to_builder, "mono_string_utf16_to_builder", "void ptr ptr", FALSE);
+               register_icall (mono_string_utf16_to_builder2, "mono_string_utf16_to_builder2", "object ptr", FALSE);
                register_icall (mono_marshal_free_array, "mono_marshal_free_array", "void ptr int32", FALSE);
                register_icall (mono_string_to_byvalstr, "mono_string_to_byvalstr", "void ptr ptr int32", FALSE);
                register_icall (mono_string_to_byvalwstr, "mono_string_to_byvalwstr", "void ptr ptr int32", FALSE);
@@ -554,6 +555,7 @@ mono_array_to_lparray (MonoArray *array)
 
        if (!array)
                return NULL;
+#ifndef DISABLE_COM
 
        klass = array->obj.vtable->klass;
 
@@ -594,13 +596,14 @@ mono_array_to_lparray (MonoArray *array)
                g_warning ("type 0x%x not handled", klass->element_class->byval_arg.type);
                g_assert_not_reached ();
        }
-
+#endif
        return array->vector;
 }
 
 void
 mono_free_lparray (MonoArray *array, gpointer* nativeArray)
 {
+#ifndef DISABLE_COM
        MonoClass *klass;
        int i = 0;
 
@@ -609,7 +612,6 @@ mono_free_lparray (MonoArray *array, gpointer* nativeArray)
 
        if (!nativeArray)
                return;
-
        klass = array->obj.vtable->klass;
 
        switch (klass->element_class->byval_arg.type) {
@@ -619,6 +621,7 @@ mono_free_lparray (MonoArray *array, gpointer* nativeArray)
                        free(nativeArray);
                break;
        }               
+#endif
 }
 
 static void
@@ -756,6 +759,45 @@ mono_string_utf16_to_builder (MonoStringBuilder *sb, gunichar2 *text)
        sb->length = len;
 }
 
+MonoStringBuilder *
+mono_string_utf16_to_builder2 (gunichar2 *text)
+{
+       int len;
+       MonoStringBuilder *sb;
+       static MonoClass *string_builder_class;
+       static MonoMethod *sb_ctor;
+       void *args [1];
+       MonoObject *exc;
+
+       if (!text)
+               return NULL;
+
+       if (!string_builder_class) {
+               MonoMethodDesc *desc;
+
+               string_builder_class = mono_class_from_name (mono_defaults.corlib, "System.Text", "StringBuilder");
+               g_assert (string_builder_class);
+               desc = mono_method_desc_new (":.ctor(int)", FALSE);
+               sb_ctor = mono_method_desc_search_in_class (desc, string_builder_class);
+               g_assert (sb_ctor);
+               mono_method_desc_free (desc);
+       }
+
+       for (len = 0; text [len] != 0; ++len)
+               ;
+
+       sb = (MonoStringBuilder*)mono_object_new (mono_domain_get (), string_builder_class);
+       g_assert (sb);
+       args [0] = &len;
+       mono_runtime_invoke (sb_ctor, sb, args, &exc);
+       g_assert (!exc);
+
+       sb->length = len;
+       memcpy (mono_string_chars (sb->str), text, len * 2);
+
+       return sb;
+}
+
 /**
  * mono_string_builder_to_utf8:
  * @sb: the string builder
@@ -1362,9 +1404,13 @@ emit_ptr_to_object_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv
        case MONO_MARSHAL_CONV_STR_ANSIBSTR:
        case MONO_MARSHAL_CONV_STR_TBSTR:
        case MONO_MARSHAL_CONV_ARRAY_SAVEARRAY:
-       default:
-               g_warning ("marshaling conversion %d not implemented", conv);
-               g_assert_not_reached ();
+       default: {
+               char *msg = g_strdup_printf ("marshaling conversion %d not implemented", conv);
+
+               mono_mb_emit_exception_marshal_directive (mb, msg);
+               g_free (msg);
+               break;
+       }
        }
 }
 
@@ -1696,7 +1742,7 @@ emit_object_to_ptr_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv
        default: {
                char *msg = g_strdup_printf ("marshalling conversion %d not implemented", conv);
                MonoException *exc = mono_get_exception_not_implemented (msg);
-               g_warning (msg);
+               g_warning ("%s", msg);
                g_free (msg);
                mono_raise_exception (exc);
        }
@@ -1731,6 +1777,15 @@ emit_struct_conv (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object)
                return;
        }
 
+       if (klass != mono_defaults.safehandle_class) {
+               if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT) {
+                       char *msg = g_strdup_printf ("Type %s which is passed to unmanaged code must have a StructLayout attribute.",
+                                                                                mono_type_full_name (&klass->byval_arg));
+                       mono_mb_emit_exception_marshal_directive (mb, msg);
+                       return;
+               }
+       }
+
        for (i = 0; i < info->num_fields; i++) {
                MonoMarshalNative ntype;
                MonoMarshalConv conv;
@@ -1765,11 +1820,6 @@ emit_struct_conv (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object)
                                                 "reference field at the same offset as another field.",
                                                 mono_type_full_name (&klass->byval_arg));
                        }
-                       
-                       if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT)
-                               g_error ("Type %s which is passed to unmanaged code must have a StructLayout attribute",
-                                        mono_type_full_name (&klass->byval_arg));
-                       
                }
                
                switch (conv) {
@@ -1981,19 +2031,19 @@ mono_delegate_begin_invoke (MonoDelegate *delegate, gpointer *params)
                        MonoAsyncResult *ares;
                        MonoObject *exc;
                        MonoArray *out_args;
-                       HANDLE handle;
                        method = delegate->method;
 
                        msg = mono_method_call_message_new (mono_marshal_method_from_wrapper (method), params, NULL, &async_callback, &state);
-                       handle = CreateEvent (NULL, TRUE, FALSE, NULL);
-                       g_assert(handle != NULL);
-                       ares = mono_async_result_new (mono_domain_get (), handle, state, handle, NULL);
+                       ares = mono_async_result_new (mono_domain_get (), NULL, state, NULL, NULL);
                        MONO_OBJECT_SETREF (ares, async_delegate, (MonoObject *)delegate);
                        MONO_OBJECT_SETREF (ares, async_callback, (MonoObject *)async_callback);
                        MONO_OBJECT_SETREF (msg, async_result, ares);
                        msg->call_type = CallType_BeginInvoke;
 
+                       exc = NULL;
                        mono_remoting_invoke ((MonoObject *)tp->rp, msg, &exc, &out_args);
+                       if (exc)
+                               mono_raise_exception ((MonoException *) exc);
                        return ares;
                }
        }
@@ -2471,8 +2521,10 @@ mono_delegate_end_invoke (MonoDelegate *delegate, gpointer *params)
        msg = mono_method_call_message_new (method, params, NULL, NULL, NULL);
 
        ares = mono_array_get (msg->args, gpointer, sig->param_count - 1);
-       if (ares == NULL)
+       if (ares == NULL) {
                mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System.Runtime.Remoting", "RemotingException", "The async result object is null or of an unexpected type."));
+               return NULL;
+       }
 
        if (ares->async_delegate != (MonoObject*)delegate && mono_framework_version () >= 2) {
                mono_raise_exception (mono_get_exception_invalid_operation (
@@ -2677,12 +2729,17 @@ mono_marshal_get_remoting_invoke (MonoMethod *method)
                return method;
 
        /* this seems to be the best plase to put this, as all remoting invokes seem to get filtered through here */
-       if ((method->klass->is_com_object || method->klass == mono_defaults.com_object_class) && !mono_class_vtable (mono_domain_get (), method->klass)->remote) {
+       if (method->klass->is_com_object || method->klass == mono_defaults.com_object_class) {
+               MonoVTable *vtable = mono_class_vtable (mono_domain_get (), method->klass);
+               g_assert (vtable); /*FIXME do proper error handling*/
+
+               if (!vtable->remote) {
 #ifndef DISABLE_COM
-               return mono_cominterop_get_invoke (method);
+                       return mono_cominterop_get_invoke (method);
 #else
-               g_assert_not_reached ();
+                       g_assert_not_reached ();
 #endif
+               }
        }
 
        sig = mono_signature_no_pinvoke (method);
@@ -2758,7 +2815,7 @@ mono_get_xdomain_marshal_type (MonoType *t)
 /* mono_marshal_xdomain_copy_value
  * Makes a copy of "val" suitable for the current domain.
  */
-static MonoObject *
+MonoObject *
 mono_marshal_xdomain_copy_value (MonoObject *val)
 {
        MonoDomain *domain;
@@ -3133,6 +3190,8 @@ mono_marshal_get_xappdomain_dispatch (MonoMethod *method, int *marshal_types, in
                        mono_mb_emit_ldloc (mb, loc_array);
                        mono_mb_emit_icon (mb, complex_count);  /* The array has an additional slot to hold the ret value */
                        mono_mb_emit_ldloc (mb, loc_return);
+
+                       g_assert (ret_class); /*FIXME properly fail here*/
                        if (ret_class->valuetype) {
                                mono_mb_emit_op (mb, CEE_BOX, ret_class);
                        }
@@ -3888,6 +3947,22 @@ add_string_ctor_signature (MonoMethod *method)
        return callsig;
 }
 
+/*
+ * mono_marshal_get_string_ctor_signature:
+ *
+ *   Return the modified signature used by string ctors (they return the newly created
+ * string).
+ */
+MonoMethodSignature*
+mono_marshal_get_string_ctor_signature (MonoMethod *method)
+{
+       MonoMethodSignature *sig = lookup_string_ctor_signature (mono_method_signature (method));
+       if (!sig)
+               sig = add_string_ctor_signature (method);
+
+       return sig;
+}
+
 static MonoType*
 get_runtime_invoke_type (MonoType *t, gboolean ret)
 {
@@ -4076,6 +4151,8 @@ mono_marshal_get_runtime_invoke (MonoMethod *method, gboolean virtual)
                         * Create a new signature to reflect this.
                         */
                        callsig = signature_dup_add_this (mono_method_signature (method), method->klass);
+                       /* Can't share this as it would be shared with static methods taking an IntPtr argument */
+                       need_direct_wrapper = TRUE;
                } else {
                        if (method->dynamic)
                                callsig = signature_dup (method->klass->image, mono_method_signature (method));
@@ -4432,6 +4509,127 @@ handle_enum:
        return res;     
 }
 
+/*
+ * mono_marshal_get_runtime_invoke_dynamic:
+ *
+ *   Return a method which can be used to invoke managed methods from native code
+ * dynamically.
+ * The signature of the returned method is given by RuntimeInvokeDynamicFunction:
+ * void runtime_invoke (void *args, MonoObject **exc, void *compiled_method)
+ * ARGS should point to an architecture specific structure containing 
+ * the arguments and space for the return value.
+ * The other arguments are the same as for runtime_invoke (), except that
+ * ARGS should contain the this argument too.
+ * This wrapper serves the same purpose as the runtime-invoke wrappers, but there
+ * is only one copy of it, which is useful in full-aot.
+ */
+MonoMethod*
+mono_marshal_get_runtime_invoke_dynamic (void)
+{
+       static MonoMethod *method;
+       MonoMethodSignature *csig;
+       MonoExceptionClause *clause;
+       MonoMethodBuilder *mb;
+       int pos, posna;
+       char *name;
+
+       if (method)
+               return method;
+
+       csig = mono_metadata_signature_alloc (mono_defaults.corlib, 4);
+
+       csig->ret = &mono_defaults.void_class->byval_arg;
+       csig->params [0] = &mono_defaults.int_class->byval_arg;
+       csig->params [1] = &mono_defaults.int_class->byval_arg;
+       csig->params [2] = &mono_defaults.int_class->byval_arg;
+       csig->params [3] = &mono_defaults.int_class->byval_arg;
+
+       name = g_strdup ("runtime_invoke_dynamic");
+       mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_RUNTIME_INVOKE);
+       g_free (name);
+
+       /* allocate local 0 (object) tmp */
+       mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
+       /* allocate local 1 (object) exc */
+       mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
+
+       /* cond set *exc to null */
+       mono_mb_emit_byte (mb, CEE_LDARG_1);
+       mono_mb_emit_byte (mb, CEE_BRFALSE_S);
+       mono_mb_emit_byte (mb, 3);      
+       mono_mb_emit_byte (mb, CEE_LDARG_1);
+       mono_mb_emit_byte (mb, CEE_LDNULL);
+       mono_mb_emit_byte (mb, CEE_STIND_REF);
+
+       emit_thread_force_interrupt_checkpoint (mb);
+
+       mono_mb_emit_byte (mb, CEE_LDARG_0);
+       mono_mb_emit_byte (mb, CEE_LDARG_2);
+       mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+       mono_mb_emit_byte (mb, CEE_MONO_DYN_CALL);
+
+       pos = mono_mb_emit_branch (mb, CEE_LEAVE);
+
+       clause = mono_image_alloc0 (mono_defaults.corlib, sizeof (MonoExceptionClause));
+       clause->flags = MONO_EXCEPTION_CLAUSE_FILTER;
+       clause->try_len = mono_mb_get_label (mb);
+
+       /* filter code */
+       clause->data.filter_offset = mono_mb_get_label (mb);
+       
+       mono_mb_emit_byte (mb, CEE_POP);
+       mono_mb_emit_byte (mb, CEE_LDARG_1);
+       mono_mb_emit_byte (mb, CEE_LDC_I4_0);
+       mono_mb_emit_byte (mb, CEE_PREFIX1);
+       mono_mb_emit_byte (mb, CEE_CGT_UN);
+       mono_mb_emit_byte (mb, CEE_PREFIX1);
+       mono_mb_emit_byte (mb, CEE_ENDFILTER);
+
+       clause->handler_offset = mono_mb_get_label (mb);
+
+       /* handler code */
+       /* store exception */
+       mono_mb_emit_stloc (mb, 1);
+       
+       mono_mb_emit_byte (mb, CEE_LDARG_1);
+       mono_mb_emit_ldloc (mb, 1);
+       mono_mb_emit_byte (mb, CEE_STIND_REF);
+
+       mono_mb_emit_byte (mb, CEE_LDNULL);
+       mono_mb_emit_stloc (mb, 0);
+
+       /* Check for the abort exception */
+       mono_mb_emit_ldloc (mb, 1);
+       mono_mb_emit_op (mb, CEE_ISINST, mono_defaults.threadabortexception_class);
+       posna = mono_mb_emit_short_branch (mb, CEE_BRFALSE_S);
+
+       /* Delay the abort exception */
+       mono_mb_emit_icall (mb, ves_icall_System_Threading_Thread_ResetAbort);
+
+       mono_mb_patch_short_branch (mb, posna);
+       mono_mb_emit_branch (mb, CEE_LEAVE);
+
+       clause->handler_len = mono_mb_get_pos (mb) - clause->handler_offset;
+
+       mono_mb_set_clauses (mb, 1, clause);
+
+       /* return result */
+       mono_mb_patch_branch (mb, pos);
+       //mono_mb_emit_ldloc (mb, 0);
+       mono_mb_emit_byte (mb, CEE_RET);
+
+       mono_loader_lock ();
+       /* double-checked locking */
+       if (!method) {
+               method = mono_mb_create_method (mb, csig, 16);
+       }
+       mono_loader_unlock ();
+
+       mono_mb_free (mb);
+
+       return method;
+}
+
 static void
 mono_mb_emit_auto_layout_exception (MonoMethodBuilder *mb, MonoClass *klass)
 {
@@ -5380,17 +5578,38 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t,
                                        MarshalAction action)
 {
        MonoMethodBuilder *mb = m->mb;
-       MonoClass *klass;
+       MonoClass *klass, *date_time_class;
        int pos = 0, pos2;
 
        klass = mono_class_from_mono_type (t);
 
+       date_time_class = mono_class_from_name_cached (mono_defaults.corlib, "System", "DateTime");
+
        switch (action) {
        case MARSHAL_ACTION_CONV_IN:
                if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
                        klass->blittable || klass->enumtype)
                        break;
 
+               if (klass == date_time_class) {
+                       /* Convert it to an OLE DATE type */
+                       static MonoMethod *to_oadate;
+
+                       if (!to_oadate)
+                               to_oadate = mono_class_get_method_from_name (date_time_class, "ToOADate", 0);
+                       g_assert (to_oadate);
+
+                       if (t->byref)
+                               g_assert_not_reached ();
+
+                       conv_arg = mono_mb_add_local (mb, &mono_defaults.double_class->byval_arg);
+
+                       mono_mb_emit_ldarg_addr (mb, argnum);
+                       mono_mb_emit_managed_call (mb, to_oadate, NULL);
+                       mono_mb_emit_stloc (mb, conv_arg);
+                       break;
+               }
+
                conv_arg = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
                        
                /* store the address of the source into local variable 0 */
@@ -5442,6 +5661,11 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t,
                        break;
                }
 
+               if (klass == date_time_class) {
+                       mono_mb_emit_ldloc (mb, conv_arg);
+                       break;
+               }
+
                if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
                        klass->blittable || klass->enumtype) {
                        mono_mb_emit_ldarg (mb, argnum);
@@ -5489,6 +5713,7 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t,
                        mono_mb_emit_stloc (mb, 3);
                        break;
                }
+
                /* load pointer to returned value type */
                mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
                mono_mb_emit_byte (mb, CEE_MONO_VTADDR);
@@ -5625,7 +5850,7 @@ emit_marshal_string (EmitMarshalContext *m, int argnum, MonoType *t,
                if (conv == -1) {
                        char *msg = g_strdup_printf ("string marshalling conversion %d not implemented", encoding);
                        MonoException *exc = mono_get_exception_not_implemented (msg);
-                       g_warning (msg);
+                       g_warning ("%s", msg);
                        g_free (msg);
                        mono_raise_exception (exc);
                }
@@ -5994,7 +6219,14 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t,
                        MonoMarshalNative encoding = mono_marshal_get_string_encoding (m->piinfo, spec);
                        MonoMarshalConv conv = mono_marshal_get_stringbuilder_to_ptr_conv (m->piinfo, spec);
                        
-                       g_assert (!t->byref);
+                       if (t->byref) {
+                               if (!(t->attrs & PARAM_ATTRIBUTE_OUT)) {
+                                       char *msg = g_strdup_printf ("Byref marshalling of stringbuilders is not implemented.");
+                                       mono_mb_emit_exception_marshal_directive (mb, msg);
+                               }
+                               break;
+                       }
+
                        mono_mb_emit_ldarg (mb, argnum);
 
                        if (conv != -1)
@@ -6002,7 +6234,7 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t,
                        else {
                                char *msg = g_strdup_printf ("stringbuilder marshalling conversion %d not implemented", encoding);
                                MonoException *exc = mono_get_exception_not_implemented (msg);
-                               g_warning (msg);
+                               g_warning ("%s", msg);
                                g_free (msg);
                                mono_raise_exception (exc);
                        }
@@ -6082,13 +6314,34 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t,
                        encoding = mono_marshal_get_string_encoding (m->piinfo, spec);
                        conv = mono_marshal_get_ptr_to_stringbuilder_conv (m->piinfo, spec, &need_free);
 
-                       g_assert (!t->byref);
                        g_assert (encoding != -1);
 
-                       mono_mb_emit_ldarg (mb, argnum);
-                       mono_mb_emit_ldloc (mb, conv_arg);
+                       if (t->byref) {
+                               g_assert ((t->attrs & PARAM_ATTRIBUTE_OUT));
 
-                       mono_mb_emit_icall (mb, conv_to_icall (conv));
+                               need_free = TRUE;
+
+                               mono_mb_emit_ldarg (mb, argnum);
+                               mono_mb_emit_ldloc (mb, conv_arg);
+
+                               switch (encoding) {
+                               case MONO_NATIVE_LPWSTR:
+                                       mono_mb_emit_icall (mb, mono_string_utf16_to_builder2);
+                                       break;
+                               case MONO_NATIVE_LPSTR:
+                                       mono_mb_emit_icall (mb, mono_string_utf8_to_builder2);
+                                       break;
+                               default:
+                                       g_assert_not_reached ();
+                               }
+
+                               mono_mb_emit_byte (mb, CEE_STIND_REF);
+                       } else {
+                               mono_mb_emit_ldarg (mb, argnum);
+                               mono_mb_emit_ldloc (mb, conv_arg);
+
+                               mono_mb_emit_icall (mb, conv_to_icall (conv));
+                       }
 
                        if (need_free) {
                                mono_mb_emit_ldloc (mb, conv_arg);
@@ -6582,7 +6835,7 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
                                if (conv == -1) {
                                        char *msg = g_strdup_printf ("string/stringbuilder marshalling conversion %d not implemented", encoding);
                                        MonoException *exc = mono_get_exception_not_implemented (msg);
-                                       g_warning (msg);
+                                       g_warning ("%s", msg);
                                        g_free (msg);
                                        mono_raise_exception (exc);
                                }
@@ -6911,15 +7164,15 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
                 * from 0.
                 */
 
-               if (param_num == -1)
+               if (param_num == -1) {
                        mono_mb_emit_icon (mb, num_elem);
-               else {
-                       /* FIXME: Add the two together */
+               } else {
                        mono_mb_emit_ldarg (mb, param_num);
                        if (num_elem > 0) {
                                mono_mb_emit_icon (mb, num_elem);
                                mono_mb_emit_byte (mb, CEE_ADD);
                        }
+                       mono_mb_emit_byte (mb, CEE_CONV_OVF_I);
                }
 
                mono_mb_emit_op (mb, CEE_NEWARR, eklass);