2 * object.c: Object creation for the Mono runtime
5 * Miguel de Icaza (miguel@ximian.com)
7 * (C) 2001 Ximian, Inc.
12 #include <mono/metadata/loader.h>
13 #include <mono/metadata/object.h>
16 * mono_object_allocate:
17 * @size: number of bytes to allocate
19 * This is a very simplistic routine until we have our GC-aware
22 * Returns: an allocated object of size @size, or NULL on failure.
25 mono_object_allocate (size_t size)
27 void *o = calloc (1, size);
35 * Frees the memory used by the object. Debugging purposes
36 * only, as we will have our GC system.
39 mono_object_free (MonoObject *o)
41 MonoClass *c = o->klass;
43 memset (o, 0, c->instance_size);
49 * @klass: the class of the object that we want to create
51 * Returns: A newly created object whose definition is
52 * looked up using @klass
55 mono_new_object (MonoClass *klass)
59 if (!klass->metadata_inited)
60 mono_class_metadata_init (klass);
62 o = mono_object_allocate (klass->instance_size);
65 mono_threads_synchronisation_init(&o->synchronisation);
71 * mono_new_object_from_token:
72 * @image: Context where the type_token is hosted
73 * @token: a token of the type that we want to create
75 * Returns: A newly created object whose definition is
76 * looked up using @token in the @image image
79 mono_new_object_from_token (MonoImage *image, guint32 token)
83 class = mono_class_get (image, token);
85 return mono_new_object (class);
91 * @obj: the object to clone
93 * Returns: A newly created object who is a shallow copy of @obj
96 mono_object_clone (MonoObject *obj)
101 size = obj->klass->instance_size;
102 o = mono_object_allocate (size);
104 memcpy (o, obj, size);
111 * @image: image where the object is being referenced
112 * @eclass: element class
113 * @n: number of array elements
115 * This routine creates a new szarray with @n elements of type @token
118 mono_new_szarray (MonoClass *eclass, guint32 n)
125 c = mono_array_class_get (eclass, 1);
126 g_assert (c != NULL);
128 o = mono_new_object (c);
130 ao = (MonoArrayObject *)o;
131 ac = (MonoArrayClass *)c;
133 ao->bounds = g_malloc0 (sizeof (MonoArrayBounds));
134 ao->bounds [0].length = n;
135 ao->bounds [0].lower_bound = 0;
137 ao->vector = g_malloc0 (n * mono_array_element_size (ac));
143 * mono_new_utf16_string:
144 * @text: a pointer to an utf16 string
145 * @len: the length of the string
147 * Returns: A newly created string object which contains @text.
150 mono_new_utf16_string (const char *text, gint32 len)
155 s = mono_new_object (mono_defaults.string_class);
156 g_assert (s != NULL);
158 ca = (MonoArrayObject *)mono_new_szarray (mono_defaults.string_class, len);
159 g_assert (ca != NULL);
161 ((MonoStringObject *)s)->c_str = ca;
162 ((MonoStringObject *)s)->length = len;
164 memcpy (ca->vector, text, len * 2);
171 * @text: a pointer to an utf8 string
173 * Returns: A newly created string object which contains @text.
176 mono_new_string (const char *text)
182 /* fixme: use some kind of unicode library here */
187 for (i = 0; i < l; i++)
190 o = mono_new_utf16_string ((char *)ut, l);
199 * @class: the class of the value
200 * @value: a pointer to the unboxed data
202 * Returns: A newly created object which contains @value.
205 mono_value_box (MonoClass *class, gpointer value)
210 g_assert (class->valuetype);
212 size = mono_class_instance_size (class);
213 res = mono_object_allocate (size);
216 size = size - sizeof (MonoObject);
218 memcpy ((char *)res + sizeof (MonoObject), value, size);
224 * mono_object_isinst:
226 * @klass: a pointer to a class
228 * Returns: #TRUE if @obj is derived from @klass
231 mono_object_isinst (MonoObject *obj, MonoClass *klass)
233 MonoClass *oklass = obj->klass;
238 oklass = oklass->parent;
243 static GHashTable *ldstr_table = NULL;
246 ldstr_hash (const char* str)
250 len = mono_metadata_decode_blob_size (str, &str);
254 * FIXME: The distribution may not be so nice with lots of
255 * null chars in the string.
257 for (str += 1; str < end; str++)
258 h = (h << 5) - h + *str;
263 ldstr_equal (const char *str1, const char *str2) {
265 if ((len=mono_metadata_decode_blob_size (str1, &str1)) !=
266 mono_metadata_decode_blob_size (str2, &str2))
268 return memcmp (str1, str2, len) == 0;
277 check_interned (gpointer key, MonoObject *value, InternCheck *check)
279 if (value == check->obj)
280 check->found = value;
284 mono_string_is_interned (MonoObject *o)
290 * Yes, this is slow. Our System.String implementation needs to be redone.
291 * And GLib needs foreach() methods that can be stopped halfway.
293 g_hash_table_foreach (ldstr_table, (GHFunc)check_interned, &check);
298 mono_string_intern (MonoObject *o)
301 MonoStringObject *str = (MonoStringObject*) o;
302 char *ins = g_malloc (4 + str->length * 2);
305 /* Encode the length */
307 mono_metadata_encode_value (str->length, p, &p);
308 memcpy (p, str->c_str->vector, str->length * 2);
310 if ((res = g_hash_table_lookup (ldstr_table, str))) {
314 g_hash_table_insert (ldstr_table, ins, str);
315 return (MonoObject*)str;
319 mono_ldstr (MonoImage *image, guint32 index)
321 const char *str, *sig;
326 ldstr_table = g_hash_table_new ((GHashFunc)ldstr_hash, (GCompareFunc)ldstr_equal);
328 sig = str = mono_metadata_user_string (image, index);
330 if ((o = g_hash_table_lookup (ldstr_table, str)))
333 len = mono_metadata_decode_blob_size (str, &str);
334 o = mono_new_utf16_string (str, len >> 1);
335 g_hash_table_insert (ldstr_table, sig, o);
341 mono_string_to_utf8 (MonoObject *o)
343 MonoStringObject *s = (MonoStringObject *)o;
347 g_assert (o != NULL);
350 return g_strdup ("");
352 vector = s->c_str->vector;
354 g_assert (vector != NULL);
356 as = g_malloc (s->length + 1);
358 /* fixme: replace with a real unicode/ansi conversion */
359 for (i = 0; i < s->length; i++) {
360 as [i] = vector [i*2];