Ticket #1644: pasmserializer.2.pmc

File pasmserializer.2.pmc, 6.0 KB (added by plobsing, 4 years ago)
Line 
1/*
2Copyright (C) 2010, Parrot Foundation.
3$Id$
4
5=head1
6
7src/pmc/pasmserializer - PASM Object Serializer
8
9=head1 DESCRIPTION
10
11Freezes and thaws PMCs using a text format suitable for use in PASM.
12
13=head2 Vtables
14
15=over 4
16
17=cut
18
19*/
20
21/* HEADERIZER HFILE: none */
22
23pmclass PASMSerializer auto_attrs {
24    ATTR PMC     *buffer;
25    ATTR PMC     *seen;
26    ATTR PMC     *todo;
27    ATTR UINTVAL  id;
28    ATTR INTVAL   action;
29
30/*
31
32=item C<void init()>
33
34Initialize the serializer.
35
36=cut
37
38*/
39
40    VTABLE void init() {
41        PARROT_PASMSERIALIZER(SELF)->buffer = PMCNULL;
42        PARROT_PASMSERIALIZER(SELF)->todo   = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
43        PARROT_PASMSERIALIZER(SELF)->seen   = PMCNULL;
44        PARROT_PASMSERIALIZER(SELF)->id     = 0;
45
46        PObj_custom_mark_SET(SELF);
47    }
48
49/*
50
51=item C<void mark()>
52
53Mark the PMC as alive.
54
55=cut
56
57*/
58
59    VTABLE void mark() {
60        Parrot_gc_mark_PMC_alive(INTERP, PARROT_PASMSERIALIZER(SELF)->buffer);
61        Parrot_gc_mark_PMC_alive(INTERP, PARROT_PASMSERIALIZER(SELF)->todo);
62        Parrot_gc_mark_PMC_alive(INTERP, PARROT_PASMSERIALIZER(SELF)->seen);
63    }
64
65/*
66
67=item C<PMC *get_iter()>
68
69Get the C<todo> list for this freeze/thaw for iterating over.
70
71=cut
72
73*/
74
75    VTABLE PMC *get_iter() {
76        return PARROT_PASMSERIALIZER(SELF)->todo;
77    }
78
79/*
80
81=item C<INTVAL get_integer()>
82
83Get the flags describing this visit action
84
85=cut
86
87*/
88
89    VTABLE INTVAL get_integer() {
90        return PARROT_PASMSERIALIZER(SELF)->action;
91    }
92
93/*
94
95=item C<void push_integer(INTVAL v)>
96
97=item C<void push_float(FLOATVAL v)>
98
99=item C<void push_string(STRING *v)>
100
101=item C<void push_pmc(PMC *v)>
102
103Push data item C<v> onto the end of the image being frozen.
104
105=cut
106
107*/
108
109    VTABLE void push_integer(INTVAL v) {
110        PMC *buf = PARROT_PASMSERIALIZER(SELF)->buffer;
111        VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, " "));
112        VTABLE_push_string(INTERP, buf, Parrot_str_from_int(INTERP, v));
113        VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, " "));
114    }
115
116    VTABLE void push_float(FLOATVAL v) {
117        PMC *buf = PARROT_PASMSERIALIZER(SELF)->buffer;
118        VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, " "));
119        VTABLE_push_string(INTERP, buf, Parrot_str_from_num(INTERP, v));
120        VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, " "));
121    }
122
123    VTABLE void push_string(STRING *v) {
124        PMC *buf = PARROT_PASMSERIALIZER(SELF)->buffer;
125        VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, " "));
126        if (STRING_IS_NULL(v)) {
127            VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, "STRINGNULL"));
128        }
129        else {
130            VTABLE_push_string(INTERP, buf,
131                    Parrot_encoding_name(INTERP, Parrot_encoding_number_of_str(INTERP, v)));
132            VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, ":"));
133            VTABLE_push_string(INTERP, buf,
134                    Parrot_charset_name(INTERP, Parrot_charset_number_of_str(INTERP, v)));
135            VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, ":\""));
136            VTABLE_push_string(INTERP, buf, Parrot_str_escape(INTERP, v));
137            VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, "\""));
138        }
139        VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, " "));
140    }
141
142    VTABLE void push_pmc(PMC *v) {
143        PMC    *buf       = PARROT_PASMSERIALIZER(SELF)->buffer;
144        PMC    *seen      = PARROT_PASMSERIALIZER(SELF)->seen;
145        INTVAL  id;
146        INTVAL  was_seen;
147
148        VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, " "));
149
150        if (PMC_IS_NULL(v)) {
151            id = 0;
152            was_seen = 1;
153        }
154        else {
155            was_seen = VTABLE_exists_keyed(INTERP, seen, v);
156            if (was_seen)
157                id = VTABLE_get_integer_keyed(INTERP, seen, v);
158            else
159                id = ++PARROT_PASMSERIALIZER(SELF)->id;
160        }
161
162        VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, "$"));
163        VTABLE_push_string(INTERP, buf, Parrot_str_from_int(INTERP, id));
164
165        if (!was_seen) {
166            VTABLE_set_integer_keyed(INTERP, seen, v, id);
167            VTABLE_push_pmc(INTERP, PARROT_PASMSERIALIZER(SELF)->todo, v);
168
169            VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, ":"));
170            VTABLE_push_string(INTERP, buf, VTABLE_name(INTERP, v));
171        }
172
173        VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, " "));
174    }
175
176/*
177
178=item C<STRING *get_string()>
179
180Get the serialized image as a string (after freezing).
181
182=cut
183
184*/
185
186    VTABLE STRING *get_string() {
187        return VTABLE_get_string(INTERP, PARROT_PASMSERIALIZER(SELF)->buffer);
188    }
189
190/*
191
192=item C<void set_pmc(PMC *p)>
193
194Freeze the PMC C<p> into the buffer.
195
196=cut
197
198*/
199
200    VTABLE void set_pmc(PMC *p) {
201        PARROT_PASMSERIALIZER(SELF)->action = VISIT_FREEZE_NORMAL;
202        PARROT_PASMSERIALIZER(SELF)->buffer = Parrot_pmc_new(INTERP, enum_class_StringBuilder);
203        PARROT_PASMSERIALIZER(SELF)->seen   = Parrot_pmc_new(INTERP, enum_class_Hash);
204        VTABLE_set_pointer(INTERP, PARROT_PASMSERIALIZER(SELF)->seen,
205                parrot_new_intval_hash(INTERP));
206        SELF.push_pmc(p);
207
208        // Parrot_visit_loop_visit(INTERP, SELF);
209        {
210            INTVAL i;
211            PMC *buf  = PARROT_PASMSERIALIZER(SELF)->buffer;
212            PMC *todo = VTABLE_get_iter(INTERP, SELF);
213            for (i = 0; i < VTABLE_elements(INTERP, todo); i++) {
214                PMC *current = VTABLE_get_pmc_keyed_int(INTERP, todo, i);
215
216                VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, "\n$"));
217                VTABLE_push_string(INTERP, buf, Parrot_str_from_int(INTERP, i + 1));
218                VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, ":["));
219
220                VTABLE_freeze(INTERP, current, SELF);
221                VTABLE_visit(INTERP, current, SELF);
222                VISIT_PMC(INTERP, SELF, PMC_metadata(current));
223
224                VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, "]"));
225            }
226        }
227    }
228}
229
230/*
231
232=back
233
234=cut
235
236*/
237
238/*
239 * Local variables:
240 *   c-file-style: "parrot"
241 * End:
242 * vim: expandtab shiftwidth=4:
243 */