2001-08-10 Dietmar Maurer <dietmar@ximian.com>
authorDietmar Maurer <dietmar@mono-cvs.ximian.com>
Fri, 10 Aug 2001 05:24:01 +0000 (05:24 -0000)
committerDietmar Maurer <dietmar@mono-cvs.ximian.com>
Fri, 10 Aug 2001 05:24:01 +0000 (05:24 -0000)
* interp.c (ves_exec_method): impl. BOX/UNBOX
(ves_icall_System_Array_GetValue): impl.
(ves_icall_System_Array_SetValue): impl.

* mono/tests/array.cs: more array tests

svn path=/trunk/mono/; revision=456

12 files changed:
ChangeLog
mono/cli/class.c
mono/cli/class.h
mono/cli/object.c
mono/cli/object.h
mono/interpreter/ChangeLog
mono/interpreter/interp.c
mono/metadata/class.c
mono/metadata/class.h
mono/metadata/object.c
mono/metadata/object.h
mono/tests/array.cs

index 89dfd899093e4a5ec61edf38579cee85b1aa1c0f..4690a074367fbbb78ff67f2572e6168f9408de18 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2001-08-10  Dietmar Maurer  <dietmar@ximian.com>
+
+       * mono/tests/array.cs: more array tests
+
 2001-08-09  Dietmar Maurer  <dietmar@ximian.com>
 
        * mono/tests/array.cs: more array tests
index df71fcaee068befcc4f773b8d08315b8d908db44..300975441e5e426932fdca3f8b2967d5e9e4530d 100644 (file)
@@ -383,11 +383,12 @@ mono_array_class_get (MonoImage *image, guint32 etype, guint32 rank)
        class->parent = parent;
        class->instance_size = class->parent->instance_size;
        class->class_size = sizeof (MonoArrayClass);
-       
+       class->evaltype = eclass->valuetype;
+
        aclass->rank = rank;
        aclass->etype_token = eclass->type_token;
        aclass->esize = esize;
-
+       
        g_hash_table_insert (image->array_cache, GUINT_TO_POINTER (key), class);
        return class;
 }
index e04c9e8561441e97f3c479b34985c2decd25f409..501f2db876fdd6cce6308a40a889a70c8ab84d27 100644 (file)
@@ -19,7 +19,8 @@ struct _MonoClass {
        guint32    type_token;
 
        guint inited : 1;
-       guint valuetype : 1;
+       guint valuetype : 1; /* derives from System.ValueType */
+       guint evaltype : 1; /* element type derives from System.ValueType */
 
        MonoClass *parent;
        
index 44bc9d7c431ba42a71218a172e0840e54886b707..f89258e002864d74be57f190caca55a289542bdd 100644 (file)
@@ -80,7 +80,6 @@ mono_new_szarray (MonoImage *image, guint32 etype, guint32 n)
        MonoObject *o;
        MonoArrayObject *ao;
        MonoArrayClass *ac;
-       guint32 esize;
 
        c = mono_array_class_get (image, etype, 1);
        g_assert (c != NULL);
@@ -99,3 +98,21 @@ mono_new_szarray (MonoImage *image, guint32 etype, guint32 n)
 
        return o;
 }
+
+MonoObject *
+mono_value_box (MonoImage *image, guint32 etype, gpointer val)
+{
+       MonoObject *res;
+       int size;
+
+       res = mono_object_new (image, etype);
+
+       g_assert (res->klass->valuetype);
+
+       size = res->klass->instance_size - sizeof (MonoObject);
+
+       memcpy ((char *)res + sizeof (MonoObject), val, size);
+
+       return res;
+}
+
index 5c8a61118fc289ace521eecdf28ebc262306b3b9..37848c761ad05733687c9c46790d14264a855d0b 100644 (file)
@@ -32,6 +32,9 @@ mono_new_szarray      (MonoImage *image, guint32 etype, guint32 n);
 
 void       
 mono_object_free      (MonoObject *o);
