|
3 | 3 | #include "parrot/extend.h"
|
4 | 4 | #include "../sixmodelobject.h"
|
5 | 5 | #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" |
12 | 7 |
|
13 | 8 | /* This representation's function pointer table. */
|
14 | 9 | static REPROps *this_repr;
|
@@ -448,7 +443,47 @@ static void * get_attribute_ref(PARROT_INTERP, STable *st, void *data, PMC *clas
|
448 | 443 |
|
449 | 444 | /* Binds the given value to the specified attribute. */
|
450 | 445 | 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 | + } |
452 | 487 | }
|
453 | 488 | static void bind_attribute_ref(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint, void *value) {
|
454 | 489 | CStructREPRData *repr_data = (CStructREPRData *)st->REPR_data;
|
|
0 commit comments