@@ -25,8 +25,6 @@ static INTVAL smo_id = 0;
25
25
* never move, and is unique per type object too. */
26
26
#define CLASS_KEY (c ) ((INTVAL)PMC_data(STABLE_PMC(c)))
27
27
28
- /* XXXXX From here goes away after REPR compose refactors. XXXXX */
29
-
30
28
/* Helper to make an introspection call, possibly with :local. */
31
29
static PMC * introspection_call (PARROT_INTERP , PMC * WHAT , PMC * HOW , STRING * name , INTVAL local ) {
32
30
PMC * old_ctx , * cappy ;
@@ -53,281 +51,6 @@ static PMC * introspection_call(PARROT_INTERP, PMC *WHAT, PMC *HOW, STRING *name
53
51
return VTABLE_get_pmc_keyed_int (interp , cappy , 0 );
54
52
}
55
53
56
- /* Helper to make an accessor call. */
57
- static PMC * accessor_call (PARROT_INTERP , PMC * obj , STRING * name ) {
58
- PMC * old_ctx , * cappy ;
59
-
60
- /* Look up method; if there is none hand back a null. */
61
- PMC * meth = VTABLE_find_method (interp , obj , name );
62
- if (PMC_IS_NULL (meth ))
63
- return meth ;
64
-
65
- /* Set up call capture. */
66
- old_ctx = Parrot_pcc_get_signature (interp , CURRENT_CONTEXT (interp ));
67
- cappy = Parrot_pmc_new (interp , enum_class_CallContext );
68
- VTABLE_push_pmc (interp , cappy , obj );
69
-
70
- /* Call. */
71
- Parrot_pcc_invoke_from_sig_object (interp , meth , cappy );
72
-
73
- /* Grab result. */
74
- cappy = Parrot_pcc_get_signature (interp , CURRENT_CONTEXT (interp ));
75
- Parrot_pcc_set_signature (interp , CURRENT_CONTEXT (interp ), old_ctx );
76
- return VTABLE_get_pmc_keyed_int (interp , cappy , 0 );
77
- }
78
-
79
- /* Locates all of the attributes. Puts them onto a flattened, ordered
80
- * list of attributes (populating the passed flat_list). Also builds
81
- * the index mapping for doing named lookups. Note index is not related
82
- * to the storage position. */
83
- static PMC * index_mapping_and_flat_list_OLD (PARROT_INTERP , PMC * WHAT , P6opaqueREPRData * repr_data ) {
84
- PMC * flat_list = Parrot_pmc_new (interp , enum_class_ResizablePMCArray );
85
- PMC * class_list = Parrot_pmc_new (interp , enum_class_ResizablePMCArray );
86
- PMC * attr_map_list = Parrot_pmc_new (interp , enum_class_ResizablePMCArray );
87
- STRING * attributes_str = Parrot_str_new_constant (interp , "attributes" );
88
- STRING * parents_str = Parrot_str_new_constant (interp , "parents" );
89
- STRING * name_str = Parrot_str_new_constant (interp , "name" );
90
- STRING * mro_str = Parrot_str_new_constant (interp , "mro" );
91
- INTVAL current_slot = 0 ;
92
-
93
- INTVAL num_classes , i ;
94
- P6opaqueNameMap * result = NULL ;
95
-
96
- /* Get the MRO. */
97
- PMC * mro = introspection_call (interp , WHAT , STABLE (WHAT )-> HOW , mro_str , 0 );
98
- INTVAL mro_idx = VTABLE_elements (interp , mro );
99
-
100
- /* Walk through the parents list. */
101
- while (mro_idx )
102
- {
103
- /* Get current class in MRO. */
104
- PMC * current_class = decontainerize (interp , VTABLE_get_pmc_keyed_int (interp , mro , -- mro_idx ));
105
- PMC * HOW = STABLE (current_class )-> HOW ;
106
-
107
- /* Get its local parents. */
108
- PMC * parents = introspection_call (interp , current_class , HOW , parents_str , 1 );
109
- INTVAL num_parents = VTABLE_elements (interp , parents );
110
-
111
- /* Get attributes and iterate over them. */
112
- PMC * attributes = introspection_call (interp , current_class , HOW , attributes_str , 1 );
113
- PMC * attr_map = PMCNULL ;
114
- PMC * attr_iter = VTABLE_get_iter (interp , attributes );
115
- while (VTABLE_get_bool (interp , attr_iter )) {
116
- /* Get attribute. */
117
- PMC * attr = VTABLE_shift_pmc (interp , attr_iter );
118
-
119
- /* Get its name. */
120
- PMC * name_pmc = accessor_call (interp , attr , name_str );
121
- STRING * name = VTABLE_get_string (interp , name_pmc );
122
-
123
- /* Allocate a slot. */
124
- if (PMC_IS_NULL (attr_map ))
125
- attr_map = Parrot_pmc_new (interp , enum_class_Hash );
126
- VTABLE_set_pmc_keyed_str (interp , attr_map , name ,
127
- Parrot_pmc_new_init_int (interp , enum_class_Integer , current_slot ));
128
- current_slot ++ ;
129
-
130
- /* Push attr onto the flat list. */
131
- VTABLE_push_pmc (interp , flat_list , attr );
132
- }
133
-
134
- /* Add to class list and map list. */
135
- VTABLE_push_pmc (interp , class_list , current_class );
136
- VTABLE_push_pmc (interp , attr_map_list , attr_map );
137
-
138
- /* If there's more than one parent, flag that we in an MI
139
- * situation. */
140
- if (num_parents > 1 )
141
- repr_data -> mi = 1 ;
142
- }
143
-
144
- /* We can now form the name map. */
145
- num_classes = VTABLE_elements (interp , class_list );
146
- result = (P6opaqueNameMap * ) mem_sys_allocate_zeroed (sizeof (P6opaqueNameMap ) * (1 + num_classes ));
147
- for (i = 0 ; i < num_classes ; i ++ ) {
148
- result [i ].class_key = VTABLE_get_pmc_keyed_int (interp , class_list , i );
149
- result [i ].name_map = VTABLE_get_pmc_keyed_int (interp , attr_map_list , i );
150
- }
151
- repr_data -> name_to_index_mapping = result ;
152
-
153
- return flat_list ;
154
- }
155
-
156
- /* This works out an allocation strategy for the object. It takes care of
157
- * "inlining" storage of attributes that are natively typed, as well as
158
- * noting unbox targets. */
159
- static void compute_allocation_strategy_OLD (PARROT_INTERP , PMC * WHAT , P6opaqueREPRData * repr_data ) {
160
- STRING * type_str = Parrot_str_new_constant (interp , "type" );
161
- STRING * box_target_str = Parrot_str_new_constant (interp , "box_target" );
162
- STRING * avcont_str = Parrot_str_new_constant (interp , "auto_viv_container" );
163
- PMC * flat_list ;
164
-
165
- /*
166
- * We have to block GC mark here. Because "repr" is assotiated with some
167
- * PMC which is not accessible in this function. And we have to write
168
- * barrier this PMC because we are poking inside it guts directly. We
169
- * do have WB in caller function, but it can be triggered too late is
170
- * any of allocation will cause GC run.
171
- *
172
- * This is kind of minor evil until after I'll find better solution.
173
- */
174
- Parrot_block_GC_mark (interp );
175
-
176
- /* Compute index mapping table and get flat list of attributes. */
177
- flat_list = index_mapping_and_flat_list_OLD (interp , WHAT , repr_data );
178
-
179
- /* If we have no attributes in the index mapping, then just the header. */
180
- if (repr_data -> name_to_index_mapping [0 ].class_key == NULL ) {
181
- repr_data -> allocation_size = sizeof (P6opaqueInstance );
182
- }
183
-
184
- /* Otherwise, we need to compute the allocation strategy. */
185
- else {
186
- /* We track the size of the body part, since that's what we want offsets into. */
187
- INTVAL cur_size = 0 ;
188
-
189
- /* Get number of attributes and set up various counters. */
190
- INTVAL num_attrs = VTABLE_elements (interp , flat_list );
191
- INTVAL info_alloc = num_attrs == 0 ? 1 : num_attrs ;
192
- INTVAL cur_pmc_attr = 0 ;
193
- INTVAL cur_init_slot = 0 ;
194
- INTVAL cur_mark_slot = 0 ;
195
- INTVAL cur_cleanup_slot = 0 ;
196
- INTVAL cur_unbox_slot = 0 ;
197
- INTVAL i ;
198
-
199
- /* Allocate offset array and GC mark info arrays. */
200
- repr_data -> num_attributes = num_attrs ;
201
- repr_data -> attribute_offsets = (INTVAL * ) mem_sys_allocate (info_alloc * sizeof (INTVAL ));
202
- repr_data -> flattened_stables = (STable * * ) mem_sys_allocate_zeroed (info_alloc * sizeof (PMC * ));
203
- repr_data -> unbox_int_slot = -1 ;
204
- repr_data -> unbox_num_slot = -1 ;
205
- repr_data -> unbox_str_slot = -1 ;
206
-
207
- /* Go over the attributes and arrange their allocation. */
208
- for (i = 0 ; i < num_attrs ; i ++ ) {
209
- PMC * attr = VTABLE_get_pmc_keyed_int (interp , flat_list , i );
210
-
211
- /* Fetch its type and box target flag, if available. */
212
- PMC * type = accessor_call (interp , attr , type_str );
213
- PMC * box_target = accessor_call (interp , attr , box_target_str );
214
- PMC * av_cont = accessor_call (interp , attr , avcont_str );
215
-
216
- /* Work out what unboxed type it is, if any. Default to a boxed. */
217
- INTVAL unboxed_type = STORAGE_SPEC_BP_NONE ;
218
- INTVAL bits = sizeof (PMC * ) * 8 ;
219
- INTVAL align = ALIGNOF1 (PMC * );
220
- if (!PMC_IS_NULL (type )) {
221
- /* Get the storage spec of the type and see what it wants. */
222
- storage_spec spec = REPR (type )-> get_storage_spec (interp , STABLE (type ));
223
- if (spec .inlineable == STORAGE_SPEC_INLINED ) {
224
- /* Yes, it's something we'll flatten. */
225
- unboxed_type = spec .boxed_primitive ;
226
- bits = spec .bits ;
227
- align = spec .align ;
228
- repr_data -> flattened_stables [i ] = STABLE (type );
229
-
230
- if (bits % 8 ) bits += 8 - bits %8 ;
231
-
232
- /* Does it need special initialization? */
233
- if (REPR (type )-> initialize ) {
234
- if (!repr_data -> initialize_slots )
235
- repr_data -> initialize_slots = (INTVAL * ) mem_sys_allocate_zeroed ((info_alloc + 1 ) * sizeof (INTVAL ));
236
- repr_data -> initialize_slots [cur_init_slot ] = i ;
237
- cur_init_slot ++ ;
238
- }
239
-
240
- /* Does it have special GC needs? */
241
- if (REPR (type )-> gc_mark ) {
242
- if (!repr_data -> gc_mark_slots )
243
- repr_data -> gc_mark_slots = (INTVAL * ) mem_sys_allocate_zeroed ((info_alloc + 1 ) * sizeof (INTVAL ));
244
- repr_data -> gc_mark_slots [cur_mark_slot ] = i ;
245
- cur_mark_slot ++ ;
246
- }
247
- if (REPR (type )-> gc_cleanup ) {
248
- if (!repr_data -> gc_cleanup_slots )
249
- repr_data -> gc_cleanup_slots = (INTVAL * ) mem_sys_allocate_zeroed ((info_alloc + 1 ) * sizeof (INTVAL ));
250
- repr_data -> gc_cleanup_slots [cur_cleanup_slot ] = i ;
251
- cur_cleanup_slot ++ ;
252
- }
253
-
254
- /* Is it a target for box/unbox operations? */
255
- if (!PMC_IS_NULL (box_target ) && VTABLE_get_bool (interp , box_target )) {
256
- /* If it boxes a primitive, note that. */
257
- switch (unboxed_type ) {
258
- case STORAGE_SPEC_BP_INT :
259
- if (repr_data -> unbox_int_slot >= 0 )
260
- Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
261
- "Duplicate box_target for native int" );
262
- repr_data -> unbox_int_slot = i ;
263
- break ;
264
- case STORAGE_SPEC_BP_NUM :
265
- if (repr_data -> unbox_num_slot >= 0 )
266
- Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
267
- "Duplicate box_target for native num" );
268
- repr_data -> unbox_num_slot = i ;
269
- break ;
270
- case STORAGE_SPEC_BP_STR :
271
- if (repr_data -> unbox_str_slot >= 0 )
272
- Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
273
- "Duplicate box_target for native str" );
274
- repr_data -> unbox_str_slot = i ;
275
- break ;
276
- default :
277
- /* nothing, just suppress 'missing default' warning */
278
- break ;
279
- }
280
-
281
- /* Also list in the by-repr unbox list. */
282
- if (repr_data -> unbox_slots == NULL )
283
- repr_data -> unbox_slots = (P6opaqueBoxedTypeMap * ) mem_sys_allocate_zeroed (info_alloc * sizeof (P6opaqueBoxedTypeMap ));
284
- repr_data -> unbox_slots [cur_unbox_slot ].repr_id = REPR (type )-> ID ;
285
- repr_data -> unbox_slots [cur_unbox_slot ].slot = i ;
286
- cur_unbox_slot ++ ;
287
- }
288
- }
289
- }
290
-
291
- /* Handle PMC attributes, which need marking and may have auto-viv needs. */
292
- if (unboxed_type == STORAGE_SPEC_BP_NONE ) {
293
- if (!repr_data -> gc_pmc_mark_offsets )
294
- repr_data -> gc_pmc_mark_offsets = (INTVAL * ) mem_sys_allocate_zeroed (info_alloc * sizeof (INTVAL ));
295
- repr_data -> gc_pmc_mark_offsets [cur_pmc_attr ] = cur_size ;
296
- cur_pmc_attr ++ ;
297
- if (!PMC_IS_NULL (av_cont )) {
298
- if (!repr_data -> auto_viv_values )
299
- repr_data -> auto_viv_values = (PMC * * ) mem_sys_allocate_zeroed (info_alloc * sizeof (PMC * ));
300
- repr_data -> auto_viv_values [i ] = av_cont ;
301
- }
302
- }
303
-
304
- /* Do allocation. Before updating the size of the structure, we
305
- * make sure the object will be aligned appropriately. */
306
- if (cur_size % align ) {
307
- cur_size += align - cur_size % align ;
308
- }
309
-
310
- repr_data -> attribute_offsets [i ] = cur_size ;
311
- cur_size += bits / 8 ;
312
- }
313
-
314
- /* Finally, put computed allocation size in place; it's body size plus
315
- * header size. Also number of markables and sentinels. */
316
- repr_data -> allocation_size = cur_size + sizeof (P6opaqueInstance );
317
- repr_data -> gc_pmc_mark_offsets_count = cur_pmc_attr ;
318
- if (repr_data -> initialize_slots )
319
- repr_data -> initialize_slots [cur_init_slot ] = -1 ;
320
- if (repr_data -> gc_mark_slots )
321
- repr_data -> gc_mark_slots [cur_mark_slot ] = -1 ;
322
- if (repr_data -> gc_cleanup_slots )
323
- repr_data -> gc_cleanup_slots [cur_cleanup_slot ] = -1 ;
324
- }
325
-
326
- Parrot_unblock_GC_mark (interp );
327
- }
328
-
329
- /* XXXXX To here goes away after REPR compose refactors. XXXXX */
330
-
331
54
/* Locates all of the attributes. Puts them onto a flattened, ordered
332
55
* list of attributes (populating the passed flat_list). Also builds
333
56
* the index mapping for doing named lookups. Note index is not related
@@ -651,10 +374,9 @@ static PMC * allocate(PARROT_INTERP, STable *st) {
651
374
652
375
/* Compute allocation strategy if we've not already done so. */
653
376
P6opaqueREPRData * repr_data = (P6opaqueREPRData * ) st -> REPR_data ;
654
- if (!repr_data -> allocation_size ) {
655
- compute_allocation_strategy_OLD (interp , st -> WHAT , repr_data );
656
- PARROT_GC_WRITE_BARRIER (interp , st -> stable_pmc );
657
- }
377
+ if (!repr_data -> allocation_size )
378
+ Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
379
+ "Representation must be composed before it can be allocated" );
658
380
659
381
/* Allocate and set up object instance. */
660
382
obj = (P6opaqueInstance * ) Parrot_gc_allocate_fixed_size_storage (interp , repr_data -> allocation_size );
@@ -880,10 +602,8 @@ static INTVAL is_attribute_initialized(PARROT_INTERP, STable *st, void *data, PM
880
602
static INTVAL hint_for (PARROT_INTERP , STable * st , PMC * class_key , STRING * name ) {
881
603
INTVAL slot ;
882
604
P6opaqueREPRData * repr_data = (P6opaqueREPRData * )st -> REPR_data ;
883
- if (!repr_data -> allocation_size ) {
884
- compute_allocation_strategy_OLD (interp , st -> WHAT , repr_data );
885
- PARROT_GC_WRITE_BARRIER (interp , st -> stable_pmc );
886
- }
605
+ if (!repr_data -> allocation_size )
606
+ return NO_HINT ;
887
607
slot = try_get_slot (interp , repr_data , class_key , name );
888
608
return slot >= 0 ? slot : NO_HINT ;
889
609
}
@@ -1138,10 +858,9 @@ static void change_type(PARROT_INTERP, PMC *obj, PMC *new_type) {
1138
858
"P6opaque only supports type changes where the MRO of the original type is a suffix of the MRO of the new type" );
1139
859
1140
860
/* If the new REPR never calculated it's object layout, do so now. */
1141
- if (!new_repr_data -> allocation_size ) {
1142
- compute_allocation_strategy_OLD (interp , new_type , new_repr_data );
1143
- PARROT_GC_WRITE_BARRIER (interp , STABLE_PMC (new_type ));
1144
- }
861
+ if (!new_repr_data -> allocation_size )
862
+ Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
863
+ "Representation must be composed before change_type" );
1145
864
1146
865
/* Reallocate ourself to the new allocation size, if needed, and
1147
866
* ensure new chunk of the memory is zeroed. Note that we can't
@@ -1166,10 +885,9 @@ static void serialize(PARROT_INTERP, STable *st, void *data, SerializationWriter
1166
885
P6opaqueREPRData * repr_data = (P6opaqueREPRData * )st -> REPR_data ;
1167
886
INTVAL num_attributes , i ;
1168
887
1169
- if (!repr_data -> allocation_size ) {
1170
- compute_allocation_strategy_OLD (interp , st -> WHAT , repr_data );
1171
- PARROT_GC_WRITE_BARRIER (interp , st -> stable_pmc );
1172
- }
888
+ if (!repr_data -> allocation_size )
889
+ Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
890
+ "Representation must be composed before it can be serialized" );
1173
891
1174
892
num_attributes = repr_data -> num_attributes ;
1175
893
for (i = 0 ; i < num_attributes ; i ++ ) {
@@ -1207,10 +925,9 @@ static void serialize_repr_data(PARROT_INTERP, STable *st, SerializationWriter *
1207
925
P6opaqueREPRData * repr_data = (P6opaqueREPRData * )st -> REPR_data ;
1208
926
INTVAL i , num_classes ;
1209
927
1210
- if (!repr_data -> allocation_size ) {
1211
- compute_allocation_strategy_OLD (interp , st -> WHAT , repr_data );
1212
- PARROT_GC_WRITE_BARRIER (interp , st -> stable_pmc );
1213
- }
928
+ if (!repr_data -> allocation_size )
929
+ Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
930
+ "Representation must be composed before it can be serialized" );
1214
931
1215
932
writer -> write_int (interp , writer , repr_data -> num_attributes );
1216
933
0 commit comments