+2008-03-20 Mark Probst <mark.probst@gmail.com>
+
+ * generic-sharing.c, class-internals.h: Code for putting
+ reflection types into the runtime generic context.
+
2008-03-19 Rodrigo Kumpera <rkumpera@novell.com>
* icall.c (ves_icall_get_method_info): Return correct values for the call convention.
MONO_RGCTX_INFO_STATIC_DATA,
MONO_RGCTX_INFO_KLASS,
MONO_RGCTX_INFO_VTABLE,
+ MONO_RGCTX_INFO_REFLECTION_TYPE,
MONO_RGCTX_INFO_METHOD,
MONO_RGCTX_INFO_GENERIC_METHOD_CODE
};
case MONO_RGCTX_INFO_STATIC_DATA:
case MONO_RGCTX_INFO_KLASS:
case MONO_RGCTX_INFO_VTABLE:
+ case MONO_RGCTX_INFO_REFLECTION_TYPE:
return mono_class_inflate_generic_type (data, context);
case MONO_RGCTX_INFO_METHOD:
return class_type_info (domain, arg_class, oti->info_type);
}
+ case MONO_RGCTX_INFO_REFLECTION_TYPE:
+ return mono_type_get_object (domain, data);
case MONO_RGCTX_INFO_METHOD:
return data;
case MONO_RGCTX_INFO_GENERIC_METHOD_CODE:
case MONO_RGCTX_INFO_STATIC_DATA:
case MONO_RGCTX_INFO_KLASS:
case MONO_RGCTX_INFO_VTABLE:
+ case MONO_RGCTX_INFO_REFLECTION_TYPE:
return mono_class_from_mono_type (data1) == mono_class_from_mono_type (data2);
case MONO_RGCTX_INFO_METHOD:
case MONO_RGCTX_INFO_GENERIC_METHOD_CODE:
+2008-03-20 Mark Probst <mark.probst@gmail.com>
+
+ * generic-sharing.c: Put reflection types in the extensible part
+ of the runtime generic context.
+
+ * mini.c: Generic sharing of the GetTypeHandle special case of the
+ ldtoken instruction.
+
2008-03-20 Zoltan Varga <vargaz@gmail.com>
* mini.h (MONO_BB_FOR_EACH_INS_SAFE): New helper macro.
mono_class_get_runtime_generic_context_template (method_klass);
int i;
- for (i = 0; i < rgctx_template->num_arg_infos; ++i) {
- MonoType *arg_info = rgctx_template->arg_infos [i];
- MonoType *inflated_arg;
-
- if (arg_info == NULL)
- continue;
-
- inflated_arg = mono_class_inflate_generic_type(arg_info, generic_context);
-
- if (inflated_type_is_equal_to_class (inflated_arg, klass)) {
- if (arg_num)
- *arg_num = i;
- return MINI_GENERIC_CLASS_RELATION_ARGUMENT;
+ /* Reflection types can only be handled in the extensible
+ rgctx part. */
+ if (info_type != MONO_RGCTX_INFO_REFLECTION_TYPE) {
+ for (i = 0; i < rgctx_template->num_arg_infos; ++i) {
+ MonoType *arg_info = rgctx_template->arg_infos [i];
+ MonoType *inflated_arg;
+
+ if (arg_info == NULL)
+ continue;
+
+ inflated_arg = mono_class_inflate_generic_type(arg_info, generic_context);
+
+ if (inflated_type_is_equal_to_class (inflated_arg, klass)) {
+ if (arg_num)
+ *arg_num = i;
+ return MINI_GENERIC_CLASS_RELATION_ARGUMENT;
+ }
}
- }
- if (!klass->generic_class && !klass->generic_container)
- g_assert_not_reached ();
+ if (!klass->generic_class && !klass->generic_container)
+ g_assert_not_reached ();
- if (mini_class_get_container_class (klass) == mini_class_get_container_class (method_klass) &&
- mono_generic_context_equal_deep (mini_class_get_context (klass), generic_context))
- return MINI_GENERIC_CLASS_RELATION_SELF;
+ if (mini_class_get_container_class (klass) == mini_class_get_container_class (method_klass) &&
+ mono_generic_context_equal_deep (mini_class_get_context (klass), generic_context))
+ return MINI_GENERIC_CLASS_RELATION_SELF;
+ }
i = mono_class_lookup_or_register_other_info (method_klass, &klass->byval_arg, info_type, generic_context);
if (arg_num)
case CEE_LDTOKEN: {
gpointer handle;
MonoClass *handle_class;
+ int context_used = 0;
CHECK_STACK_OVF (1);
}
else {
handle = mono_ldtoken (image, n, &handle_class, generic_context);
- if (cfg->generic_sharing_context &&
- mono_class_check_context_used (handle_class))
- GENERIC_SHARING_FAILURE (CEE_LDTOKEN);
}
if (!handle)
goto load_error;
mono_class_init (handle_class);
+ if (cfg->generic_sharing_context) {
+ if (handle_class == mono_defaults.typehandle_class) {
+ /* If we get a MONO_TYPE_CLASS
+ then we need to provide the
+ open type, not an
+ instantiation of it. */
+ if (mono_type_get_type (handle) == MONO_TYPE_CLASS)
+ context_used = 0;
+ else
+ context_used = mono_class_check_context_used (mono_class_from_mono_type (handle));
+ } else if (handle_class == mono_defaults.fieldhandle_class)
+ context_used = mono_class_check_context_used (((MonoClassField*)handle)->parent);
+ else if (handle_class == mono_defaults.methodhandle_class)
+ context_used = mono_method_check_context_used (handle);
+ else
+ g_assert_not_reached ();
+
+ if (context_used & MONO_GENERIC_CONTEXT_USED_METHOD)
+ GENERIC_SHARING_FAILURE (CEE_LDTOKEN);
+ }
+
if (cfg->opt & MONO_OPT_SHARED) {
int temp;
MonoInst *res, *store, *addr, *vtvar, *iargs [3];
(strcmp (cmethod->name, "GetTypeFromHandle") == 0)) {
MonoClass *tclass = mono_class_from_mono_type (handle);
mono_class_init (tclass);
- if (cfg->compile_aot)
+ if (context_used) {
+ MonoInst *this, *rgctx;
+
+ g_assert (!cfg->compile_aot);
+ if (!(method->flags & METHOD_ATTRIBUTE_STATIC))
+ NEW_ARGLOAD (cfg, this, 0);
+ rgctx = get_runtime_generic_context (cfg, method, this, ip);
+ ins = get_runtime_generic_context_ptr (cfg, method, bblock, tclass,
+ token, MINI_TOKEN_SOURCE_CLASS, generic_context,
+ rgctx, MONO_RGCTX_INFO_REFLECTION_TYPE, ip);
+ } else if (cfg->compile_aot) {
NEW_TYPE_FROM_HANDLE_CONST (cfg, ins, image, n);
- else
+ } else {
NEW_PCONST (cfg, ins, mono_type_get_object (cfg->domain, handle));
+ }
ins->type = STACK_OBJ;
ins->klass = cmethod->klass;
ip += 5;
} else {
MonoInst *store, *addr, *vtvar;
+ GENERIC_SHARING_FAILURE (CEE_LDTOKEN);
+
if (cfg->compile_aot)
NEW_LDTOKENCONST (cfg, ins, image, n);
else
+2008-03-20 Mark Probst <mark.probst@gmail.com>
+
+ * generics-sharing.2.cs: Test cases for ldtoken.
+
2008-03-19 Rodrigo Kumpera <rkumpera@novell.com>
* bug-340662_bug.cs: Added. Regression test for the bug.
}
}
+public interface IGen<T> {
+ T[] iMethod ();
+ void voidIMethod (int x);
+ long longIMethod (long x);
+ float floatIMethod ();
+ GenStruct<T> valueIMethod (int x);
+}
+
public class GenA<T> {
public static T[] arr;
return (T)obj;
}
+ public Type ldtokenT () {
+ return typeof (T);
+ }
+
+ public Type ldtokenIGenT () {
+ return typeof (IGen<T>);
+ }
+
+ public Type ldtokenGenAIGenT () {
+ return typeof (GenA<IGen<T>>);
+ }
+
+ public Type ldtokenGenB () {
+ return typeof (GenB<>);
+ }
+
public void except () {
try {
NonGen.doThrow ();
if (!comp.Equals (ga.cast (obj), obj))
error ("cast");
+ if (ga.ldtokenT () != typeof (T))
+ error ("ldtokenT");
+ if (ga.ldtokenIGenT () != typeof (IGen<T>))
+ error ("ldtokenIGenT");
+ if (ga.ldtokenGenAIGenT () != typeof (GenA<IGen<T>>))
+ error ("ldtokenGenAIGenT");
+ if (ga.ldtokenGenB () != typeof (GenB<>))
+ error ("ldtokenGenB");
+
if (callStaticMethod<T> () != 54321)
error ("staticMethod");