2001-08-21 Dietmar Maurer <dietmar@ximian.com>
[mono.git] / mono / metadata / object.c
1 /*
2  * object.c: Object creation for the Mono runtime
3  *
4  * Author:
5  *   Miguel de Icaza (miguel@ximian.com)
6  *
7  * (C) 2001 Ximian, Inc.
8  */
9 #include <config.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <mono/metadata/loader.h>
13 #include <mono/metadata/object.h>
14
15 /**
16  * mono_object_allocate:
17  * @size: number of bytes to allocate
18  *
19  * This is a very simplistic routine until we have our GC-aware
20  * memory allocator. 
21  *
22  * Returns: an allocated object of size @size, or NULL on failure.
23  */
24 static void *
25 mono_object_allocate (size_t size)
26 {
27         void *o = calloc (1, size);
28
29         return o;
30 }
31
32 /**
33  * mono_object_free:
34  *
35  * Frees the memory used by the object.  Debugging purposes
36  * only, as we will have our GC system.
37  */
38 void
39 mono_object_free (MonoObject *o)
40 {
41         MonoClass *c = o->klass;
42         
43         memset (o, 0, c->instance_size);
44         free (o);
45 }
46
47 /**
48  * mono_object_new:
49  * @image: Context where the type_token is hosted
50  * @type_token: a token of the type that we want to create
51  *
52  * Returns: A newly created object whose definition is
53  * looked up using @type_token in the @image image
54  */
55 MonoObject *
56 mono_object_new (MonoImage *image, guint32 type_token)
57 {
58         MonoClass *c;
59         MonoObject *o;
60
61         c = mono_class_get (image, type_token);
62         o = mono_object_allocate (c->instance_size);
63         o->klass = c;
64
65         return o;
66 }
67
68 /**
69  * mono_object_clone:
70  * @obj: the object to clone
71  *
72  * Returns: A newly created object who is a shallow copy of @obj
73  */
74 MonoObject *
75 mono_object_clone (MonoObject *obj)
76 {
77         MonoObject *o;
78         int size;
79         
80         size = obj->klass->instance_size;
81         o = mono_object_allocate (size);
82         
83         memcpy (o, obj, size);
84
85         return o;
86 }
87
88 /*
89  * mono_new_szarray:
90  * @image: image where the object is being referenced
91  * @etype: element type token
92  * @n: number of array elements
93  *
94  * This routine creates a new szarray with @n elements of type @token
95  */
96 MonoObject *
97 mono_new_szarray (MonoImage *image, guint32 etype, guint32 n)
98 {
99         MonoClass *c;
100         MonoObject *o;
101         MonoArrayObject *ao;
102         MonoArrayClass *ac;
103
104         c = mono_array_class_get (image, etype, 1);
105         g_assert (c != NULL);
106
107         o = mono_object_allocate (c->instance_size);
108         o->klass = c;
109
110         ao = (MonoArrayObject *)o;
111         ac = (MonoArrayClass *)c;
112
113         ao->bounds = g_malloc0 (sizeof (MonoArrayBounds));
114         ao->bounds [0].length = n;
115         ao->bounds [0].lower_bound = 0;
116
117         
118         ao->vector = g_malloc0 (n * mono_array_element_size (ac));
119
120         return o;
121 }
122
123 MonoObject *
124 mono_new_utf16_string (const char *text, gint32 len)
125 {
126         MonoObject *s;
127         MonoArrayObject *ca;
128
129         s = mono_object_new (mono_defaults.corlib, mono_defaults.string_token);
130         g_assert (s != NULL);
131
132         ca = (MonoArrayObject *)mono_new_szarray (mono_defaults.corlib, mono_defaults.string_token, len);
133         g_assert (ca != NULL);
134         
135         ((MonoStringObject *)s)->c_str = ca;
136         ((MonoStringObject *)s)->length = len;
137
138         memcpy (ca->vector, text, len * 2);
139
140         return s;
141 }
142
143 MonoObject *
144 mono_new_string (const char *text)
145 {
146         MonoObject *o;
147         guint16 *ut;
148         int i, l;
149
150         /* fixme: use some kind of unicode library here */
151
152         l = strlen (text);
153         ut = g_malloc (l*2);
154
155         for (i = 0; i < l; i++)
156                 ut [i] = text[i];
157         
158         o = mono_new_utf16_string ((char *)ut, l);
159
160         g_free (ut);
161
162         return o;
163 }
164
165 MonoObject *
166 mono_value_box (MonoClass *class, gpointer val)
167 {
168         MonoObject *res;
169         int size;
170
171         g_assert (class->valuetype);
172
173         res = mono_object_allocate (class->instance_size);
174         res->klass = class;
175
176         size = res->klass->instance_size - sizeof (MonoObject);
177
178         memcpy ((char *)res + sizeof (MonoObject), val, size);
179
180         return res;
181 }
182
183 gboolean
184 mono_object_isinst (MonoObject *obj, MonoClass *klass)
185 {
186         MonoClass *oklass = obj->klass;
187
188         while (oklass) {
189                 if (oklass == klass)
190                         return TRUE;
191                 oklass = oklass->parent;
192         }
193         return FALSE;
194 }
195