25
25
/* Possible reference types we can serialize. */
26
26
#define REFVAR_NULL 1
27
27
#define REFVAR_OBJECT 2
28
- #define REFVAR_VM_INT 3
29
- #define REFVAR_VM_NUM 4
30
- #define REFVAR_VM_STR 5
31
- #define REFVAR_VM_ARR_VAR 6
32
- #define REFVAR_VM_ARR_STR 7
33
- #define REFVAR_VM_ARR_INT 8
34
- #define REFVAR_VM_HASH_STR_VAR 9
35
- #define REFVAR_STATIC_CODEREF 10
28
+ #define REFVAR_VM_NULL 3
29
+ #define REFVAR_VM_INT 4
30
+ #define REFVAR_VM_NUM 5
31
+ #define REFVAR_VM_STR 6
32
+ #define REFVAR_VM_ARR_VAR 7
33
+ #define REFVAR_VM_ARR_STR 8
34
+ #define REFVAR_VM_ARR_INT 9
35
+ #define REFVAR_VM_HASH_STR_VAR 10
36
+ #define REFVAR_STATIC_CODEREF 11
37
+
38
+ /* Cached type IDs. */
39
+ static INTVAL smo_id = 0 ;
36
40
37
41
/* ***************************************************************************
38
42
* Serialization (writing related)
@@ -179,11 +183,51 @@ void write_str_func(PARROT_INTERP, SerializationWriter *writer, STRING *value) {
179
183
}
180
184
}
181
185
186
+ /* Writes an object reference. */
187
+ void write_obj_ref (PARROT_INTERP , SerializationWriter * writer , PMC * ref ) {
188
+ Parrot_Int4 sc_id , idx ;
189
+
190
+ if (PMC_IS_NULL (SC_PMC (ref ))) {
191
+ /* This object doesn't belong to an SC yet, so it must be serialized as part of
192
+ * this compilation unit. Add it to the work list. */
193
+ SC_PMC (ref ) = writer -> root .sc ;
194
+ VTABLE_push_pmc (interp , writer -> objects_list , ref );
195
+ }
196
+ sc_id = get_sc_id (interp , writer , SC_PMC (ref ));
197
+ idx = (Parrot_Int4 )SC_find_object_idx (interp , SC_PMC (ref ), ref );
198
+
199
+ expand_storage_if_needed (interp , writer , 8 );
200
+ if (writer -> writing_object ) {
201
+ write_int32 (writer -> root .objects_data , writer -> objects_data_offset , sc_id );
202
+ writer -> objects_data_offset += 4 ;
203
+ write_int32 (writer -> root .objects_data , writer -> objects_data_offset , idx );
204
+ writer -> objects_data_offset += 4 ;
205
+ }
206
+ else {
207
+ write_int32 (writer -> root .stables_data , writer -> stables_data_offset , sc_id );
208
+ writer -> stables_data_offset += 4 ;
209
+ write_int32 (writer -> root .stables_data , writer -> stables_data_offset , idx );
210
+ writer -> stables_data_offset += 4 ;
211
+ }
212
+ }
213
+
182
214
/* Writing function for references to things. */
183
215
void write_ref_func (PARROT_INTERP , SerializationWriter * writer , PMC * ref ) {
184
216
/* Work out what kind of thing we have and determine the discriminator. */
185
217
Parrot_Int2 discrim = 0 ;
186
- /* XXX */
218
+ if (ref == NULL ) {
219
+ discrim = REFVAR_NULL ;
220
+ }
221
+ else if (PMC_IS_NULL (ref )) {
222
+ discrim = REFVAR_VM_NULL ;
223
+ }
224
+ else if (ref -> vtable -> base_type == smo_id ) {
225
+ discrim = REFVAR_OBJECT ;
226
+ }
227
+ else {
228
+ Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
229
+ "Serialization Error: Unimplemented object type passed to write_ref" );
230
+ }
187
231
188
232
/* Write the discriminator. */
189
233
expand_storage_if_needed (interp , writer , 2 );
@@ -197,8 +241,18 @@ void write_ref_func(PARROT_INTERP, SerializationWriter *writer, PMC *ref) {
197
241
}
198
242
199
243
/* Now take appropriate action. */
200
- Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
201
- "write_ref not yet implemented" );
244
+ switch (discrim ) {
245
+ case REFVAR_NULL :
246
+ case REFVAR_VM_NULL :
247
+ /* Nothing to do for these. */
248
+ break ;
249
+ case REFVAR_OBJECT :
250
+ write_obj_ref (interp , writer , ref );
251
+ break ;
252
+ default :
253
+ Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
254
+ "Serialization Error: Unimplemented object type passed to write_ref" );
255
+ }
202
256
}
203
257
204
258
/* Concatenates the various output segments into a single binary string. */
@@ -380,6 +434,9 @@ STRING * Serialization_serialize(PARROT_INTERP, PMC *sc, PMC *empty_string_heap)
380
434
writer -> write_num = write_num_func ;
381
435
writer -> write_str = write_str_func ;
382
436
writer -> write_ref = write_ref_func ;
437
+
438
+ /* Other init. */
439
+ smo_id = Parrot_pmc_get_type_str (interp , Parrot_str_new (interp , "SixModelObject" , 0 ));
383
440
384
441
/* Start serializing. */
385
442
serialize (interp , writer );
@@ -524,7 +581,28 @@ STRING * read_str_func(PARROT_INTERP, SerializationReader *reader) {
524
581
}
525
582
}
526
583
527
- /* Reading function for native strings. */
584
+ /* Reads in and resolves an object references. */
585
+ PMC * read_obj_ref (PARROT_INTERP , SerializationReader * reader ) {
586
+ Parrot_Int4 sc_id , idx ;
587
+
588
+ assert_can_read (interp , reader , 8 );
589
+ if (reader -> reading_object ) {
590
+ sc_id = read_int32 (reader -> root .objects_data , reader -> objects_data_offset );
591
+ reader -> objects_data_offset += 4 ;
592
+ idx = read_int32 (reader -> root .objects_data , reader -> objects_data_offset );
593
+ reader -> objects_data_offset += 4 ;
594
+ }
595
+ else {
596
+ sc_id = read_int32 (reader -> root .stables_data , reader -> stables_data_offset );
597
+ reader -> stables_data_offset += 4 ;
598
+ idx = read_int32 (reader -> root .stables_data , reader -> stables_data_offset );
599
+ reader -> stables_data_offset += 4 ;
600
+ }
601
+
602
+ return SC_get_object (interp , locate_sc (interp , reader , sc_id ), idx );
603
+ }
604
+
605
+ /* Reading function for references. */
528
606
PMC * read_ref_func (PARROT_INTERP , SerializationReader * reader ) {
529
607
/* Read the discriminator. */
530
608
Parrot_Int2 discrim ;
@@ -539,8 +617,17 @@ PMC * read_ref_func(PARROT_INTERP, SerializationReader *reader) {
539
617
}
540
618
541
619
/* Decide what to do based on it. */
542
- Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
543
- "read_ref not yet implemented" );
620
+ switch (discrim ) {
621
+ case REFVAR_NULL :
622
+ return NULL ;
623
+ case REFVAR_OBJECT :
624
+ return read_obj_ref (interp , reader );
625
+ case REFVAR_VM_NULL :
626
+ return PMCNULL ;
627
+ default :
628
+ Parrot_ex_throw_from_c_args (interp , NULL , EXCEPTION_INVALID_OPERATION ,
629
+ "Serialization Error: Unimplemented case of read_ref" );
630
+ }
544
631
}
545
632
546
633
/* Checks the header looks sane and all of the places it points to make sense.
@@ -703,6 +790,9 @@ void Serialization_deserialize(PARROT_INTERP, PMC *sc, PMC *string_heap, STRING
703
790
reader -> read_str = read_str_func ;
704
791
reader -> read_ref = read_ref_func ;
705
792
793
+ /* Other init. */
794
+ smo_id = Parrot_pmc_get_type_str (interp , Parrot_str_new (interp , "SixModelObject" , 0 ));
795
+
706
796
/* Read header and disect the data into its parts. */
707
797
check_and_disect_input (interp , reader , data );
708
798
0 commit comments