2 * object.c: Object creation for the Mono runtime
5 * Miguel de Icaza (miguel@ximian.com)
7 * (C) 2001 Ximian, Inc.
13 #include <mono/metadata/loader.h>
14 #include <mono/metadata/object.h>
17 * mono_object_allocate:
18 * @size: number of bytes to allocate
20 * This is a very simplistic routine until we have our GC-aware
23 * Returns: an allocated object of size @size, or NULL on failure.
26 mono_object_allocate (size_t size)
28 void *o = calloc (1, size);
36 * Frees the memory used by the object. Debugging purposes
37 * only, as we will have our GC system.
40 mono_object_free (MonoObject *o)
42 MonoClass *c = o->klass;
44 memset (o, 0, c->instance_size);
50 * @klass: the class of the object that we want to create
52 * Returns: A newly created object whose definition is
53 * looked up using @klass
56 mono_object_new (MonoClass *klass)
60 if (!klass->metadata_inited)
61 mono_class_metadata_init (klass);
63 o = mono_object_allocate (klass->instance_size);
70 * mono_object_new_from_token:
71 * @image: Context where the type_token is hosted
72 * @token: a token of the type that we want to create
74 * Returns: A newly created object whose definition is
75 * looked up using @token in the @image image
78 mono_object_new_from_token (MonoImage *image, guint32 token)
82 class = mono_class_get (image, token);
84 return mono_object_new (class);
90 * @obj: the object to clone
92 * Returns: A newly created object who is a shallow copy of @obj
95 mono_object_clone (MonoObject *obj)
100 size = obj->klass->instance_size;
101 o = mono_object_allocate (size);
102 /* FIXME: handle arrays... */
104 memcpy (o, obj, size);
110 mono_array_new_full (MonoClass *array_class, guint32 *lengths, guint32 *lower_bounds)
115 MonoArrayBounds *bounds;
118 if (!array_class->metadata_inited)
119 mono_class_metadata_init (array_class);
120 byte_len = mono_array_element_size (array_class);
122 bounds = g_malloc0 (sizeof (MonoArrayBounds) * array_class->rank);
123 for (i = 0; i < array_class->rank; ++i) {
124 bounds [i].length = lengths [i];
125 byte_len *= lengths [i];
129 for (i = 0; i < array_class->rank; ++i)
130 bounds [i].lower_bound = lower_bounds [i];
132 * Following three lines almost taken from mono_object_new ():
133 * they need to be kept in sync.
135 o = mono_object_allocate (sizeof (MonoArray) + byte_len);
138 o->klass = array_class;
140 array = (MonoArray*)o;
142 array->bounds = bounds;
148 * @image: image where the object is being referenced
149 * @eclass: element class
150 * @n: number of array elements
152 * This routine creates a new szarray with @n elements of type @token
155 mono_array_new (MonoClass *eclass, guint32 n)
159 ac = mono_array_class_get (eclass, 1);
160 g_assert (ac != NULL);
162 return mono_array_new_full (ac, &n, NULL);
166 * mono_string_new_utf16:
167 * @text: a pointer to an utf16 string
168 * @len: the length of the string
170 * Returns: A newly created string object which contains @text.
173 mono_string_new_utf16 (const guint16 *text, gint32 len)
178 s = (MonoString*)mono_object_new (mono_defaults.string_class);
179 g_assert (s != NULL);
181 ca = (MonoArray *)mono_array_new (mono_defaults.string_class, len);
182 g_assert (ca != NULL);
187 memcpy (ca->vector, text, len * 2);
194 * @text: a pointer to an utf8 string
196 * Returns: A newly created string object which contains @text.
199 mono_string_new (const char *text)
205 /* fixme: use some kind of unicode library here */
210 for (i = 0; i < l; i++)
213 o = mono_string_new_utf16 (ut, l);
222 * @class: the class of the value
223 * @value: a pointer to the unboxed data
225 * Returns: A newly created object which contains @value.
228 mono_value_box (MonoClass *class, gpointer value)
233 g_assert (class->valuetype);
235 size = mono_class_instance_size (class);
236 res = mono_object_allocate (size);
239 size = size - sizeof (MonoObject);
241 memcpy ((char *)res + sizeof (MonoObject), value, size);
247 * mono_object_isinst:
249 * @klass: a pointer to a class
251 * Returns: #TRUE if @obj is derived from @klass
254 mono_object_isinst (MonoObject *obj, MonoClass *klass)
256 MonoClass *oklass = obj->klass;
261 oklass = oklass->parent;
266 static GHashTable *ldstr_table = NULL;
269 ldstr_hash (const char* str)
273 len = mono_metadata_decode_blob_size (str, &str);
277 * FIXME: The distribution may not be so nice with lots of
278 * null chars in the string.
280 for (str += 1; str < end; str++)
281 h = (h << 5) - h + *str;
286 ldstr_equal (const char *str1, const char *str2) {
288 if ((len=mono_metadata_decode_blob_size (str1, &str1)) !=
289 mono_metadata_decode_blob_size (str2, &str2))
291 return memcmp (str1, str2, len) == 0;
300 check_interned (gpointer key, MonoString *value, InternCheck *check)
302 if (value == check->obj)
303 check->found = value;
307 mono_string_is_interned (MonoString *o)
313 * Yes, this is slow. Our System.String implementation needs to be redone.
314 * And GLib needs foreach() methods that can be stopped halfway.
316 g_hash_table_foreach (ldstr_table, (GHFunc)check_interned, &check);
321 mono_string_intern (MonoString *str)
324 char *ins = g_malloc (4 + str->length * 2);
327 /* Encode the length */
329 mono_metadata_encode_value (str->length, p, &p);
330 memcpy (p, str->c_str->vector, str->length * 2);
332 if ((res = g_hash_table_lookup (ldstr_table, str))) {
336 g_hash_table_insert (ldstr_table, ins, str);
341 mono_ldstr (MonoImage *image, guint32 index)
343 const char *str, *sig;
348 ldstr_table = g_hash_table_new ((GHashFunc)ldstr_hash, (GCompareFunc)ldstr_equal);
350 sig = str = mono_metadata_user_string (image, index);
352 if ((o = g_hash_table_lookup (ldstr_table, str)))
355 len = mono_metadata_decode_blob_size (str, &str);
356 o = mono_string_new_utf16 ((guint16*)str, len >> 1);
357 g_hash_table_insert (ldstr_table, (gpointer)sig, o);
363 mono_string_to_utf8 (MonoString *s)
368 g_assert (s != NULL);
370 if (!s->length || !s->c_str)
371 return g_strdup ("");
373 vector = (char*)s->c_str->vector;
375 g_assert (vector != NULL);
377 as = g_malloc (s->length + 1);
379 /* fixme: replace with a real unicode/ansi conversion */
380 for (i = 0; i < s->length; i++) {
381 as [i] = vector [i*2];
390 default_ex_handler (MonoException *ex)
392 MonoObject *o = (MonoObject*)ex;
393 g_error ("Exception %s.%s raised in C code", o->klass->name_space, o->klass->name);
396 static MonoExceptionFunc ex_handler = default_ex_handler;
399 mono_install_handler (MonoExceptionFunc func)
401 ex_handler = func? func: default_ex_handler;
405 mono_raise_exception (MonoException *ex)