Merge pull request #3854 from lateralusX/jlorenss/win-clang-toolchain
[mono.git] / mono / metadata / cominterop.c
index 8b4143b7ac5d34cb9805cea47c685e8838d2a4ce..cf61058a3a7525b92fa2ad8c0f355db5b1289bd0 100644 (file)
 #include <string.h>
 #include <errno.h>
 
+#if defined(HOST_WIN32)
+#include <oleauto.h>
+#endif
+
 /*
 Code shared between the DISABLE_COM and !DISABLE_COM
 */
@@ -51,6 +55,15 @@ register_icall (gpointer func, const char *name, const char *sigstr, gboolean sa
        mono_register_jit_icall (func, name, sig, save);
 }
 
+gpointer
+mono_string_to_bstr(MonoString* ptr)
+{
+       if (!ptr)
+               return NULL;
+
+       return mono_ptr_to_bstr(mono_string_chars(ptr), mono_string_length(ptr));
+}
+
 #ifndef DISABLE_COM
 
 #define OPDEF(a,b,c,d,e,f,g,h,i,j) \
@@ -347,7 +360,8 @@ cominterop_get_method_interface (MonoMethod* method)
                                gboolean found = FALSE;
                                ic = (MonoClass *)g_ptr_array_index (ifaces, i);
                                offset = mono_class_interface_offset (method->klass, ic);
