/* * icall.c: * * Authors: * Dietmar Maurer (dietmar@ximian.com) * * (C) 2001 Ximian, Inc. */ #include #include #include #include #include #include #include static MonoObject * ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs) { MonoClass *ac, *ic; MonoArray *ao, *io; gint32 i, pos, *ind, esize; gpointer *ea; io = (MonoArray *)idxs; ic = (MonoClass *)io->obj.klass; ao = (MonoArray *)this; ac = (MonoClass *)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; esize = mono_array_element_size (ac); ea = ao->vector + (pos * esize); if (ac->element_class->valuetype) return mono_value_box (ac->element_class, ea); else return *ea; } static void ves_icall_System_Array_SetValue (MonoObject *this, MonoObject *value, MonoObject *idxs) { MonoArray *ao, *io, *vo; MonoClass *ac, *ic, *vc; gint32 i, pos, *ind, esize; gpointer *ea; vo = (MonoArray *)value; vc = (MonoClass *)vo->obj.klass; io = (MonoArray *)idxs; ic = (MonoClass *)io->obj.klass; ao = (MonoArray *)this; ac = (MonoClass *)ao->obj.klass; g_assert (ic->rank == 1); g_assert (io->bounds [0].length == ac->rank); g_assert (ac->element_class == vo->obj.klass); 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; esize = mono_array_element_size (ac); ea = ao->vector + (pos * esize); if (ac->element_class->valuetype) { g_assert (vc->valuetype); memcpy (ea, (char *)vo + sizeof (MonoObject), esize); } else *ea = (gpointer)vo; } static void ves_icall_array_ctor (MonoObject *this, gint32 n1, ...) { va_list ap; MonoArray *ao; MonoClass *ac; gint32 i, s, len, esize; va_start (ap, n1); ao = (MonoArray *)this; ac = (MonoClass *)this->klass; g_assert (ac->rank >= 1); ao->bounds = g_malloc0 (ac->rank * sizeof (MonoArrayBounds)); len = n1; ao->bounds [0].length = n1; for (i = 1; i < ac->rank; i++) { s = va_arg (ap, gint32); len *= s; ao->bounds [i].length = s; } esize = mono_array_element_size (ac); ao->vector = g_malloc0 (len * esize); } static void ves_icall_array_bound_ctor (MonoObject *this, gint32 n1, ...) { va_list ap; MonoArray *ao; MonoClass *ac; gint32 i, s, len, esize; va_start (ap, n1); ao = (MonoArray *)this; ac = (MonoClass *)this->klass; g_assert (ac->rank >= 1); ao->bounds = g_malloc0 (ac->rank * sizeof (MonoArrayBounds)); ao->bounds [0].lower_bound = n1; for (i = 1; i < ac->rank; i++) ao->bounds [i].lower_bound = va_arg (ap, gint32); len = va_arg (ap, gint32); ao->bounds [0].length = len; for (i = 1; i < ac->rank; i++) { s = va_arg (ap, gint32); len *= s; ao->bounds [i].length = s; } esize = mono_array_element_size (ac); ao->vector = g_malloc0 (len * esize); } static void ves_icall_System_Array_CreateInstance () { g_warning ("not implemented"); g_assert_not_reached (); } static gint32 ves_icall_System_Array_GetRank (MonoObject *this) { return this->klass->rank; } static gint32 ves_icall_System_Array_GetLength (MonoObject *this, gint32 dimension) { return ((MonoArray *)this)->bounds [dimension].length; } static gint32 ves_icall_System_Array_GetLowerBound (MonoObject *this, gint32 dimension) { return ((MonoArray *)this)->bounds [dimension].lower_bound; } static MonoObject * ves_icall_System_Object_MemberwiseClone (MonoObject *this) { return mono_object_clone (this); } static MonoObject * ves_icall_app_get_cur_domain () { MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System", "AppDomain"); return mono_object_new (klass); } static MonoObject * my_mono_new_object (MonoClass *klass, gpointer data) { MonoClassField *field; MonoObject *res = mono_object_new (klass); gpointer *slot; field = mono_class_get_field_from_name (klass, "_impl"); slot = (gpointer*)((char*)res + field->offset); *slot = data; return res; } static gint32 ves_icall_get_data_chunk (MonoReflectionAssemblyBuilder *assb, gint32 type, MonoArray *buf) { int count; if (type == 0) { /* get the header */ count = mono_image_get_header (assb, buf->vector, buf->bounds->length); if (count != -1) return count; } else { MonoDynamicAssembly *ass = assb->dynamic_assembly; count = ass->code.index + ass->meta_size; if (count > buf->bounds->length) return 0; memcpy (buf->vector, ass->code.data, ass->code.index); memcpy (buf->vector + ass->code.index, ass->assembly.image->raw_metadata, ass->meta_size); return count; } return 0; } static MonoObject* ves_icall_type_from_name (MonoObject *name) { return NULL; } static MonoObject* ves_icall_type_from_handle (gpointer handle) { return my_mono_new_object (mono_defaults.type_class, handle); } static gpointer icall_map [] = { /* * System.Array */ "__array_ctor", ves_icall_array_ctor, "__array_bound_ctor", ves_icall_array_bound_ctor, "System.Array::GetValue", ves_icall_System_Array_GetValue, "System.Array::SetValue", ves_icall_System_Array_SetValue, "System.Array::GetRank", ves_icall_System_Array_GetRank, "System.Array::GetLength", ves_icall_System_Array_GetLength, "System.Array::GetLowerBound", ves_icall_System_Array_GetLowerBound, "System.Array::CreateInstance", ves_icall_System_Array_CreateInstance, /* * System.Object */ "System.Object::MemberwiseClone", ves_icall_System_Object_MemberwiseClone, /* * System.String */ "System.String::IsInterned", mono_string_is_interned, "System.String::Intern", mono_string_intern, /* * System.AppDomain */ "System.AppDomain::getCurDomain", ves_icall_app_get_cur_domain, /* * ModuleBuilder */ /* * AssemblyBuilder */ "System.Reflection.Emit.AssemblyBuilder::getDataChunk", ves_icall_get_data_chunk, /* * TypeBuilder */ /* * MethodBuilder */ /* * System.Type */ "System.Type::internal_from_name", ves_icall_type_from_name, "System.Type::internal_from_handle", ves_icall_type_from_handle, /* * System.Threading */ "System.Threading.Thread::Thread_internal", ves_icall_System_Threading_Thread_Thread_internal, "System.Threading.Thread::Start_internal", ves_icall_System_Threading_Thread_Start_internal, "System.Threading.Thread::Sleep_internal", ves_icall_System_Threading_Thread_Sleep_internal, "System.Threading.Thread::Schedule_internal", ves_icall_System_Threading_Thread_Schedule_internal, "System.Threading.Thread::CurrentThread_internal", ves_icall_System_Threading_Thread_CurrentThread_internal, "System.Threading.Thread::Join_internal", ves_icall_System_Threading_Thread_Join_internal, "System.Threading.Thread::DataSlot_register", ves_icall_System_Threading_Thread_DataSlot_register, "System.Threading.Thread::DataSlot_store", ves_icall_System_Threading_Thread_DataSlot_store, "System.Threading.Thread::DataSlot_retrieve", ves_icall_System_Threading_Thread_DataSlot_retrieve, /* Not in the System.Threading namespace, but part of the same code */ "System.LocalDataStoreSlot::DataSlot_unregister", ves_icall_System_LocalDataStoreSlot_DataSlot_unregister, "System.Threading.Monitor::Monitor_enter", ves_icall_System_Threading_Monitor_Monitor_enter, "System.Threading.Monitor::Monitor_exit", ves_icall_System_Threading_Monitor_Monitor_exit, "System.Threading.Monitor::Monitor_test_owner", ves_icall_System_Threading_Monitor_Monitor_test_owner, "System.Threading.Monitor::Monitor_test_synchronised", ves_icall_System_Threading_Monitor_Monitor_test_synchronised, "System.Threading.Monitor::Monitor_pulse", ves_icall_System_Threading_Monitor_Monitor_pulse, "System.Threading.Monitor::Monitor_pulse_all", ves_icall_System_Threading_Monitor_Monitor_pulse_all, "System.Threading.Monitor::Monitor_try_enter", ves_icall_System_Threading_Monitor_Monitor_try_enter, "System.Threading.Monitor::Monitor_wait", ves_icall_System_Threading_Monitor_Monitor_wait, /* * add other internal calls here */ NULL, NULL }; void mono_init_icall () { char *n; int i = 0; while ((n = icall_map [i])) { mono_add_internal_call (n, icall_map [i+1]); i += 2; } }