+
+MonoObject *
+mono_value_box        (MonoImage *image, guint32 etype, gpointer val);
                      
 #endif
 
index de703c087ab8533bdd991704acce0c1a2fd5279b..a1eb78d849ba3536df7b5c07690d15a1159ff066 100644 (file)
@@ -1,3 +1,9 @@
+2001-08-10  Dietmar Maurer  <dietmar@ximian.com>
+
+       * interp.c (ves_exec_method): impl. BOX/UNBOX
+       (ves_icall_System_Array_GetValue): impl.
+       (ves_icall_System_Array_SetValue): impl.
+
 2001-08-09  Dietmar Maurer  <dietmar@ximian.com>
 
        * implemented arrays, but you will need a modified version of 
index 76e4cb791c1d633ccb8d8edfde3e31f0170f8834..3f92a70a8d6c497183d3c04691c1f97796bb82ef 100644 (file)
@@ -227,6 +227,7 @@ stackval_from_data (MonoType *type, const char *data, guint offset)
        case MONO_TYPE_STRING:
        case MONO_TYPE_SZARRAY:
        case MONO_TYPE_CLASS:
+       case MONO_TYPE_OBJECT:
        case MONO_TYPE_ARRAY:
                result.type = VAL_OBJ;
                result.data.p = *(gpointer*)(data + offset);
@@ -266,6 +267,7 @@ stackval_to_data (MonoType *type, stackval *val, char *data, guint offset)
        case MONO_TYPE_STRING:
        case MONO_TYPE_SZARRAY:
        case MONO_TYPE_CLASS:
+       case MONO_TYPE_OBJECT:
        case MONO_TYPE_ARRAY:
                *(gpointer*)(data + offset) = val->data.p;
                break;
@@ -320,7 +322,7 @@ ves_icall_array_Set (MonoMethod *mh, stackval *sp)
 
        g_assert (ac->rank >= 1);
 
