@@ -237,6 +237,60 @@ static void compute_allocation_strategy(PARROT_INTERP, PMC *WHAT, CStructREPRDat
237
237
Parrot_unblock_GC_mark (interp );
238
238
}
239
239
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
+
240
294
/* Creates a new type object of this representation, and associates it with
241
295
* the given HOW. */
242
296
static PMC * type_object_for (PARROT_INTERP , PMC * HOW ) {
@@ -246,6 +300,9 @@ static PMC * type_object_for(PARROT_INTERP, PMC *HOW) {
246
300
/* Build an STable. */
247
301
PMC * st_pmc = create_stable_func (interp , this_repr , HOW );
248
302
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 );
249
306
250
307
/* Create type object and point it back at the STable. */
251
308
obj -> common .stable = st_pmc ;
@@ -260,21 +317,54 @@ static PMC * type_object_for(PARROT_INTERP, PMC *HOW) {
260
317
261
318
/* Creates a new instance based on the type object. */
262
319
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 );
264
332
obj -> common .stable = st -> stable_pmc ;
333
+ /* XXX allocate child str and obj arrays if needed. */
334
+
265
335
return wrap_object_func (interp , obj );
266
336
}
267
337
268
338
/* Initialize a new instance. */
269
339
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
+ }
271
349
}
272
350
273
351
/* Copies to the body of one object to another. */
274
352
static void copy_to (PARROT_INTERP , STable * st , void * src , void * dest ) {
353
+ CStructREPRData * repr_data = (CStructREPRData * ) st -> REPR_data ;
275
354
CStructBody * src_body = (CStructBody * )src ;
276
355
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 )));
278
368
}
279
369
280
370
/* 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
357
447
358
448
/* This Parrot-specific addition to the API is used to mark an object. */
359
449
static void gc_mark (PARROT_INTERP , STable * st , void * data ) {
450
+ CStructREPRData * repr_data = (CStructREPRData * ) st -> REPR_data ;
360
451
CStructBody * body = (CStructBody * )data ;
361
452
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 ]);
365
455
}
366
456
367
457
/* 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) {
374
464
375
465
/* This Parrot-specific addition to the API is used to free an object. */
376
466
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 ));
379
473
PMC_data (obj ) = NULL ;
380
474
}
381
475
0 commit comments