@@ -189,6 +189,7 @@ static void compute_allocation_strategy(PARROT_INTERP, PMC *WHAT, P6opaqueREPRDa
189
189
INTVAL cur_init_slot = 0 ;
190
190
INTVAL cur_mark_slot = 0 ;
191
191
INTVAL cur_cleanup_slot = 0 ;
192
+ INTVAL cur_unbox_slot = 0 ;
192
193
INTVAL i ;
193
194
194
195
/* Allocate offset array and GC mark info arrays. */
@@ -244,6 +245,7 @@ static void compute_allocation_strategy(PARROT_INTERP, PMC *WHAT, P6opaqueREPRDa
244
245
245
246
/* Is it a target for box/unbox operations? */
246
247
if (!PMC_IS_NULL (box_target ) && VTABLE_get_bool (interp , box_target )) {
248
+ /* If it boxes a primitive, note that. */
247
249
switch (unboxed_type ) {
248
250
case STORAGE_SPEC_BP_INT :
249
251
if (repr_data -> unbox_int_slot >= 0 )
@@ -264,9 +266,16 @@ static void compute_allocation_strategy(PARROT_INTERP, PMC *WHAT, P6opaqueREPRDa
264
266
repr_data -> unbox_str_slot = i ;
265
267
break ;
266
268
default :
267
- /* nothing, just suppress 'missing default' warning */
269
+ /* nothing, just suppress 'missing default' warning */
268
270
break ;
269
271
}
272
+
273
+ /* Also list in the by-repr unbox list. */
274
+ if (repr_data -> unbox_slots == NULL )
275
+ repr_data -> unbox_slots = (P6opaqueBoxedTypeMap * ) mem_sys_allocate_zeroed (info_alloc * sizeof (P6opaqueBoxedTypeMap ));
276
+ repr_data -> unbox_slots [cur_unbox_slot ].repr_id = REPR (type )-> ID ;
277
+ repr_data -> unbox_slots [cur_unbox_slot ].slot = i ;
278
+ cur_unbox_slot ++ ;
270
279
}
271
280
}
272
281
}
@@ -657,8 +666,18 @@ static STRING * get_str(PARROT_INTERP, STable *st, void *data) {
657
666
* gets the reference to such things, using the representation ID to distinguish
658
667
* them. */
659
668
static void * get_boxed_ref (PARROT_INTERP , STable * st , void * data , INTVAL repr_id ) {
669
+ P6opaqueREPRData * repr_data = (P6opaqueREPRData * )st -> REPR_data ;
670
+ if (repr_data -> unbox_slots ) {
671
+ INTVAL i ;
672
+ for (i = 0 ; i < repr_data -> num_attributes ; i ++ )
673
+ if (repr_data -> unbox_slots [i ].repr_id == repr_id )
674
+ return (char * )data + repr_data -> attribute_offsets [repr_data -> unbox_slots [i ].slot ];
675
+ else if (repr_data -> unbox_slots [i ].repr_id == 0 )
676
+ break ;
677
+ }
660
678
Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
661
- "get_boxed_ref NYI in P6opaque" );
679
+ "get_boxed_ref could not unbox for the given representation" );
680
+ return NULL ;
662
681
}
663
682
664
683
/* This Parrot-specific addition to the API is used to mark an object. */
0 commit comments