-       pos = sp [1].data.i - ao->bounds [1].lower_bound;
+       pos = sp [1].data.i - ao->bounds [0].lower_bound;
        for (i = 1; i < ac->rank; i++) {
                if ((t = sp [i + 1].data.i - ao->bounds [i].lower_bound) >= ao->bounds [i].length) {
                        g_warning ("wrong array index");
@@ -350,7 +352,7 @@ ves_icall_array_Get (MonoMethod *mh, stackval *sp)
 
        g_assert (ac->rank >= 1);
 
-       pos = sp [1].data.i - ao->bounds [1].lower_bound;
+       pos = sp [1].data.i - ao->bounds [0].lower_bound;
        for (i = 1; i < ac->rank; i++)
                pos = pos*ao->bounds [i].length + sp [i + 1].data.i - ao->bounds [i].lower_bound;
 
@@ -360,6 +362,87 @@ ves_icall_array_Get (MonoMethod *mh, stackval *sp)
        memcpy (&sp [0].data.p, ea, ac->esize);
 }
 
+static void 
+ves_icall_System_Array_GetValue (MonoMethod *mh, stackval *sp)
+{
+       MonoArrayObject *ao, *io;
+       MonoArrayClass *ac, *ic;
+       gint32 i, pos, *ind;
+       gpointer *ea;
+
+       g_assert (sp [0].type == VAL_OBJ);
+       g_assert (sp [1].type == VAL_OBJ); /* expect an array of integers */
+
+       io = sp [1].data.p;
+       ic = (MonoArrayClass *)io->obj.klass;
+       
+       ao = (MonoArrayObject *)sp [0].data.p;
+       ac = (MonoArrayClass *)ao->obj.klass;
+
+       g_assert (ic->rank == 1);
+       g_assert (io->bounds [0].length == ac->rank);
+
+       ind = (guint32 *)io->vector;
+
+       pos = ind [0] - ao->bounds [0].lower_bound;
+       for (i = 1; i < ac->rank; i++)
+               pos = pos*ao->bounds [i].length + ind [i] - 
+                       ao->bounds [i].lower_bound;
+
+       ea = ao->vector + (pos * ac->esize);
+
+       sp [0].type = VAL_OBJ; 
+
+       if (ac->class.evaltype)
+               sp [0].data.p = mono_value_box (ac->class.image, 
+                                               ac->etype_token, ea);
+       else
+               sp [0].data.p = ea;
+}
+
+static void 
+ves_icall_System_Array_SetValue (MonoMethod *mh, stackval *sp)
+{
+       MonoArrayObject *ao, *io, *vo;
+       MonoArrayClass *ac, *ic, *vc;
+       gint32 i, pos, *ind;
+       gpointer *ea;
+
+       g_assert (sp [0].type == VAL_OBJ);
+       g_assert (sp [1].type == VAL_OBJ); /* the value object */
+       g_assert (sp [2].type == VAL_OBJ); /* expect an array of integers */
+
+       vo = sp [1].data.p;
+       vc = (MonoArrayClass *)vo->obj.klass;
+
+       io = sp [2].data.p;
+       ic = (MonoArrayClass *)io->obj.klass;
+       
+       ao = (MonoArrayObject *)sp [0].data.p;
+       ac = (MonoArrayClass *)ao->obj.klass;
+
+       g_assert (ic->rank == 1);
+       g_assert (io->bounds [0].length == ac->rank);
+
+       g_assert (ac->etype_token == vc->class.type_token);
+
+       ind = (guint32 *)io->vector;
+
+       pos = ind [0] - ao->bounds [0].lower_bound;
+       for (i = 1; i < ac->rank; i++)
+               pos = pos*ao->bounds [i].length + ind [i] - 
+                       ao->bounds [i].lower_bound;
+
+       ea = ao->vector + (pos * ac->esize);
+
+       if (ac->class.evaltype) {
+               g_assert (vc->class.valuetype);
+
+               memcpy (ea, (char *)vo + sizeof (MonoObject), ac->esize);
+       } else
+               ea = (gpointer)vo;
+}
+
 static void 
 ves_icall_array_ctor (MonoMethod *mh, stackval *sp)
 {
@@ -402,13 +485,6 @@ ves_icall_array_bound_ctor (MonoMethod *mh, stackval *sp)
        g_assert_not_reached ();
 }
 
-static void 
-ves_icall_System_Array_InternalGetValue (MonoMethod *mh, stackval *sp)
-{
-       g_warning ("experimental implementation");
-       g_assert_not_reached ();
-}
-
 static void 
 ves_icall_System_Array_GetRank (MonoMethod *mh, stackval *sp)
 {
@@ -465,8 +541,10 @@ mono_lookup_internal_call (const char *name)
                                     &ves_icall_array_ctor);
                g_hash_table_insert (icall_hash, "__array_bound_ctor", 
                                     &ves_icall_array_bound_ctor);
-               g_hash_table_insert (icall_hash, "System.Array::InternalGetValue", 
-                                    &ves_icall_System_Array_InternalGetValue);
+               g_hash_table_insert (icall_hash, "System.Array::GetValue", 
+                                    &ves_icall_System_Array_GetValue);
+               g_hash_table_insert (icall_hash, "System.Array::SetValue", 
+                                    &ves_icall_System_Array_SetValue);
                g_hash_table_insert (icall_hash, "System.Array::GetRank", 
                                     &ves_icall_System_Array_GetRank);
                g_hash_table_insert (icall_hash, "System.Array::GetLength", 
@@ -564,7 +642,7 @@ ves_pinvoke_method (MonoMethod *mh, stackval *sp)
                *sp = stackval_from_data (mh->signature->ret->type, res, 0);
 }
 
-#define DEBUG_INTERP 0
+#define DEBUG_INTERP 1
 #if DEBUG_INTERP
 #define OPDEF(a,b,c,d,e,f,g,h,i,j)  b,
 static char *opcode_names[] = {
@@ -1494,7 +1572,26 @@ ves_exec_method (MonoMethod *mh, stackval *args)
                CASE (CEE_CONV_R_UN) ves_abort(); BREAK;
                CASE (CEE_UNUSED58) ves_abort(); BREAK;
                CASE (CEE_UNUSED1) ves_abort(); BREAK;
-               CASE (CEE_UNBOX) ves_abort(); BREAK;
+               CASE (CEE_UNBOX) {
+                       MonoObject *o;
+                       MonoClass *c;
+                       guint32 token;
+
+                       ++ip;
+                       token = read32 (ip);
+                       
+                       c = mono_class_get (mh->image, token);
+                       
+                       o = sp [-1].data.p;
+
+                       g_assert (o->klass->type_token == c->type_token);
+
+                       sp [-1].type = VAL_MP;
+                       sp [-1].data.p = (char *)o + sizeof (MonoObject);
+
+                       ip += 4;
+                       BREAK;
+               }
                CASE (CEE_THROW) ves_abort(); BREAK;
                CASE (CEE_LDFLD) {
                        MonoObject *obj;
@@ -1522,6 +1619,7 @@ ves_exec_method (MonoMethod *mh, stackval *args)
                        token = read32 (ip);
                        ip += 4;
                        
+                       printf ("FIELD %08x\n",token);
                        sp -= 2;
                        
                        g_assert (sp [0].type == VAL_OBJ);
@@ -1579,7 +1677,20 @@ ves_exec_method (MonoMethod *mh, stackval *args)
                CASE (CEE_CONV_OVF_U8_UN) ves_abort(); BREAK;
                CASE (CEE_CONV_OVF_I_UN) ves_abort(); BREAK;
                CASE (CEE_CONV_OVF_U_UN) ves_abort(); BREAK;
-               CASE (CEE_BOX) ves_abort(); BREAK;
+               CASE (CEE_BOX) {
+                       guint32 token;
+
+                       ip++;
+                       token = read32 (ip);
+
+                       sp [-1].type = VAL_OBJ;
+                       sp [-1].data.p = mono_value_box (mh->image, token, 
+                                                        &sp [-1]);
+
+                       ip += 4;
+
+                       BREAK;
+               }
                CASE (CEE_NEWARR) {
                        MonoObject *o;
                        guint32 token;
index df71fcaee068befcc4f773b8d08315b8d908db44..300975441e5e426932fdca3f8b2967d5e9e4530d 100644 (file)
@@ -383,11 +383,12 @@ mono_array_class_get (MonoImage *image, guint32 etype, guint32 rank)
        class->parent = parent;
        class->instance_size = class->parent->instance_size;
        class->class_size = sizeof (MonoArrayClass);
-       
+       class->evaltype = eclass->valuetype;
+
        aclass->rank = rank;
        aclass->etype_token = eclass->type_token;
        aclass->esize = esize;
-
+       
        g_hash_table_insert (image->array_cache, GUINT_TO_POINTER (key), class);
        return class;
 }
index e04c9e8561441e97f3c479b34985c2decd25f409..501f2db876fdd6cce6308a40a889a70c8ab84d27 100644 (file)
@@ -19,7 +19,8 @@ struct _MonoClass {
        guint32    type_token;
 
        guint inited : 1;
-       guint valuetype : 1;
+       guint valuetype : 1; /* derives from System.ValueType */
+       guint evaltype : 1; /* element type derives from System.ValueType */
 
        MonoClass *parent;
        
index 44bc9d7c431ba42a71218a172e0840e54886b707..f89258e002864d74be57f190caca55a289542bdd 100644 (file)
@@ -80,7 +80,6 @@ mono_new_szarray (MonoImage *image, guint32 etype, guint32 n)
        MonoObject *o;
        MonoArrayObject *ao;
        MonoArrayClass *ac;
-       guint32 esize;
 
        c = mono_array_class_get (image, etype, 1);
        g_assert (c != NULL);
@@ -99,3 +98,21 @@ mono_new_szarray (MonoImage *image, guint32 etype, guint32 n)
 
        return o;
 }
+
+MonoObject *
+mono_value_box (MonoImage *image, guint32 etype, gpointer val)
+{
+       MonoObject *res;
+       int size;
+
+       res = mono_object_new (image, etype);
+
+       g_assert (res->klass->valuetype);
+
+       size = res->klass->instance_size - sizeof (MonoObject);
+
+       memcpy ((char *)res + sizeof (MonoObject), val, size);
+
+       return res;
+}
+
index 5c8a61118fc289ace521eecdf28ebc262306b3b9..37848c761ad05733687c9c46790d14264a855d0b 100644 (file)
@@ -32,6 +32,9 @@ mono_new_szarray      (MonoImage *image, guint32 etype, guint32 n);
 
 void       
 mono_object_free      (MonoObject *o);
+
+MonoObject *
+mono_value_box        (MonoImage *image, guint32 etype, gpointer val);
                      
 #endif
 
index 0eadfd56bd8f618c6089acb2f668f349434e7ab9..9f587eea3b82b6a9b004f47eaf5051d1eca599f4 100755 (executable)
@@ -6,7 +6,8 @@ public class Test {
        [DllImport("cygwin1.dll", EntryPoint="puts", CharSet=CharSet.Ansi)]
        public static extern int puts (string name);
 
-       public static int jagged () {
+       public static int jagged ()
+       {
                int[][] j2 = new int [3][];
 
                // does not work 
@@ -29,7 +30,8 @@ public class Test {
                return 0;
        }
 
-       public static int stest () {
+       public static int stest ()
+       {
                string[] sa = new string[32];
 
                sa [0] = "This";
@@ -45,7 +47,8 @@ public class Test {
                return 0;
        }
        
-       public static int atest2 () {
+       public static int atest2 ()
+       {
                int[,] ia = new int[32,32];
 
                for (int i = 0; i <ia.GetLength (0); i++)
@@ -55,21 +58,62 @@ public class Test {
                        if (ia [i,i] != i*i)
                                return 1;
 
+               for (int i = 0; i <ia.GetLength (0); i++)
+                       ia.SetValue (i*i*i, i, i);
+
+               for (int i = 0; i <ia.GetLength (0); i++)
+                       if ((int)ia.GetValue (i, i) != i*i*i)
+                               return 1;
+
                return 0;
        }
        
-       public static int Main () {
+       public static int atest ()
+       {
                int[] ia = new int[32];
 
                for (int i = 0; i <ia.Length; i++)
                        ia [i] = i*i;
-
+               
                for (int i = 0; i <ia.Length; i++)
                        if (ia [i] != i*i)
                                return 1;
                
                if (ia.Rank != 1)
                        return 1;
+
+               if (ia.GetValue (2) == null)
+                       return 1;
+
+               for (int i = 0; i <ia.Length; i++)
+                       ia.SetValue (i*i*i, i);
+
+               for (int i = 0; i <ia.Length; i++)
+                       if ((int)ia.GetValue (i) != i*i*i)
+                               return 1;
+               
+               return 0;
+       }
+       
+       public static int boxtest ()
+       {
+               int i = 123;
+               object o = i;
+               int j = (int) o;
+
+               if (i != j)
+                       return 1;
+               
+               return 0;
+       }
+
+       public static int Main () {
+              
+               if (boxtest () != 0)
+                       return 1;
+              
+               if (atest () != 0)
+                       return 1;
                
                if (atest2 () != 0)
                        return 1;
@@ -82,9 +126,6 @@ public class Test {
                if (jagged () != 0)
                        return 1;
                
-
-               if (ia.GetValue (2) == null)
-                       return 1;
                
                return 0;
        }