Fri Sep 28 19:26:30 CEST 2001 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / metadata / icall.c
1 /*
2  * icall.c:
3  *
4  * Authors:
5  *   Dietmar Maurer (dietmar@ximian.com)
6  *
7  * (C) 2001 Ximian, Inc.
8  */
9
10 #include <config.h>
11 #include <glib.h>
12 #include <stdarg.h>
13
14 #include <mono/metadata/object.h>
15 #include <mono/metadata/threads.h>
16
17 static MonoObject *
18 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
19 {
20         MonoArrayObject *ao, *io;
21         MonoArrayClass *ac, *ic;
22         gint32 i, pos, *ind, esize;
23         gpointer *ea;
24
25         io = (MonoArrayObject *)idxs;
26         ic = (MonoArrayClass *)io->obj.klass;
27         
28         ao = (MonoArrayObject *)this;
29         ac = (MonoArrayClass *)ao->obj.klass;
30
31         g_assert (ic->rank == 1);
32         g_assert (io->bounds [0].length == ac->rank);
33
34         ind = (guint32 *)io->vector;
35
36         pos = ind [0] - ao->bounds [0].lower_bound;
37         for (i = 1; i < ac->rank; i++)
38                 pos = pos*ao->bounds [i].length + ind [i] - 
39                         ao->bounds [i].lower_bound;
40
41         esize = mono_array_element_size (ac);
42         ea = ao->vector + (pos * esize);
43
44         if (ac->element_class->valuetype)
45                 return mono_value_box (ac->element_class, ea);
46         else
47                 return *ea;
48 }
49
50 static void 
51 ves_icall_System_Array_SetValue (MonoObject *this, MonoObject *value,
52                                  MonoObject *idxs)
53 {
54         MonoArrayObject *ao, *io, *vo;
55         MonoArrayClass *ac, *ic, *vc;
56         gint32 i, pos, *ind, esize;
57         gpointer *ea;
58
59         vo = (MonoArrayObject *)value;
60         vc = (MonoArrayClass *)vo->obj.klass;
61
62         io = (MonoArrayObject *)idxs;
63         ic = (MonoArrayClass *)io->obj.klass;
64         
65         ao = (MonoArrayObject *)this;
66         ac = (MonoArrayClass *)ao->obj.klass;
67
68         g_assert (ic->rank == 1);
69         g_assert (io->bounds [0].length == ac->rank);
70         g_assert (ac->element_class == vo->obj.klass);
71
72         ind = (guint32 *)io->vector;
73
74         pos = ind [0] - ao->bounds [0].lower_bound;
75         for (i = 1; i < ac->rank; i++)
76                 pos = pos*ao->bounds [i].length + ind [i] - 
77                         ao->bounds [i].lower_bound;
78
79         esize = mono_array_element_size (ac);
80         ea = ao->vector + (pos * esize);
81
82         if (ac->element_class->valuetype) {
83                 g_assert (vc->klass.valuetype);
84
85                 memcpy (ea, (char *)vo + sizeof (MonoObject), esize);
86         } else
87                 *ea = (gpointer)vo;
88
89 }
90
91 static void 
92 ves_icall_array_ctor (MonoObject *this, gint32 n1, ...)
93 {
94         va_list ap;
95         MonoArrayObject *ao;
96         MonoArrayClass *ac;
97         gint32 i, s, len, esize;
98
99         va_start (ap, n1);
100
101         ao = (MonoArrayObject *)this;
102         ac = (MonoArrayClass *)this->klass;
103
104         g_assert (ac->rank >= 1);
105
106         ao->bounds = g_malloc0 (ac->rank * sizeof (MonoArrayBounds));
107
108         len = n1;
109         ao->bounds [0].length = n1;
110         for (i = 1; i < ac->rank; i++) {
111                 s = va_arg (ap, gint32);
112                 len *= s;
113                 ao->bounds [i].length = s;
114         }
115
116         esize = mono_array_element_size (ac);
117         ao->vector = g_malloc0 (len * esize);
118 }
119
120 static void 
121 ves_icall_array_bound_ctor (MonoObject *this, gint32 n1, ...)
122 {
123         va_list ap;
124         MonoArrayObject *ao;
125         MonoArrayClass *ac;
126         gint32 i, s, len, esize;
127
128         va_start (ap, n1);
129
130         ao = (MonoArrayObject *)this;
131         ac = (MonoArrayClass *)this->klass;
132
133         g_assert (ac->rank >= 1);
134
135         ao->bounds = g_malloc0 (ac->rank * sizeof (MonoArrayBounds));
136
137         ao->bounds [0].lower_bound = n1;
138         for (i = 1; i < ac->rank; i++)
139                 ao->bounds [i].lower_bound = va_arg (ap, gint32);
140
141         len = va_arg (ap, gint32);
142         ao->bounds [0].length = len;
143         for (i = 1; i < ac->rank; i++) {
144                 s = va_arg (ap, gint32);
145                 len *= s;
146                 ao->bounds [i].length = s;
147         }
148
149         esize = mono_array_element_size (ac);
150         ao->vector = g_malloc0 (len * esize);
151 }
152
153 static void
154 ves_icall_System_Array_CreateInstance ()
155 {
156         g_warning ("not implemented");
157         g_assert_not_reached ();
158 }
159
160
161 static gint32 
162 ves_icall_System_Array_GetRank (MonoObject *this)
163 {
164         return ((MonoArrayClass *)this->klass)->rank;
165 }
166
167 static gint32
168 ves_icall_System_Array_GetLength (MonoObject *this, gint32 dimension)
169 {
170         return ((MonoArrayObject *)this)->bounds [dimension].length;
171 }
172
173 static gint32
174 ves_icall_System_Array_GetLowerBound (MonoObject *this, gint32 dimension)
175 {
176         return ((MonoArrayObject *)this)->bounds [dimension].lower_bound;
177 }
178
179 static MonoObject *
180 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
181 {
182         return mono_object_clone (this);
183 }
184
185 static MonoObject *
186 ves_icall_app_get_cur_domain ()
187 {
188         MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System", "AppDomain");
189
190         return mono_new_object (klass);
191 }
192
193 static MonoObject *
194 ves_icall_app_define_assembly (MonoObject *appdomain, MonoObject *assembly_name, int access)
195 {
196         MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "AssemblyBuilder");
197
198         return mono_new_object (klass);
199 }
200
201 static MonoObject *
202 ves_icall_define_type (MonoObject *moduleb, MonoObject *name, int attrs)
203 {
204         MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "TypeBuilder");
205
206         return mono_new_object (klass);
207 }
208
209 static MonoObject *
210 ves_icall_define_module (MonoObject *assb, MonoObject *name, MonoObject *fname)
211 {
212         MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "ModuleBuilder");
213
214         return mono_new_object (klass);
215 }
216
217 static MonoObject *
218 ves_icall_define_method (MonoObject *typeb, MonoObject *name, int attrs, int callconv, MonoObject *rettype, MonoObject *paramtypes)
219 {
220         MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "MethodBuilder");
221
222         return mono_new_object (klass);
223 }
224
225 static gpointer icall_map [] = {
226         /*
227          * System.Array
228          */
229         "__array_ctor",                   ves_icall_array_ctor,
230         "__array_bound_ctor",             ves_icall_array_bound_ctor,
231         "System.Array::GetValue",         ves_icall_System_Array_GetValue,
232         "System.Array::SetValue",         ves_icall_System_Array_SetValue,
233         "System.Array::GetRank",          ves_icall_System_Array_GetRank,
234         "System.Array::GetLength",        ves_icall_System_Array_GetLength,
235         "System.Array::GetLowerBound",    ves_icall_System_Array_GetLowerBound,
236         "System.Array::CreateInstance",   ves_icall_System_Array_CreateInstance,
237
238         /*
239          * System.Object
240          */
241         "System.Object::MemberwiseClone", ves_icall_System_Object_MemberwiseClone,
242
243         /*
244          * System.String
245          */
246         "System.String::IsInterned", mono_string_is_interned,
247         "System.String::Intern", mono_string_intern,
248
249         /*
250          * System.AppDomain
251          */
252         "System.AppDomain::getCurDomain", ves_icall_app_get_cur_domain,
253         "System.AppDomain::defineAssembly", ves_icall_app_define_assembly,
254
255         /*
256          * ModuleBuilder
257          */
258         "System.Reflection.Emit.ModuleBuilder::defineType", ves_icall_define_type,
259         
260         /*
261          * AssemblyBuilder
262          */
263         "System.Reflection.Emit.AssemblyBuilder::defineModule", ves_icall_define_module,
264         
265         /*
266          * TypeBuilder
267          */
268         "System.Reflection.Emit.TypeBuilder::defineMethod", ves_icall_define_method,
269         
270         /*
271          * System.Threading
272          */
273         "System.Threading.Thread::Thread_internal", ves_icall_System_Threading_Thread_Thread_internal,
274         "System.Threading.Thread::Start_internal", ves_icall_System_Threading_Thread_Start_internal,
275         "System.Threading.Thread::Sleep_internal", ves_icall_System_Threading_Thread_Sleep_internal,
276         "System.Threading.Thread::Schedule_internal", ves_icall_System_Threading_Thread_Schedule_internal,
277         "System.Threading.Thread::CurrentThread_internal", ves_icall_System_Threading_Thread_CurrentThread_internal,
278         "System.Threading.Thread::Join_internal", ves_icall_System_Threading_Thread_Join_internal,
279         "System.Threading.Thread::DataSlot_register", ves_icall_System_Threading_Thread_DataSlot_register,
280         "System.Threading.Thread::DataSlot_store", ves_icall_System_Threading_Thread_DataSlot_store,
281         "System.Threading.Thread::DataSlot_retrieve", ves_icall_System_Threading_Thread_DataSlot_retrieve,
282         "System.LocalDataStoreSlot::DataSlot_unregister", ves_icall_System_LocalDataStoreSlot_DataSlot_unregister,
283
284         /*
285          * add other internal calls here
286          */
287         NULL, NULL
288 };
289
290 void
291 mono_init_icall ()
292 {
293         char *n;
294         int i = 0;
295
296         while ((n = icall_map [i])) {
297                 mono_add_internal_call (n, icall_map [i+1]);
298                 i += 2;
299         }
300        
301 }
302
303