fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / src / pmc / imageiosize.pmc
blob11b02f651644834784120bd7bb52da19bcb26284
1 /*
2 Copyright (C) 2010, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/pmc/imageiosize.pmc - ImageIOSize PMC
9 =head1 DESCRIPTION
11 Gets the size of an ImageIO image without the allocation costs.
13 =cut
17 #define GROW_TO_16_BYTE_BOUNDARY(size) ((size) + ((size) % 16 ? 16 - (size) % 16 : 0))
19 /* HEADERIZER HFILE: none */
21 pmclass ImageIOSize auto_attrs {
22     ATTR PMC                        *seen; /* seen hash */
23     ATTR PMC                        *todo; /* todo list */
24     ATTR struct PackFile            *pf;
25     ATTR struct PackFile_ConstTable *pf_ct;
26     ATTR INTVAL                      size;
30 =head1 VTABLES
32 =over 4
34 =cut
40 =item C<void init()>
42 Initializes the PMC.
44 =cut
47     VTABLE void init() {
48         PARROT_IMAGEIOSIZE(SELF)->todo  = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
49         PARROT_IMAGEIOSIZE(SELF)->pf    = PackFile_new(INTERP, 0);
50         PARROT_IMAGEIOSIZE(SELF)->pf_ct = NULL;
51         PARROT_IMAGEIOSIZE(SELF)->size  = 0;
53         PARROT_IMAGEIOSIZE(SELF)->seen = Parrot_pmc_new(INTERP, enum_class_Hash);
54         VTABLE_set_pointer(INTERP, PARROT_IMAGEIOSIZE(SELF)->seen,
55             parrot_new_intval_hash(INTERP));
57         PObj_flag_CLEAR(private1, SELF);
59         PObj_custom_mark_destroy_SETALL(SELF);
60     }
64 =item C<void init_pmc()>
66 Initializes the PMC with a pre-existing C<PackFile_ConstTable>.
68 =cut
71     VTABLE void init_pmc(PMC *pf_ct) {
72         PARROT_IMAGEIOSIZE(SELF)->todo  = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
73         PARROT_IMAGEIOSIZE(SELF)->pf    = PackFile_new(INTERP, 0);
74         PARROT_IMAGEIOSIZE(SELF)->pf_ct =
75             (PackFile_ConstTable *)VTABLE_get_pointer(INTERP, pf_ct);
76         PARROT_IMAGEIOSIZE(SELF)->size  = 0;
78         PARROT_IMAGEIOSIZE(SELF)->seen = Parrot_pmc_new(INTERP, enum_class_Hash);
79         VTABLE_set_pointer(INTERP, PARROT_IMAGEIOSIZE(SELF)->seen,
80             parrot_new_intval_hash(INTERP));
82         PObj_flag_SET(private1, SELF);
84         PObj_custom_mark_destroy_SETALL(SELF);
85     }
90 =item C<void destroy()>
92 Destroys the PMC.
94 =cut
97     VTABLE void destroy() {
98         PackFile_destroy(INTERP, PARROT_IMAGEIOSIZE(SELF)->pf);
99     }
103 =item C<void mark()>
105 Marks the PMC as alive.
107 =cut
110     VTABLE void mark() {
111         Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOSIZE(SELF)->todo);
112         Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOSIZE(SELF)->seen);
113     }
117 =item C<VTABLE PMC *get_pmc()>
119 Gets the result PMC after a thaw.
121 =cut
125     VTABLE PMC *get_pmc() {
126         PMC * const ret = Parrot_pmc_new_init_int(INTERP, enum_class_Integer,
127                 PARROT_IMAGEIOSIZE(SELF)->size);
128         return ret;
129     }
133 =item C<VTABLE PMC *get_iter()>
135 Get the C<todo> list for this freeze/thaw for iterating over.
137 =cut
141     VTABLE PMC *get_iter() {
142         return PARROT_IMAGEIOSIZE(SELF)->todo;
143     }
147 =item C<VTABLE INTVAL get_integer()>
149 Returns the flags describing the visit action
151 =cut
155     VTABLE INTVAL get_integer() {
156         return VISIT_FREEZE_NORMAL;
157     }
161 =item C<VTABLE void push_integer(INTVAL v)>
163 Pushes the integer C<v> onto the end of the image.
165 =cut
169     VTABLE void push_integer(INTVAL v) {
170         const size_t len = PF_size_integer() * sizeof (opcode_t);
171         PARROT_IMAGEIOSIZE(SELF)->size += len;
172     }
177 =item C<VTABLE void push_float(FLOATVAL v)>
179 Pushes the float C<v> onto the end of the image.
181 =cut
185     VTABLE void push_float(FLOATVAL v)
186     {
187         const size_t len = PF_size_number() * sizeof (opcode_t);
188         PARROT_IMAGEIOSIZE(SELF)->size += len;
189     }
194 =item C<VTABLE void push_string(STRING *v)>
196 Pushes the string C<*v> onto the end of the image.
198 =cut
202     VTABLE void push_string(STRING *v) {
203         if (PObj_flag_TEST(private1, SELF)) {
204             /* store a reference to constant table entry of string */
205             PMC *v_pmc = key_new_string(interp, v);
206             PackFile_ConstTable *table = PARROT_IMAGEIOSIZE(SELF)->pf_ct;
207             int idx = PackFile_ConstTable_rlookup(INTERP, table, v_pmc, PFC_STRING);
209             if (idx >= 0) {
210                 STATICSELF.push_integer(idx);
211                 return;
212             }
214             /* XXX
215              * handle cases where the PMC has changed after Parrot_freeze_strings was called
216              * eg: :immediate subs
217              */
218             STATICSELF.push_integer(-1);
219             /* TODO
220              * should really be:
221              * PANIC(INTERP, "string not previously in constant table when freezing to packfile");
222              */
223         }
225         {
226             const size_t len = PF_size_string(v) * sizeof (opcode_t);
227             PARROT_IMAGEIOSIZE(SELF)->size += len;
228         }
229     }
233 =item C<VTABLE void push_pmc(PMC *v)>
235 Pushes a reference to pmc C<*v> onto the end of the image. If C<*v>
236 hasn't been seen yet, it is also pushed onto the todo list.
238 =cut
242     VTABLE void push_pmc(PMC *v) {
243         int is_new = 0;
245         if (!PMC_IS_NULL(v)) {
246             Hash * const hash = (Hash *)VTABLE_get_pointer(INTERP, PARROT_IMAGEIOSIZE(SELF)->seen);
247             HashBucket * const b = parrot_hash_get_bucket(INTERP, hash, v);
248             is_new = !b;
249         }
251         SELF.push_integer(0);
253         if (is_new) {
254             Hash * const hash = (Hash *)VTABLE_get_pointer(INTERP, PARROT_IMAGEIOSIZE(SELF)->seen);
256             parrot_hash_put(INTERP, hash, v, v);
258             /* workaround to keep ParrotInterpreter PBC hack working */
259             if (v->vtable->base_type == enum_class_ParrotInterpreter)
260                 PObj_flag_CLEAR(private1, SELF);
262             VTABLE_push_integer(INTERP, SELF, v->vtable->base_type);
263             VTABLE_push_pmc(INTERP, PARROT_IMAGEIOSIZE(SELF)->todo, v);
264         }
265     }
267     VTABLE void set_pmc(PMC *p)
268     {
269         if (!PObj_flag_TEST(private1, SELF)) {
270             UINTVAL header_length = GROW_TO_16_BYTE_BOUNDARY(PACKFILE_HEADER_BYTES);
271             PARROT_IMAGEIOSIZE(SELF)->size += header_length;
272         }
274         STATICSELF.push_pmc(p);
275         Parrot_visit_loop_visit(INTERP, SELF);
276     }
280 =back
282 =cut
289  * Local variables:
290  *   c-file-style: "parrot"
291  * End:
292  * vim: expandtab shiftwidth=4:
293  */