[marshal] Rethrow in native-to-managed wrapper to keep exception stacktrace (#5384)
[mono.git] / mono / metadata / marshal.c
index 9403e54a149ad81b16ba8f945bacddbed73718a9..63358bf3baff17983faf525d7d4c0fe1c9d5b5b1 100644 (file)
@@ -799,12 +799,13 @@ mono_array_to_lparray (MonoArray *array)
 
        int i = 0;
        MonoClass *klass;
+       MonoError error;
 #endif
 
        if (!array)
                return NULL;
 #ifndef DISABLE_COM
-
+       error_init (&error);
        klass = array->obj.vtable->klass;
 
        switch (klass->element_class->byval_arg.type) {
@@ -813,9 +814,12 @@ mono_array_to_lparray (MonoArray *array)
                break;
        case MONO_TYPE_CLASS:
                nativeArraySize = array->max_length;
-               nativeArray = (void **)malloc(sizeof(gpointer) * nativeArraySize);
-               for(i = 0; i < nativeArraySize; ++i)    
-                       nativeArray[i] = ves_icall_System_Runtime_InteropServices_Marshal_GetIUnknownForObjectInternal(((MonoObject **)array->vector)[i]);
+               nativeArray = (void **)g_malloc (sizeof(gpointer) * nativeArraySize);
+               for(i = 0; i < nativeArraySize; ++i) {
+                       nativeArray[i] = mono_cominterop_get_com_interface (((MonoObject **)array->vector)[i], klass->element_class, &error);
+                       if (mono_error_set_pending_exception (&error))
+                               break;
+               }
                return nativeArray;
        case MONO_TYPE_U1:
        case MONO_TYPE_BOOLEAN:
@@ -853,7 +857,6 @@ mono_free_lparray (MonoArray *array, gpointer* nativeArray)
 {
 #ifndef DISABLE_COM
        MonoClass *klass;
-       int i = 0;
 
        if (!array)
                return;
@@ -862,11 +865,8 @@ mono_free_lparray (MonoArray *array, gpointer* nativeArray)
                return;
        klass = array->obj.vtable->klass;
 
-       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));
+       if (klass->element_class->byval_arg.type == MONO_TYPE_CLASS)
                g_free (nativeArray);
-       }
 #endif
 }
 
@@ -11590,7 +11590,6 @@ mono_marshal_load_type_info (MonoClass* klass)
 
        layout = mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK;
 
-       /* The mempool is protected by the loader lock */
        info = (MonoMarshalType *)mono_image_alloc0 (klass->image, MONO_SIZEOF_MARSHAL_TYPE + sizeof (MonoMarshalField) * count);
        info->num_fields = count;
        
@@ -11677,8 +11676,11 @@ mono_marshal_load_type_info (MonoClass* klass)
        info->min_align = min_align;
 
        /* Update the class's blittable info, if the layouts don't match */
-       if (info->native_size != mono_class_value_size (klass, NULL))
+       if (info->native_size != mono_class_value_size (klass, NULL)) {
+               mono_loader_lock ();
                klass->blittable = FALSE;
+               mono_loader_unlock ();
+       }
 
        /* If this is an array type, ensure that we have element info */
        if (klass->rank && !mono_marshal_is_loading_type_info (klass->element_class)) {
@@ -12364,7 +12366,7 @@ ftnptr_eh_callback_default (guint32 gchandle)
 
        mono_gchandle_free (gchandle);
 
-       mono_raise_exception (exc);
+       mono_reraise_exception (exc);
 }
 
 /*