Merge pull request #2820 from kumpera/license-change-rebased
[mono.git] / mono / metadata / reflection.c
index d0ec44bbcb578434c4d77ade662ee4fa378d1a2c..200c41e5f804fa015801317184020629b1c46501 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
  * Copyright 2011 Rodrigo Kumpera
  *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 #include <config.h>
 #include "mono/utils/mono-digest.h"
@@ -187,6 +188,8 @@ static gboolean is_sr_mono_property (MonoClass *klass);
 static gboolean is_sre_method_on_tb_inst (MonoClass *klass);
 static gboolean is_sre_ctor_on_tb_inst (MonoClass *klass);
 
+static gboolean type_is_reference (MonoType *type);
+
 static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
 static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error);
@@ -5533,7 +5536,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
        /* Check for user defined reflection objects */
        /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
        if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
-               mono_error_set_generic_error (error, "System", "NotSupportedException", "User defined subclasses of System.Type are not yet supported");
+               mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
                return 0;
        }
 
@@ -8923,8 +8926,8 @@ mono_reflection_get_token_checked (MonoObject *obj, MonoError *error)
        } else if (strcmp (klass->name, "Assembly") == 0 || strcmp (klass->name, "MonoAssembly") == 0) {
                token = mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1);
        } else {
-               mono_error_set_generic_error (error, "System", "NotImplementedException",
-                                             "MetadataToken is not supported for type '%s.%s'", klass->name_space, klass->name);
+               mono_error_set_not_implemented (error, "MetadataToken is not supported for type '%s.%s'",
+                                               klass->name_space, klass->name);
                return 0;
        }
 
@@ -9215,6 +9218,28 @@ handle_type:
        return NULL;
 }
 
+static MonoObject*
+load_cattr_value_boxed (MonoDomain *domain, MonoImage *image, MonoType *t, const char* p, const char** end, MonoError *error)
+{
+       mono_error_init (error);
+
+       gboolean is_ref = type_is_reference (t);
+
+       void *val = load_cattr_value (image, t, p, end, error);
+       if (!is_ok (error)) {
+               if (is_ref)
+                       g_free (val);
+               return NULL;
+       }
+
+       if (is_ref)
+               return (MonoObject*)val;
+
+       MonoObject *boxed = mono_value_box_checked (domain, mono_class_from_mono_type (t), val, error);
+       g_free (val);
+       return boxed;
+}
+
 static MonoObject*
 create_cattr_typed_arg (MonoType *t, MonoObject *val, MonoError *error)
 {
@@ -9550,21 +9575,10 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth
        p += 2;
        for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
                MonoObject *obj;
-               void *val;
 
-               val = load_cattr_value (image, mono_method_signature (method)->params [i], p, &p, error);
-               if (!mono_error_ok (error)) {
-                       if (!type_is_reference (mono_method_signature (method)->params [i]))
-                               g_free (val);
-                       return;
-               }
-
-               obj = (MonoObject *)(type_is_reference (mono_method_signature (method)->params [i]) ?
-                       val : mono_value_box (domain, mono_class_from_mono_type (mono_method_signature (method)->params [i]), val));
+               obj = load_cattr_value_boxed (domain, image, mono_method_signature (method)->params [i], p, &p, error);
+               return_if_nok (error);
                mono_array_setref (typedargs, i, obj);
-
-               if (!type_is_reference (mono_method_signature (method)->params [i]))
-                       g_free (val);
        }
 
        named = p;
