1/* 2Copyright (C) 2010-2014, Parrot Foundation. 3 4=head1 NAME 5 6src/pmc/imageiostrings.pmc - ImageIOStrings PMC 7 8=head1 DESCRIPTION 9 10Get a list of strings in an object graph. Used in packfile creation. 11 12=cut 13 14*/ 15 16/* HEADERIZER HFILE: none */ 17/* HEADERIZER BEGIN: static */ 18/* HEADERIZER END: static */ 19 20pmclass ImageIOStrings auto_attrs { 21 ATTR PMC *seen; /* seen hash */ 22 ATTR PMC *todo; /* todo list */ 23 ATTR PMC *list; /* list of strings seen */ 24 25/* 26 27=head1 VTABLES 28 29=over 4 30 31=cut 32 33*/ 34 35/* 36 37=item C<void init()> 38 39Initializes the PMC. 40 41=cut 42 43*/ 44 VTABLE void init() { 45 PARROT_IMAGEIOSTRINGS(SELF)->todo = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray); 46 47 PARROT_IMAGEIOSTRINGS(SELF)->seen = Parrot_pmc_new(INTERP, enum_class_Hash); 48 VTABLE_set_pointer(INTERP, PARROT_IMAGEIOSTRINGS(SELF)->seen, 49 Parrot_hash_new_intval_hash(INTERP)); 50 51 PARROT_IMAGEIOSTRINGS(SELF)->list = Parrot_pmc_new(INTERP, enum_class_ResizableStringArray); 52 53 PObj_custom_mark_SET(SELF); 54 } 55 56/* 57 58=item C<void mark()> 59 60Marks the PMC as alive. 61 62=cut 63 64*/ 65 VTABLE void mark() :no_wb { 66 Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOSTRINGS(SELF)->todo); 67 Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOSTRINGS(SELF)->seen); 68 Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOSTRINGS(SELF)->list); 69 } 70 71/* 72 73=item C<VTABLE PMC *get_pmc()> 74 75Gets the result PMC after a thaw. 76 77=cut 78 79*/ 80 81 VTABLE PMC *get_pmc() :no_wb { 82 UNUSED(INTERP) 83 return PARROT_IMAGEIOSTRINGS(SELF)->list; 84 } 85 86/* 87 88=item C<VTABLE INTVAL get_integer()> 89 90Returns the flags describing the visit action 91 92=cut 93 94*/ 95 96 VTABLE INTVAL get_integer() :no_wb { 97 UNUSED(INTERP) 98 UNUSED(SELF) 99 return VISIT_FREEZE_NORMAL; 100 } 101 102 103/* 104 105=item C<VTABLE void push_integer(INTVAL v)> 106 107Do nothing. 108 109=cut 110 111*/ 112 113 VTABLE void push_integer(INTVAL v) :no_wb { 114 UNUSED(INTERP) 115 UNUSED(SELF) 116 UNUSED(v) 117 } 118 119 120/* 121 122=item C<VTABLE void push_float(FLOATVAL v)> 123 124Do nothing. 125 126=cut 127 128*/ 129 130 VTABLE void push_float(FLOATVAL v) :no_wb { 131 UNUSED(INTERP) 132 UNUSED(SELF) 133 UNUSED(v) 134 } 135 136 137/* 138 139=item C<VTABLE void push_string(STRING *v)> 140 141Adds the string to the list of strings. 142 143=cut 144 145*/ 146 147 VTABLE void push_string(STRING *v) :manual_wb { 148 VTABLE_push_string(INTERP, PARROT_IMAGEIOSTRINGS(SELF)->list, v); 149 } 150 151/* 152 153=item C<VTABLE void push_pmc(PMC *v)> 154 155Checks new pmcs for strings. 156 157=cut 158 159*/ 160 161 VTABLE void push_pmc(PMC *v) :manual_wb { 162 if (!PMC_IS_NULL(v)) { 163 Hash * const hash = (Hash *)VTABLE_get_pointer(INTERP, 164 PARROT_IMAGEIOSTRINGS(SELF)->seen); 165 HashBucket * const b = Parrot_hash_get_bucket(INTERP, hash, v); 166 if (!b) { 167 /* not yet seen */ 168 Parrot_hash_put(INTERP, hash, v, v); 169 VTABLE_push_pmc(INTERP, PARROT_IMAGEIOSTRINGS(SELF)->todo, v); 170 } 171 else 172 PARROT_GC_WRITE_BARRIER(INTERP, SELF); 173 } 174 } 175 176 VTABLE void set_pmc(PMC *p) :manual_wb { 177 PMC * const todo = PARROT_IMAGEIOSTRINGS(SELF)->todo; 178 STATICSELF.push_pmc(p); 179 while (VTABLE_elements(INTERP, todo)) { 180 PMC * const current = VTABLE_shift_pmc(INTERP, todo); 181 VTABLE_freeze(INTERP, current, SELF); 182 VTABLE_visit(INTERP, current, SELF); 183 SELF.push_pmc(PMC_metadata(current)); 184 } 185 } 186 187/* 188 189=back 190 191=cut 192 193*/ 194 195} 196 197/* 198 * Local variables: 199 * c-file-style: "parrot" 200 * End: 201 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' : 202 */ 203