Author: benm
Date: 2005-12-05 20:13:29 -0500 (Mon, 05 Dec 2005)
New Revision: 53961

Added:
   trunk/mono/mono/mini/generics.2.cs
Modified:
   trunk/mono/mono/metadata/ChangeLog
   trunk/mono/mono/metadata/appdomain.c
   trunk/mono/mono/metadata/class-internals.h
   trunk/mono/mono/metadata/class.c
   trunk/mono/mono/metadata/domain.c
   trunk/mono/mono/mini/ChangeLog
   trunk/mono/mono/mini/Makefile.am
   trunk/mono/mono/mini/inssel.brg
   trunk/mono/mono/mini/mini.c
Log:
In mini:
2005-12-05  Ben Maurer  <[EMAIL PROTECTED]>

        Support for boxing and unboxing nullable types as well as the
        isinst operation on nullables, per the CLI ammendment.

        * inssel.brg (CEE_ISINST): Special case for nullable

        * mini.c (handle_unbox_nullable): new method
        (handle_box): Special case for nullable types
        (mono_method_to_ir): Call handle_unbox_nullable in correct
        places.

        * generics.2.cs: New test suite

        * Makefile.am: Support for regression tests with generics.

In metadata:
2005-12-05  Ben Maurer  <[EMAIL PROTECTED]>

        Beginning of support for nullable types in the runtime. Parts of
        this patch are from Martin.

        * appdomain.c (MONO_CORLIB_VERSION): Bump

        * domain.c (mono_init_internal): get the nullable type

        * class.c (mono_class_is_nullable): New method
        (mono_class_get_nullable_param): New mehod
        (mono_class_create_generic): In types T? set cast_class to T

        * class-internals.h (MonoDefaults): new nullable default class
        (mono_class_get_nullable_param, mono_class_get_nullable_param):
        new methods.



Modified: trunk/mono/mono/metadata/ChangeLog
===================================================================
--- trunk/mono/mono/metadata/ChangeLog  2005-12-06 00:20:40 UTC (rev 53960)
+++ trunk/mono/mono/metadata/ChangeLog  2005-12-06 01:13:29 UTC (rev 53961)
@@ -1,3 +1,20 @@
+2005-12-05  Ben Maurer  <[EMAIL PROTECTED]>
+
+       Beginning of support for nullable types in the runtime. Parts of
+       this patch are from Martin.
+
+       * appdomain.c (MONO_CORLIB_VERSION): Bump
+
+       * domain.c (mono_init_internal): get the nullable type
+
+       * class.c (mono_class_is_nullable): New method
+       (mono_class_get_nullable_param): New mehod
+       (mono_class_create_generic): In types T? set cast_class to T
+
+       * class-internals.h (MonoDefaults): new nullable default class
+       (mono_class_get_nullable_param, mono_class_get_nullable_param):
+       new methods.
+
 2005-12-05  Raja R Harinath  <[EMAIL PROTECTED]>
 
        * metadata.c (select_container): New.  Refactor code to select the

Modified: trunk/mono/mono/metadata/appdomain.c
===================================================================
--- trunk/mono/mono/metadata/appdomain.c        2005-12-06 00:20:40 UTC (rev 
53960)
+++ trunk/mono/mono/metadata/appdomain.c        2005-12-06 01:13:29 UTC (rev 
53961)
@@ -30,7 +30,7 @@
 #include <mono/metadata/threadpool.h>
 #include <mono/utils/mono-uri.h>
 
-#define MONO_CORLIB_VERSION 43
+#define MONO_CORLIB_VERSION 44
 
 CRITICAL_SECTION mono_delegate_section;
 

Modified: trunk/mono/mono/metadata/class-internals.h
===================================================================
--- trunk/mono/mono/metadata/class-internals.h  2005-12-06 00:20:40 UTC (rev 
53960)
+++ trunk/mono/mono/metadata/class-internals.h  2005-12-06 01:13:29 UTC (rev 
53961)
@@ -682,6 +682,7 @@
        MonoClass *runtimesecurityframe_class;
        MonoClass *executioncontext_class;
        MonoClass *generic_array_class;
