X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmarshal.c;h=f688ff41b8da4eac788cfccd4bf6aa08ddbdb384;hb=438e3b5ac335f69a620d2db738626fca1d0c2980;hp=adb955b4699e59c874d3aa2a929fdd1a6cad0fae;hpb=2b19bdc99c0a18b514eddfdeb4a6d2ad8d8b0a18;p=mono.git diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index adb955b4699..f688ff41b8d 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -628,13 +628,11 @@ mono_free_lparray (MonoArray *array, gpointer* nativeArray) return; klass = array->obj.vtable->klass; - switch (klass->element_class->byval_arg.type) { - case MONO_TYPE_CLASS: - for(i = 0; i < array->max_length; ++i) - mono_marshal_free_ccw(nativeArray[i]); - free(nativeArray); - break; - } + if (klass->element_class->byval_arg.type == MONO_TYPE_CLASS) { + for(i = 0; i < array->max_length; ++i) + mono_marshal_free_ccw (mono_array_get (array, MonoObject*, i)); + free(nativeArray); + } #endif } @@ -696,49 +694,16 @@ mono_array_to_byte_byvalarray (gpointer native_arr, MonoArray *arr, guint32 elnu mono_array_to_byvalarray (native_arr, arr, mono_defaults.byte_class, elnum); } -void -mono_string_utf8_to_builder (MonoStringBuilder *sb, char *text) -{ - GError *error = NULL; - guint16 *ut; - glong items_written; - int l; - - if (!sb || !text) - return; - - l = strlen (text); - - ut = g_utf8_to_utf16 (text, l, NULL, &items_written, &error); - - if (items_written > mono_stringbuilder_capacity (sb)) - items_written = mono_stringbuilder_capacity (sb); - - if (!error) { - if (! sb->str || sb->str == sb->cached_str) - MONO_OBJECT_SETREF (sb, str, mono_string_new_size (mono_domain_get (), items_written)); - - memcpy (mono_string_chars (sb->str), ut, items_written * 2); - sb->length = items_written; - sb->cached_str = NULL; - } else - g_error_free (error); - - g_free (ut); -} - -MonoStringBuilder * -mono_string_utf8_to_builder2 (char *text) +static MonoStringBuilder * +mono_string_builder_new (int starting_string_length) { - int l; - MonoStringBuilder *sb; static MonoClass *string_builder_class; static MonoMethod *sb_ctor; - void *args [1]; - MonoObject *exc; + static void *args [1]; + int initial_len = starting_string_length; - if (!text) - return NULL; + if (initial_len < 0) + initial_len = 0; if (!string_builder_class) { MonoMethodDesc *desc; @@ -749,78 +714,101 @@ mono_string_utf8_to_builder2 (char *text) sb_ctor = mono_method_desc_search_in_class (desc, string_builder_class); g_assert (sb_ctor); mono_method_desc_free (desc); - } - l = strlen (text); + // We make a new array in the _to_builder function, so this + // array will always be garbage collected. + args [0] = &initial_len; + } - sb = (MonoStringBuilder*)mono_object_new (mono_domain_get (), string_builder_class); + MonoStringBuilder *sb = (MonoStringBuilder*)mono_object_new (mono_domain_get (), string_builder_class); + MonoObject *exc; g_assert (sb); - args [0] = &l; + mono_runtime_invoke (sb_ctor, sb, args, &exc); + + g_assert (sb->chunkChars->max_length >= initial_len); g_assert (!exc); - mono_string_utf8_to_builder (sb, text); + return sb; +} + +static void +mono_string_utf16_to_builder_copy (MonoStringBuilder *sb, gunichar2 *text, size_t string_len) +{ + gunichar2 *charDst = (gunichar2 *)sb->chunkChars->vector; + gunichar2 *charSrc = (gunichar2 *)text; + memcpy (charDst, charSrc, sizeof (gunichar2) * string_len); + + sb->chunkLength = string_len; + + return; +} + +MonoStringBuilder * +mono_string_utf16_to_builder2 (gunichar2 *text) +{ + if (!text) + return NULL; + + int len; + for (len = 0; text [len] != 0; ++len); + + MonoStringBuilder *sb = mono_string_builder_new (len); + mono_string_utf16_to_builder (sb, text); return sb; } -/* - * FIXME: This routine does not seem to do what it seems to do - * the @text is never copied into the string builder - */ void -mono_string_utf16_to_builder (MonoStringBuilder *sb, gunichar2 *text) +mono_string_utf8_to_builder (MonoStringBuilder *sb, char *text) { - guint32 len; - if (!sb || !text) return; - g_assert (mono_string_chars (sb->str) == text); + int len = strlen (text); + if (len > mono_string_builder_capacity (sb)) + len = mono_string_builder_capacity (sb); - for (len = 0; text [len] != 0; ++len) - ; + GError *error = NULL; + glong copied; + gunichar2* ut = g_utf8_to_utf16 (text, len, NULL, &copied, &error); - sb->length = len; + if (!error) { + MONO_OBJECT_SETREF (sb, chunkPrevious, NULL); + mono_string_utf16_to_builder_copy (sb, ut, copied); + } else + g_error_free (error); + + g_free (ut); } MonoStringBuilder * -mono_string_utf16_to_builder2 (gunichar2 *text) +mono_string_utf8_to_builder2 (char *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; + int len = strlen (text); + MonoStringBuilder *sb = mono_string_builder_new (len); + mono_string_utf8_to_builder (sb, text); - 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); - } + return sb; +} - 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); +void +mono_string_utf16_to_builder (MonoStringBuilder *sb, gunichar2 *text) +{ + if (!sb || !text) + return; - sb->length = len; - memcpy (mono_string_chars (sb->str), text, len * 2); + guint32 len; + for (len = 0; text [len] != 0; ++len); + + if (len > mono_string_builder_capacity (sb)) + len = mono_string_builder_capacity (sb); - return sb; + mono_string_utf16_to_builder_copy (sb, text, len); } /** @@ -833,35 +821,38 @@ mono_string_utf16_to_builder2 (gunichar2 *text) * * The return value must be released with g_free. */ -gpointer +gchar* mono_string_builder_to_utf8 (MonoStringBuilder *sb) { GError *error = NULL; - gchar *tmp, *res = NULL; if (!sb) return NULL; - if ((sb->str == sb->cached_str) && (sb->str->length == 0)) { - /* - * The sb could have been allocated with the default capacity and be empty. - * we need to alloc a buffer of the default capacity in this case. - */ - MONO_OBJECT_SETREF (sb, str, mono_string_new_size (mono_domain_get (), 16)); - sb->cached_str = NULL; - } - tmp = g_utf16_to_utf8 (mono_string_chars (sb->str), sb->length, NULL, NULL, &error); + gunichar2 *str_utf16 = mono_string_builder_to_utf16 (sb); + + guint str_len = mono_string_builder_string_length (sb); + + gchar *tmp = g_utf16_to_utf8 (str_utf16, str_len, NULL, NULL, &error); + if (error) { g_error_free (error); + g_free (str_utf16); mono_raise_exception (mono_get_exception_execution_engine ("Failed to convert StringBuilder from utf16 to utf8")); + return NULL; } else { - res = mono_marshal_alloc (mono_stringbuilder_capacity (sb) + 1); - memcpy (res, tmp, sb->length + 1); + guint len = mono_string_builder_capacity (sb) + 1; + gchar *res = mono_marshal_alloc (len * sizeof (gchar)); + g_assert (str_len < len); + memcpy (res, tmp, str_len * sizeof (gchar)); + res[str_len] = '\0'; + + + g_free (str_utf16); g_free (tmp); + return res; } - - return res; } /** @@ -874,35 +865,43 @@ mono_string_builder_to_utf8 (MonoStringBuilder *sb) * * The return value must not be freed. */ -gpointer +gunichar2* mono_string_builder_to_utf16 (MonoStringBuilder *sb) { if (!sb) return NULL; - g_assert (sb->str); + g_assert (sb->chunkChars); - /* - * The stringbuilder might not have ownership of this string. If this is - * the case, we must duplicate the string, so that we don't munge immutable - * strings - */ - if (sb->str == sb->cached_str) { - /* - * The sb could have been allocated with the default capacity and be empty. - * we need to alloc a buffer of the default capacity in this case. - */ - if (sb->str->length == 0) - MONO_OBJECT_SETREF (sb, str, mono_string_new_size (mono_domain_get (), 16)); - else - MONO_OBJECT_SETREF (sb, str, mono_string_new_utf16 (mono_domain_get (), mono_string_chars (sb->str), mono_stringbuilder_capacity (sb))); - sb->cached_str = NULL; - } - - if (sb->length == 0) - *(mono_string_chars (sb->str)) = '\0'; + guint len = mono_string_builder_capacity (sb); + + if (len == 0) + len = 1; - return mono_string_chars (sb->str); + gunichar2 *str = mono_marshal_alloc ((len + 1) * sizeof (gunichar2)); + str[len] = '\0'; + + if (len == 0) + return str; + + MonoStringBuilder* chunk = sb; + do { + if (chunk->chunkLength > 0) { + // Check that we will not overrun our boundaries. + gunichar2 *source = (gunichar2 *)chunk->chunkChars->vector; + + if (chunk->chunkLength <= len) { + memcpy (str + chunk->chunkOffset, source, chunk->chunkLength * sizeof(gunichar2)); + } else { + g_error ("A chunk in the StringBuilder had a length longer than expected from the offset."); + } + + len -= chunk->chunkLength; + } + chunk = chunk->chunkPrevious; + } while (chunk != NULL); + + return str; } static gpointer @@ -1708,27 +1707,8 @@ emit_object_to_ptr_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv #endif /* DISABLE_COM */ case MONO_MARSHAL_CONV_SAFEHANDLE: { - int dar_release_slot, pos; + int pos; - dar_release_slot = mono_mb_add_local (mb, &mono_defaults.boolean_class->byval_arg); - - /* - * The following is ifdefed-out, because I have no way of doing the - * DangerousRelease when destroying the structure - */ -#if 0 - /* set release = false */ - mono_mb_emit_icon (mb, 0); - mono_mb_emit_stloc (mb, dar_release_slot); - if (!sh_dangerous_add_ref) - init_safe_handle (); - - /* safehandle.DangerousAddRef (ref release) */ - mono_mb_emit_ldloc (mb, 0); /* the source */ - mono_mb_emit_byte (mb, CEE_LDIND_I); - mono_mb_emit_ldloc_addr (mb, dar_release_slot); - mono_mb_emit_managed_call (mb, sh_dangerous_add_ref, NULL); -#endif mono_mb_emit_ldloc (mb, 0); mono_mb_emit_byte (mb, CEE_LDIND_I); pos = mono_mb_emit_branch (mb, CEE_BRTRUE); @@ -2010,9 +1990,10 @@ emit_struct_free (MonoMethodBuilder *mb, MonoClass *klass, int struct_var) static void emit_thread_interrupt_checkpoint_call (MonoMethodBuilder *mb, gpointer checkpoint_func) { - int pos_noabort; + int pos_noabort, pos_noex; - mono_mb_emit_ptr (mb, (gpointer) mono_thread_interruption_request_flag ()); + mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX); + mono_mb_emit_byte (mb, CEE_MONO_LDPTR_INT_REQ_FLAG); mono_mb_emit_byte (mb, CEE_LDIND_U4); pos_noabort = mono_mb_emit_branch (mb, CEE_BRFALSE); @@ -2020,6 +2001,12 @@ emit_thread_interrupt_checkpoint_call (MonoMethodBuilder *mb, gpointer checkpoin mono_mb_emit_byte (mb, CEE_MONO_NOT_TAKEN); mono_mb_emit_icall (mb, checkpoint_func); + /* Throw the exception returned by the checkpoint function, if any */ + mono_mb_emit_byte (mb, CEE_DUP); + pos_noex = mono_mb_emit_branch (mb, CEE_BRFALSE); + mono_mb_emit_byte (mb, CEE_THROW); + mono_mb_patch_branch (mb, pos_noex); + mono_mb_emit_byte (mb, CEE_POP); mono_mb_patch_branch (mb, pos_noabort); } @@ -2036,7 +2023,7 @@ emit_thread_interrupt_checkpoint (MonoMethodBuilder *mb) static void emit_thread_force_interrupt_checkpoint (MonoMethodBuilder *mb) { - emit_thread_interrupt_checkpoint_call (mb, mono_thread_force_interruption_checkpoint); + emit_thread_interrupt_checkpoint_call (mb, mono_thread_force_interruption_checkpoint_noraise); } void @@ -2320,7 +2307,6 @@ static gboolean mono_marshal_need_free (MonoType *t, MonoMethodPInvoke *piinfo, MonoMarshalSpec *spec) { MonoMarshalNative encoding; - MonoMarshalConv conv; switch (t->type) { case MONO_TYPE_VALUETYPE: @@ -2330,7 +2316,7 @@ mono_marshal_need_free (MonoType *t, MonoMethodPInvoke *piinfo, MonoMarshalSpec case MONO_TYPE_CLASS: if (t->data.klass == mono_defaults.stringbuilder_class) { gboolean need_free; - conv = mono_marshal_get_ptr_to_stringbuilder_conv (piinfo, spec, &need_free); + mono_marshal_get_ptr_to_stringbuilder_conv (piinfo, spec, &need_free); return need_free; } return FALSE; @@ -2460,14 +2446,18 @@ mono_marshal_method_from_wrapper (MonoMethod *wrapper) res = mono_marshal_get_wrapper_info (wrapper); if (res == NULL) return wrapper; - if (wrapper->is_inflated) + if (wrapper->is_inflated) { + MonoError error; + MonoMethod *result; /* * A method cannot be inflated and a wrapper at the same time, so the wrapper info * contains an uninflated method. */ - return mono_class_inflate_generic_method (res, mono_method_get_context (wrapper)); - else - return res; + result = mono_class_inflate_generic_method_checked (res, mono_method_get_context (wrapper), &error); + g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ + return result; + } + return res; case MONO_WRAPPER_MANAGED_TO_NATIVE: info = mono_marshal_get_wrapper_info (wrapper); if (info && (info->subtype == WRAPPER_SUBTYPE_NONE || info->subtype == WRAPPER_SUBTYPE_NATIVE_FUNC_AOT || info->subtype == WRAPPER_SUBTYPE_PINVOKE)) @@ -2582,10 +2572,8 @@ check_generic_wrapper_cache (GHashTable *cache, MonoMethod *orig_method, gpointe MonoMethod *res; MonoMethod *inst, *def; MonoGenericContext *ctx; - MonoMethod *def_method; g_assert (orig_method->is_inflated); - def_method = ((MonoMethodInflated*)orig_method)->declaring; ctx = mono_method_get_context (orig_method); /* @@ -2600,7 +2588,9 @@ check_generic_wrapper_cache (GHashTable *cache, MonoMethod *orig_method, gpointe */ def = mono_marshal_find_in_cache (cache, def_key); if (def) { - inst = mono_class_inflate_generic_method (def, ctx); + MonoError error; + inst = mono_class_inflate_generic_method_checked (def, ctx, &error); + g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ /* Cache it */ mono_memory_barrier (); mono_marshal_lock (); @@ -2618,12 +2608,14 @@ check_generic_wrapper_cache (GHashTable *cache, MonoMethod *orig_method, gpointe static MonoMethod* cache_generic_wrapper (GHashTable *cache, MonoMethod *orig_method, MonoMethod *def, MonoGenericContext *ctx, gpointer key) { + MonoError error; MonoMethod *inst, *res; /* * We use the same cache for the generic definition and the instances. */ - inst = mono_class_inflate_generic_method (def, ctx); + inst = mono_class_inflate_generic_method_checked (def, ctx, &error); + g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ mono_memory_barrier (); mono_marshal_lock (); res = g_hash_table_lookup (cache, key); @@ -2638,6 +2630,7 @@ cache_generic_wrapper (GHashTable *cache, MonoMethod *orig_method, MonoMethod *d static MonoMethod* check_generic_delegate_wrapper_cache (GHashTable *cache, MonoMethod *orig_method, MonoMethod *def_method, MonoGenericContext *ctx) { + MonoError error; MonoMethod *res; MonoMethod *inst, *def; @@ -2653,7 +2646,9 @@ check_generic_delegate_wrapper_cache (GHashTable *cache, MonoMethod *orig_method */ def = mono_marshal_find_in_cache (cache, def_method->klass); if (def) { - inst = mono_class_inflate_generic_method (def, ctx); + inst = mono_class_inflate_generic_method_checked (def, ctx, &error); + g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ + /* Cache it */ mono_memory_barrier (); mono_marshal_lock (); @@ -2671,12 +2666,15 @@ check_generic_delegate_wrapper_cache (GHashTable *cache, MonoMethod *orig_method static MonoMethod* cache_generic_delegate_wrapper (GHashTable *cache, MonoMethod *orig_method, MonoMethod *def, MonoGenericContext *ctx) { + MonoError error; MonoMethod *inst, *res; /* * We use the same cache for the generic definition and the instances. */ - inst = mono_class_inflate_generic_method (def, ctx); + inst = mono_class_inflate_generic_method_checked (def, ctx, &error); + g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ + mono_memory_barrier (); mono_marshal_lock (); res = g_hash_table_lookup (cache, orig_method->klass); @@ -2979,34 +2977,34 @@ mono_marshal_get_delegate_end_invoke (MonoMethod *method) typedef struct { MonoMethodSignature *sig; - MonoMethod *method; -} SignatureMethodPair; + gpointer pointer; +} SignaturePointerPair; static guint -signature_method_pair_hash (gconstpointer data) +signature_pointer_pair_hash (gconstpointer data) { - SignatureMethodPair *pair = (SignatureMethodPair*)data; + SignaturePointerPair *pair = (SignaturePointerPair*)data; - return mono_signature_hash (pair->sig) ^ mono_aligned_addr_hash (pair->method); + return mono_signature_hash (pair->sig) ^ mono_aligned_addr_hash (pair->pointer); } static gboolean -signature_method_pair_equal (SignatureMethodPair *pair1, SignatureMethodPair *pair2) +signature_pointer_pair_equal (gconstpointer data1, gconstpointer data2) { - return mono_metadata_signature_equal (pair1->sig, pair2->sig) && (pair1->method == pair2->method); + SignaturePointerPair *pair1 = (SignaturePointerPair*) data1, *pair2 = (SignaturePointerPair*) data2; + return mono_metadata_signature_equal (pair1->sig, pair2->sig) && (pair1->pointer == pair2->pointer); } static gboolean -signature_method_pair_matches_method (gpointer key, gpointer value, gpointer user_data) +signature_pointer_pair_matches_pointer (gpointer key, gpointer value, gpointer user_data) { - SignatureMethodPair *pair = (SignatureMethodPair*)key; - MonoMethod *method = (MonoMethod*)user_data; + SignaturePointerPair *pair = (SignaturePointerPair*)key; - return pair->method == method; + return pair->pointer == user_data; } static void -free_signature_method_pair (SignatureMethodPair *pair) +free_signature_pointer_pair (SignaturePointerPair *pair) { g_free (pair); } @@ -3020,8 +3018,8 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt MonoMethod *res; GHashTable *cache; gpointer cache_key = NULL; - SignatureMethodPair key; - SignatureMethodPair *new_key; + SignaturePointerPair key; + SignaturePointerPair *new_key; int local_prev, local_target; int pos0; char *name; @@ -3110,10 +3108,10 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt /* We need to cache the signature+method pair */ mono_marshal_lock (); if (!*cache_ptr) - *cache_ptr = g_hash_table_new_full (signature_method_pair_hash, (GEqualFunc)signature_method_pair_equal, (GDestroyNotify)free_signature_method_pair, NULL); + *cache_ptr = g_hash_table_new_full (signature_pointer_pair_hash, (GEqualFunc)signature_pointer_pair_equal, (GDestroyNotify)free_signature_pointer_pair, NULL); cache = *cache_ptr; key.sig = invoke_sig; - key.method = target_method; + key.pointer = target_method; res = g_hash_table_lookup (cache, &key); mono_marshal_unlock (); if (res) @@ -3181,10 +3179,13 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt mono_mb_emit_ldloc (mb, local_prev); for (i = 0; i < sig->param_count; i++) mono_mb_emit_ldarg (mb, i + 1); - if (ctx) - mono_mb_emit_op (mb, CEE_CALLVIRT, mono_class_inflate_generic_method (method, &container->context)); - else + if (ctx) { + MonoError error; + mono_mb_emit_op (mb, CEE_CALLVIRT, mono_class_inflate_generic_method_checked (method, &container->context, &error)); + g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ + } else { mono_mb_emit_op (mb, CEE_CALLVIRT, method); + } if (sig->ret->type != MONO_TYPE_VOID) mono_mb_emit_byte (mb, CEE_POP); @@ -3261,7 +3262,7 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt def = mono_mb_create_and_cache (cache, cache_key, mb, sig, sig->param_count + 16); res = cache_generic_delegate_wrapper (cache, orig_method, def, ctx); } else if (callvirt) { - new_key = g_new0 (SignatureMethodPair, 1); + new_key = g_new0 (SignaturePointerPair, 1); *new_key = key; info = mono_wrapper_info_create (mb, subtype); @@ -4159,20 +4160,23 @@ emit_marshal_custom (EmitMarshalContext *m, int argnum, MonoType *t, int pos2; if (!ICustomMarshaler) { - ICustomMarshaler = mono_class_from_name (mono_defaults.corlib, "System.Runtime.InteropServices", "ICustomMarshaler"); - if (!ICustomMarshaler) { + MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Runtime.InteropServices", "ICustomMarshaler"); + if (!klass) { exception_msg = g_strdup ("Current profile doesn't support ICustomMarshaler"); goto handle_exception; } - cleanup_native = mono_class_get_method_from_name (ICustomMarshaler, "CleanUpNativeData", 1); + cleanup_native = mono_class_get_method_from_name (klass, "CleanUpNativeData", 1); g_assert (cleanup_native); - cleanup_managed = mono_class_get_method_from_name (ICustomMarshaler, "CleanUpManagedData", 1); + cleanup_managed = mono_class_get_method_from_name (klass, "CleanUpManagedData", 1); g_assert (cleanup_managed); - marshal_managed_to_native = mono_class_get_method_from_name (ICustomMarshaler, "MarshalManagedToNative", 1); + marshal_managed_to_native = mono_class_get_method_from_name (klass, "MarshalManagedToNative", 1); g_assert (marshal_managed_to_native); - marshal_native_to_managed = mono_class_get_method_from_name (ICustomMarshaler, "MarshalNativeToManaged", 1); + marshal_native_to_managed = mono_class_get_method_from_name (klass, "MarshalNativeToManaged", 1); g_assert (marshal_native_to_managed); + + mono_memory_barrier (); + ICustomMarshaler = klass; } if (spec->data.custom_data.image) @@ -5974,6 +5978,31 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t, need_free = mono_marshal_need_free (&klass->element_class->byval_arg, m->piinfo, spec); + if ((t->attrs & PARAM_ATTRIBUTE_OUT) && spec && spec->native == MONO_NATIVE_LPARRAY && spec->data.array_data.param_num != -1) { + int param_num = spec->data.array_data.param_num; + MonoType *param_type; + + param_type = m->sig->params [param_num]; + + if (param_type->byref && param_type->type != MONO_TYPE_I4) { + char *msg = g_strdup ("Not implemented."); + mono_mb_emit_exception_marshal_directive (mb, msg); + break; + } + + mono_mb_emit_ldarg (mb, argnum); + + /* Create the managed array */ + mono_mb_emit_ldarg (mb, param_num); + if (m->sig->params [param_num]->byref) + // FIXME: Support other types + mono_mb_emit_byte (mb, CEE_LDIND_I4); + mono_mb_emit_byte (mb, CEE_CONV_OVF_I); + mono_mb_emit_op (mb, CEE_NEWARR, klass->element_class); + /* Store into argument */ + mono_mb_emit_byte (mb, CEE_STIND_I); + } + if (need_convert || need_free) { /* FIXME: Optimize blittable case */ MonoClass *eklass; @@ -6089,6 +6118,8 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t, /* free memory allocated (if any) by MONO_MARSHAL_CONV_ARRAY_LPARRAY */ mono_mb_emit_ldarg (mb, argnum); + if (t->byref) + mono_mb_emit_byte (mb, CEE_LDIND_REF); mono_mb_emit_ldloc (mb, conv_arg); mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_FREE_LPARRAY)); } @@ -6110,7 +6141,7 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t, case MARSHAL_ACTION_MANAGED_CONV_IN: { MonoClass *eklass; guint32 label1, label2, label3; - int index_var, src_ptr, loc, esize, param_num, num_elem; + int index_var, src_ptr, esize, param_num, num_elem; MonoMarshalConv conv; gboolean is_string = FALSE; @@ -6171,7 +6202,6 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t, else esize = mono_class_native_size (eklass, NULL); src_ptr = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg); - loc = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg); mono_mb_emit_byte (mb, CEE_LDNULL); mono_mb_emit_stloc (mb, conv_arg); @@ -6288,7 +6318,7 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t, case MARSHAL_ACTION_MANAGED_CONV_OUT: { MonoClass *eklass; guint32 label1, label2, label3; - int index_var, dest_ptr, loc, esize, param_num, num_elem; + int index_var, dest_ptr, esize, param_num, num_elem; MonoMarshalConv conv; gboolean is_string = FALSE; @@ -6336,7 +6366,6 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t, esize = mono_class_native_size (eklass, NULL); dest_ptr = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg); - loc = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg); /* Check null */ mono_mb_emit_ldloc (mb, conv_arg); @@ -6883,8 +6912,9 @@ emit_marshal (EmitMarshalContext *m, int argnum, MonoType *t, return emit_marshal_vtype (m, argnum, t, spec, conv_arg, conv_arg_type, action); else return emit_marshal_object (m, argnum, t, spec, conv_arg, conv_arg_type, action); + default: + return conv_arg; } - return conv_arg; } #ifndef DISABLE_JIT @@ -6911,7 +6941,9 @@ mono_marshal_emit_native_wrapper (MonoImage *image, MonoMethodBuilder *mb, MonoM int type, param_shift = 0; static MonoMethodSignature *get_last_error_sig = NULL; + memset (&m, 0, sizeof (m)); m.mb = mb; + m.sig = sig; m.piinfo = piinfo; /* we copy the signature, so that we can set pinvoke to 0 */ @@ -7099,6 +7131,8 @@ mono_marshal_emit_native_wrapper (MonoImage *image, MonoMethodBuilder *mb, MonoM case MONO_TYPE_BOOLEAN: emit_marshal (&m, argnum, t, spec, tmp_locals [i], NULL, MARSHAL_ACTION_CONV_OUT); break; + default: + break; } } @@ -7351,13 +7385,18 @@ mono_marshal_get_native_func_wrapper (MonoImage *image, MonoMethodSignature *sig { MonoMethodSignature *csig; + SignaturePointerPair key, *new_key; MonoMethodBuilder *mb; MonoMethod *res; GHashTable *cache; + gboolean found; char *name; - cache = get_cache (&image->native_wrapper_cache, mono_aligned_addr_hash, NULL); - if ((res = mono_marshal_find_in_cache (cache, func))) + key.sig = sig; + key.pointer = func; + + cache = get_cache (&image->native_func_wrapper_cache, signature_pointer_pair_hash, signature_pointer_pair_equal); + if ((res = mono_marshal_find_in_cache (cache, &key))) return res; name = g_strdup_printf ("wrapper_native_%p", func); @@ -7370,8 +7409,15 @@ mono_marshal_get_native_func_wrapper (MonoImage *image, MonoMethodSignature *sig csig = signature_dup (image, sig); csig->pinvoke = 0; - res = mono_mb_create_and_cache (cache, func, - mb, csig, csig->param_count + 16); + + new_key = g_new (SignaturePointerPair,1); + new_key->sig = csig; + new_key->pointer = func; + + res = mono_mb_create_and_cache_full (cache, new_key, mb, csig, csig->param_count + 16, NULL, &found); + if (found) + g_free (new_key); + mono_mb_free (mb); mono_marshal_set_wrapper_info (res, NULL); @@ -7638,6 +7684,8 @@ mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *i case MONO_TYPE_BOOLEAN: emit_marshal (m, i, t, mspecs [i + 1], tmp_locals [i], NULL, MARSHAL_ACTION_MANAGED_CONV_OUT); break; + default: + break; } } else if (invoke_sig->params [i]->attrs & PARAM_ATTRIBUTE_OUT) { @@ -7761,6 +7809,7 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, csig->hasthis = 0; csig->pinvoke = 1; + memset (&m, 0, sizeof (m)); m.mb = mb; m.sig = sig; m.piinfo = NULL; @@ -7802,8 +7851,6 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, gint32 call_conv; gint32 charset = 0; MonoBoolean set_last_error = 0; - MonoBoolean best_fit_mapping = 0; - MonoBoolean throw_on_unmappable = 0; MonoError error; mono_reflection_create_custom_attr_data_args (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, &typed_args, &named_args, &arginfo, &error); @@ -7826,9 +7873,9 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, } else if (!strcmp (narg->field->name, "SetLastError")) { set_last_error = *(MonoBoolean*)mono_object_unbox (o); } else if (!strcmp (narg->field->name, "BestFitMapping")) { - best_fit_mapping = *(MonoBoolean*)mono_object_unbox (o); + // best_fit_mapping = *(MonoBoolean*)mono_object_unbox (o); } else if (!strcmp (narg->field->name, "ThrowOnUnmappableChar")) { - throw_on_unmappable = *(MonoBoolean*)mono_object_unbox (o); + // throw_on_unmappable = *(MonoBoolean*)mono_object_unbox (o); } else { g_assert_not_reached (); } @@ -7907,6 +7954,7 @@ mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16 type) csig->hasthis = 0; csig->pinvoke = 1; + memset (&m, 0, sizeof (m)); m.mb = mb; m.sig = sig; m.piinfo = NULL; @@ -8096,7 +8144,7 @@ mono_marshal_get_isinst_with_cache (void) mono_mb_emit_ldloc (mb, 1); mono_mb_emit_byte (mb, CEE_LDC_I4); mono_mb_emit_i4 (mb, ~0x1); - mono_mb_emit_byte (mb, CEE_CONV_U); + mono_mb_emit_byte (mb, CEE_CONV_I); mono_mb_emit_byte (mb, CEE_AND); mono_mb_emit_ldloc (mb, 0); /*if ((cached_vtable & ~0x1)== obj_vtable)*/ @@ -8520,11 +8568,9 @@ mono_marshal_get_synchronized_inner_wrapper (MonoMethod *method) MonoMethodSignature *sig; MonoMethod *res; MonoGenericContext *ctx = NULL; - MonoMethod *orig_method = NULL; MonoGenericContainer *container = NULL; if (method->is_inflated && !mono_method_get_context (method)->method_inst) { - orig_method = method; ctx = &((MonoMethodInflated*)method)->context; method = ((MonoMethodInflated*)method)->declaring; container = mono_method_get_generic_container (method); @@ -8544,8 +8590,11 @@ mono_marshal_get_synchronized_inner_wrapper (MonoMethod *method) info->d.synchronized_inner.method = method; res = mono_mb_create (mb, sig, 0, info); mono_mb_free (mb); - if (ctx) - res = mono_class_inflate_generic_method (res, ctx); + if (ctx) { + MonoError error; + res = mono_class_inflate_generic_method_checked (res, ctx, &error); + g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ + } return res; } @@ -8686,10 +8735,13 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method) for (i = 0; i < sig->param_count; i++) mono_mb_emit_ldarg (mb, i + (sig->hasthis == TRUE)); - if (ctx) - mono_mb_emit_managed_call (mb, mono_class_inflate_generic_method (method, &container->context), NULL); - else + if (ctx) { + MonoError error; + mono_mb_emit_managed_call (mb, mono_class_inflate_generic_method_checked (method, &container->context, &error), NULL); + g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ + } else { mono_mb_emit_managed_call (mb, method, NULL); + } if (!MONO_TYPE_IS_VOID (sig->ret)) mono_mb_emit_stloc (mb, ret_local); @@ -9506,10 +9558,11 @@ static int elem_addr_cache_next = 0; * @rank: rank of the array type * @elem_size: size in bytes of an element of an array. * - * Returns a MonoMethd that implements the code to get the address + * Returns a MonoMethod that implements the code to get the address * of an element in a multi-dimenasional array of @rank dimensions. * The returned method takes an array as the first argument and then * @rank indexes for the @rank dimensions. + * If ELEM_SIZE is 0, read the array size from the array object. */ MonoMethod* mono_marshal_get_array_address (int rank, int elem_size) @@ -9518,6 +9571,7 @@ mono_marshal_get_array_address (int rank, int elem_size) MonoMethodBuilder *mb; MonoMethodSignature *sig; WrapperInfo *info; + char *name; int i, bounds, ind, realidx; int branch_pos, *branch_positions; int cached; @@ -9545,7 +9599,9 @@ mono_marshal_get_array_address (int rank, int elem_size) sig->params [i + 1] = &mono_defaults.int32_class->byval_arg; } - mb = mono_mb_new (mono_defaults.object_class, "ElementAddr", MONO_WRAPPER_MANAGED_TO_MANAGED); + name = g_strdup_printf ("ElementAddr_%d", elem_size); + mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_MANAGED_TO_MANAGED); + g_free (name); #ifndef DISABLE_JIT bounds = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg); @@ -9613,8 +9669,24 @@ mono_marshal_get_array_address (int rank, int elem_size) mono_mb_emit_ldarg (mb, 0); mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoArray, vector)); mono_mb_emit_ldloc (mb, ind); - mono_mb_emit_icon (mb, elem_size); - mono_mb_emit_byte (mb, CEE_MUL); + if (elem_size) { + mono_mb_emit_icon (mb, elem_size); + } else { + /* Load arr->vtable->klass->sizes.element_class */ + mono_mb_emit_ldarg (mb, 0); + mono_mb_emit_byte (mb, CEE_CONV_I); + mono_mb_emit_icon (mb, MONO_STRUCT_OFFSET (MonoObject, vtable)); + mono_mb_emit_byte (mb, CEE_ADD); + mono_mb_emit_byte (mb, CEE_LDIND_I); + mono_mb_emit_icon (mb, MONO_STRUCT_OFFSET (MonoVTable, klass)); + mono_mb_emit_byte (mb, CEE_ADD); + mono_mb_emit_byte (mb, CEE_LDIND_I); + /* sizes is an union, so this reads sizes.element_size */ + mono_mb_emit_icon (mb, MONO_STRUCT_OFFSET (MonoClass, sizes)); + mono_mb_emit_byte (mb, CEE_ADD); + mono_mb_emit_byte (mb, CEE_LDIND_I4); + } + mono_mb_emit_byte (mb, CEE_MUL); mono_mb_emit_byte (mb, CEE_ADD); mono_mb_emit_byte (mb, CEE_RET); @@ -9711,10 +9783,13 @@ mono_marshal_get_array_accessor_wrapper (MonoMethod *method) for (i = 0; i < sig->param_count; i++) mono_mb_emit_ldarg (mb, i + (sig->hasthis == TRUE)); - if (ctx) - mono_mb_emit_managed_call (mb, mono_class_inflate_generic_method (method, &container->context), NULL); - else + if (ctx) { + MonoError error; + mono_mb_emit_managed_call (mb, mono_class_inflate_generic_method_checked (method, &container->context, &error), NULL); + g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ + } else { mono_mb_emit_managed_call (mb, method, NULL); + } mono_mb_emit_byte (mb, CEE_RET); #endif @@ -9823,19 +9898,25 @@ ves_icall_System_Runtime_InteropServices_Marshal_copy_to_unmanaged (MonoArray *s int element_size; void *source_addr; - MONO_ARCH_SAVE_REGS; + MONO_CHECK_ARG_NULL (src,); + MONO_CHECK_ARG_NULL (dest,); - MONO_CHECK_ARG_NULL (src); - MONO_CHECK_ARG_NULL (dest); - - if (src->obj.vtable->klass->rank != 1) - mono_raise_exception (mono_get_exception_argument ("array", "array is multi-dimensional")); - if (start_index < 0) - mono_raise_exception (mono_get_exception_argument ("startIndex", "Must be >= 0")); - if (length < 0) - mono_raise_exception (mono_get_exception_argument ("length", "Must be >= 0")); - if (start_index + length > mono_array_length (src)) - mono_raise_exception (mono_get_exception_argument ("length", "start_index + length > array length")); + if (src->obj.vtable->klass->rank != 1) { + mono_set_pending_exception (mono_get_exception_argument ("array", "array is multi-dimensional")); + return; + } + if (start_index < 0) { + mono_set_pending_exception (mono_get_exception_argument ("startIndex", "Must be >= 0")); + return; + } + if (length < 0) { + mono_set_pending_exception (mono_get_exception_argument ("length", "Must be >= 0")); + return; + } + if (start_index + length > mono_array_length (src)) { + mono_set_pending_exception (mono_get_exception_argument ("length", "start_index + length > array length")); + return; + } element_size = mono_array_element_size (src->obj.vtable->klass); @@ -9852,20 +9933,25 @@ ves_icall_System_Runtime_InteropServices_Marshal_copy_from_unmanaged (gpointer s int element_size; void *dest_addr; - MONO_ARCH_SAVE_REGS; - - MONO_CHECK_ARG_NULL (src); - MONO_CHECK_ARG_NULL (dest); - - if (dest->obj.vtable->klass->rank != 1) - mono_raise_exception (mono_get_exception_argument ("array", "array is multi-dimensional")); - if (start_index < 0) - mono_raise_exception (mono_get_exception_argument ("startIndex", "Must be >= 0")); - if (length < 0) - mono_raise_exception (mono_get_exception_argument ("length", "Must be >= 0")); - if (start_index + length > mono_array_length (dest)) - mono_raise_exception (mono_get_exception_argument ("length", "start_index + length > array length")); + MONO_CHECK_ARG_NULL (src,); + MONO_CHECK_ARG_NULL (dest,); + if (dest->obj.vtable->klass->rank != 1) { + mono_set_pending_exception (mono_get_exception_argument ("array", "array is multi-dimensional")); + return; + } + if (start_index < 0) { + mono_set_pending_exception (mono_get_exception_argument ("startIndex", "Must be >= 0")); + return; + } + if (length < 0) { + mono_set_pending_exception (mono_get_exception_argument ("length", "Must be >= 0")); + return; + } + if (start_index + length > mono_array_length (dest)) { + mono_set_pending_exception (mono_get_exception_argument ("length", "start_index + length > array length")); + return; + } element_size = mono_array_element_size (dest->obj.vtable->klass); /* no references should be involved */ @@ -9877,8 +9963,6 @@ ves_icall_System_Runtime_InteropServices_Marshal_copy_from_unmanaged (gpointer s MonoString * ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi (char *ptr) { - MONO_ARCH_SAVE_REGS; - if (ptr == NULL) return NULL; else @@ -9888,11 +9972,8 @@ ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi (char *ptr) MonoString * ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi_len (char *ptr, gint32 len) { - MONO_ARCH_SAVE_REGS; - if (ptr == NULL) { - mono_raise_exception (mono_get_exception_argument_null ("ptr")); - g_assert_not_reached (); + mono_set_pending_exception (mono_get_exception_argument_null ("ptr")); return NULL; } else { return mono_string_new_len (mono_domain_get (), ptr, len); @@ -9906,8 +9987,6 @@ ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni (guint16 *ptr) int len = 0; guint16 *t = ptr; - MONO_ARCH_SAVE_REGS; - if (ptr == NULL) return NULL; @@ -9922,11 +10001,8 @@ ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni_len (guint16 *pt { MonoDomain *domain = mono_domain_get (); - MONO_ARCH_SAVE_REGS; - if (ptr == NULL) { - mono_raise_exception (mono_get_exception_argument_null ("ptr")); - g_assert_not_reached (); + mono_set_pending_exception (mono_get_exception_argument_null ("ptr")); return NULL; } else { return mono_string_new_utf16 (domain, ptr, len); @@ -9936,8 +10012,6 @@ ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni_len (guint16 *pt guint32 ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error (void) { - MONO_ARCH_SAVE_REGS; - return (GPOINTER_TO_INT (mono_native_tls_get_value (last_error_tls_id))); } @@ -9948,14 +10022,14 @@ ves_icall_System_Runtime_InteropServices_Marshal_SizeOf (MonoReflectionType *rty MonoType *type; guint32 layout; - MONO_ARCH_SAVE_REGS; - - MONO_CHECK_ARG_NULL (rtype); + MONO_CHECK_ARG_NULL (rtype, 0); type = rtype->type; klass = mono_class_from_mono_type (type); - if (!mono_class_init (klass)) - mono_raise_exception (mono_class_get_exception_for_failure (klass)); + if (!mono_class_init (klass)) { + mono_set_pending_exception (mono_class_get_exception_for_failure (klass)); + return 0; + } layout = (klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK); @@ -9968,10 +10042,10 @@ ves_icall_System_Runtime_InteropServices_Marshal_SizeOf (MonoReflectionType *rty msg = g_strdup_printf ("Type %s cannot be marshaled as an unmanaged structure.", klass->name); exc = mono_get_exception_argument ("t", msg); g_free (msg); - mono_raise_exception (exc); + mono_set_pending_exception (exc); + return 0; } - return mono_class_native_size (klass, NULL); } @@ -9981,10 +10055,8 @@ ves_icall_System_Runtime_InteropServices_Marshal_StructureToPtr (MonoObject *obj MonoMethod *method; gpointer pa [3]; - MONO_ARCH_SAVE_REGS; - - MONO_CHECK_ARG_NULL (obj); - MONO_CHECK_ARG_NULL (dst); + MONO_CHECK_ARG_NULL (obj,); + MONO_CHECK_ARG_NULL (dst,); method = mono_marshal_get_struct_to_ptr (obj->vtable->klass); @@ -10014,10 +10086,8 @@ ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure (gpointer src, M { MonoType *t; - MONO_ARCH_SAVE_REGS; - - MONO_CHECK_ARG_NULL (src); - MONO_CHECK_ARG_NULL (dst); + MONO_CHECK_ARG_NULL (src,); + MONO_CHECK_ARG_NULL (dst,); t = mono_type_get_underlying_type (mono_class_get_type (dst->vtable->klass)); @@ -10029,7 +10099,7 @@ ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure (gpointer src, M exc = mono_get_exception_argument ("dst", tmp); g_free (tmp); - mono_raise_exception (exc); + mono_set_pending_exception (exc); return; } @@ -10043,15 +10113,15 @@ ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure_type (gpointer s MonoDomain *domain = mono_domain_get (); MonoObject *res; - MONO_ARCH_SAVE_REGS; - if (src == NULL) return NULL; - MONO_CHECK_ARG_NULL (type); + MONO_CHECK_ARG_NULL (type, NULL); klass = mono_class_from_mono_type (type->type); - if (!mono_class_init (klass)) - mono_raise_exception (mono_class_get_exception_for_failure (klass)); + if (!mono_class_init (klass)) { + mono_set_pending_exception (mono_class_get_exception_for_failure (klass)); + return NULL; + } res = mono_object_new (domain, klass); @@ -10068,15 +10138,15 @@ ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf (MonoReflectionType *t char *fname; int match_index = -1; - MONO_ARCH_SAVE_REGS; - - MONO_CHECK_ARG_NULL (type); - MONO_CHECK_ARG_NULL (field_name); + MONO_CHECK_ARG_NULL (type, 0); + MONO_CHECK_ARG_NULL (field_name, 0); fname = mono_string_to_utf8 (field_name); klass = mono_class_from_mono_type (type->type); - if (!mono_class_init (klass)) - mono_raise_exception (mono_class_get_exception_for_failure (klass)); + if (!mono_class_init (klass)) { + mono_set_pending_exception (mono_class_get_exception_for_failure (klass)); + return 0; + } while (klass && match_index == -1) { MonoClassField* field; @@ -10109,7 +10179,8 @@ ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf (MonoReflectionType *t exc = mono_get_exception_argument ("fieldName", tmp); g_free (tmp); - mono_raise_exception ((MonoException*)exc); + mono_set_pending_exception ((MonoException*)exc); + return 0; } info = mono_marshal_load_type_info (klass); @@ -10140,8 +10211,6 @@ ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi (MonoString gpointer ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalUni (MonoString *string) { - MONO_ARCH_SAVE_REGS; - if (string == NULL) return NULL; else { @@ -10166,7 +10235,6 @@ mono_struct_delete_old (MonoClass *klass, char *ptr) info = mono_marshal_load_type_info (klass); for (i = 0; i < info->num_fields; i++) { - MonoMarshalNative ntype; MonoMarshalConv conv; MonoType *ftype = info->fields [i].field->type; char *cpos; @@ -10174,8 +10242,8 @@ mono_struct_delete_old (MonoClass *klass, char *ptr) if (ftype->attrs & FIELD_ATTRIBUTE_STATIC) continue; - ntype = mono_type_to_unmanaged (ftype, info->fields [i].mspec, TRUE, - klass->unicode, &conv); + mono_type_to_unmanaged (ftype, info->fields [i].mspec, TRUE, + klass->unicode, &conv); cpos = ptr + info->fields [i].offset; @@ -10213,14 +10281,14 @@ ves_icall_System_Runtime_InteropServices_Marshal_DestroyStructure (gpointer src, { MonoClass *klass; - MONO_ARCH_SAVE_REGS; - - MONO_CHECK_ARG_NULL (src); - MONO_CHECK_ARG_NULL (type); + MONO_CHECK_ARG_NULL (src,); + MONO_CHECK_ARG_NULL (type,); klass = mono_class_from_mono_type (type->type); - if (!mono_class_init (klass)) - mono_raise_exception (mono_class_get_exception_for_failure (klass)); + if (!mono_class_init (klass)) { + mono_set_pending_exception (mono_class_get_exception_for_failure (klass)); + return; + } mono_struct_delete_old (klass, (char *)src); } @@ -10230,8 +10298,6 @@ ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal (int size) { gpointer res; - MONO_ARCH_SAVE_REGS; - if ((gulong)size == 0) /* This returns a valid pointer for size 0 on MS.NET */ size = 4; @@ -10271,8 +10337,6 @@ ves_icall_System_Runtime_InteropServices_Marshal_ReAllocHGlobal (gpointer ptr, i void ves_icall_System_Runtime_InteropServices_Marshal_FreeHGlobal (void *ptr) { - MONO_ARCH_SAVE_REGS; - #ifdef HOST_WIN32 GlobalFree (ptr); #else @@ -10283,20 +10347,25 @@ ves_icall_System_Runtime_InteropServices_Marshal_FreeHGlobal (void *ptr) void* ves_icall_System_Runtime_InteropServices_Marshal_AllocCoTaskMem (int size) { - MONO_ARCH_SAVE_REGS; + void *res; #ifdef HOST_WIN32 - return CoTaskMemAlloc (size); + res = CoTaskMemAlloc (size); #else - return g_try_malloc ((gulong)size); + if ((gulong)size == 0) + /* This returns a valid pointer for size 0 on MS.NET */ + size = 4; + + res = g_try_malloc ((gulong)size); #endif + if (!res) + mono_gc_out_of_memory ((gulong)size); + return res; } void ves_icall_System_Runtime_InteropServices_Marshal_FreeCoTaskMem (void *ptr) { - MONO_ARCH_SAVE_REGS; - #ifdef HOST_WIN32 CoTaskMemFree (ptr); #else @@ -10307,13 +10376,16 @@ ves_icall_System_Runtime_InteropServices_Marshal_FreeCoTaskMem (void *ptr) gpointer ves_icall_System_Runtime_InteropServices_Marshal_ReAllocCoTaskMem (gpointer ptr, int size) { - MONO_ARCH_SAVE_REGS; + void *res; #ifdef HOST_WIN32 - return CoTaskMemRealloc (ptr, size); + res = CoTaskMemRealloc (ptr, size); #else - return g_try_realloc (ptr, (gulong)size); + res = g_try_realloc (ptr, (gulong)size); #endif + if (!res) + mono_gc_out_of_memory ((gulong)size); + return res; } void* @@ -10326,8 +10398,10 @@ MonoDelegate* ves_icall_System_Runtime_InteropServices_Marshal_GetDelegateForFunctionPointerInternal (void *ftn, MonoReflectionType *type) { MonoClass *klass = mono_type_get_class (type->type); - if (!mono_class_init (klass)) - mono_raise_exception (mono_class_get_exception_for_failure (klass)); + if (!mono_class_init (klass)) { + mono_set_pending_exception (mono_class_get_exception_for_failure (klass)); + return NULL; + } return mono_ftnptr_to_delegate (klass, ftn); } @@ -10777,10 +10851,10 @@ mono_marshal_asany (MonoObject *o, MonoMarshalNative string_encoding, int param_ return res; } + default: + break; } - mono_raise_exception (mono_get_exception_argument ("", "No PInvoke conversion exists for value passed to Object-typed parameter.")); - return NULL; } @@ -11101,7 +11175,7 @@ mono_marshal_free_dynamic_wrappers (MonoMethod *method) if (image->runtime_invoke_direct_cache) g_hash_table_remove (image->runtime_invoke_direct_cache, method); if (image->delegate_abstract_invoke_cache) - g_hash_table_foreach_remove (image->delegate_abstract_invoke_cache, signature_method_pair_matches_method, method); + g_hash_table_foreach_remove (image->delegate_abstract_invoke_cache, signature_pointer_pair_matches_pointer, method); // FIXME: Need to clear the caches in other images as well if (image->delegate_bound_static_invoke_cache) g_hash_table_remove (image->delegate_bound_static_invoke_cache, mono_method_signature (method)); @@ -11111,9 +11185,9 @@ mono_marshal_free_dynamic_wrappers (MonoMethod *method) } static gboolean -signature_method_pair_matches_signature (gpointer key, gpointer value, gpointer user_data) +signature_pointer_pair_matches_signature (gpointer key, gpointer value, gpointer user_data) { - SignatureMethodPair *pair = (SignatureMethodPair*)key; + SignaturePointerPair *pair = (SignaturePointerPair*)key; MonoMethodSignature *sig = (MonoMethodSignature*)user_data; return mono_metadata_signature_equal (pair->sig, sig); @@ -11157,11 +11231,11 @@ mono_marshal_free_inflated_wrappers (MonoMethod *method) g_hash_table_remove (method->klass->image->runtime_invoke_vtype_cache, sig); /* - * indexed by SignatureMethodPair + * indexed by SignaturePointerPair */ if (sig && method->klass->image->delegate_abstract_invoke_cache) g_hash_table_foreach_remove (method->klass->image->delegate_abstract_invoke_cache, - signature_method_pair_matches_signature, (gpointer)sig); + signature_pointer_pair_matches_signature, (gpointer)sig); /* * indexed by MonoMethod pointers