[cominterop] MonoError-ize mono_string_from_bstr
authorAleksey Kliger <aleksey@xamarin.com>
Thu, 21 Apr 2016 18:52:57 +0000 (14:52 -0400)
committerAleksey Kliger <aleksey@xamarin.com>
Thu, 12 May 2016 15:15:28 +0000 (11:15 -0400)
Runtime should use mono_string_from_bstr_checked. The icall is
mono_string_from_bstr_icall. Marked mono_string_from_bstr external only.

mono/metadata/cominterop.c
mono/metadata/cominterop.h
mono/metadata/marshal.c

index 3ebe507d0d185472c7aada8bed2713c8b11847df..1b66e550e1b57206514f701e3194437c1529259a 100644 (file)
@@ -599,7 +599,7 @@ mono_cominterop_init (void)
        register_icall (cominterop_get_interface, "cominterop_get_interface", "ptr object ptr int32", FALSE);
 
        register_icall (mono_string_to_bstr, "mono_string_to_bstr", "ptr obj", FALSE);
-       register_icall (mono_string_from_bstr, "mono_string_from_bstr", "obj ptr", FALSE);
+       register_icall (mono_string_from_bstr_icall, "mono_string_from_bstr_icall", "obj ptr", FALSE);
        register_icall (mono_free_bstr, "mono_free_bstr", "void ptr", FALSE);
        register_icall (cominterop_type_from_handle, "cominterop_type_from_handle", "object ptr", FALSE);
 
@@ -1696,9 +1696,11 @@ ves_icall_System_ComObject_CreateRCW (MonoReflectionType *type)
         * Constructor does not need to be called. Will be called later.
        */
        MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
-       mono_error_raise_exception (&error);
+       if (mono_error_set_pending_exception (&error))
+               return NULL;
        obj = mono_object_new_alloc_specific_checked (vtable, &error);
-       mono_error_raise_exception (&error);
+       if (mono_error_set_pending_exception (&error))
+               return NULL;
 
        return obj;
 }
