* st/CompiledMethod.st: Added methods for querying method
[panda.git] / src / st-array.c
blobaf0a899b27ccb7460a71773c7266a655e63dc6f0
1 /*
2 * st-array.c
4 * Copyright (c) 2008 Vincent Geddes
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
24 #include "st-array.h"
25 #include "st-universe.h"
26 #include "st-utils.h"
27 #include "st-descriptor.h"
28 #include "st-behavior.h"
29 #include <string.h>
31 static st_oop
32 array_allocate_arrayed (st_oop class,
33 st_smi size)
35 st_oop array;
36 st_oop *elements;
38 st_assert (size >= 0);
40 array = st_memory_allocate (ST_SIZE_OOPS (struct st_array) + size);
41 st_object_initialize_header (array, class);
43 ST_ARRAYED_OBJECT (array)->size = st_smi_new (size);
44 elements = ST_ARRAY (array)->elements;
45 for (st_smi i = 0; i < size; i++)
46 elements[i] = st_nil;
48 return array;
51 static st_uint
52 array_size (st_oop object)
54 return ST_SIZE_OOPS (struct st_arrayed_object) + st_smi_value (st_arrayed_object_size (object));
57 static void
58 array_contents (st_oop object, st_oop **oops, st_uint *size)
60 *oops = st_array_elements (object);
61 *size = st_smi_value (st_arrayed_object_size (object));
64 st_descriptor *
65 st_array_descriptor (void)
67 static st_descriptor __descriptor =
68 { .allocate = NULL,
69 .allocate_arrayed = array_allocate_arrayed,
70 .size = array_size,
71 .contents = array_contents,
74 return & __descriptor;
77 /* ByteArray */
79 static st_oop
80 byte_allocate_arrayed (st_oop class,
81 st_smi size)
83 st_uint size_oops;
84 st_oop array;
86 st_assert (size >= 0);
88 /* add 1 byte for NULL terminator. Allows toll-free bridging with C string function */
89 size_oops = ST_ROUNDED_UP_OOPS (size + 1);
91 array = st_memory_allocate (ST_SIZE_OOPS (struct st_byte_array) + size_oops);
92 st_object_initialize_header (array, class);
94 ST_ARRAYED_OBJECT (array)->size = st_smi_new (size);
95 memset (st_byte_array_bytes (array), 0, ST_OOPS_TO_BYTES (size_oops));
97 return array;
100 bool
101 st_byte_array_equal (st_oop object, st_oop other)
103 st_smi size, size_other;
105 if (st_object_class (other) != st_byte_array_class &&
106 st_object_class (other) != st_string_class &&
107 st_object_class (other) != st_symbol_class)
108 return false;
110 size = st_smi_value (ST_ARRAYED_OBJECT (object)->size);
111 size_other = st_smi_value (ST_ARRAYED_OBJECT (other)->size);
113 if (size != size_other)
114 return false;
116 return memcmp (st_byte_array_bytes (object), st_byte_array_bytes (other), size) == 0;
119 st_uint
120 st_byte_array_hash (st_oop object)
122 return st_string_hash ((char *) st_byte_array_bytes (object));
125 static st_uint
126 byte_array_size (st_oop object)
128 st_uint size;
130 size = st_smi_value (st_arrayed_object_size (object));
131 return ST_SIZE_OOPS (struct st_arrayed_object) + ST_ROUNDED_UP_OOPS (size + 1);
134 static void
135 byte_array_contents (st_oop object, st_oop **oops, st_uint *size)
137 *oops = NULL;
138 *size = 0;
141 st_descriptor *
142 st_byte_array_descriptor (void)
144 static st_descriptor __descriptor =
145 { .allocate = NULL,
146 .allocate_arrayed = byte_allocate_arrayed,
147 .size = byte_array_size,
148 .contents = byte_array_contents,
151 return & __descriptor;
154 /* WordArray */
156 static st_oop
157 word_allocate_arrayed (st_oop class, st_smi size)
159 st_oop array;
160 st_smi size_oops;
161 st_uint *elements;
163 st_assert (size >= 0);
165 size_oops = size / (sizeof (st_oop) / sizeof (st_uint));
167 array = st_memory_allocate (ST_SIZE_OOPS (struct st_word_array) + size_oops);
168 st_object_initialize_header (array, class);
170 ST_ARRAYED_OBJECT (array)->size = st_smi_new (size);
171 elements = st_word_array_elements (array);
172 for (st_smi i = 0; i < size; i++)
173 elements[i] = 0;
175 return array;
179 static st_uint
180 word_array_size (st_oop object)
182 return ST_SIZE_OOPS (struct st_arrayed_object)
183 + (st_smi_value (st_arrayed_object_size (object)) / (sizeof (st_oop) / sizeof (st_uint)));
186 static void
187 word_array_contents (st_oop object, st_oop **oops, st_uint *size)
189 *oops = NULL;
190 *size = 0;
193 st_descriptor *
194 st_word_array_descriptor (void)
196 static st_descriptor __descriptor =
197 { .allocate = NULL,
198 .allocate_arrayed = word_allocate_arrayed,
199 .size = word_array_size,
200 .contents = word_array_contents,
202 return & __descriptor;
206 /* FloatArray */
208 static st_oop
209 float_allocate_arrayed (st_oop class, st_smi size)
211 st_oop object;
212 double *elements;
213 st_smi size_oops;
215 st_assert (size >= 0);
217 /* get actual size in oops (dependent on whether system is 64bit or 32bit) */
218 size_oops = size * (sizeof (double) / sizeof (st_oop));
220 object = st_memory_allocate (ST_SIZE_OOPS (struct st_float_array) + size_oops);
221 st_object_initialize_header (object, class);
223 ST_ARRAYED_OBJECT (object)->size = st_smi_new (size);
225 elements = ST_FLOAT_ARRAY (object)->elements;
226 for (st_smi i = 0; i < size; i++)
227 elements[i] = (double) 0;
229 return object;
232 static st_uint
233 float_array_size (st_oop object)
235 return ST_SIZE_OOPS (struct st_arrayed_object) + (st_smi_value (st_arrayed_object_size (object)) * ST_SIZE_OOPS (double));
238 static void
239 float_array_contents (st_oop object, st_oop **oops, st_uint *size)
241 *oops = NULL;
242 *size = 0;
245 st_descriptor *
246 st_float_array_descriptor (void)
248 static st_descriptor __descriptor =
249 { .allocate = NULL,
250 .allocate_arrayed = float_allocate_arrayed,
251 .size = float_array_size,
252 .contents = float_array_contents,
255 return & __descriptor;