-                               for (j = 0; j < ic->method.count; ++j) {
+                               int mcount = mono_class_get_method_count (ic);
+                               for (j = 0; j < mcount; ++j) {
                                        if (method->klass->vtable [j + offset] == method) {
                                                found = TRUE;
                                                break;
@@ -387,7 +401,8 @@ cominterop_get_com_slot_for_method (MonoMethod* method)
                ic = cominterop_get_method_interface (method);
                offset = mono_class_interface_offset (method->klass, ic);
                g_assert(offset >= 0);
-               for(i = 0; i < ic->method.count; ++i) {
+               int mcount = mono_class_get_method_count (ic);
+               for(i = 0; i < mcount; ++i) {
                        if (method->klass->vtable [i + offset] == method)
                        {
                                slot = ic->methods[i]->slot;
@@ -1493,7 +1508,7 @@ ves_icall_System_Runtime_InteropServices_Marshal_ReleaseInternal (gpointer pUnk)
 
 static gboolean cominterop_can_support_dispatch (MonoClass* klass)
 {
-       if (!(klass->flags & TYPE_ATTRIBUTE_PUBLIC) )
+       if (!mono_class_is_public (klass))
                return FALSE;
 
        if (!cominterop_com_visible (klass))
@@ -1984,8 +1999,7 @@ cominterop_get_ccw_checked (MonoObject* object, MonoClass* itf, MonoError *error
                g_hash_table_insert (ccw_hash, GINT_TO_POINTER (mono_object_hash (object)), ccw_list);
                mono_cominterop_unlock ();
                /* register for finalization to clean up ccw */
-               mono_object_register_finalizer (object, error);
-               return_val_if_nok (error, NULL);
+               mono_object_register_finalizer (object);
        }
 
        cinfo = mono_custom_attrs_from_class_checked (itf, error);
@@ -2010,7 +2024,7 @@ cominterop_get_ccw_checked (MonoObject* object, MonoClass* itf, MonoError *error
                start_slot = 7;
        }
        else {
-               method_count += iface->method.count;
+               method_count += mono_class_get_method_count (iface);
                start_slot = cominterop_get_com_slot_begin (iface);
                iface = NULL;
        }
@@ -2025,7 +2039,7 @@ cominterop_get_ccw_checked (MonoObject* object, MonoClass* itf, MonoError *error
                        memcpy (vtable+3, idispatch, sizeof (idispatch));
 
                iface = itf;
-               for (i = iface->method.count-1; i >= 0;i--) {
+               for (i = mono_class_get_method_count (iface) - 1; i >= 0; i--) {
                        int param_index = 0;
                        MonoMethodBuilder *mb;
                        MonoMarshalSpec ** mspecs;
@@ -2115,12 +2129,14 @@ cominterop_get_ccw_checked (MonoObject* object, MonoClass* itf, MonoError *error
                        wrapper_method = mono_mb_create_method (mb, m.csig, m.csig->param_count + 16);
                        mono_cominterop_unlock ();
 
-                       vtable [vtable_index--] = mono_compile_method (wrapper_method);
+                       vtable [vtable_index--] = mono_compile_method_checked (wrapper_method, error);
 
+                       // cleanup, then error out if compile_method failed
                        for (param_index = sig_adjusted->param_count; param_index >= 0; param_index--)
                                if (mspecs [param_index])
                                        mono_metadata_free_marshal_spec (mspecs [param_index]);
                        g_free (mspecs);
+                       return_val_if_nok (error, NULL);
                }
 
                ccw_entry = g_new0 (MonoCCWInterface, 1);
@@ -2741,37 +2757,37 @@ init_com_provider_ms (void)
 }
 
 gpointer
-mono_string_to_bstr (MonoString *string_obj)
+mono_ptr_to_bstr(gpointer ptr, int slen)
 {
-       if (!string_obj)
+       if (!ptr)
                return NULL;
 #ifdef HOST_WIN32
-       return SysAllocStringLen (mono_string_chars (string_obj), mono_string_length (string_obj));
+       return SysAllocStringLen (ptr, slen);
 #else
        if (com_provider == MONO_COM_DEFAULT) {
-               int slen = mono_string_length (string_obj);
                /* allocate len + 1 utf16 characters plus 4 byte integer for length*/
-               char *ret = (char *)g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
+               char *ret = (char *)g_malloc((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
                if (ret == NULL)
                        return NULL;
-               memcpy (ret + sizeof(guint32), mono_string_chars (string_obj), slen * sizeof(gunichar2));
-               * ((guint32 *) ret) = slen * sizeof(gunichar2);
-               ret [4 + slen * sizeof(gunichar2)] = 0;
-               ret [5 + slen * sizeof(gunichar2)] = 0;
+               memcpy(ret + sizeof(guint32), ptr, slen * sizeof(gunichar2));
+               *((guint32 *)ret) = slen * sizeof(gunichar2);
+               ret[4 + slen * sizeof(gunichar2)] = 0;
+               ret[5 + slen * sizeof(gunichar2)] = 0;
 
                return ret + 4;
-       } else if (com_provider == MONO_COM_MS && init_com_provider_ms ()) {
+       }
+       else if (com_provider == MONO_COM_MS && init_com_provider_ms()) {
                gpointer ret = NULL;
                gunichar* str = NULL;
-               guint32 len;
-               len = mono_string_length (string_obj);
-               str = g_utf16_to_ucs4 (mono_string_chars (string_obj), len,
+               guint32 len = slen;
+               str = g_utf16_to_ucs4(ptr, len,
                        NULL, NULL, NULL);
-               ret = sys_alloc_string_len_ms (str, len);
+               ret = sys_alloc_string_len_ms(str, len);
                g_free(str);
                return ret;
-       } else {
-               g_assert_not_reached ();
+       }
+       else {
+               g_assert_not_reached();
        }
 #endif
 }
@@ -3410,20 +3426,19 @@ cominterop_release_all_rcws (void)
 }
 
 gpointer
-mono_string_to_bstr (MonoString *string_obj)
+mono_ptr_to_bstr (gpointer ptr, int slen)
 {
-       if (!string_obj)
+       if (!ptr)
                return NULL;
 #ifdef HOST_WIN32
-       return SysAllocStringLen (mono_string_chars (string_obj), mono_string_length (string_obj));
+       return SysAllocStringLen (ptr, slen);
 #else
        {
-               int slen = mono_string_length (string_obj);
                /* allocate len + 1 utf16 characters plus 4 byte integer for length*/
                char *ret = g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
                if (ret == NULL)
                        return NULL;
-               memcpy (ret + sizeof(guint32), mono_string_chars (string_obj), slen * sizeof(gunichar2));
+               memcpy (ret + sizeof(guint32), ptr, slen * sizeof(gunichar2));
                * ((guint32 *) ret) = slen * sizeof(gunichar2);
                ret [4 + slen * sizeof(gunichar2)] = 0;
                ret [5 + slen * sizeof(gunichar2)] = 0;
@@ -3523,6 +3538,12 @@ ves_icall_System_Runtime_InteropServices_Marshal_StringToBSTR (MonoString* ptr)
        return mono_string_to_bstr(ptr);
 }
 
+gpointer
+ves_icall_System_Runtime_InteropServices_Marshal_BufferToBSTR (MonoArray* ptr, int len)
+{
+       return mono_ptr_to_bstr (ptr->vector, len);
+}
+
 void
 ves_icall_System_Runtime_InteropServices_Marshal_FreeBSTR (gpointer ptr)
 {