Merge pull request #2820 from kumpera/license-change-rebased
[mono.git] / mono / metadata / icall.c
index d9d9f259325c5c9299ce8121a81d86672d0b29c6..cea8809e84fe18aeeb18f6eb2a16a58168c93fbc 100644 (file)
@@ -11,6 +11,7 @@
  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
  * Copyright 2011-2015 Xamarin Inc (http://www.xamarin.com).
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include <config.h>
@@ -207,6 +208,7 @@ ves_icall_System_Array_GetValue (MonoArray *arr, MonoArray *idxs)
 ICALL_EXPORT void
 ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 pos)
 {
+       MonoError error;
        MonoClass *ac, *vc, *ec;
        gint32 esize, vsize;
        gpointer *ea, *va;
@@ -216,6 +218,8 @@ ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32
        gint64 i64 = 0;
        gdouble r64 = 0;
 
+       mono_error_init (&error);
+
        if (value)
                vc = value->vtable->klass;
        else
@@ -293,19 +297,24 @@ ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32
        }
 
        if (!ec->valuetype) {
-               if (!mono_object_isinst (value, ec))
+               gboolean castOk = (NULL != mono_object_isinst_checked (value, ec, &error));
+               if (mono_error_set_pending_exception (&error))
+                       return;
+               if (!castOk)
                        INVALID_CAST;
                mono_gc_wbarrier_set_arrayref (arr, ea, (MonoObject*)value);
                return;
        }
 
-       if (mono_object_isinst (value, ec)) {
+       if (mono_object_isinst_checked (value, ec, &error)) {
                if (ec->has_references)
                        mono_value_copy (ea, (char*)value + sizeof (MonoObject), ec);
                else
                        mono_gc_memmove_atomic (ea, (char *)value + sizeof (MonoObject), esize);
                return;
        }
+       if (mono_error_set_pending_exception (&error))
+               return;
 
        if (!vc->valuetype)
                INVALID_CAST;
@@ -1630,8 +1639,13 @@ ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionType *type, MonoObje
        MonoError error;
        MonoClass *klass = mono_class_from_mono_type (type->type);
        mono_class_init_checked (klass, &error);
-       mono_error_raise_exception (&error);
-       return mono_object_isinst (obj, klass) != NULL;
+       if (!is_ok (&error)) {
+               mono_error_set_pending_exception (&error);
+               return FALSE;
+       }
+       guint32 result = (mono_object_isinst_checked (obj, klass, &error) != NULL);
+       mono_error_set_pending_exception (&error);
+       return result;
 }
 
 ICALL_EXPORT guint32
@@ -1856,8 +1870,11 @@ ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *ob
                return NULL;
        }
 
-       if (mono_security_core_clr_enabled ())
-               mono_security_core_clr_ensure_reflection_access_field (cf);
+       if (mono_security_core_clr_enabled () &&
+           !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
+               mono_error_set_pending_exception (&error);
+               return NULL;
+       }
 
        MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
        mono_error_set_pending_exception (&error);
@@ -1878,8 +1895,11 @@ ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *ob
                return;
        }
 
-       if (mono_security_core_clr_enabled ())
-               mono_security_core_clr_ensure_reflection_access_field (cf);
+       if (mono_security_core_clr_enabled () &&
+           !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
+               mono_error_set_pending_exception (&error);
+               return;
+       }
 
        type = mono_field_get_type_checked (cf, &error);
        if (!mono_error_ok (&error)) {
@@ -3056,8 +3076,11 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, Mo
 
        *exc = NULL;
 
-       if (mono_security_core_clr_enabled ())
-               mono_security_core_clr_ensure_reflection_access_method (m);
+       if (mono_security_core_clr_enabled () &&
+           !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
+               mono_error_set_pending_exception (&error);
+               return NULL;
+       }
 
        if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
                if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
@@ -3067,7 +3090,11 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, Mo
                }
 
                if (this_arg) {
-                       if (!mono_object_isinst (this_arg, m->klass)) {
+                       if (!mono_object_isinst_checked (this_arg, m->klass, &error)) {
+                               if (!is_ok (&error)) {
+                                       mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_error_convert_to_exception (&error));
+                                       return NULL;
+                               }
                                char *this_name = mono_type_get_full_name (mono_object_get_class (this_arg));
                                char *target_name = mono_type_get_full_name (m->klass);
                                char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
@@ -4373,8 +4400,7 @@ ves_icall_Type_GetNestedTypes (MonoReflectionType *type, MonoString *name, guint
 
        mono_ptr_array_destroy (tmp_array);
 
-       if (!str)
-               g_free (str);
+       g_free (str);
 
        return res;
 }
@@ -5809,10 +5835,13 @@ mono_memberref_is_method (MonoImage *image, guint32 token)
                mono_metadata_decode_blob_size (sig, &sig);
                return (*sig != 0x6);
        } else {
+               MonoError error;
                MonoClass *handle_class;
 
-               if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL))
+               if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
+                       mono_error_cleanup (&error); /* just probing, ignore error */
                        return FALSE;
