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);
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;
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");
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;
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)
{
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)
{
&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",
*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[] = {
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;
token = read32 (ip);
ip += 4;
+ printf ("FIELD %08x\n",token);
sp -= 2;
g_assert (sp [0].type == VAL_OBJ);
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;
[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
return 0;
}
- public static int stest () {
+ public static int stest ()
+ {
string[] sa = new string[32];
sa [0] = "This";
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++)
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;
if (jagged () != 0)
return 1;
-
- if (ia.GetValue (2) == null)
- return 1;
return 0;
}