2004-10-12 Martin Baulig <martin@ximian.com>
[mono.git] / mono / metadata / icall.c
index fab4ce15f23670821c48777e3daa54f04d06a3a3..f9d71dbe17ebb2bb4001af0fa1b5d2b4e00e0cb0 100644 (file)
@@ -1215,7 +1215,7 @@ ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *
        MonoMarshalType *info;
        int i;
 
-       if (klass->gen_params ||
+       if (klass->generic_container ||
            (klass->generic_inst && klass->generic_inst->is_open))
                return NULL;
 
@@ -1506,7 +1506,8 @@ ves_icall_Type_GetInterfaces (MonoReflectionType* type)
 {
        MonoDomain *domain = mono_object_domain (type); 
        MonoArray *intf;
-       int ninterf, i;
+       GPtrArray *ifaces = NULL;
+       int i;
        MonoClass *class = mono_class_from_mono_type (type->type);
        MonoClass *parent;
        MonoBitSet *slots = mono_bitset_new (class->max_interface_id + 1, 0);
@@ -1519,32 +1520,37 @@ ves_icall_Type_GetInterfaces (MonoReflectionType* type)
                return mono_array_new (domain, mono_defaults.monotype_class, 0);
        }
 
-       ninterf = 0;
        for (parent = class; parent; parent = parent->parent) {
-               for (i = 0; i < parent->interface_count; ++i) {
-                       if (mono_bitset_test (slots, parent->interfaces [i]->interface_id))
-                               continue;
+               GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
+               if (tmp_ifaces) {
+                       for (i = 0; i < tmp_ifaces->len; ++i) {
+                               MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
+
+                               if (mono_bitset_test (slots, ic->interface_id))
+                                       continue;
 
-                       mono_bitset_set (slots, parent->interfaces [i]->interface_id);
-                       ++ninterf;
+                               mono_bitset_set (slots, ic->interface_id);
+                               if (ifaces == NULL)
+                                       ifaces = g_ptr_array_new ();
+                               g_ptr_array_add (ifaces, ic);
+                       }
+                       g_ptr_array_free (tmp_ifaces, TRUE);
                }
        }
+       mono_bitset_free (slots);
 
-       intf = mono_array_new (domain, mono_defaults.monotype_class, ninterf);
-       ninterf = 0;
-       for (parent = class; parent; parent = parent->parent) {
-               for (i = 0; i < parent->interface_count; ++i) {
-                       if (!mono_bitset_test (slots, parent->interfaces [i]->interface_id))
-                               continue;
-
-                       mono_bitset_clear (slots, parent->interfaces [i]->interface_id);
-                       mono_array_set (intf, gpointer, ninterf,
-                                       mono_type_get_object (domain, &parent->interfaces [i]->byval_arg));
-                       ++ninterf;
-               }
+       if (!ifaces)
+               return mono_array_new (domain, mono_defaults.monotype_class, 0);
+               
+       intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
+       for (i = 0; i < ifaces->len; ++i) {
+               MonoClass *ic = g_ptr_array_index (ifaces, i);
+               
+               mono_array_set (intf, gpointer, i,
+                                               mono_type_get_object (domain, &ic->byval_arg));
        }
+       g_ptr_array_free (ifaces, TRUE);
 
-       mono_bitset_free (slots);
        return intf;
 }
 
@@ -1711,7 +1717,10 @@ ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
        while (class->nested_in)
                class = class->nested_in;
 
-       return mono_string_new (domain, class->name_space);
+       if (class->name_space [0] == '\0')
+               return NULL;
+       else
+               return mono_string_new (domain, class->name_space);
 }
 
 static gint32
@@ -1736,10 +1745,11 @@ ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
 
        if (type->type->byref) {
                res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, 0);
-       } else if (klass->gen_params) {
-               res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, klass->num_gen_params);
-               for (i = 0; i < klass->num_gen_params; ++i) {
-                       pklass = mono_class_from_generic_parameter (&klass->gen_params [i], klass->image, FALSE);
+       } else if (klass->generic_container) {
+               MonoGenericContainer *container = klass->generic_container;
+               res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, container->type_argc);
+               for (i = 0; i < container->type_argc; ++i) {
+                       pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
                        mono_array_set (res, gpointer, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
                }
        } else if (klass->generic_inst) {
@@ -1764,7 +1774,7 @@ ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
                return FALSE;
        klass = mono_class_from_mono_type (type->type);
 
-       return klass->gen_params != NULL;
+       return klass->generic_container != NULL;
 }
 
 static MonoReflectionType*