+               }
 
                return mono_defaults.methodhandle_class == handle_class;
        }
@@ -5853,12 +5882,14 @@ ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 t
 
        if (image_is_dynamic (image)) {
                if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
-                       klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
+                       klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
+                       mono_error_cleanup (&error);
                        return klass ? &klass->byval_arg : NULL;
                }
 
                init_generic_context_from_args (&context, type_args, method_args);
-               klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context);
+               klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
+               mono_error_cleanup (&error);
                return klass ? &klass->byval_arg : NULL;
        }
 
@@ -5901,8 +5932,11 @@ ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32
        }
 
        if (image_is_dynamic (image)) {
-               if (table == MONO_TABLE_METHOD)
-                       return (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
+               if (table == MONO_TABLE_METHOD) {
+                       method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
+                       mono_error_cleanup (&error);
+                       return method;
+               }
 
                if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
                        *resolve_error = ResolveTokenError_BadTable;
@@ -5910,7 +5944,9 @@ ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32
                }
 
                init_generic_context_from_args (&context, type_args, method_args);
-               return (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context);
+               method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
+               mono_error_cleanup (&error);
+               return method;
        }
 
        if ((index <= 0) || (index > image->tables [table].rows)) {
@@ -5930,23 +5966,27 @@ ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32
 }
 
 ICALL_EXPORT MonoString*
-ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
 {
+       MonoError error;
        int index = mono_metadata_token_index (token);
 
-       *error = ResolveTokenError_Other;
+       *resolve_error = ResolveTokenError_Other;
 
        /* Validate token */
        if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
-               *error = ResolveTokenError_BadTable;
+               *resolve_error = ResolveTokenError_BadTable;
                return NULL;
        }
 
-       if (image_is_dynamic (image))
-               return (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
+       if (image_is_dynamic (image)) {
+               MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
+               mono_error_cleanup (&error);
+               return result;
+       }
 
        if ((index <= 0) || (index >= image->heap_us.size)) {
-               *error = ResolveTokenError_OutOfRange;
+               *resolve_error = ResolveTokenError_OutOfRange;
                return NULL;
        }
 
@@ -5974,8 +6014,11 @@ ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32
        }
 
        if (image_is_dynamic (image)) {
-               if (table == MONO_TABLE_FIELD)
-                       return (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
+               if (table == MONO_TABLE_FIELD) {
+                       field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
+                       mono_error_cleanup (&error);
+                       return field;
+               }
 
                if (mono_memberref_is_method (image, token)) {
                        *resolve_error = ResolveTokenError_BadTable;
@@ -5983,7 +6026,9 @@ ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32
                }
 
                init_generic_context_from_args (&context, type_args, method_args);
-               return (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context);
+               field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
+               mono_error_cleanup (&error);
+               return field;
        }
 
        if ((index <= 0) || (index > image->tables [table].rows)) {
@@ -6292,8 +6337,13 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon
        }
 
        if (mono_security_core_clr_enabled ()) {
-               if (!mono_security_core_clr_ensure_delegate_creation (method, throwOnBindFailure))
+               if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
+                       if (throwOnBindFailure)
+                               mono_error_set_pending_exception (&error);
+                       else
+                               mono_error_cleanup (&error);
                        return NULL;
+               }
        }
 
        delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
@@ -6459,7 +6509,11 @@ ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this_obj, MonoStri
                return NULL;
        }
 
-       tp->custom_type_info = (mono_object_isinst (this_obj, mono_defaults.iremotingtypeinfo_class) != NULL);
+       tp->custom_type_info = (mono_object_isinst_checked (this_obj, mono_defaults.iremotingtypeinfo_class, &error) != NULL);
+       if (!is_ok (&error)) {
+               mono_error_set_pending_exception (&error);
+               return NULL;
+       }
        tp->remote_class = mono_remote_class (domain, class_name, klass, &error);
        if (!is_ok (&error)) {
                mono_error_set_pending_exception (&error);
@@ -7983,20 +8037,6 @@ ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code)
        return message;
 }
 
-ICALL_EXPORT int
-ves_icall_System_StackFrame_GetILOffsetFromFile (MonoString *path, guint32 method_token, guint32 method_index, int native_offset)
-{
-       guint32 il_offset;
-       char *path_str = mono_string_to_utf8 (path);
-
-       if (!mono_seq_point_data_get_il_offset (path_str, method_token, method_index, native_offset, &il_offset))
-               il_offset = -1;
-
-       g_free (path_str);
-
-       return il_offset;
-}
-
 ICALL_EXPORT gpointer
 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcess (void)
 {