@@ -45,6 +45,7 @@ static void compose(PARROT_INTERP, STable *st, PMC *repr_info) {
45
45
(spec .boxed_primitive == STORAGE_SPEC_BP_INT ||
46
46
spec .boxed_primitive == STORAGE_SPEC_BP_NUM )) {
47
47
repr_data -> elem_size = spec .bits ;
48
+ repr_data -> elem_kind = spec .boxed_primitive ;
48
49
}
49
50
}
50
51
}
@@ -85,36 +86,207 @@ static storage_spec get_storage_spec(PARROT_INTERP, STable *st) {
85
86
return spec ;
86
87
}
87
88
89
+ PARROT_DOES_NOT_RETURN static void die_no_native (PARROT_INTERP , const char * operation ) {
90
+ Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
91
+ "VMArray: Can't perform native %s when containing boxed types" , operation );
92
+ }
93
+
94
+ PARROT_DOES_NOT_RETURN static void die_no_boxed (PARROT_INTERP , const char * operation ) {
95
+ Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
96
+ "VMArray: Can't perform native %s when containing native types" , operation );
97
+ }
98
+
99
+ /* Wrapper functions to set an array offset to a value for the various types
100
+ * we support. */
101
+ static void set_pos_int1 (Parrot_Int1 * slots , INTVAL offset , Parrot_Int1 val ) { slots [offset ] = val ; }
102
+ static void set_pos_int2 (Parrot_Int2 * slots , INTVAL offset , Parrot_Int2 val ) { slots [offset ] = val ; }
103
+ static void set_pos_int4 (Parrot_Int4 * slots , INTVAL offset , Parrot_Int4 val ) { slots [offset ] = val ; }
104
+ static void set_pos_int8 (Parrot_Int8 * slots , INTVAL offset , Parrot_Int8 val ) { slots [offset ] = val ; }
105
+ static void set_pos_float4 (Parrot_Float4 * slots , INTVAL offset , Parrot_Float4 val ) { slots [offset ] = val ; }
106
+ static void set_pos_float8 (Parrot_Float8 * slots , INTVAL offset , Parrot_Float8 val ) { slots [offset ] = val ; }
107
+ static void set_pos_pmc (PMC * * slots , INTVAL offset , PMC * obj ) { slots [offset ] = obj ; }
108
+
109
+ /* Convenience method to set a given offset to a sensible NULL value. */
110
+ static void null_pos (PARROT_INTERP , VMArrayREPRData * repr_data , void * slots , INTVAL offset ) {
111
+ if (!repr_data -> elem_size ) {
112
+ set_pos_pmc ((PMC * * ) slots , offset , PMCNULL );
113
+ }
114
+ else if (repr_data -> elem_kind == STORAGE_SPEC_BP_INT ) {
115
+ switch (repr_data -> elem_size ) {
116
+ case 8 :
117
+ set_pos_int1 ((Parrot_Int1 * ) slots , offset , 0 );
118
+ break ;
119
+ case 16 :
120
+ set_pos_int2 ((Parrot_Int2 * ) slots , offset , 0 );
121
+ break ;
122
+ case 32 :
123
+ set_pos_int4 ((Parrot_Int4 * ) slots , offset , 0 );
124
+ break ;
125
+ case 64 :
126
+ set_pos_int8 ((Parrot_Int8 * ) slots , offset , 0 );
127
+ break ;
128
+ default :
129
+ Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
130
+ "VMArray: Only supports 8, 16, 32 and 64 bit integers." );
131
+ }
132
+ }
133
+ else if (repr_data -> elem_kind == STORAGE_SPEC_BP_NUM ) {
134
+ switch (repr_data -> elem_size ) {
135
+ case 32 :
136
+ set_pos_float4 ((Parrot_Float4 * ) slots , offset , 0.0 );
137
+ break ;
138
+ case 64 :
139
+ set_pos_float8 ((Parrot_Float8 * ) slots , offset , 0.0 );
140
+ break ;
141
+ default :
142
+ Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
143
+ "VMArray: Only supports 32 and 64 bit floats." );
144
+ }
145
+ }
146
+ else {
147
+ Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
148
+ "VMArray: Only flattened ints and floats." );
149
+ }
150
+ }
151
+
152
+ /* Ensure that the array has enough size */
153
+ static void ensure_size (PARROT_INTERP , VMArrayBody * body , VMArrayREPRData * repr_data , INTVAL n ) {
154
+ INTVAL elems = body -> elems ;
155
+ INTVAL start = body -> start ;
156
+ INTVAL ssize = body -> ssize ;
157
+ void * slots = body -> slots ;
158
+
159
+ if (n < 0 ) {
160
+ Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
161
+ "VMArray: Can't resize to negative size" );
162
+ }
163
+
164
+ if (n == elems ) { return ; }
165
+
166
+ /* If there aren't enough slots at the end, shift off empty slots
167
+ * from the beginning first */
168
+ if (start > 0 && n + start > ssize ) {
169
+ if (elems > 0 ) {
170
+ INTVAL elem_size = repr_data -> elem_size /8 ;
171
+ void * dest = ((char * ) slots ) + start * elem_size ;
172
+ memmove (slots , slots + start , elems * elem_size );
173
+ }
174
+ body -> start = 0 ;
175
+ /* fill out any unused slots with PMCNULL pointers */
176
+ while (elems < ssize ) {
177
+ null_pos (interp , repr_data , slots , elems );
178
+ elems ++ ;
179
+ }
180
+ }
181
+
182
+ body -> elems = n ;
183
+ if (n <= ssize ) {
184
+ /* We already have n slots available, we can just return */
185
+ return ;
186
+ }
187
+
188
+ /* We need more slots. If the current slot size is less
189
+ * than 8K, use the larger of twice the current slot size
190
+ * or the actual number of elements needed. Otherwise,
191
+ * grow the slots to the next multiple of 4096 (0x1000). */
192
+ if (ssize < 8192 ) {
193
+ ssize *= 2 ;
194
+ if (n > ssize ) ssize = n ;
195
+ if (ssize < 8 ) ssize = 8 ;
196
+ }
197
+ else {
198
+ ssize = (n + 0x1000 ) & ~0xfff ;
199
+ }
200
+
201
+ /* Now allocate the new slot buffer */
202
+ slots = (slots )
203
+ /* XXX: Change these to allocate non-GCed memory? */
204
+ ? mem_gc_realloc_n_typed (interp , slots , ssize , PMC * )
205
+ : mem_gc_allocate_n_typed (interp , ssize , PMC * );
206
+
207
+ /* Fill out any unused slots with PMCNULL pointers */
208
+ while (elems < ssize ) {
209
+ null_pos (interp , repr_data , slots , elems );
210
+ elems ++ ;
211
+ }
212
+
213
+ body -> ssize = ssize ;
214
+ body -> slots = slots ;
215
+ }
216
+
88
217
static void at_pos_native (PARROT_INTERP , STable * st , void * data , INTVAL index , NativeValue * value ) {
218
+ VMArrayREPRData * repr_data = (VMArrayREPRData * ) st -> REPR_data ;
219
+
220
+ if (!repr_data -> elem_size )
221
+ die_no_native (interp , "get" );
222
+
89
223
/* TODO */
90
224
}
91
225
92
226
static PMC * at_pos_boxed (PARROT_INTERP , STable * st , void * data , INTVAL index ) {
227
+ VMArrayREPRData * repr_data = (VMArrayREPRData * ) st -> REPR_data ;
228
+
229
+ if (!repr_data -> elem_size )
230
+ die_no_native (interp , "set" );
231
+
93
232
/* TODO */
233
+ return PMCNULL ;
94
234
}
95
235
96
236
static void bind_pos_native (PARROT_INTERP , STable * st , void * data , INTVAL index , NativeValue * value ) {
237
+ VMArrayREPRData * repr_data = (VMArrayREPRData * ) st -> REPR_data ;
238
+
239
+ if (!repr_data -> elem_size )
240
+ die_no_boxed (interp , "get" );
241
+
97
242
/* TODO */
98
243
}
99
244
100
245
static void bind_pos_boxed (PARROT_INTERP , STable * st , void * data , INTVAL index , PMC * obj ) {
246
+ VMArrayREPRData * repr_data = (VMArrayREPRData * ) st -> REPR_data ;
247
+
248
+ if (!repr_data -> elem_size )
249
+ die_no_boxed (interp , "set" );
250
+
101
251
/* TODO */
102
252
}
103
253
104
254
static void push_boxed (PARROT_INTERP , STable * st , void * data , PMC * obj ) {
255
+ VMArrayREPRData * repr_data = (VMArrayREPRData * ) st -> REPR_data ;
256
+
257
+ if (!repr_data -> elem_size )
258
+ die_no_boxed (interp , "push" );
259
+
105
260
/* TODO */
106
261
}
107
262
108
- static void pop_boxed (PARROT_INTERP , STable * st , void * data ) {
263
+ static PMC * pop_boxed (PARROT_INTERP , STable * st , void * data ) {
264
+ VMArrayREPRData * repr_data = (VMArrayREPRData * ) st -> REPR_data ;
265
+
266
+ if (!repr_data -> elem_size )
267
+ die_no_boxed (interp , "pop" );
268
+
109
269
/* TODO */
270
+ return PMCNULL ;
110
271
}
111
272
112
273
static void unshift_boxed (PARROT_INTERP , STable * st , void * data , PMC * obj ) {
274
+ VMArrayREPRData * repr_data = (VMArrayREPRData * ) st -> REPR_data ;
275
+
276
+ if (!repr_data -> elem_size )
277
+ die_no_boxed (interp , "unshift" );
278
+
113
279
/* TODO */
114
280
}
115
281
116
- static void shift_boxed (PARROT_INTERP , STable * st , void * data ) {
282
+ static PMC * shift_boxed (PARROT_INTERP , STable * st , void * data ) {
283
+ VMArrayREPRData * repr_data = (VMArrayREPRData * ) st -> REPR_data ;
284
+
285
+ if (!repr_data -> elem_size )
286
+ die_no_boxed (interp , "shift" );
287
+
117
288
/* TODO */
289
+ return PMCNULL ;
118
290
}
119
291
120
292
/* Initializes the VMArray representation. */
0 commit comments