@@ -1776,7 +1786,7 @@ ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
        if (type->type->byref)
                return NULL;
        klass = mono_class_from_mono_type (type->type);
-       if (klass->gen_params) {
+       if (klass->generic_container) {
                return type; /* check this one */
        }
        if (klass->generic_inst) {
@@ -1880,7 +1890,7 @@ ves_icall_MonoType_get_HasGenericArguments (MonoReflectionType *type)
        if (type->type->byref)
                return FALSE;
        klass = mono_class_from_mono_type (type->type);
-       if (klass->gen_params || klass->generic_inst)
+       if (klass->generic_container || klass->generic_inst)
                return TRUE;
        return FALSE;
 }
@@ -1929,7 +1939,7 @@ ves_icall_MonoGenericInst_GetParentType (MonoReflectionGenericInst *type)
                return NULL;
 
        klass = mono_class_from_mono_type (ginst->parent);
-       if (!klass->generic_inst && !klass->gen_params)
+       if (!klass->generic_inst && !klass->generic_container)
                return NULL;
 
        return mono_type_get_object (mono_object_domain (type), ginst->parent);
@@ -2307,7 +2317,7 @@ ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
        res = mono_array_new (domain, mono_defaults.monotype_class, count);
 
        for (i = 0; i < count; i++) {
-               MonoGenericParam *param = &mn->gen_params [i];
+               MonoGenericParam *param = &mn->generic_container->type_params [i];
                MonoClass *pklass = mono_class_from_generic_parameter (
                        param, method->method->klass->image, TRUE);
                mono_array_set (res, gpointer, i,
@@ -2345,6 +2355,9 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr
        if (pcount != m->signature->param_count)
                mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
 
+       if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor"))
+               mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
+
        if (m->klass->rank && !strcmp (m->name, ".ctor")) {
                int i;
                guint32 *lengths;
@@ -3703,7 +3716,7 @@ ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly
        MonoClass *klass;
        int i, j, file_count = 0;
        MonoImage **modules;
-       guint32 module_count;
+       guint32 module_count, real_module_count;
        MonoTableInfo *table;
 
        g_assert (assembly->assembly->image != NULL);
@@ -3714,13 +3727,21 @@ ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly
        modules = assembly->assembly->image->modules;
        module_count = assembly->assembly->image->module_count;
 
+       real_module_count = 0;
+       for (i = 0; i < module_count; ++i)
+               if (modules [i])
+                       real_module_count ++;
+
        klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
-       res = mono_array_new (domain, klass, 1 + module_count + file_count);
+       res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
 
        mono_array_set (res, gpointer, 0, mono_module_get_object (domain, assembly->assembly->image));
        j = 1;
-       for (i = 0; i < module_count; ++i, ++j)
-               mono_array_set (res, gpointer, j, mono_module_get_object (domain, modules[i]));
+       for (i = 0; i < module_count; ++i)
+               if (modules [i]) {
+                       mono_array_set (res, gpointer, j, mono_module_get_object (domain, modules[i]));
+                       ++j;
+               }
 
        for (i = 0; i < file_count; ++i, ++j)
                mono_array_set (res, gpointer, j, mono_module_file_get_object (domain, assembly->assembly->image, i));
@@ -3744,6 +3765,12 @@ ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *
        return mono_method_get_object (mono_domain_get (), method, NULL);
 }
 
+static MonoReflectionMethodBody*
+ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
+{
+       return mono_method_body_get_object (mono_domain_get (), method);
+}
+
 static MonoReflectionAssembly*
 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
 {
@@ -3969,7 +3996,7 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly,
 
        if (assembly->assembly->dynamic) {
                MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
-               if (abuilder->modules)
+               if (abuilder->modules) {
                        for (i = 0; i < mono_array_length(abuilder->modules); i++) {
                                MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
                                if (res == NULL)
@@ -3992,6 +4019,20 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly,
                                        }
                                }
                        }
+
+                       /* 
+                        * Replace TypeBuilders with the created types to be compatible
+                        * with MS.NET.
+                        */
+                       if (res) {
+                               for (i = 0; i < mono_array_length (res); ++i) {
+                                       MonoReflectionTypeBuilder *tb = mono_array_get (res, MonoReflectionTypeBuilder*, i);
+                                       if (tb->created)
+                                               mono_array_set (res, MonoReflectionType*, i, tb->created);
+                               }
+                       }
+               }
+
                if (abuilder->loaded_modules)
                        for (i = 0; i < mono_array_length(abuilder->loaded_modules); i++) {
                                MonoReflectionModule *rm = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
@@ -4058,6 +4099,11 @@ ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
        MONO_ARCH_SAVE_REGS;
 
        g_assert (module->image);
+
+       if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
+               /* These images do not have a global type */
+               return NULL;
+
        klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
        return mono_type_get_object (domain, &klass->byval_arg);
 }
@@ -4084,8 +4130,9 @@ static void
 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
 {
        if (image->dynamic) {
-               *pe_kind = 0x1; /* ILOnly */
-               *machine = 0x14c; /* I386 */
+               MonoDynamicImage *dyn = (MonoDynamicImage*)image;
+               *pe_kind = dyn->pe_kind;
+               *machine = dyn->machine;
        }
        else {
                *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
@@ -4112,7 +4159,7 @@ mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
        mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
        sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
        mono_metadata_decode_blob_size (sig, &sig);
-       return (*sig == 0x6);
+       return (*sig != 0x6);
 }
 
 static MonoType*
@@ -5914,6 +5961,7 @@ static const IcallEntry assembly_icalls [] = {
 
 static const IcallEntry methodbase_icalls [] = {
        {"GetCurrentMethod", ves_icall_GetCurrentMethod},
+       {"GetMethodBodyInternal", ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal},
        {"GetMethodFromHandleInternal", ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal}
 };
 
@@ -6066,6 +6114,7 @@ static const IcallEntry signaturehelper_icalls [] = {
 };
 
 static const IcallEntry typebuilder_icalls [] = {
+       {"create_generic_class", mono_reflection_create_generic_class},
        {"create_internal_class", mono_reflection_create_internal_class},
        {"create_runtime_class", mono_reflection_create_runtime_class},
        {"get_IsGenericParameter", ves_icall_TypeBuilder_get_IsGenericParameter},
@@ -6100,6 +6149,7 @@ static const IcallEntry marshal_icalls [] = {
        {"DestroyStructure", ves_icall_System_Runtime_InteropServices_Marshal_DestroyStructure},
        {"FreeCoTaskMem", ves_icall_System_Runtime_InteropServices_Marshal_FreeCoTaskMem},
        {"FreeHGlobal", ves_icall_System_Runtime_InteropServices_Marshal_FreeHGlobal},
+       {"GetDelegateForFunctionPointerInternal", ves_icall_System_Runtime_InteropServices_Marshal_GetDelegateForFunctionPointerInternal},
        {"GetFunctionPointerForDelegateInternal", mono_delegate_to_ftnptr},
        {"GetLastWin32Error", ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error},
        {"OffsetOf", ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf},