[sgen] Binary protocol for every write barrier, not just the generic store one.
[mono.git] / mono / metadata / cominterop.c
index 6d9fe24c3c1ddb829b7cc7dbf74e1329b46cfdab..a87d9953322c5bba39deff56747ef58259f4665c 100644 (file)
@@ -801,7 +801,7 @@ cominterop_get_native_wrapper_adjusted (MonoMethod *method)
                                mspecs[mspec_index] = g_new0 (MonoMarshalSpec, 1);
                                mspecs[mspec_index]->native = MONO_NATIVE_INTERFACE;
                        }
-                       else if (sig_native->params[i]->type == MONO_NATIVE_BOOLEAN) {
+                       else if (sig_native->params[i]->type == MONO_TYPE_BOOLEAN) {
                                mspecs[mspec_index] = g_new0 (MonoMarshalSpec, 1);
                                mspecs[mspec_index]->native = MONO_NATIVE_VARIANTBOOL;
                        }
@@ -824,7 +824,7 @@ cominterop_get_native_wrapper_adjusted (MonoMethod *method)
                                mspecs[0] = g_new0 (MonoMarshalSpec, 1);
                                mspecs[0]->native = MONO_NATIVE_INTERFACE;
                        }
-                       else if (sig->ret->type == MONO_NATIVE_BOOLEAN) {
+                       else if (sig->ret->type == MONO_TYPE_BOOLEAN) {
                                mspecs[0] = g_new0 (MonoMarshalSpec, 1);
                                mspecs[0]->native = MONO_NATIVE_VARIANTBOOL;
                        }
@@ -1525,6 +1525,9 @@ ves_icall_System_Runtime_InteropServices_Marshal_GetCCW (MonoObject* object, Mon
        g_assert (type->type);
        klass = mono_type_get_class (type->type);
        g_assert (klass);
+       if (!mono_class_init (klass))
+               mono_raise_exception (mono_class_get_exception_for_failure (klass));
+
        itf = cominterop_get_ccw (object, klass);
        g_assert (itf);
        return itf;
@@ -1680,7 +1683,11 @@ gpointer
 ves_icall_System_ComObject_GetInterfaceInternal (MonoComObject* obj, MonoReflectionType* type, MonoBoolean throw_exception)
 {
 #ifndef DISABLE_COM
-       return cominterop_get_interface (obj, mono_type_get_class (type->type), (gboolean)throw_exception);
+       MonoClass *class = mono_type_get_class (type->type);
+       if (!mono_class_init (class))
+               mono_raise_exception (mono_class_get_exception_for_failure (class));
+
+       return cominterop_get_interface (obj, class, (gboolean)throw_exception);
 #else
        g_assert_not_reached ();
 #endif
@@ -1732,30 +1739,6 @@ ves_icall_Mono_Interop_ComInteropProxy_FindProxy (gpointer pUnk)
 #endif
 }
 
-MonoString *
-ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringBSTR (gpointer ptr)
-{
-       MONO_ARCH_SAVE_REGS;
-
-       return mono_string_from_bstr(ptr);
-}
-
-gpointer
-ves_icall_System_Runtime_InteropServices_Marshal_StringToBSTR (MonoString* ptr)
-{
-       MONO_ARCH_SAVE_REGS;
-
-       return mono_string_to_bstr(ptr);
-}
-
-void
-ves_icall_System_Runtime_InteropServices_Marshal_FreeBSTR (gpointer ptr)
-{
-       MONO_ARCH_SAVE_REGS;
-
-       mono_free_bstr (ptr);
-}
-
 /**
  * cominterop_get_ccw_object:
  * @ccw_entry: a pointer to the CCWEntry
@@ -1969,7 +1952,7 @@ cominterop_get_ccw (MonoObject* object, MonoClass* itf)
                                                mspecs[mspec_index] = g_new0 (MonoMarshalSpec, 1);
                                                mspecs[mspec_index]->native = MONO_NATIVE_INTERFACE;
                                        }
-                                       else if (sig_adjusted->params[param_index]->type == MONO_NATIVE_BOOLEAN) {
+                                       else if (sig_adjusted->params[param_index]->type == MONO_TYPE_BOOLEAN) {
                                                mspecs[mspec_index] = g_new0 (MonoMarshalSpec, 1);
                                                mspecs[mspec_index]->native = MONO_NATIVE_VARIANTBOOL;
                                        }
@@ -2000,7 +1983,7 @@ cominterop_get_ccw (MonoObject* object, MonoClass* itf)
                                                mspecs[0] = g_new0 (MonoMarshalSpec, 1);
                                                mspecs[0]->native = MONO_NATIVE_INTERFACE;
                                        }
-                                       else if (sig_adjusted->params[sig_adjusted->param_count-1]->type == MONO_NATIVE_BOOLEAN) {
+                                       else if (sig_adjusted->params[sig_adjusted->param_count-1]->type == MONO_TYPE_BOOLEAN) {
                                                mspecs[0] = g_new0 (MonoMarshalSpec, 1);
                                                mspecs[0]->native = MONO_NATIVE_VARIANTBOOL;
                                        }
@@ -2015,7 +1998,7 @@ cominterop_get_ccw (MonoObject* object, MonoClass* itf)
 
                        cominterop_setup_marshal_context (&m, adjust_method);
                        m.mb = mb;
-                       mono_marshal_emit_managed_wrapper (mb, sig_adjusted, mspecs, &m, adjust_method, NULL);
+                       mono_marshal_emit_managed_wrapper (mb, sig_adjusted, mspecs, &m, adjust_method, 0);
                        mono_loader_lock ();
                        mono_cominterop_lock ();
                        wrapper_method = mono_mb_create_method (mb, m.csig, m.csig->param_count + 16);
@@ -2692,7 +2675,7 @@ mono_cominterop_emit_marshal_safearray (EmitMarshalContext *m, int argnum, MonoT
 
                        if (t->byref) {
                                mono_mb_emit_ldarg (mb, argnum);
-                               mono_mb_emit_byte (mb, CEE_LDIND_I);
+                               mono_mb_emit_byte (mb, CEE_LDIND_REF);
                        } else
                                mono_mb_emit_ldarg (mb, argnum);
 
@@ -2707,7 +2690,7 @@ mono_cominterop_emit_marshal_safearray (EmitMarshalContext *m, int argnum, MonoT
 
                        label2 = mono_mb_emit_short_branch (mb, CEE_BRTRUE_S);
 
-                       index_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
+                       index_var = mono_mb_add_local (mb, &mono_defaults.int32_class->byval_arg);
                        mono_mb_emit_byte (mb, CEE_LDC_I4_0);
                        mono_mb_emit_stloc (mb, index_var);
 
@@ -2719,7 +2702,7 @@ mono_cominterop_emit_marshal_safearray (EmitMarshalContext *m, int argnum, MonoT
 
                        if (t->byref) {
                                mono_mb_emit_ldarg (mb, argnum);
-                               mono_mb_emit_byte (mb, CEE_LDIND_I);
+                               mono_mb_emit_byte (mb, CEE_LDIND_REF);
                        } else
                                mono_mb_emit_ldarg (mb, argnum);
 
@@ -3180,21 +3163,73 @@ mono_marshal_free_ccw (MonoObject* object)
 gpointer
 mono_string_to_bstr (MonoString *string_obj)
 {
-       g_assert_not_reached ();
-       return NULL;
+       if (!string_obj)
+               return NULL;
+#ifdef HOST_WIN32
+       return SysAllocStringLen (mono_string_chars (string_obj), mono_string_length (string_obj));
+#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));
+               * ((guint32 *) ret) = slen * sizeof(gunichar2);
+               ret [4 + slen * sizeof(gunichar2)] = 0;
+               ret [5 + slen * sizeof(gunichar2)] = 0;
+
+               return ret + 4;
+       }
+#endif
 }
 
 MonoString *
 mono_string_from_bstr (gpointer bstr)
 {
-       g_assert_not_reached ();
-       return NULL;
+       if (!bstr)
+               return NULL;
+#ifdef HOST_WIN32
+       return mono_string_new_utf16 (mono_domain_get (), bstr, SysStringLen (bstr));
+#else
+       return mono_string_new_utf16 (mono_domain_get (), bstr, *((guint32 *)bstr - 1) / sizeof(gunichar2));
+#endif
 }
 
 void
 mono_free_bstr (gpointer bstr)
 {
-       g_assert_not_reached ();
+       if (!bstr)
+               return;
+#ifdef HOST_WIN32
+       SysFreeString ((BSTR)bstr);
+#else
+       g_free (((char *)bstr) - 4);
+#endif
 }
 
 #endif /* DISABLE_COM */
+
+MonoString *
+ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringBSTR (gpointer ptr)
+{
+       MONO_ARCH_SAVE_REGS;
+
+       return mono_string_from_bstr(ptr);
+}
+
+gpointer
+ves_icall_System_Runtime_InteropServices_Marshal_StringToBSTR (MonoString* ptr)
+{
+       MONO_ARCH_SAVE_REGS;
+
+       return mono_string_to_bstr(ptr);
+}
+
+void
+ves_icall_System_Runtime_InteropServices_Marshal_FreeBSTR (gpointer ptr)
+{
+       MONO_ARCH_SAVE_REGS;
+
+       mono_free_bstr (ptr);
+}