+       MonoClass *generic_nullable_class;
 } MonoDefaults;
 
 extern MonoDefaults mono_defaults;
@@ -772,5 +773,8 @@
 MonoArrayType *mono_dup_array_type (MonoArrayType *a);
 MonoMethodSignature *mono_metadata_signature_deep_dup (MonoMethodSignature 
*sig);
 
+gboolean mono_class_is_nullable (MonoClass *klass);
+MonoClass *mono_class_get_nullable_param (MonoClass *klass);
+
 #endif /* __MONO_METADATA_CLASS_INTERBALS_H__ */
 

Modified: trunk/mono/mono/metadata/class.c
===================================================================
--- trunk/mono/mono/metadata/class.c    2005-12-06 00:20:40 UTC (rev 53960)
+++ trunk/mono/mono/metadata/class.c    2005-12-06 01:13:29 UTC (rev 53961)
@@ -2719,6 +2719,23 @@
        return class;
 }
 
+/** is klass Nullable<T>? */
+gboolean
+mono_class_is_nullable (MonoClass *klass)
+{
+       return klass->generic_class != NULL &&
+               klass->generic_class->container_class == 
mono_defaults.generic_nullable_class;
+}
+
+
+/** if klass is T? return T */
+MonoClass*
+mono_class_get_nullable_param (MonoClass *klass)
+{
+       g_assert (mono_class_is_nullable (klass));
+       return mono_class_from_mono_type (klass->generic_class->inst->type_argv 
[0]);
+}
+
 /*
  * Create the `MonoClass' for an instantiation of a generic type.
  * We only do this if we actually need it.
@@ -2754,6 +2771,9 @@
 
        klass->cast_class = klass->element_class = klass;
 
+       if (mono_class_is_nullable (klass))
+               klass->cast_class = klass->element_class = 
mono_class_get_nullable_param (klass);
+
        if (gclass->generic_class.is_dynamic) {
                klass->instance_size = gklass->instance_size;
                klass->class_size = gklass->class_size;

Modified: trunk/mono/mono/metadata/domain.c
===================================================================
--- trunk/mono/mono/metadata/domain.c   2005-12-06 00:20:40 UTC (rev 53960)
+++ trunk/mono/mono/metadata/domain.c   2005-12-06 01:13:29 UTC (rev 53961)
@@ -758,12 +758,14 @@
                mono_defaults.corlib, "System.Threading", "ExecutionContext");
 
        /*
-        * Note that mono_defaults.generic_array_class is only non-NULL if we're
+        * Note that mono_defaults.generic_*_class is only non-NULL if we're
         * using the 2.0 corlib.
         */
        mono_class_init (mono_defaults.array_class);
        mono_defaults.generic_array_class = mono_class_from_name (
                mono_defaults.corlib, "System", "Array/InternalArray`1");
+       mono_defaults.generic_nullable_class = mono_class_from_name (
+               mono_defaults.corlib, "System", "Nullable`1");
 
        domain->friendly_name = g_path_get_basename (filename);
 

Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog      2005-12-06 00:20:40 UTC (rev 53960)
+++ trunk/mono/mono/mini/ChangeLog      2005-12-06 01:13:29 UTC (rev 53961)
@@ -1,3 +1,19 @@
+2005-12-05  Ben Maurer  <[EMAIL PROTECTED]>
+
+       Support for boxing and unboxing nullable types as well as the
+       isinst operation on nullables, per the CLI ammendment.
+
+       * inssel.brg (CEE_ISINST): Special case for nullable
+
+       * mini.c (handle_unbox_nullable): new method
+       (handle_box): Special case for nullable types
+       (mono_method_to_ir): Call handle_unbox_nullable in correct
+       places.
+
+       * generics.2.cs: New test suite
+
+       * Makefile.am: Support for regression tests with generics.
+
 2005-12-03  Zoltan Varga  <[EMAIL PROTECTED]>
 
        * mini-amd64.c (emit_load_volatile_arguments): Add loading of arguments

Modified: trunk/mono/mono/mini/Makefile.am
===================================================================
--- trunk/mono/mono/mini/Makefile.am    2005-12-06 00:20:40 UTC (rev 53960)
+++ trunk/mono/mono/mini/Makefile.am    2005-12-06 01:13:29 UTC (rev 53961)
@@ -29,11 +29,17 @@
        $(libgc_static_libs) \
        $(ICU_LIBS)
 
