Skip to content

Commit 480d22d

Browse files
committed
[CArray] Refactor bind_pos_boxed/at_pos_boxed.
Since we've added child_objs, we can cache the generated String objects as well, and eliminate the need for at/bind_pos_complex.
1 parent a04da69 commit 480d22d

File tree

1 file changed

+38
-55
lines changed

1 file changed

+38
-55
lines changed

src/6model/reprs/CArray.c

Lines changed: 38 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ static void initialize(PARROT_INTERP, STable *st, void *data) {
127127
body->storage = mem_sys_allocate(4 * repr_data->elem_size);
128128
body->managed = 1;
129129
/* Don't need child_objs for numerics or strings. */
130-
if (repr_data->elem_kind == CARRAY_ELEM_KIND_NUMERIC || repr_data->elem_kind == CARRAY_ELEM_KIND_STRING)
130+
if (repr_data->elem_kind == CARRAY_ELEM_KIND_NUMERIC)
131131
body->child_objs = NULL;
132132
else
133133
body->child_objs = mem_sys_allocate_zeroed(4*sizeof(PMC *));
@@ -208,7 +208,8 @@ static void expand(PARROT_INTERP, CArrayREPRData *repr_data, CArrayBody *body, I
208208

209209
is_complex = (repr_data->elem_kind == CARRAY_ELEM_KIND_CARRAY
210210
|| repr_data->elem_kind == CARRAY_ELEM_KIND_CPOINTER
211-
|| repr_data->elem_kind == CARRAY_ELEM_KIND_CSTRUCT);
211+
|| repr_data->elem_kind == CARRAY_ELEM_KIND_CSTRUCT
212+
|| repr_data->elem_kind == CARRAY_ELEM_KIND_STRING);
212213
if (is_complex)
213214
body->child_objs = mem_sys_realloc_zeroed(body->child_objs, next_size * sizeof(PMC *), body->allocated * sizeof(PMC *));
214215
body->allocated = next_size;
@@ -226,10 +227,24 @@ static void * at_pos_ref(PARROT_INTERP, STable *st, void *data, INTVAL index) {
226227
"at_pos_ref on CArray REPR only usable with numeric element types");
227228
}
228229
}
229-
static PMC * at_pos_complex(PARROT_INTERP, STable *st, void *data, INTVAL index) {
230+
static PMC * at_pos_boxed(PARROT_INTERP, STable *st, void *data, INTVAL index) {
230231
CArrayREPRData *repr_data = (CArrayREPRData *)st->REPR_data;
231232
CArrayBody *body = (CArrayBody *)data;
232233

234+
switch (repr_data->elem_kind) {
235+
case CARRAY_ELEM_KIND_STRING:
236+
case CARRAY_ELEM_KIND_CARRAY:
237+
case CARRAY_ELEM_KIND_CPOINTER:
238+
case CARRAY_ELEM_KIND_CSTRUCT:
239+
break;
240+
default:
241+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
242+
"at_pos_boxed on CArray REPR not usable with this element type");
243+
}
244+
245+
if (body->managed && index >= body->elems)
246+
return repr_data->elem_type;
247+
233248
if (body->managed) {
234249
/* We manage this array. */
235250
if (index < body->elems && body->child_objs[index])
@@ -256,6 +271,17 @@ static PMC * at_pos_complex(PARROT_INTERP, STable *st, void *data, INTVAL index)
256271
* put it in the cache and return it. */
257272
else if (storage[index]) {
258273
switch (repr_data->elem_kind) {
274+
case CARRAY_ELEM_KIND_STRING:
275+
{
276+
char *elem = *((char **)(((char *)body->storage) + index * repr_data->elem_size));
277+
STRING *str = Parrot_str_new_init(interp, elem, strlen(elem), Parrot_utf8_encoding_ptr, 0);
278+
279+
obj = REPR(repr_data->elem_type)->allocate(interp, STABLE(repr_data->elem_type));
280+
REPR(obj)->initialize(interp, STABLE(obj), OBJECT_BODY(obj));
281+
REPR(obj)->box_funcs->set_str(interp, STABLE(obj), OBJECT_BODY(obj), str);
282+
PARROT_GC_WRITE_BARRIER(interp, obj);
283+
break;
284+
}
259285
case CARRAY_ELEM_KIND_CARRAY:
260286
obj = make_carray_result(interp, repr_data->elem_type, storage[index]);
261287
break;
@@ -275,36 +301,6 @@ static PMC * at_pos_complex(PARROT_INTERP, STable *st, void *data, INTVAL index)
275301
}
276302
}
277303
}
278-
static PMC * at_pos_boxed(PARROT_INTERP, STable *st, void *data, INTVAL index) {
279-
CArrayREPRData *repr_data = (CArrayREPRData *)st->REPR_data;
280-
CArrayBody *body = (CArrayBody *)data;
281-
if (body->managed && index >= body->elems)
282-
return repr_data->elem_type;
283-
switch (repr_data->elem_kind) {
284-
case CARRAY_ELEM_KIND_STRING:
285-
{
286-
char *elem = *((char **)(((char *)body->storage) + index * repr_data->elem_size));
287-
if (elem) {
288-
STRING *str = Parrot_str_new_init(interp, elem, strlen(elem), Parrot_utf8_encoding_ptr, 0);
289-
PMC *res = REPR(repr_data->elem_type)->allocate(interp, STABLE(repr_data->elem_type));
290-
REPR(res)->initialize(interp, STABLE(res), OBJECT_BODY(res));
291-
REPR(res)->box_funcs->set_str(interp, STABLE(res), OBJECT_BODY(res), str);
292-
PARROT_GC_WRITE_BARRIER(interp, res);
293-
return res;
294-
}
295-
else
296-
return repr_data->elem_type;
297-
break;
298-
}
299-
case CARRAY_ELEM_KIND_CARRAY:
300-
case CARRAY_ELEM_KIND_CPOINTER:
301-
case CARRAY_ELEM_KIND_CSTRUCT:
302-
return at_pos_complex(interp, st, data, index);
303-
default:
304-
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
305-
"at_pos_boxed on CArray REPR not usable with this element type");
306-
}
307-
}
308304
static void bind_pos_ref(PARROT_INTERP, STable *st, void *data, INTVAL index, void *value) {
309305
CArrayREPRData *repr_data = (CArrayREPRData *)st->REPR_data;
310306
CArrayBody *body = (CArrayBody *)data;
@@ -322,7 +318,7 @@ static void bind_pos_ref(PARROT_INTERP, STable *st, void *data, INTVAL index, vo
322318
"bind_pos_ref on CArray REPR only usable with numeric element types");
323319
}
324320
}
325-
static void bind_pos_complex(PARROT_INTERP, STable *st, void *data, INTVAL index, PMC *obj) {
321+
static void bind_pos_boxed(PARROT_INTERP, STable *st, void *data, INTVAL index, PMC *obj) {
326322
CArrayREPRData *repr_data = (CArrayREPRData *)st->REPR_data;
327323
CArrayBody *body = (CArrayBody *)data;
328324
void **storage = (void **) body->storage;
@@ -334,6 +330,14 @@ static void bind_pos_complex(PARROT_INTERP, STable *st, void *data, INTVAL index
334330
body->elems = index + 1;
335331

336332
switch (repr_data->elem_kind) {
333+
case CARRAY_ELEM_KIND_STRING:
334+
{
335+
STRING *str = REPR(obj)->box_funcs->get_str(interp, STABLE(obj), OBJECT_BODY(obj));
336+
char *elem = Parrot_str_to_encoded_cstring(interp, str, Parrot_utf8_encoding_ptr);
337+
*((char **)(((char *)body->storage) + index * repr_data->elem_size)) = elem;
338+
body->child_objs[index] = obj;
339+
break;
340+
}
337341
case CARRAY_ELEM_KIND_CARRAY:
338342
storage[index] = ((CArrayBody *) OBJECT_BODY(obj))->storage;
339343
body->child_objs[index] = obj;
@@ -346,27 +350,6 @@ static void bind_pos_complex(PARROT_INTERP, STable *st, void *data, INTVAL index
346350
storage[index] = ((CPointerBody *) OBJECT_BODY(obj))->ptr;
347351
body->child_objs[index] = obj;
348352
break;
349-
}
350-
}
351-
static void bind_pos_boxed(PARROT_INTERP, STable *st, void *data, INTVAL index, PMC *obj) {
352-
CArrayREPRData *repr_data = (CArrayREPRData *)st->REPR_data;
353-
CArrayBody *body = (CArrayBody *)data;
354-
if (body->managed && index >= body->allocated)
355-
expand(interp, repr_data, body, index + 1);
356-
if (index >= body->elems)
357-
body->elems = index + 1;
358-
switch (repr_data->elem_kind) {
359-
case CARRAY_ELEM_KIND_STRING:
360-
{
361-
STRING *str = REPR(obj)->box_funcs->get_str(interp, STABLE(obj), OBJECT_BODY(obj));
362-
char *elem = Parrot_str_to_encoded_cstring(interp, str, Parrot_utf8_encoding_ptr);
363-
*((char **)(((char *)body->storage) + index * repr_data->elem_size)) = elem;
364-
break;
365-
}
366-
case CARRAY_ELEM_KIND_CARRAY:
367-
case CARRAY_ELEM_KIND_CPOINTER:
368-
case CARRAY_ELEM_KIND_CSTRUCT:
369-
return bind_pos_complex(interp, st, data, index, obj);
370353
default:
371354
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
372355
"bind_pos_boxed on CArray REPR not usable with this element type");

0 commit comments

Comments
 (0)