Skip to content

Commit 682e311

Browse files
committed
Implement setting of CArray members in CStructs.
Confirmed working in Perl 6-land, C-land working or breakage to be determined.
1 parent b85e904 commit 682e311

File tree

1 file changed

+42
-7
lines changed

1 file changed

+42
-7
lines changed

src/6model/reprs/CStruct.c

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,7 @@
33
#include "parrot/extend.h"
44
#include "../sixmodelobject.h"
55
#include "CStruct.h"
6-
7-
/* TODO:
8-
* - We need to handle setting and getting non-number members. In particular,
9-
* setting an object member needs to not only update the child_obj pointer,
10-
* but also set the pointer in the cstruct part.
11-
*/
6+
#include "CArray.h"
127

138
/* This representation's function pointer table. */
149
static REPROps *this_repr;
@@ -448,7 +443,47 @@ static void * get_attribute_ref(PARROT_INTERP, STable *st, void *data, PMC *clas
448443

449444
/* Binds the given value to the specified attribute. */
450445
static void bind_attribute_boxed(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint, PMC *value) {
451-
die_no_attrs(interp);
446+
CStructREPRData *repr_data = (CStructREPRData *)st->REPR_data;
447+
CStructBody *body = (CStructBody *)data;
448+
STRING *type_str = Parrot_str_new_constant(interp, "type");
449+
STRING *carray_str = Parrot_str_new_constant(interp, "CArray");
450+
INTVAL slot;
451+
452+
/* Try to find the slot. */
453+
slot = hint >= 0 ? hint :
454+
try_get_slot(interp, repr_data, class_handle, name);
455+
if (slot >= 0) {
456+
STable *st = repr_data->flattened_stables[slot];
457+
if (st)
458+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
459+
"CStruct Can't perform boxed bind on flattened attributes yet");
460+
else {
461+
INTVAL placement = repr_data->attribute_locations[slot] & CSTRUCT_ATTR_MASK;
462+
INTVAL real_slot = repr_data->attribute_locations[slot] >> CSTRUCT_ATTR_SHIFT;
463+
464+
if(IS_CONCRETE(value)) {
465+
PMC *value_type = STABLE(value)->WHAT;
466+
void *cobj = NULL;
467+
468+
body->child_objs[real_slot] = value;
469+
470+
/* Set cobj to correct pointer based on type of value. */
471+
if(STRING_equal(interp, REPR(value_type)->name, carray_str)) {
472+
cobj = ((CArrayInstance *) value)->body.storage;
473+
}
474+
475+
set_ptr_at_offset(body->cstruct, repr_data->struct_offsets[slot], cobj);
476+
}
477+
else {
478+
body->child_objs[real_slot] = NULL;
479+
set_ptr_at_offset(body->cstruct, repr_data->struct_offsets[slot], NULL);
480+
}
481+
}
482+
}
483+
else {
484+
/* Otherwise, complain that the attribute doesn't exist. */
485+
no_such_attribute(interp, "bind", class_handle, name);
486+
}
452487
}
453488
static void bind_attribute_ref(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint, void *value) {
454489
CStructREPRData *repr_data = (CStructREPRData *)st->REPR_data;

0 commit comments

Comments
 (0)