-RUNTIME = MONO_PATH=$(mcs_topdir)/class/lib/default 
$(top_builddir)/runtime/mono-wrapper
+CLASS1=$(mcs_topdir)/class/lib/default
+CLASS2=$(mcs_topdir)/class/lib/net_2_0
 
-MCS = $(RUNTIME) $(mcs_topdir)/class/lib/default/mcs.exe -unsafe -nowarn:0162
-ILASM = $(RUNTIME) $(mcs_topdir)/class/lib/default/ilasm.exe
+RUNTIME = MONO_PATH=$(CLASS1) $(top_builddir)/runtime/mono-wrapper
+RUNTIME2 = MONO_PATH=$(CLASS2) $(top_builddir)/runtime/mono-wrapper
 
+MCS = $(RUNTIME) $(CLASS1)/mcs.exe -unsafe -nowarn:0162
+GMCS = $(RUNTIME2) $(CLASS2)/gmcs.exe -unsafe -nowarn:0162
+ILASM = $(RUNTIME) $(CLASS1)/ilasm.exe
+
+
 AM_CFLAGS = \
        -I$(top_srcdir)         \
        $(LIBGC_CFLAGS)         \
@@ -213,7 +219,7 @@
        test.cs
 
 regtests=basic.exe arrays.exe basic-float.exe basic-math.exe basic-long.exe 
objects.exe basic-calls.exe iltests.exe exceptions.exe bench.exe
-
+regtests2=generics.exe
 common_BURGSRC= $(srcdir)/inssel.brg $(srcdir)/inssel-float.brg
 
 if X86
@@ -308,6 +314,9 @@
        $(libs) \
        $(PLATFORM_LIB)
 
+%.exe: %.2.cs TestDriver.dll
+       $(GMCS) -out:$@ $< -r:TestDriver.dll 
+
 %.exe: %.cs TestDriver.dll
        $(MCS) /out:$*.exe /unsafe $< /r:TestDriver.dll
 
@@ -371,12 +380,18 @@
 checktests: $(regtests)
        for i in $(regtests); do $(RUNTIME) $$i; done
 
-rcheck: mono $(regtests)
+checktests2: $(regtests2)
+       for i in $(regtests); do $(RUNTIME2) $$i; done
+
+rcheck: mono $(regtests) $(regtests2)
        $(RUNTIME) --regression $(regtests)
+       $(RUNTIME2) --regression $(regtests2)
 
 aotcheck: mono $(regtests)
        for i in $(regtests); do $(RUNTIME) --aot $$i; done
+       for i in $(regtests2); do $(RUNTIME2) --aot $$i; done
        $(RUNTIME) --verbose --regression $(regtests)
+       $(RUNTIME2) --verbose --regression $(regtests2)
        rm -f *.exe.so
 
 bench: mono test.exe

Added: trunk/mono/mono/mini/generics.2.cs
===================================================================
--- trunk/mono/mono/mini/generics.2.cs  2005-12-06 00:20:40 UTC (rev 53960)
+++ trunk/mono/mono/mini/generics.2.cs  2005-12-06 01:13:29 UTC (rev 53961)
@@ -0,0 +1,44 @@
+using System;
+
+class Tests {
+
+       static int Main ()
+       {
+               return TestDriver.RunTests (typeof (Tests));
+       }
+       
+       public static int test_1_nullable_unbox ()
+       {
+               return Unbox<int?> (1).Value;
+       }
+
+       public static int test_1_nullable_unbox_null ()
+       {
+               return Unbox<int?> (null).HasValue ? 0 : 1;
+       }
+
+       public static int test_1_nullable_box ()
+       {
+               return (int) Box<int?> (1);
+       }
+
+       public static int test_1_nullable_box_null ()
+       {
+               return Box<int?> (null) == null ? 1 : 0;
+       }
+
+       public static int test_1_isinst_nullable ()
+       {
+               object o = 1;
+               return (o is int?) ? 1 : 0;
+       }
+
+       static object Box<T> (T t)
+       {
+               return t;
+       }
+       
+       static T Unbox <T> (object o) {
+               return (T) o;
+       }
+}


