5 * Dietmar Maurer (dietmar@ximian.com)
7 * (C) 2001 Ximian, Inc.
13 #include <mono/metadata/loader.h>
18 ves_icall_array_Set (MonoInvocation *frame)
20 stackval *sp = frame->stack_args;
24 gint32 i, t, pos, esize;
28 ao = (MonoArrayObject *)o;
29 ac = (MonoArrayClass *)o->klass;
31 g_assert (ac->rank >= 1);
33 pos = sp [0].data.i - ao->bounds [0].lower_bound;
34 for (i = 1; i < ac->rank; i++) {
35 if ((t = sp [i].data.i - ao->bounds [i].lower_bound) >=
36 ao->bounds [i].length) {
37 g_warning ("wrong array index");
38 g_assert_not_reached ();
40 pos = pos*ao->bounds [i].length + sp [i].data.i -
41 ao->bounds [i].lower_bound;
44 esize = mono_array_element_size (ac);
45 ea = ao->vector + (pos * esize);
46 memcpy (ea, &sp [ac->rank].data.p, esize);
50 ves_icall_array_Get (MonoInvocation *frame)
52 stackval *sp = frame->stack_args;
60 ao = (MonoArrayObject *)o;
61 ac = (MonoArrayClass *)o->klass;
63 g_assert (ac->rank >= 1);
65 pos = sp [0].data.i - ao->bounds [0].lower_bound;
66 for (i = 1; i < ac->rank; i++)
67 pos = pos*ao->bounds [i].length + sp [i].data.i -
68 ao->bounds [i].lower_bound;
70 esize = mono_array_element_size (ac);
71 ea = ao->vector + (pos * esize);
73 frame->retval->type = VAL_I32; /* fixme: not really true */
74 memcpy (&frame->retval->data.p, ea, esize);
78 ves_icall_System_Array_GetValue (MonoInvocation *frame)
80 stackval *sp = frame->stack_args;
81 MonoArrayObject *ao, *io;
82 MonoArrayClass *ac, *ic;
83 gint32 i, pos, *ind, esize;
86 g_assert (sp [0].type == VAL_OBJ); /* expect an array of integers */
89 ic = (MonoArrayClass *)io->obj.klass;
91 ao = (MonoArrayObject *)frame->obj;
92 ac = (MonoArrayClass *)ao->obj.klass;
94 g_assert (ic->rank == 1);
95 g_assert (io->bounds [0].length == ac->rank);
97 ind = (guint32 *)io->vector;
99 pos = ind [0] - ao->bounds [0].lower_bound;
100 for (i = 1; i < ac->rank; i++)
101 pos = pos*ao->bounds [i].length + ind [i] -
102 ao->bounds [i].lower_bound;
104 esize = mono_array_element_size (ac);
105 ea = ao->vector + (pos * esize);
107 frame->retval->type = VAL_OBJ;
109 if (ac->element_class->valuetype)
110 frame->retval->data.p = mono_value_box (ac->element_class, ea);
112 frame->retval->data.p = ea;
116 ves_icall_System_Array_SetValue (MonoInvocation *frame)
118 stackval *sp = frame->stack_args;
119 MonoArrayObject *ao, *io, *vo;
120 MonoArrayClass *ac, *ic, *vc;
121 gint32 i, pos, *ind, esize;
124 g_assert (sp [0].type == VAL_OBJ); /* the value object */
125 g_assert (sp [1].type == VAL_OBJ); /* expect an array of integers */
128 vc = (MonoArrayClass *)vo->obj.klass;
131 ic = (MonoArrayClass *)io->obj.klass;
133 ao = (MonoArrayObject *)frame->obj;
134 ac = (MonoArrayClass *)ao->obj.klass;
136 g_assert (ic->rank == 1);
137 g_assert (io->bounds [0].length == ac->rank);
139 g_assert (ac->element_class == vo->obj.klass);
141 ind = (guint32 *)io->vector;
143 pos = ind [0] - ao->bounds [0].lower_bound;
144 for (i = 1; i < ac->rank; i++)
145 pos = pos*ao->bounds [i].length + ind [i] -
146 ao->bounds [i].lower_bound;
148 esize = mono_array_element_size (ac);
149 ea = ao->vector + (pos * esize);
151 if (ac->element_class->valuetype) {
152 g_assert (vc->class.valuetype);
154 memcpy (ea, (char *)vo + sizeof (MonoObject), esize);
160 ves_icall_array_ctor (MonoInvocation *frame)
162 stackval *sp = frame->stack_args;
166 gint32 i, len, esize;
169 ao = (MonoArrayObject *)o;
170 ac = (MonoArrayClass *)o->klass;
172 g_assert (ac->rank >= 1);
175 for (i = 1; i < ac->rank; i++)
176 len *= sp [i].data.i;
178 esize = mono_array_element_size (ac);
179 ao->vector = g_malloc0 (len * esize);
180 ao->bounds = g_malloc0 (ac->rank * sizeof (MonoArrayBounds));
182 for (i = 0; i < ac->rank; i++)
183 ao->bounds [i].length = sp [i].data.i;
187 ves_icall_array_bound_ctor (MonoInvocation *frame)
193 ac = (MonoArrayClass *)o->klass;
195 g_warning ("experimental implementation");
196 g_assert_not_reached ();
200 ves_icall_System_Array_CreateInstance (MonoInvocation *frame)
202 g_warning ("not implemented");
203 g_assert_not_reached ();
207 ves_icall_System_Array_GetRank (MonoInvocation *frame)
213 frame->retval->data.i = ((MonoArrayClass *)o->klass)->rank;
214 frame->retval->type = VAL_I32;
218 ves_icall_System_Array_GetLength (MonoInvocation *frame)
220 stackval *sp = frame->stack_args;
225 frame->retval->data.i = ((MonoArrayObject *)o)->bounds [sp [0].data.i].length;
226 frame->retval->type = VAL_I32;
230 ves_icall_System_Array_GetLowerBound (MonoInvocation *frame)
232 stackval *sp = frame->stack_args;
235 ao = (MonoArrayObject *)frame->obj;
237 frame->retval->data.i = ao->bounds [sp [0].data.i].lower_bound;
238 frame->retval->type = VAL_I32;
242 ves_icall_System_Object_MemberwiseClone (MonoInvocation *frame)
244 frame->retval->type = VAL_OBJ;
245 frame->retval->data.p = mono_object_clone (frame->obj);
248 static gpointer icall_map [] = {
252 "__array_Set", ves_icall_array_Set,
253 "__array_Get", ves_icall_array_Get,
254 "__array_ctor", ves_icall_array_ctor,
255 "__array_bound_ctor", ves_icall_array_bound_ctor,
256 "System.Array::GetValue", ves_icall_System_Array_GetValue,
257 "System.Array::SetValue", ves_icall_System_Array_SetValue,
258 "System.Array::GetRank", ves_icall_System_Array_GetRank,
259 "System.Array::GetLength", ves_icall_System_Array_GetLength,
260 "System.Array::GetLowerBound", ves_icall_System_Array_GetLowerBound,
261 "System.Array::CreateInstance", ves_icall_System_Array_CreateInstance,
266 "System.Object::MemberwiseClone", ves_icall_System_Object_MemberwiseClone,
269 * add other internal calls here
280 while ((n = icall_map [i])) {
281 mono_add_internal_call (n, icall_map [i+1]);