@@ -9607,7 +9621,6 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth
                if (named_type == 0x53) {
                        MonoObject *obj;
                        MonoClassField *field = mono_class_get_field_from_name (attrklass, name);
-                       void *val;
 
                        if (!field) {
                                g_free (name);
@@ -9617,23 +9630,17 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth
                        arginfo [j].type = field->type;
                        arginfo [j].field = field;
 
-                       val = load_cattr_value (image, field->type, named, &named, error);
-                       if (!mono_error_ok (error)) {
-                               if (!type_is_reference (field->type))
-                                       g_free (val);
+                       obj = load_cattr_value_boxed (domain, image, field->type, named, &named, error);
+                       if (!is_ok (error)) {
                                g_free (name);
                                return;
                        }
-
-                       obj = (MonoObject *)(type_is_reference (field->type) ? val : mono_value_box (domain, mono_class_from_mono_type (field->type), val));
                        mono_array_setref (namedargs, j, obj);
-                       if (!type_is_reference (field->type))
-                               g_free (val);
+
                } else if (named_type == 0x54) {
                        MonoObject *obj;
                        MonoType *prop_type;
                        MonoProperty *prop = mono_class_get_property_from_name (attrklass, name);
-                       void *val;
 
                        if (!prop || !prop->set) {
                                g_free (name);
@@ -9646,18 +9653,12 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth
                        arginfo [j].type = prop_type;
                        arginfo [j].prop = prop;
 
-                       val = load_cattr_value (image, prop_type, named, &named, error);
-                       if (!mono_error_ok (error)) {
-                               if (!type_is_reference (prop_type))
-                                       g_free (val);
+                       obj = load_cattr_value_boxed (domain, image, prop_type, named, &named, error);
+                       if (!is_ok (error)) {
                                g_free (name);
                                return;
                        }
-
-                       obj = (MonoObject *)(type_is_reference (prop_type) ? val : mono_value_box (domain, mono_class_from_mono_type (prop_type), val));
                        mono_array_setref (namedargs, j, obj);
-                       if (!type_is_reference (prop_type))
-                               g_free (val);
                }
                g_free (name);
        }
@@ -10371,7 +10372,7 @@ mono_reflection_get_custom_attrs_info_checked (MonoObject *obj, MonoError *error
 #endif
                else {
                        char *type_name = mono_type_get_full_name (member_class);
-                       mono_error_set_generic_error (error, "System", "NotSupportedException",
+                       mono_error_set_not_supported (error,
                                                      "Custom attributes on a ParamInfo with member %s are not supported",
                                                      type_name);
                        g_free (type_name);
@@ -10944,7 +10945,7 @@ mono_reflection_type_resolve_user_types (MonoReflectionType *type, MonoError *er
                type = mono_reflection_type_get_underlying_system_type (type, error);
                return_val_if_nok (error, NULL);
                if (is_usertype (type)) {
-                       mono_error_set_generic_error (error, "System", "NotSupportedException", "User defined subclasses of System.Type are not yet supported22");
+                       mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported22");
                        return NULL;
                }
        }
@@ -11133,10 +11134,14 @@ handle_type:
                
                klass = mono_object_class (arg);
 
-               if (mono_object_isinst (arg, mono_defaults.systemtype_class)) {
+               if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
                        *p++ = 0x50;
                        goto handle_type;
-               } else if (klass->enumtype) {
+               } else {
+                       return_if_nok (error);
+               }
+
+               if (klass->enumtype) {
                        *p++ = 0x55;
                } else if (klass == mono_defaults.string_class) {
                        simple_type = MONO_TYPE_STRING;
@@ -12894,7 +12899,7 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        }
 
        klass->instance_size = MAX (klass->instance_size, real_size);
-       mono_class_layout_fields (klass);
+       mono_class_layout_fields (klass, klass->instance_size);
 }
 
 static void
@@ -13691,25 +13696,27 @@ mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32
  * LOCKING: Take the loader lock
  */
 gpointer
-mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context)
+mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
 {
-       MonoError error;
        MonoDynamicImage *assembly = (MonoDynamicImage*)image;
        MonoObject *obj;
        MonoClass *klass;
 
+       mono_error_init (error);
+       
        obj = lookup_dyn_token (assembly, token);
        if (!obj) {
                if (valid_token)
                        g_error ("Could not find required dynamic token 0x%08x", token);
-               else
+               else {
+                       mono_error_set_execution_engine (error, "Could not find dynamic token 0x%08x", token);
                        return NULL;
+               }
        }
 
        if (!handle_class)
                handle_class = &klass;
-       gpointer result = resolve_object (image, obj, handle_class, context, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       gpointer result = resolve_object (image, obj, handle_class, context, error);
        return result;
 }