Property changes on: trunk/mono/mono/mini/generics.2.cs
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/mono/mono/mini/inssel.brg
===================================================================
--- trunk/mono/mono/mini/inssel.brg     2005-12-06 00:20:40 UTC (rev 53960)
+++ trunk/mono/mono/mini/inssel.brg     2005-12-06 01:13:29 UTC (rev 53961)
@@ -1068,6 +1068,10 @@
                                /* the object_is_null target simply copies the 
input register to the output */
                                mini_emit_isninst_cast (s, eclass_reg, 
klass->cast_class, false_label, object_is_null);
                        }
+               } else if (mono_class_is_nullable (klass)) {
+                       MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, vtable_reg, 
G_STRUCT_OFFSET (MonoVTable, klass));
+                       /* the object_is_null target simply copies the input 
register to the output */
+                       mini_emit_isninst_cast (s, klass_reg, 
klass->cast_class, false_label, object_is_null);
                } else {
                        if (!s->compile_aot && !(s->opt & MONO_OPT_SHARED) && 
(klass->flags & TYPE_ATTRIBUTE_SEALED)) {
                                /* the remoting code is broken, access the 
class for now */

Modified: trunk/mono/mono/mini/mini.c
===================================================================
--- trunk/mono/mono/mini/mini.c 2005-12-06 00:20:40 UTC (rev 53960)
+++ trunk/mono/mono/mini/mini.c 2005-12-06 01:13:29 UTC (rev 53961)
@@ -2568,13 +2568,35 @@
 
        return mono_emit_jit_icall (cfg, bblock, alloc_ftn, iargs, ip);
 }
+
+/**
+ * Handles unbox of a Nullable<T>, returning a temp variable
+ * where the result is stored
+ */
+static int
+handle_unbox_nullable (MonoCompile* cfg, MonoBasicBlock* bblock, MonoInst* 
val, const guchar *ip, MonoClass* klass)
+{
+       MonoMethod* method = mono_class_get_method_from_name (klass, "Unbox", 
1);
+       return mono_emit_method_call_spilled (cfg, bblock, method, 
mono_method_signature (method), &val, ip, NULL);
        
+}
+
+
+
 static MonoInst *
 handle_box (MonoCompile *cfg, MonoBasicBlock *bblock, MonoInst *val, const 
guchar *ip, MonoClass *klass)
 {
        MonoInst *dest, *vtoffset, *add, *vstore;
        int temp;
 
+       if (mono_class_is_nullable (klass)) {
+               MonoMethod* method = mono_class_get_method_from_name (klass, 
"Box", 1);
+               temp = mono_emit_method_call_spilled (cfg, bblock, method, 
mono_method_signature (method), &val, ip, NULL);
+               NEW_TEMPLOAD (cfg, dest, temp);
+               return dest;
+       }
+
+
        temp = handle_alloc (cfg, bblock, klass, TRUE, ip);
        NEW_TEMPLOAD (cfg, dest, temp);
        NEW_ICONST (cfg, vtoffset, sizeof (MonoObject));
@@ -5039,6 +5061,14 @@
                                break;
                        }
 
+                       if (mono_class_is_nullable (klass)) {
+                               int v = handle_unbox_nullable (cfg, bblock, 
*sp, ip, klass);
+                               NEW_TEMPLOAD (cfg, *sp, v);
+                               sp ++;
+                               ip += 5;
+                               break;
+                       }
+
                        MONO_INST_NEW (cfg, ins, OP_UNBOXCAST);
                        ins->type = STACK_OBJ;
                        ins->inst_left = *sp;
@@ -5089,6 +5119,14 @@
                        if (!klass)
                                goto load_error;
 
+                       if (mono_class_is_nullable (klass)) {
+                               int v = handle_unbox_nullable (cfg, bblock, 
*sp, ip, klass);
+                               NEW_TEMPLOAD (cfg, *sp, v);
+                               sp ++;
+                               ip += 5;
+                               break;
+                       }
+
                        /* Needed by the code generated in inssel.brg */
                        mono_get_got_var (cfg);
 

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to