@@ -2424,15 +2426,15 @@ static const IID MONO_IID_IMarshal = {0x3, 0x0, 0x0, {0xC0, 0x0, 0x0, 0x0, 0x0,
 #ifdef HOST_WIN32
 /* All ccw objects are free threaded */
 static int
-cominterop_ccw_getfreethreadedmarshaler (MonoCCW* ccw, MonoObject* object, gpointer* ppv)
+cominterop_ccw_getfreethreadedmarshaler (MonoCCW* ccw, MonoObject* object, gpointer* ppv, MonoError *error)
 {
+       mono_error_init (error);
 #ifdef HOST_WIN32
-       MonoError error;
        if (!ccw->free_marshaler) {
                int ret = 0;
                gpointer tunk;
-               tunk = cominterop_get_ccw_checked (object, mono_class_get_iunknown_class (), &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               tunk = cominterop_get_ccw_checked (object, mono_class_get_iunknown_class (), error);
+               return_val_if_nok (error, MONO_E_NOINTERFACE);
                ret = CoCreateFreeThreadedMarshaler (tunk, (LPUNKNOWN*)&ccw->free_marshaler);
        }
                
@@ -2491,7 +2493,9 @@ cominterop_ccw_queryinterface (MonoCCWInterface* ccwe, guint8* riid, gpointer* p
 #ifdef HOST_WIN32
        /* handle IMarshal special */
        if (0 == memcmp (riid, &MONO_IID_IMarshal, sizeof (IID))) {
-               return cominterop_ccw_getfreethreadedmarshaler (ccw, object, ppv);      
+               int res = cominterop_ccw_getfreethreadedmarshaler (ccw, object, ppv, &error);
+               mono_error_assert_ok (&error);
+               return res;
        }
 #endif
        klass_iter = klass;
@@ -2776,22 +2780,41 @@ MonoString *
 mono_string_from_bstr (gpointer bstr)
 {
        MonoError error;
+       MonoString *result = mono_string_from_bstr_checked (bstr, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+
+MonoString *
+mono_string_from_bstr_icall (gpointer bstr)
+{
+       MonoError error;
+       MonoString *result = mono_string_from_bstr_checked (bstr, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
+}
+
+MonoString *
+mono_string_from_bstr_checked (gpointer bstr, MonoError *error)
+{
        MonoString * res = NULL;
        
+       mono_error_init (error);
+
        if (!bstr)
                return NULL;
 #ifdef HOST_WIN32
-       res = mono_string_new_utf16_checked (mono_domain_get (), bstr, SysStringLen (bstr), &error);
+       res = mono_string_new_utf16_checked (mono_domain_get (), bstr, SysStringLen (bstr), error);
 #else
        if (com_provider == MONO_COM_DEFAULT) {
-               res = mono_string_new_utf16_checked (mono_domain_get (), (const mono_unichar2 *)bstr, *((guint32 *)bstr - 1) / sizeof(gunichar2), &error);
+               res = mono_string_new_utf16_checked (mono_domain_get (), (const mono_unichar2 *)bstr, *((guint32 *)bstr - 1) / sizeof(gunichar2), error);
        } else if (com_provider == MONO_COM_MS && init_com_provider_ms ()) {
                MonoString* str = NULL;
                glong written = 0;
                gunichar2* utf16 = NULL;
 
                utf16 = g_ucs4_to_utf16 ((const gunichar *)bstr, sys_string_len_ms (bstr), NULL, &written, NULL);
-               str = mono_string_new_utf16_checked (mono_domain_get (), utf16, written, &error);
+               str = mono_string_new_utf16_checked (mono_domain_get (), utf16, written, error);
                g_free (utf16);
                res = str;
        } else {
@@ -2799,7 +2822,6 @@ mono_string_from_bstr (gpointer bstr)
        }
 
 #endif
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
        return res;
 }
 
@@ -3360,7 +3382,7 @@ mono_cominterop_init (void)
        emit an exception in the generated IL.
        */
        register_icall (mono_string_to_bstr, "mono_string_to_bstr", "ptr obj", FALSE);
-       register_icall (mono_string_from_bstr, "mono_string_from_bstr", "obj ptr", FALSE);
+       register_icall (mono_string_from_bstr_icall, "mono_string_from_bstr_icall", "obj ptr", FALSE);
        register_icall (mono_free_bstr, "mono_free_bstr", "void ptr", FALSE);
 }
 
@@ -3398,19 +3420,37 @@ mono_string_to_bstr (MonoString *string_obj)
 #endif
 }
 
+
 MonoString *
 mono_string_from_bstr (gpointer bstr)
 {
-       MonoString *res = NULL;
        MonoError error;
+       MonoString *result = mono_string_from_bstr_checked (bstr, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+
+MonoString *
+mono_string_from_bstr_icall (gpointer bstr)
+{
+       MonoError error;
+       MonoString *result = mono_string_from_bstr_checked (bstr, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
+}
+
+MonoString *
+mono_string_from_bstr_checked (gpointer bstr, MonoError *error)
+{
+       MonoString *res = NULL;
+       mono_error_init (error);
        if (!bstr)
                return NULL;
 #ifdef HOST_WIN32
-       res = mono_string_new_utf16_checked (mono_domain_get (), bstr, SysStringLen (bstr), &error);
+       res = mono_string_new_utf16_checked (mono_domain_get (), bstr, SysStringLen (bstr), error);
 #else
-       res = mono_string_new_utf16_checked (mono_domain_get (), bstr, *((guint32 *)bstr - 1) / sizeof(gunichar2), &error);
+       res = mono_string_new_utf16_checked (mono_domain_get (), bstr, *((guint32 *)bstr - 1) / sizeof(gunichar2), error);
 #endif
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
        return res;
 }
 
@@ -3458,7 +3498,10 @@ ves_icall_System_Runtime_InteropServices_Marshal_QueryInterfaceInternal (gpointe
 MonoString *
 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringBSTR (gpointer ptr)
 {
-       return mono_string_from_bstr(ptr);
+       MonoError error;
+       MonoString *result = mono_string_from_bstr_checked (ptr, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
 }
 
 gpointer
index 1338bd3b5bc169c8b440a59ea7d6941155542dbf..d80021aa93bba6172773640a9e9d23c49917d76f 100644 (file)
@@ -47,9 +47,16 @@ mono_cominterop_emit_marshal_safearray (EmitMarshalContext *m, int argnum,
                                                                                int conv_arg, MonoType **conv_arg_type,
                                                                                MarshalAction action);
 
+MONO_RT_EXTERNAL_ONLY
 MONO_API MonoString * 
 mono_string_from_bstr (gpointer bstr);
 
+MonoString *
+mono_string_from_bstr_icall (gpointer bstr);
+
+MonoString *
+mono_string_from_bstr_checked (gpointer bstr, MonoError *error);
+
 MONO_API void 
 mono_free_bstr (gpointer bstr);
 
index dfe806d97ec86f6875d742d66168887f19fd127a..6b59e38ac01da2c4a2c0665adb9f03e30d556923 100644 (file)
@@ -1600,7 +1600,7 @@ conv_to_icall (MonoMarshalConv conv, int *ind_store_type)
                return mono_string_to_bstr;
        case MONO_MARSHAL_CONV_BSTR_STR:
                *ind_store_type = CEE_STIND_REF;
-               return mono_string_from_bstr;
+               return mono_string_from_bstr_icall;
        case MONO_MARSHAL_CONV_STR_TBSTR:
        case MONO_MARSHAL_CONV_STR_ANSIBSTR:
                return mono_string_to_ansibstr;