X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Ficall.c;h=181a8da644abd0a7fe5724ea3aa4febcef8c55de;hb=1a94285f85c1ba875655732e38653dec79081770;hp=cedc649af652e319e4b7342c67796c3164dd6850;hpb=69a9d04cabcddc9eabda99761c14c2e98c5bb1de;p=mono.git diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index cedc649af65..181a8da644a 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -14,8 +14,12 @@ #include #include #include +#ifdef HAVE_SYS_TIME_H #include +#endif +#ifdef HAVE_UNISTD_H #include +#endif #if defined (PLATFORM_WIN32) #include #endif @@ -66,6 +70,8 @@ static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void); +static MonoArray* +type_array_from_modifiers (MonoImage *image, MonoType *type, int optional); static inline MonoBoolean is_generic_parameter (MonoType *type) @@ -687,6 +693,25 @@ ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpoin memcpy (value, ea, esize); } +static void +ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value) +{ + MonoClass *ac; + MonoArray *ao; + gint32 esize; + gpointer *ea; + + MONO_ARCH_SAVE_REGS; + + ao = (MonoArray *)this; + ac = (MonoClass *)ao->obj.vtable->klass; + + esize = mono_array_element_size (ac); + ea = (gpointer*)((char*)ao->vector + (pos * esize)); + + memcpy (ea, value, esize); +} + static void ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle) { @@ -781,6 +806,18 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (Mo mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass)); } +static void +ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image) +{ + MONO_ARCH_SAVE_REGS; + + mono_image_check_for_module_cctor (image); + if (image->has_module_cctor) { + MonoClass *module_klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 1); + mono_runtime_class_init (mono_class_vtable (mono_domain_get (), module_klass)); + } +} + static MonoObject * ves_icall_System_Object_MemberwiseClone (MonoObject *this) { @@ -1018,8 +1055,7 @@ type_from_name (const char *str, MonoBoolean ignoreCase) /* mono_reflection_parse_type() mangles the string */ if (!mono_reflection_parse_type (temp_str, &info)) { - g_list_free (info.modifiers); - g_list_free (info.nested); + mono_reflection_free_type_info (&info); g_free (temp_str); return NULL; } @@ -1055,8 +1091,7 @@ type_from_name (const char *str, MonoBoolean ignoreCase) if (!info.assembly.name && !type) /* try mscorlib */ type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve); - g_list_free (info.modifiers); - g_list_free (info.nested); + mono_reflection_free_type_info (&info); g_free (temp_str); if (!type) @@ -1301,7 +1336,7 @@ ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField * int i; if (klass->generic_container || - (klass->generic_class && klass->generic_class->inst->is_open)) + (klass->generic_class && klass->generic_class->context.class_inst->is_open)) return NULL; info = mono_marshal_load_type_info (klass); @@ -1318,6 +1353,20 @@ ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField * return NULL; } +static MonoReflectionField* +ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass) +{ + g_assert (handle); + + if (!klass) + klass = handle->parent; + + /* FIXME: check that handle is a field of klass or of a parent: return null + * and throw the exception in managed code. + */ + return mono_field_get_object (mono_domain_get (), klass, handle); +} + static MonoReflectionField* ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle) { @@ -1328,6 +1377,14 @@ ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *hand return mono_field_get_object (mono_domain_get (), handle->parent, handle); } +static MonoArray* +ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional) +{ + MonoType *type = field->field->type; + + return type_array_from_modifiers (field->field->parent->image, type, optional); +} + static void ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info) { @@ -1335,10 +1392,11 @@ ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info) MonoMethodSignature* sig; MONO_ARCH_SAVE_REGS; - if (method->is_inflated) - method = mono_get_inflated_method (method); - sig = mono_method_signature (method); + if (!sig) { + g_assert (mono_loader_get_last_error ()); + mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ())); + } info->parent = mono_type_get_object (domain, &method->klass->byval_arg); info->ret = mono_type_get_object (domain, sig->ret); @@ -1360,11 +1418,6 @@ ves_icall_get_parameter_info (MonoMethod *method) { MonoDomain *domain = mono_domain_get (); - MONO_ARCH_SAVE_REGS; - - if (method->is_inflated) - method = mono_get_inflated_method (method); - return mono_param_get_objects (domain, method); } @@ -1376,11 +1429,6 @@ ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method) MonoMarshalSpec **mspecs; int i; - MONO_ARCH_SAVE_REGS; - - if (method->is_inflated) - method = mono_get_inflated_method (method); - mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1); mono_method_get_marshal_info (method, mspecs); @@ -1557,23 +1605,22 @@ ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *ob break; case MONO_TYPE_GENERICINST: { MonoGenericClass *gclass = cf->type->data.generic_class; - g_assert (!gclass->inst->is_open); + g_assert (!gclass->context.class_inst->is_open); if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) { MonoClass *nklass = mono_class_from_mono_type (cf->type); - guint8 *buf; + MonoObject *nullable; /* * Convert the boxed vtype into a Nullable structure. * This is complicated by the fact that Nullables have * a variable structure. */ - /* Allocate using alloca so it gets GC tracking */ - buf = alloca (nklass->instance_size); + nullable = mono_object_new (mono_domain_get (), nklass); - mono_nullable_init (buf, value, nklass); + mono_nullable_init (mono_object_unbox (nullable), value, nklass); - v = (gchar*)buf; + v = mono_object_unbox (nullable); } else if (gclass->container_class->valuetype && (v != NULL)) @@ -1600,7 +1647,7 @@ ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *ob static MonoReflectionType* ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod) { - MonoMethod *method = mono_get_inflated_method (rmethod->method.method); + MonoMethod *method = rmethod->method.method; return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg); } @@ -1687,8 +1734,7 @@ ves_icall_Type_GetInterfaces (MonoReflectionType* type) MONO_ARCH_SAVE_REGS; - /* open generic-instance classes can share their interface_id */ - if (class->generic_class && class->generic_class->inst->is_open) { + if (class->generic_class && class->generic_class->context.class_inst->is_open) { context = mono_class_get_context (class); class = class->generic_class->container_class; } @@ -1723,7 +1769,7 @@ ves_icall_Type_GetInterfaces (MonoReflectionType* type) for (i = 0; i < ifaces->len; ++i) { MonoClass *ic = g_ptr_array_index (ifaces, i); MonoType *ret = &ic->byval_arg; - if (context && ic->generic_class && ic->generic_class->inst->is_open) + if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open) ret = mono_class_inflate_generic_type (ret, context); mono_array_setref (intf, i, mono_type_get_object (domain, ret)); @@ -1749,11 +1795,11 @@ ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType mono_class_setup_vtable (class); /* type doesn't implement iface: the exception is thrown in managed code */ - if ((iclass->interface_id > class->max_interface_id) || !class->interface_offsets [iclass->interface_id]) + if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id)) return; len = mono_class_num_methods (iclass); - ioffset = class->interface_offsets [iclass->interface_id]; + ioffset = mono_class_interface_offset (class, iclass); domain = mono_object_domain (type); *targets = mono_array_new (domain, mono_defaults.method_info_class, len); *methods = mono_array_new (domain, mono_defaults.method_info_class, len); @@ -1786,10 +1832,12 @@ ves_icall_MonoType_GetElementType (MonoReflectionType *type) MONO_ARCH_SAVE_REGS; - // GetElementType should only return a type for: + // GelElementType should only return a type for: // Array Pointer PassedByRef if (type->type->byref) return mono_type_get_object (mono_object_domain (type), &class->byval_arg); + if (class->enumtype && class->enum_basetype) /* types that are modifierd typebuilkders may not have enum_basetype set */ + return mono_type_get_object (mono_object_domain (type), class->enum_basetype); else if (class->element_class && MONO_CLASS_IS_ARRAY (class)) return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg); else if (class->element_class && type->type->type == MONO_TYPE_PTR) @@ -1963,7 +2011,7 @@ ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type) mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg)); } } else if (klass->generic_class) { - MonoGenericInst *inst = klass->generic_class->inst; + MonoGenericInst *inst = klass->generic_class->context.class_inst; res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, inst->type_argc); for (i = 0; i < inst->type_argc; ++i) mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i])); @@ -2568,24 +2616,20 @@ ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method) static MonoReflectionMethod * ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method) { - MonoGenericContext *context; MonoMethodInflated *imethod; MONO_ARCH_SAVE_REGS; - if (!method->method->is_inflated) { - if (mono_method_signature (method->method)->generic_param_count) - return method; + if (method->method->generic_container) + return method; + if (!method->method->is_inflated) return NULL; - } imethod = (MonoMethodInflated *) method->method; - /* FIXME: should reflection_info be part of imethod? */ - context = mono_method_get_context (method->method); - if (context->gmethod && context->gmethod->reflection_info) - return context->gmethod->reflection_info; + if (imethod->reflection_info) + return imethod->reflection_info; else return mono_method_get_object ( mono_object_domain (method), imethod->declaring, NULL); @@ -2604,8 +2648,7 @@ ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method { MONO_ARCH_SAVE_REGS; - return !method->method->is_inflated && - (mono_method_signature (method->method)->generic_param_count != 0); + return method->method->generic_container != NULL; } static MonoArray* @@ -2619,14 +2662,14 @@ ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method) domain = mono_object_domain (method); if (method->method->is_inflated) { - MonoGenericMethod *gmethod = mono_method_get_context (method->method)->gmethod; + MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst; - if (gmethod) { - count = gmethod->inst->type_argc; + if (inst) { + count = inst->type_argc; res = mono_array_new (domain, mono_defaults.monotype_class, count); for (i = 0; i < count; i++) - mono_array_setref (res, i, mono_type_get_object (domain, gmethod->inst->type_argv [i])); + mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i])); return res; } @@ -2654,7 +2697,7 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr * is stupid), mono_runtime_invoke_*() calls the provided method, allowing * greater flexibility. */ - MonoMethod *m = mono_get_inflated_method (method->method); + MonoMethod *m = method->method; int pcount; void *obj = this; @@ -2676,7 +2719,7 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr if (pcount != mono_method_signature (m)->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")) + if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this) mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class.")); if (m->klass->image->assembly->ref_only) @@ -3053,9 +3096,15 @@ ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bfl compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp; handle_parent: + if (klass->exception_type != MONO_EXCEPTION_NONE) + mono_raise_exception (mono_class_get_exception_for_failure (klass)); + iter = NULL; while ((field = mono_class_get_fields (klass, &iter))) { match = 0; + + if (field->type == NULL) + continue; if (mono_field_is_deleted (field)) continue; if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) { @@ -3119,6 +3168,9 @@ ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, Mon len = 2; res = mono_array_new (domain, mono_defaults.field_info_class, len); handle_parent: + if (klass->exception_type != MONO_EXCEPTION_NONE) + mono_raise_exception (mono_class_get_exception_for_failure (klass)); + iter = NULL; while ((field = mono_class_get_fields (klass, &iter))) { match = 0; @@ -3202,7 +3254,10 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui mono_class_setup_vtable (klass); - nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size; + if (is_generic_parameter (type->type)) + nslots = klass->parent->vtable_size; + else + nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size; if (nslots >= sizeof (method_slots_default) * 8) { method_slots = g_new0 (guint32, nslots / 32 + 1); } else { @@ -3214,6 +3269,9 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui res = mono_array_new (domain, mono_defaults.method_info_class, len); handle_parent: mono_class_setup_vtable (klass); + if (klass->exception_type != MONO_EXCEPTION_NONE) + mono_raise_exception (mono_class_get_exception_for_failure (klass)); + iter = NULL; while ((method = mono_class_get_methods (klass, &iter))) { match = 0; @@ -3303,6 +3361,9 @@ ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflag klass = startklass = mono_class_from_mono_type (type->type); refklass = mono_class_from_mono_type (reftype->type); + if (klass->exception_type != MONO_EXCEPTION_NONE) + mono_raise_exception (mono_class_get_exception_for_failure (klass)); + if (!System_Reflection_ConstructorInfo) System_Reflection_ConstructorInfo = mono_class_from_name ( mono_defaults.corlib, "System.Reflection", "ConstructorInfo"); @@ -3406,6 +3467,14 @@ ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, res = mono_array_new (domain, System_Reflection_PropertyInfo, len); handle_parent: mono_class_setup_vtable (klass); + if (klass->exception_type != MONO_EXCEPTION_NONE) { + if (method_slots != method_slots_default) + g_free (method_slots); + if (name != NULL) + g_free (propname); + mono_raise_exception (mono_class_get_exception_for_failure (klass)); + } + iter = NULL; while ((prop = mono_class_get_properties (klass, &iter))) { match = 0; @@ -3502,6 +3571,9 @@ ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 domain = mono_object_domain (type); handle_parent: + if (klass->exception_type != MONO_EXCEPTION_NONE) + mono_raise_exception (mono_class_get_exception_for_failure (klass)); + iter = NULL; while ((event = mono_class_get_events (klass, &iter))) { if (strcmp (event->name, event_name)) @@ -3563,6 +3635,9 @@ ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, Mon len = 2; res = mono_array_new (domain, System_Reflection_EventInfo, len); handle_parent: + if (klass->exception_type != MONO_EXCEPTION_NONE) + mono_raise_exception (mono_class_get_exception_for_failure (klass)); + iter = NULL; while ((event = mono_class_get_events (klass, &iter))) { match = 0; @@ -3643,6 +3718,9 @@ ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint3 str = mono_string_to_utf8 (name); handle_parent: + if (klass->exception_type != MONO_EXCEPTION_NONE) + mono_raise_exception (mono_class_get_exception_for_failure (klass)); + /* * If a nested type is generic, return its generic type definition. * Note that this means that the return value is essentially a @@ -3695,6 +3773,8 @@ ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags) if (type->type->byref) return mono_array_new (domain, mono_defaults.monotype_class, 0); klass = mono_class_from_mono_type (type->type); + if (klass->exception_type != MONO_EXCEPTION_NONE) + mono_raise_exception (mono_class_get_exception_for_failure (klass)); /* * If a nested type is generic, return its generic type definition. @@ -3761,8 +3841,7 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/ if (!mono_reflection_parse_type (str, &info)) { g_free (str); - g_list_free (info.modifiers); - g_list_free (info.nested); + mono_reflection_free_type_info (&info); if (throwOnError) /* uhm: this is a parse error, though... */ mono_raise_exception (mono_get_exception_type_load (name, NULL)); /*g_print ("failed parse\n");*/ @@ -3803,8 +3882,7 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as else type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve); g_free (str); - g_list_free (info.modifiers); - g_list_free (info.nested); + mono_reflection_free_type_info (&info); if (!type) { MonoException *e = NULL; @@ -4360,6 +4438,18 @@ ves_icall_GetCurrentMethod (void) return mono_method_get_object (mono_domain_get (), m, NULL); } +static MonoReflectionMethod* +ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type) +{ + /* FIXME check that method belongs to klass or a parent */ + MonoClass *klass; + if (type) + klass = mono_class_from_mono_type (type); + else + klass = method->klass; + return mono_method_get_object (mono_domain_get (), method, klass); +} + static MonoReflectionMethod* ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method) { @@ -4431,8 +4521,10 @@ ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full if (!name) return NULL; - if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) + if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) { + g_free (name); return NULL; + } res = mono_string_new (domain, name); g_free (name); @@ -4837,13 +4929,8 @@ ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, } static gint32 -ves_icall_System_Reflection_Module_get_MDStreamVersion (MonoReflectionModule *module) +ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image) { - MonoImage *image = module->image; - - if (!image) - mono_raise_exception (mono_get_exception_not_supported ("")); - return (image->md_version_major << 16) | (image->md_version_minor); } @@ -4869,12 +4956,28 @@ mono_metadata_memberref_is_method (MonoImage *image, guint32 token) return (*sig != 0x6); } +static void +init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args) +{ + if (type_args) + context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args), + mono_array_addr (type_args, MonoType*, 0)); + else + context->class_inst = NULL; + if (method_args) + context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args), + mono_array_addr (method_args, MonoType*, 0)); + else + context->method_inst = NULL; +} + static MonoType* -ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoResolveTokenError *error) +ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error) { MonoClass *klass; int table = mono_metadata_token_table (token); int index = mono_metadata_token_index (token); + MonoGenericContext context; *error = ResolveTokenError_Other; @@ -4885,15 +4988,20 @@ ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 t return NULL; } - if (image->dynamic) - return mono_lookup_dynamic_token (image, token); + if (image->dynamic) { + if (type_args || method_args) + mono_raise_exception (mono_get_exception_not_implemented (NULL)); + return mono_lookup_dynamic_token (image, token, NULL); + } if ((index <= 0) || (index > image->tables [table].rows)) { *error = ResolveTokenError_OutOfRange; return NULL; } - klass = mono_class_get (image, token); + init_generic_context_from_args (&context, type_args, method_args); + klass = mono_class_get_full (image, token, &context); + if (klass) return &klass->byval_arg; else @@ -4901,10 +5009,12 @@ ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 t } static MonoMethod* -ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoResolveTokenError *error) +ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error) { int table = mono_metadata_token_table (token); int index = mono_metadata_token_index (token); + MonoGenericContext context; + MonoMethod *method; *error = ResolveTokenError_Other; @@ -4915,9 +5025,12 @@ ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 return NULL; } - if (image->dynamic) + if (image->dynamic) { + if (type_args || method_args) + mono_raise_exception (mono_get_exception_not_implemented (NULL)); /* FIXME: validate memberref token type */ - return mono_lookup_dynamic_token (image, token); + return mono_lookup_dynamic_token (image, token, NULL); + } if ((index <= 0) || (index > image->tables [table].rows)) { *error = ResolveTokenError_OutOfRange; @@ -4928,7 +5041,10 @@ ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 return NULL; } - return mono_get_method (image, token, NULL); + init_generic_context_from_args (&context, type_args, method_args); + method = mono_get_method_full (image, token, NULL, &context); + + return method; } static MonoString* @@ -4945,7 +5061,7 @@ ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 } if (image->dynamic) - return mono_lookup_dynamic_token (image, token); + return mono_lookup_dynamic_token (image, token, NULL); if ((index <= 0) || (index >= image->heap_us.size)) { *error = ResolveTokenError_OutOfRange; @@ -4958,11 +5074,13 @@ ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 } static MonoClassField* -ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoResolveTokenError *error) +ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error) { MonoClass *klass; int table = mono_metadata_token_table (token); int index = mono_metadata_token_index (token); + MonoGenericContext context; + MonoClassField *field; *error = ResolveTokenError_Other; @@ -4972,9 +5090,12 @@ ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 return NULL; } - if (image->dynamic) + if (image->dynamic) { + if (type_args || method_args) + mono_raise_exception (mono_get_exception_not_implemented (NULL)); /* FIXME: validate memberref token type */ - return mono_lookup_dynamic_token (image, token); + return mono_lookup_dynamic_token (image, token, NULL); + } if ((index <= 0) || (index > image->tables [table].rows)) { *error = ResolveTokenError_OutOfRange; @@ -4985,12 +5106,15 @@ ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 return NULL; } - return mono_field_from_token (image, token, &klass, NULL); + init_generic_context_from_args (&context, type_args, method_args); + field = mono_field_from_token (image, token, &klass, &context); + + return field; } static MonoObject* -ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoResolveTokenError *error) +ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error) { int table = mono_metadata_token_table (token); @@ -5000,7 +5124,7 @@ ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 case MONO_TABLE_TYPEDEF: case MONO_TABLE_TYPEREF: case MONO_TABLE_TYPESPEC: { - MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, error); + MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error); if (t) return (MonoObject*)mono_type_get_object (mono_domain_get (), t); else @@ -5008,14 +5132,14 @@ ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 } case MONO_TABLE_METHOD: case MONO_TABLE_METHODSPEC: { - MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error); + MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error); if (m) return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass); else return NULL; } case MONO_TABLE_FIELD: { - MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error); + MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error); if (f) return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f); else @@ -5023,14 +5147,14 @@ ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 } case MONO_TABLE_MEMBERREF: if (mono_metadata_memberref_is_method (image, token)) { - MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error); + MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error); if (m) return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass); else return NULL; } else { - MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error); + MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error); if (f) return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f); else @@ -5045,6 +5169,38 @@ ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 return NULL; } +static MonoArray* +ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error) +{ + int table = mono_metadata_token_table (token); + int idx = mono_metadata_token_index (token); + MonoTableInfo *tables = image->tables; + guint32 sig, len; + const char *ptr; + MonoArray *res; + + *error = ResolveTokenError_OutOfRange; + + /* FIXME: Support other tables ? */ + if (table != MONO_TABLE_STANDALONESIG) + return NULL; + + if (image->dynamic) + return NULL; + + if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows)) + return NULL; + + sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0); + + ptr = mono_metadata_blob_heap (image, sig); + len = mono_metadata_decode_blob_size (ptr, &ptr); + + res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len); + memcpy (mono_array_addr (res, guint8, 0), ptr, len); + return res; +} + static MonoReflectionType* ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers) { @@ -5177,6 +5333,23 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon return delegate; } +static void +ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this) +{ + gpointer iter; + MonoMethod *invoke; + + /* Find the Invoke method */ + iter = NULL; + while ((invoke = mono_class_get_methods (this->object.vtable->klass, &iter))) { + if (!strcmp (invoke->name, "Invoke")) + break; + } + g_assert (invoke); + + this->invoke_impl = mono_compile_method (mono_marshal_get_delegate_invoke (invoke)); +} + /* * Magic number to convert a time which is relative to * Jan 1, 1970 into a value which is relative to Jan 1, 0001. @@ -5653,12 +5826,12 @@ ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name) /* * There is no standard way to get at environ. */ -#ifndef __MINGW32_VERSION #ifndef _MSC_VER +#ifndef __MINGW32_VERSION extern -#endif char **environ; #endif +#endif static MonoArray * ves_icall_System_Environment_GetEnvironmentVariableNames (void) @@ -6165,6 +6338,15 @@ ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m) return mono_method_get_object (mono_domain_get (), result, NULL); } +static MonoString* +ves_icall_MonoMethod_get_name (MonoReflectionMethod *m) +{ + MonoMethod *method = m->method; + + MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name)); + return m->name; +} + static void mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start) { @@ -6351,7 +6533,7 @@ ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method) } /* - * We eturn NULL for no modifiers so the corlib code can return Type.EmptyTypes + * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes * and avoid useless allocations. */ static MonoArray* @@ -6436,7 +6618,14 @@ custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type) static MonoArray* custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type) { - return mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL); + MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL); + + if (mono_loader_get_last_error ()) { + mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ())); + g_assert_not_reached (); + } else { + return res; + } } static MonoBoolean