2 Copyright (C) 2010, Parrot Foundation.
7 src/pmc/imageiosize.pmc - ImageIOSize PMC
11 Gets the size of an ImageIO image without the allocation costs.
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;
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);
64 =item C<void init_pmc()>
66 Initializes the PMC with a pre-existing C<PackFile_ConstTable>.
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);
90 =item C<void destroy()>
97 VTABLE void destroy() {
98 PackFile_destroy(INTERP, PARROT_IMAGEIOSIZE(SELF)->pf);
105 Marks the PMC as alive.
111 Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOSIZE(SELF)->todo);
112 Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOSIZE(SELF)->seen);
117 =item C<VTABLE PMC *get_pmc()>
119 Gets the result PMC after a thaw.
125 VTABLE PMC *get_pmc() {
126 PMC * const ret = Parrot_pmc_new_init_int(INTERP, enum_class_Integer,
127 PARROT_IMAGEIOSIZE(SELF)->size);
133 =item C<VTABLE PMC *get_iter()>
135 Get the C<todo> list for this freeze/thaw for iterating over.
141 VTABLE PMC *get_iter() {
142 return PARROT_IMAGEIOSIZE(SELF)->todo;
147 =item C<VTABLE INTVAL get_integer()>
149 Returns the flags describing the visit action
155 VTABLE INTVAL get_integer() {
156 return VISIT_FREEZE_NORMAL;
161 =item C<VTABLE void push_integer(INTVAL v)>
163 Pushes the integer C<v> onto the end of the image.
169 VTABLE void push_integer(INTVAL v) {
170 const size_t len = PF_size_integer() * sizeof (opcode_t);
171 PARROT_IMAGEIOSIZE(SELF)->size += len;
177 =item C<VTABLE void push_float(FLOATVAL v)>
179 Pushes the float C<v> onto the end of the image.
185 VTABLE void push_float(FLOATVAL v)
187 const size_t len = PF_size_number() * sizeof (opcode_t);
188 PARROT_IMAGEIOSIZE(SELF)->size += len;
194 =item C<VTABLE void push_string(STRING *v)>
196 Pushes the string C<*v> onto the end of the image.
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);
210 STATICSELF.push_integer(idx);
215 * handle cases where the PMC has changed after Parrot_freeze_strings was called
216 * eg: :immediate subs
218 STATICSELF.push_integer(-1);
221 * PANIC(INTERP, "string not previously in constant table when freezing to packfile");
226 const size_t len = PF_size_string(v) * sizeof (opcode_t);
227 PARROT_IMAGEIOSIZE(SELF)->size += len;
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.
242 VTABLE void push_pmc(PMC *v) {
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);
251 SELF.push_integer(0);
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);
267 VTABLE void set_pmc(PMC *p)
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;
274 STATICSELF.push_pmc(p);
275 Parrot_visit_loop_visit(INTERP, SELF);
290 * c-file-style: "parrot"
292 * vim: expandtab shiftwidth=4: