Skip to content

Commit 11488d7

Browse files
committed
Fill out common bits of object deserialization, doing STable reassociation, memory allocation, and delegating off to the REPR for deserializing the object body.
1 parent 25677b2 commit 11488d7

File tree

5 files changed

+67
-4
lines changed

5 files changed

+67
-4
lines changed

src/6model/serialization.c

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ static void serialize_object(PARROT_INTERP, SerializationWriter *writer, PMC *ob
266266
/* Increment count of objects in the table. */
267267
writer->root.num_objects++;
268268

269-
/* Delegate to its serialization REPR method. */
269+
/* Delegate to its serialization REPR function. */
270270
writer->writing_object = 1;
271271
if (REPR(obj)->serialize)
272272
REPR(obj)->serialize(interp, STABLE(obj), OBJECT_BODY(obj), writer);
@@ -322,6 +322,7 @@ STRING * Serialization_serialize(PARROT_INTERP, PMC *sc, PMC *empty_string_heap)
322322
GETATTR_SerializationContext_root_stables(interp, sc, stables);
323323
GETATTR_SerializationContext_root_objects(interp, sc, objects);
324324
writer->root.version = CURRENT_VERSION;
325+
writer->root.sc = sc;
325326
writer->stables_list = stables;
326327
writer->objects_list = objects;
327328
writer->root.string_heap = empty_string_heap;
@@ -406,6 +407,24 @@ static STRING * read_string_from_heap(PARROT_INTERP, SerializationReader *reader
406407
return VTABLE_get_string_keyed_int(interp, reader->root.string_heap, idx);
407408
}
408409

410+
/* Locates a serialization context; 0 is the current one, otherwise see the
411+
* dependencies table. */
412+
static PMC * locate_sc(PARROT_INTERP, SerializationReader *reader, Parrot_Int4 sc_id) {
413+
PMC *sc;
414+
if (sc_id == 0)
415+
return reader->root.sc;
416+
sc = VTABLE_get_pmc_keyed_int(interp, reader->root.dependent_scs, sc_id - 1);
417+
if (PMC_IS_NULL(sc))
418+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
419+
"Invalid dependencies table index encountered (index %d)", sc_id);
420+
return sc;
421+
}
422+
423+
/* Looks up an STable. */
424+
static PMC * lookup_stable(PARROT_INTERP, SerializationReader *reader, Parrot_Int4 sc_id, Parrot_Int4 idx) {
425+
return SC_get_stable(interp, locate_sc(interp, reader, sc_id), idx);
426+
}
427+
409428
/* Checks the header looks sane and all of the places it points to make sense.
410429
* Also disects the input string into the tables and data segments and populates
411430
* the reader data structure more fully. */
@@ -515,8 +534,26 @@ static void deserialize_stable(PARROT_INTERP, SerializationReader *reader, INTVA
515534

516535
/* Deserializes a single object, along with its REPR data. */
517536
static void deserialize_object(PARROT_INTERP, SerializationReader *reader, INTVAL i, PMC *obj) {
518-
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
519-
"Object deserialization not yet implemented");
537+
/* Calculate location of object's table row. */
538+
char *obj_table_row = reader->root.objects_table + i * OBJECTS_TABLE_ENTRY_SIZE;
539+
540+
/* Resolve the STable. */
541+
PMC *stable = lookup_stable(interp, reader,
542+
read_int32(obj_table_row, 0), /* The SC in the dependencies table, + 1 */
543+
read_int32(obj_table_row, 4)); /* The index in that SC */
544+
545+
/* Allocate the object, fiddling things so that it gets wrapped in the
546+
* PMC we want it to. */
547+
set_wrapping_object(obj);
548+
STABLE_STRUCT(stable)->REPR->allocate(interp, STABLE_STRUCT(stable));
549+
550+
/* Delegate to its deserialization REPR function. */
551+
reader->reading_object = 1;
552+
if (REPR(obj)->deserialize)
553+
REPR(obj)->deserialize(interp, STABLE(obj), OBJECT_BODY(obj), reader);
554+
else
555+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
556+
"Missing deserialize REPR function");
520557
}
521558

522559
/* Takes serialized data, an empty SerializationContext to deserialize it into
@@ -535,6 +572,7 @@ void Serialization_deserialize(PARROT_INTERP, PMC *sc, PMC *string_heap, STRING
535572
GETATTR_SerializationContext_root_objects(interp, sc, objects);
536573
reader->stables_list = stables;
537574
reader->objects_list = objects;
575+
reader->root.sc = sc;
538576
reader->root.string_heap = string_heap;
539577
reader->root.dependent_scs = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
540578

src/6model/serialization_context.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,13 @@ INTVAL SC_find_object_idx(PARROT_INTERP, PMC *sc, PMC *obj) {
7171
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
7272
"Object does not exist in serialization context");
7373
}
74+
75+
/* Given an SC and an index, fetch the STable stored there. */
76+
PMC * SC_get_stable(PARROT_INTERP, PMC *sc, INTVAL idx) {
77+
PMC *stables;
78+
GETATTR_SerializationContext_root_stables(interp, sc, stables);
79+
if (idx >= VTABLE_elements(interp, stables))
80+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
81+
"No STable at index %d", idx);
82+
return VTABLE_get_pmc_keyed_int(interp, stables, idx);
83+
}

src/6model/serialization_context.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ INTVAL SC_find_stable_idx(PARROT_INTERP, PMC *sc, PMC *st);
77
INTVAL SC_find_object_idx(PARROT_INTERP, PMC *sc, PMC *st);
88
STRING * SC_get_handle(PARROT_INTERP, PMC *sc);
99
STRING * SC_get_description(PARROT_INTERP, PMC *sc);
10+
PMC * SC_get_stable(PARROT_INTERP, PMC *sc, INTVAL idx);
1011
#endif

src/6model/sixmodelobject.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,22 @@ void SixModelObject_initialize(PARROT_INTERP, PMC **knowhow, PMC **knowhow_attri
4545
*knowhow_attribute = SixModelObject_setup_knowhow_attribute(interp, initial_sc, *knowhow);
4646
}
4747

48+
/* Sets the object that we'll wrap the next allocation in. */
49+
static PMC *next_wrapper = NULL;
50+
void set_wrapping_object(PMC *wrapper) {
51+
next_wrapper = wrapper;
52+
}
53+
4854
/* Takes an object and wraps it in a SixModelObject PMC. */
4955
PMC * wrap_object(PARROT_INTERP, void *obj) {
50-
PMC *obj_pmc = Parrot_pmc_new_noinit(interp, smo_id);
56+
PMC *obj_pmc;
57+
if (next_wrapper) {
58+
obj_pmc = next_wrapper;
59+
next_wrapper = NULL;
60+
}
61+
else {
62+
obj_pmc = Parrot_pmc_new_noinit(interp, smo_id);
63+
}
5164
PObj_custom_mark_SET(obj_pmc);
5265
PObj_custom_destroy_SET(obj_pmc);
5366
PMC_data(obj_pmc) = obj;

src/6model/sixmodelobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ struct SixModel_REPROps {
346346
void SixModelObject_initialize(PARROT_INTERP, PMC **knowhow, PMC **knowhow_attribute);
347347

348348
/* Some utility functions. */
349+
void set_wrapping_object(PMC *wrapper);
349350
PMC * wrap_object(PARROT_INTERP, void *obj);
350351
PMC * create_stable(PARROT_INTERP, REPROps *REPR, PMC *HOW);
351352
PMC * decontainerize(PARROT_INTERP, PMC *var);

0 commit comments

Comments
 (0)