X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Ficall.c;h=181a8da644abd0a7fe5724ea3aa4febcef8c55de;hb=1a94285f85c1ba875655732e38653dec79081770;hp=91e983bde0a86347971d9f5313c71a1d60758838;hpb=b2262f41726a89c8209facb3ea9e4be9582422b5;p=mono.git diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index 91e983bde0a..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) @@ -187,6 +193,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 MonoClass *ac, *vc, *ec; gint32 esize, vsize; gpointer *ea, *va; + int et, vt; guint64 u64 = 0; gint64 i64 = 0; @@ -275,8 +282,16 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 vsize = mono_class_instance_size (vc) - sizeof (MonoObject); + et = ec->byval_arg.type; + if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype) + et = ec->byval_arg.data.klass->enum_basetype->type; + + vt = vc->byval_arg.type; + if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype) + vt = vc->byval_arg.data.klass->enum_basetype->type; + #define ASSIGN_UNSIGNED(etype) G_STMT_START{\ - switch (vc->byval_arg.type) { \ + switch (vt) { \ case MONO_TYPE_U1: \ case MONO_TYPE_U2: \ case MONO_TYPE_U4: \ @@ -298,7 +313,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 }G_STMT_END #define ASSIGN_SIGNED(etype) G_STMT_START{\ - switch (vc->byval_arg.type) { \ + switch (vt) { \ case MONO_TYPE_I1: \ case MONO_TYPE_I2: \ case MONO_TYPE_I4: \ @@ -324,7 +339,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 }G_STMT_END #define ASSIGN_REAL(etype) G_STMT_START{\ - switch (vc->byval_arg.type) { \ + switch (vt) { \ case MONO_TYPE_R4: \ case MONO_TYPE_R8: \ CHECK_WIDENING_CONVERSION(0); \ @@ -348,7 +363,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 } \ }G_STMT_END - switch (vc->byval_arg.type) { + switch (vt) { case MONO_TYPE_U1: u64 = *(guint8 *) va; break; @@ -384,7 +399,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 break; case MONO_TYPE_BOOLEAN: /* Boolean is only compatible with itself. */ - switch (ec->byval_arg.type) { + switch (et) { case MONO_TYPE_CHAR: case MONO_TYPE_U1: case MONO_TYPE_U2: @@ -404,7 +419,7 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 } /* If we can't do a direct copy, let's try a widening conversion. */ - switch (ec->byval_arg.type) { + switch (et) { case MONO_TYPE_CHAR: ASSIGN_UNSIGNED (guint16); case MONO_TYPE_U1: @@ -679,31 +694,40 @@ ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpoin } static void -ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle) +ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value) { - MonoClass *klass = array->obj.vtable->klass; - guint32 size = mono_array_element_size (klass); - int i; + MonoClass *ac; + MonoArray *ao; + gint32 esize; + gpointer *ea; MONO_ARCH_SAVE_REGS; - if (array->bounds == NULL) - size *= array->max_length; - else - for (i = 0; i < klass->rank; ++i) - size *= array->bounds [i].length; + ao = (MonoArray *)this; + ac = (MonoClass *)ao->obj.vtable->klass; - memcpy (mono_array_addr (array, char, 0), field_handle->data, size); + 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) +{ + MonoClass *klass = array->obj.vtable->klass; + guint32 size = mono_array_element_size (klass); + + size *= array->max_length; #if G_BYTE_ORDER != G_LITTLE_ENDIAN #define SWAP(n) {\ - gint i; \ - guint ## n tmp; \ guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \ + guint ## n *src = (guint ## n *) field_handle->data; \ + guint ## n *end = (guint ## n *)((char*)src + size); \ \ - for (i = 0; i < size; i += n/8, data++) { \ - tmp = read ## n (data); \ - *data = tmp; \ + for (; src < end; data++, src++) { \ + *data = read ## n (src); \ } \ } @@ -717,14 +741,32 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoAr break; case MONO_TYPE_I4: case MONO_TYPE_U4: + case MONO_TYPE_R4: SWAP (32); break; case MONO_TYPE_I8: case MONO_TYPE_U8: + case MONO_TYPE_R8: SWAP (64); break; + default: + memcpy (mono_array_addr (array, char, 0), field_handle->data, size); + break; + } +#else + memcpy (mono_array_addr (array, char, 0), field_handle->data, size); +#ifdef ARM_FPU_FPA + if (klass->element_class->byval_arg.type == MONO_TYPE_R8) { + gint i; + double tmp; + double *data = (double*)mono_array_addr (array, double, 0); + + for (i = 0; i < size; i++, data++) { + readr8 (data, &tmp); + *data = tmp; + } } - +#endif #endif } @@ -764,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) { @@ -1001,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; } @@ -1038,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) @@ -1071,8 +1123,14 @@ ves_icall_type_from_name (MonoString *name, type = type_from_name (str, ignoreCase); g_free (str); if (type == NULL){ + MonoException *e = NULL; + if (throwOnError) - mono_raise_exception (mono_get_exception_type_load (name, NULL)); + e = mono_get_exception_type_load (name, NULL); + + mono_loader_clear_error (); + if (e != NULL) + mono_raise_exception (e); } return type; @@ -1092,7 +1150,7 @@ ves_icall_type_from_handle (MonoType *handle) } static MonoBoolean -ves_icall_type_Equals (MonoReflectionType *type, MonoReflectionType *c) +ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c) { MONO_ARCH_SAVE_REGS; @@ -1278,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); @@ -1295,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) { @@ -1305,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) { @@ -1312,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); @@ -1337,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); } @@ -1353,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); @@ -1534,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)) @@ -1577,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); } @@ -1664,9 +1734,8 @@ 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) { - context = class->generic_class->context; + if (class->generic_class && class->generic_class->context.class_inst->is_open) { + context = mono_class_get_context (class); class = class->generic_class->container_class; } @@ -1700,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)); @@ -1726,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); @@ -1852,9 +1921,9 @@ ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type) if (type->type->byref) return NULL; if (type->type->type == MONO_TYPE_VAR) - class = type->type->data.generic_param->owner->klass; + class = type->type->data.generic_param->owner->owner.klass; else if (type->type->type == MONO_TYPE_MVAR) - class = type->type->data.generic_param->method->klass; + class = type->type->data.generic_param->owner->owner.method->klass; else class = mono_class_from_mono_type (type->type)->nested_in; @@ -1942,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])); @@ -2007,6 +2076,7 @@ ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array) } geninst = mono_reflection_bind_generic_parameters (type, count, types); + g_free (types); if (!geninst) return NULL; @@ -2138,7 +2208,7 @@ ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type) return NULL; inflated = mono_class_inflate_generic_type ( - parent->type, gclass->generic_class.generic_class.context); + parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass)); return mono_type_get_object (domain, inflated); } @@ -2147,7 +2217,7 @@ static MonoArray* ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type) { static MonoClass *System_Reflection_MonoGenericClass; - MonoDynamicGenericClass *gclass; + MonoGenericClass *gclass; MonoReflectionTypeBuilder *tb = NULL; MonoClass *klass = NULL; MonoDomain *domain; @@ -2164,14 +2234,14 @@ ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type) domain = mono_object_domain (type); - g_assert (type->type.type->data.generic_class->is_dynamic); - gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class; + gclass = type->type.type->data.generic_class; + g_assert (gclass->is_dynamic); if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) { tb = (MonoReflectionTypeBuilder *) type->generic_type; icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0; } else { - klass = gclass->generic_class.generic_class.container_class; + klass = gclass->container_class; mono_class_init (klass); icount = klass->interface_count; } @@ -2188,8 +2258,7 @@ ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type) } else it = &klass->interfaces [i]->byval_arg; - it = mono_class_inflate_generic_type ( - it, gclass->generic_class.generic_class.context); + it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass)); iface = mono_type_get_object (domain, it); mono_array_setref (res, i, iface); @@ -2473,7 +2542,7 @@ ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type) if (type->type->byref || type->type->type != MONO_TYPE_MVAR) return NULL; - method = type->type->data.generic_param->method; + method = type->type->data.generic_param->owner->owner.method; g_assert (method); klass = mono_class_from_mono_type (type->type); return mono_method_get_object (mono_object_domain (type), method, klass); @@ -2551,16 +2620,16 @@ ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method) 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; - if (imethod->context->gmethod && imethod->context->gmethod->reflection_info) - return imethod->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); @@ -2579,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* @@ -2594,15 +2662,14 @@ ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method) domain = mono_object_domain (method); if (method->method->is_inflated) { - MonoMethodInflated *imethod = (MonoMethodInflated *) method->method; - MonoGenericMethod *gmethod = imethod->context->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; } @@ -2630,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; @@ -2652,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) @@ -2736,7 +2803,8 @@ ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoA } else if (!strcmp (m->name, "FieldSetter")) { MonoClass *k = this->vtable->klass; MonoString *name; - guint32 size, align; + guint32 size; + gint32 align; char *str; /* If this is a proxy, then it must be a CBO */ @@ -3028,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) { @@ -3094,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; @@ -3104,7 +3181,8 @@ handle_parent: match++; } else { if (bflags & BFLAGS_NonPublic) { - if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE || startklass == klass) + /* Serialization currently depends on the old behavior. + * if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE || startklass == klass)*/ match++; } } @@ -3176,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 { @@ -3188,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; @@ -3277,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"); @@ -3380,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; @@ -3476,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)) @@ -3537,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; @@ -3603,7 +3704,7 @@ static MonoReflectionType * ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags) { MonoDomain *domain; - MonoClass *startklass, *klass; + MonoClass *klass; MonoClass *nested; GList *tmpn; char *str; @@ -3613,10 +3714,25 @@ ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint3 domain = ((MonoObject *)type)->vtable->domain; if (type->type->byref) return NULL; - klass = startklass = mono_class_from_mono_type (type->type); + klass = mono_class_from_mono_type (type->type); 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 + * nested type of the generic type definition of @klass. + * + * A note in MSDN claims that a generic type definition can have + * nested types that aren't generic. In any case, the container of that + * nested type would be the generic type definition. + */ + if (klass->generic_class) + klass = klass->generic_class->container_class; + for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) { int match = 0; nested = tmpn->data; @@ -3645,7 +3761,7 @@ ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags) { MonoDomain *domain; GList *tmpn; - MonoClass *startklass, *klass; + MonoClass *klass; MonoArray *res; MonoObject *member; int i, len, match; @@ -3656,7 +3772,21 @@ ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags) domain = ((MonoObject *)type)->vtable->domain; if (type->type->byref) return mono_array_new (domain, mono_defaults.monotype_class, 0); - klass = startklass = mono_class_from_mono_type (type->type); + 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. + * Note that this means that the return value is essentially the set + * of nested types of the generic type definition of @klass. + * + * A note in MSDN claims that a generic type definition can have + * nested types that aren't generic. In any case, the container of that + * nested type would be the generic type definition. + */ + if (klass->generic_class) + klass = klass->generic_class->container_class; i = 0; len = 1; @@ -3711,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");*/ @@ -3753,12 +3882,18 @@ 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; + if (throwOnError) - mono_raise_exception (mono_get_exception_type_load (name, NULL)); - /* g_print ("failed find\n"); */ + e = mono_get_exception_type_load (name, NULL); + + mono_loader_clear_error (); + + if (e != NULL) + mono_raise_exception (e); + return NULL; } @@ -3768,6 +3903,7 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as if (throwOnError && klass->exception_type) { /* report SecurityException (or others) that occured when loading the assembly */ MonoException *exc = mono_class_get_exception_for_failure (klass); + mono_loader_clear_error (); mono_raise_exception (exc); } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) { return NULL; @@ -4302,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) { @@ -4373,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); @@ -4700,6 +4850,7 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, list = NULL; exc = mono_get_exception_reflection_type_load (res, exl); + mono_loader_clear_error (); mono_raise_exception (exc); } @@ -4778,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); } @@ -4810,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; @@ -4826,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 @@ -4842,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; @@ -4856,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; @@ -4869,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* @@ -4886,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; @@ -4899,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; @@ -4913,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; @@ -4926,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); @@ -4941,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 @@ -4949,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 @@ -4964,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 @@ -4986,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) { @@ -5118,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. @@ -5595,9 +5827,11 @@ ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name) * There is no standard way to get at environ. */ #ifndef _MSC_VER +#ifndef __MINGW32_VERSION extern -#endif char **environ; +#endif +#endif static MonoArray * ves_icall_System_Environment_GetEnvironmentVariableNames (void) @@ -5988,6 +6222,21 @@ ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void) return mcpath; } +static MonoString * +ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (void) +{ + const gchar *machine_config; + + MONO_ARCH_SAVE_REGS; + + machine_config = mono_get_machine_config (); + + if (!machine_config) + return NULL; + + return mono_string_new (mono_domain_get (), machine_config); +} + static MonoString * ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void) { @@ -6089,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) { @@ -6104,7 +6362,8 @@ mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start) if (start) { iter->args = start; } else { - guint32 i, align, arg_size; + guint32 i, arg_size; + gint32 align; iter->args = argsp + sizeof (gpointer); #ifndef MONO_ARCH_REGPARMS for (i = 0; i < iter->sig->sentinelpos; ++i) { @@ -6121,7 +6380,8 @@ mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start) static MonoTypedRef mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter) { - guint32 i, align, arg_size; + guint32 i, arg_size; + gint32 align; MonoTypedRef res; MONO_ARCH_SAVE_REGS; @@ -6145,7 +6405,8 @@ mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter) static MonoTypedRef mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type) { - guint32 i, align, arg_size; + guint32 i, arg_size; + gint32 align; MonoTypedRef res; MONO_ARCH_SAVE_REGS; @@ -6271,6 +6532,74 @@ ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method) return method->method->token; } +/* + * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes + * and avoid useless allocations. + */ +static MonoArray* +type_array_from_modifiers (MonoImage *image, MonoType *type, int optional) +{ + MonoArray *res; + int i, count = 0; + for (i = 0; i < type->num_mods; ++i) { + if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) + count++; + } + if (!count) + return NULL; + res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count); + count = 0; + for (i = 0; i < type->num_mods; ++i) { + if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) { + MonoClass *klass = mono_class_get (image, type->modifiers [i].token); + mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg)); + count++; + } + } + return res; +} + +static MonoArray* +param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional) +{ + MonoType *type = param->ClassImpl->type; + MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl; + MonoImage *image = method->method->klass->image; + int pos = param->PositionImpl; + MonoMethodSignature *sig = mono_method_signature (method->method); + if (pos == -1) + type = sig->ret; + else + type = sig->params [pos]; + + return type_array_from_modifiers (image, type, optional); +} + +static MonoType* +get_property_type (MonoProperty *prop) +{ + MonoMethodSignature *sig; + if (prop->get) { + sig = mono_method_signature (prop->get); + return sig->ret; + } else if (prop->set) { + sig = mono_method_signature (prop->set); + return sig->params [sig->param_count - 1]; + } + return NULL; +} + +static MonoArray* +property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional) +{ + MonoType *type = get_property_type (property->property); + MonoImage *image = property->klass->image; + + if (!type) + return NULL; + return type_array_from_modifiers (image, type, optional); +} + static MonoBoolean custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type) { @@ -6289,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