Skip to content

Commit 878aafe

Browse files
committed
Get allocationy bits of CStruct in place, or at least for the basic cases.
1 parent 02dca35 commit 878aafe

File tree

2 files changed

+108
-10
lines changed

2 files changed

+108
-10
lines changed

src/6model/reprs/CStruct.c

Lines changed: 102 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,60 @@ static void compute_allocation_strategy(PARROT_INTERP, PMC *WHAT, CStructREPRDat
237237
Parrot_unblock_GC_mark(interp);
238238
}
239239

240+
/* Helper for reading an int at the specified offset. */
241+
static INTVAL get_int_at_offset(void *data, INTVAL offset) {
242+
void *location = (char *)data + offset;
243+
return *((INTVAL *)location);
244+
}
245+
246+
/* Helper for writing an int at the specified offset. */
247+
static void set_int_at_offset(void *data, INTVAL offset, INTVAL value) {
248+
void *location = (char *)data + offset;
249+
*((INTVAL *)location) = value;
250+
}
251+
252+
/* Helper for reading a num at the specified offset. */
253+
static FLOATVAL get_num_at_offset(void *data, INTVAL offset) {
254+
void *location = (char *)data + offset;
255+
return *((FLOATVAL *)location);
256+
}
257+
258+
/* Helper for writing a num at the specified offset. */
259+
static void set_num_at_offset(void *data, INTVAL offset, FLOATVAL value) {
260+
void *location = (char *)data + offset;
261+
*((FLOATVAL *)location) = value;
262+
}
263+
264+
/* Helper for reading a pointer at the specified offset. */
265+
static void * get_ptr_at_offset(void *data, INTVAL offset) {
266+
void *location = (char *)data + offset;
267+
return *((void **)location);
268+
}
269+
270+
/* Helper for writing a pointer at the specified offset. */
271+
static void set_ptr_at_offset(void *data, INTVAL offset, void *value) {
272+
void *location = (char *)data + offset;
273+
*((void **)location) = value;
274+
}
275+
276+
/* Helper for finding a slot number. */
277+
static INTVAL try_get_slot(PARROT_INTERP, CStructREPRData *repr_data, PMC *class_key, STRING *name) {
278+
INTVAL slot = -1;
279+
if (repr_data->name_to_index_mapping) {
280+
CStructNameMap *cur_map_entry = repr_data->name_to_index_mapping;
281+
while (cur_map_entry->class_key != NULL) {
282+
if (cur_map_entry->class_key == class_key) {
283+
PMC *slot_pmc = VTABLE_get_pmc_keyed_str(interp, cur_map_entry->name_map, name);
284+
if (!PMC_IS_NULL(slot_pmc))
285+
slot = VTABLE_get_integer(interp, slot_pmc);
286+
break;
287+
}
288+
cur_map_entry++;
289+
}
290+
}
291+
return slot;
292+
}
293+
240294
/* Creates a new type object of this representation, and associates it with
241295
* the given HOW. */
242296
static PMC * type_object_for(PARROT_INTERP, PMC *HOW) {
@@ -246,6 +300,9 @@ static PMC * type_object_for(PARROT_INTERP, PMC *HOW) {
246300
/* Build an STable. */
247301
PMC *st_pmc = create_stable_func(interp, this_repr, HOW);
248302
STable *st = STABLE_STRUCT(st_pmc);
303+
304+
/* Create REPR data structure and hand it off the STable. */
305+
st->REPR_data = mem_allocate_zeroed_typed(CStructREPRData);
249306

250307
/* Create type object and point it back at the STable. */
251308
obj->common.stable = st_pmc;
@@ -260,21 +317,54 @@ static PMC * type_object_for(PARROT_INTERP, PMC *HOW) {
260317

261318
/* Creates a new instance based on the type object. */
262319
static PMC * allocate(PARROT_INTERP, STable *st) {
263-
CStructInstance *obj = mem_allocate_zeroed_typed(CStructInstance);
320+
CStructInstance * obj;
321+
322+
/* Compute allocation strategy if we've not already done so. */
323+
CStructREPRData * repr_data = (CStructREPRData *) st->REPR_data;
324+
if (!repr_data->allocation_size) {
325+
compute_allocation_strategy(interp, st->WHAT, repr_data);
326+
PARROT_GC_WRITE_BARRIER(interp, st->stable_pmc);
327+
}
328+
329+
/* Allocate and set up object instance. */
330+
obj = (CStructInstance *) Parrot_gc_allocate_fixed_size_storage(interp, repr_data->allocation_size);
331+
memset(obj, 0, repr_data->allocation_size);
264332
obj->common.stable = st->stable_pmc;
333+
/* XXX allocate child str and obj arrays if needed. */
334+
265335
return wrap_object_func(interp, obj);
266336
}
267337

268338
/* Initialize a new instance. */
269339
static void initialize(PARROT_INTERP, STable *st, void *data) {
270-
/* Nothing to do here. */
340+
CStructREPRData * repr_data = (CStructREPRData *) st->REPR_data;
341+
if (repr_data->initialize_slots) {
342+
INTVAL i;
343+
for (i = 0; repr_data->initialize_slots[i] >= 0; i++) {
344+
INTVAL offset = repr_data->struct_offsets[repr_data->initialize_slots[i]];
345+
STable *st = repr_data->flattened_stables[repr_data->initialize_slots[i]];
346+
st->REPR->initialize(interp, st, (char *)data + offset);
347+
}
348+
}
271349
}
272350

273351
/* Copies to the body of one object to another. */
274352
static void copy_to(PARROT_INTERP, STable *st, void *src, void *dest) {
353+
CStructREPRData * repr_data = (CStructREPRData *) st->REPR_data;
275354
CStructBody *src_body = (CStructBody *)src;
276355
CStructBody *dest_body = (CStructBody *)dest;
277-
/* XXX TODO */
356+
memcpy(dest, src, repr_data->allocation_size - sizeof(CStructInstance));
357+
/* XXX also need to shallow copy the obj and str arrays */
358+
}
359+
360+
/* Helper for complaining about attribute access errors. */
361+
PARROT_DOES_NOT_RETURN
362+
static void no_such_attribute(PARROT_INTERP, const char *action, PMC *class_handle, STRING *name) {
363+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
364+
"Can not %s non-existant attribute '%Ss' on class '%Ss'",
365+
action, name, VTABLE_get_string(interp, introspection_call(interp,
366+
class_handle, STABLE(class_handle)->HOW,
367+
Parrot_str_new_constant(interp, "name"), 0)));
278368
}
279369

280370
/* Helper to die because this type doesn't support attributes. */
@@ -357,11 +447,11 @@ static void * get_boxed_ref(PARROT_INTERP, STable *st, void *data, INTVAL repr_i
357447

358448
/* This Parrot-specific addition to the API is used to mark an object. */
359449
static void gc_mark(PARROT_INTERP, STable *st, void *data) {
450+
CStructREPRData *repr_data = (CStructREPRData *) st->REPR_data;
360451
CStructBody *body = (CStructBody *)data;
361452
INTVAL i;
362-
if (body->child_objs)
363-
for (i = 0; i < body->num_child_objs; i++)
364-
Parrot_gc_mark_PMC_alive(interp, body->child_objs[i]);
453+
for (i = 0; i < repr_data->num_child_objs; i++)
454+
Parrot_gc_mark_PMC_alive(interp, body->child_objs[i]);
365455
}
366456

367457
/* This is called to do any cleanup of resources when an object gets
@@ -374,8 +464,12 @@ static void gc_cleanup(PARROT_INTERP, STable *st, void *data) {
374464

375465
/* This Parrot-specific addition to the API is used to free an object. */
376466
static void gc_free(PARROT_INTERP, PMC *obj) {
377-
gc_cleanup(interp, STABLE(obj), OBJECT_BODY(obj));
378-
mem_sys_free(PMC_data(obj));
467+
CStructREPRData *repr_data = (CStructREPRData *)STABLE(obj)->REPR_data;
468+
gc_cleanup(interp, STABLE(obj), OBJECT_BODY(obj));
469+
if (repr_data->allocation_size && IS_CONCRETE(obj))
470+
Parrot_gc_free_fixed_size_storage(interp, repr_data->allocation_size, PMC_data(obj));
471+
else
472+
mem_sys_free(PMC_data(obj));
379473
PMC_data(obj) = NULL;
380474
}
381475

src/6model/reprs/CStruct.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@
99
typedef struct {
1010
/* GC-marked objects that our C structure points into. */
1111
PMC **child_objs;
12-
INTVAL num_child_objs;
1312

1413
/* STRING* objects that we have converted to char arrays as well
1514
* when we put them in the C structure. */
1615
STRING **child_strs;
17-
INTVAL num_child_strs;
1816

1917
/* This is not an actual pointer; instead it's just a marker we can
2018
* use to get at the start of the data that we'll actually pass off
@@ -52,6 +50,12 @@ typedef struct {
5250
* slots can vary in size. */
5351
INTVAL num_attributes;
5452

53+
/* Number of child objects we store. */
54+
INTVAL num_child_objs;
55+
56+
/* Number of child strings we store. */
57+
INTVAL num_child_strs;
58+
5559
/* Lower bits are flags indicating what kind of attribute we have;
5660
* whether it's one that is just a simple value that we can always
5761
* access directly in the C struct body, or a more complex one that

0 commit comments

Comments
 (0)