fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / src / packdump.c
blob59d0acbf2aaa1ee785c420ad417911c2576a7388
1 /*
2 Copyright (C) 2001-2009, Parrot Foundation.
3 This program is free software. It is subject to the same license as
4 Parrot itself.
5 $Id$
7 =head1 NAME
9 src/packdump.c - Functions for dumping packfile structures
11 =head1 DESCRIPTION
13 This is only used by the PBC dumper C<pbc_dump>.
15 =head2 Functions
17 =over 4
19 =cut
23 #include "parrot/parrot.h"
24 #include "pmc/pmc_sub.h"
25 #include "pmc/pmc_key.h"
27 /* HEADERIZER HFILE: include/parrot/packfile.h */
29 /* HEADERIZER BEGIN: static */
30 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
32 static void PackFile_Constant_dump(PARROT_INTERP,
33 ARGIN(const PackFile_ConstTable *ct),
34 ARGIN(const PackFile_Constant *self))
35 __attribute__nonnull__(1)
36 __attribute__nonnull__(2)
37 __attribute__nonnull__(3);
39 static void pobj_flag_dump(PARROT_INTERP, long flags)
40 __attribute__nonnull__(1);
42 #define ASSERT_ARGS_PackFile_Constant_dump __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
43 PARROT_ASSERT_ARG(interp) \
44 , PARROT_ASSERT_ARG(ct) \
45 , PARROT_ASSERT_ARG(self))
46 #define ASSERT_ARGS_pobj_flag_dump __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
47 PARROT_ASSERT_ARG(interp))
48 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
49 /* HEADERIZER END: static */
54 =item C<void PackFile_ConstTable_dump(PARROT_INTERP, const PackFile_ConstTable
55 *self)>
57 Dumps the constant table C<self>.
59 =cut
63 PARROT_EXPORT
64 void
65 PackFile_ConstTable_dump(PARROT_INTERP, ARGIN(const PackFile_ConstTable *self))
67 ASSERT_ARGS(PackFile_ConstTable_dump)
68 opcode_t i;
70 for (i = 0; i < self->const_count; ++i) {
71 Parrot_io_printf(interp, " # %x:\n", (long)i);
72 PackFile_Constant_dump(interp, self, &self->constants[i]);
78 =item C<static void PackFile_Constant_dump(PARROT_INTERP, const
79 PackFile_ConstTable *ct, const PackFile_Constant *self)>
81 Dumps the constant C<self>.
83 =cut
87 /* [this desperately needs better abstraction, so we're not duplicating the enum
88 * PObj_enum definition in the include/parrot/pobj.h file. -- rgr, 1-Mar-08.]
90 PARROT_OBSERVER static const char * const flag_bit_names[] =
92 "private0",
93 "private1",
94 "private2",
95 "private3",
96 "private4",
97 "private5",
98 "private6",
99 "private7",
100 "is_string",
101 "is_PMC",
102 "is_shared",
103 "constant",
104 "external",
105 "aligned",
106 "sysmem",
107 "COW",
108 "is_COWable",
109 "live",
110 "on_free_list",
111 "custom_mark",
112 "custom_GC",
113 "custom_destroy",
114 "report",
115 "data_is_PMC_array",
116 "need_finalize",
117 "high_priority_gc",
118 "needs_early_gc",
119 "is_class",
120 "is_object"
125 =item C<static void pobj_flag_dump(PARROT_INTERP, long flags)>
127 Given a word of flags, generate a dump line of the whole word in hex,
128 followed by individual bits.
130 =cut
134 static void
135 pobj_flag_dump(PARROT_INTERP, long flags)
137 ASSERT_ARGS(pobj_flag_dump)
138 INTVAL idx = 0;
139 int printed_flag_p = 0;
141 Parrot_io_printf(interp, "\t\tFLAGS => 0x%04lx (", flags);
142 while (flags) {
143 if (flags & 1) {
144 if (printed_flag_p)
145 Parrot_io_printf(interp, ",");
146 Parrot_io_printf(interp, "%s", flag_bit_names[idx]);
147 ++printed_flag_p;
149 ++idx;
150 flags >>= 1;
152 Parrot_io_printf(interp, ")\n");
155 static void
156 PackFile_Constant_dump(PARROT_INTERP, ARGIN(const PackFile_ConstTable *ct),
157 ARGIN(const PackFile_Constant *self))
159 ASSERT_ARGS(PackFile_Constant_dump)
160 PMC *key;
161 size_t i;
163 switch (self->type) {
165 case PFC_NUMBER:
166 Parrot_io_printf(interp, " [ 'PFC_NUMBER', %g ],\n", self->u.number);
167 break;
169 case PFC_STRING:
170 Parrot_io_printf(interp, " [ 'PFC_STRING', {\n");
171 pobj_flag_dump(interp, (long)PObj_get_FLAGS(self->u.string));
172 Parrot_io_printf(interp, " ENCODING => %ld,\n",
173 self->u.string->encoding);
174 i = self->u.string->bufused;
175 Parrot_io_printf(interp, " SIZE => %ld,\n",
176 (long)i);
178 Parrot_io_printf(interp, " DATA => \"%Ss\"\n",
179 Parrot_str_escape(interp, self->u.string));
180 Parrot_io_printf(interp, " } ],\n");
181 break;
183 case PFC_KEY:
184 for (i = 0, key = self->u.key; key; ++i) {
185 GETATTR_Key_next_key(interp, key, key);
187 /* number of key components */
188 Parrot_io_printf(interp, " [ 'PFC_KEY' (%ld items)\n", i);
189 /* and now type / value per component */
190 for (key = self->u.key; key;) {
191 opcode_t type = PObj_get_FLAGS(key);
193 Parrot_io_printf(interp, " {\n");
195 type &= KEY_type_FLAGS;
196 pobj_flag_dump(interp, (long)PObj_get_FLAGS(key));
197 switch (type) {
198 case KEY_integer_FLAG:
199 Parrot_io_printf(interp, " TYPE => INTEGER\n");
200 Parrot_io_printf(interp, " DATA => %ld\n",
201 VTABLE_get_integer(interp, key));
202 Parrot_io_printf(interp, " },\n");
203 break;
204 case KEY_number_FLAG:
206 const PackFile_Constant *detail;
207 size_t ct_index;
209 Parrot_io_printf(interp, " TYPE => NUMBER\n");
210 ct_index = PackFile_find_in_const(interp, ct, key, PFC_NUMBER);
211 Parrot_io_printf(interp, " PFC_OFFSET => %ld\n", ct_index);
212 detail = &ct->constants[ct_index];
213 Parrot_io_printf(interp, " DATA => %ld\n", detail->u.number);
214 Parrot_io_printf(interp, " },\n");
216 break;
217 case KEY_string_FLAG:
219 const PackFile_Constant *detail;
220 size_t ct_index;
222 Parrot_io_printf(interp, " TYPE => STRING\n");
223 ct_index = PackFile_find_in_const(interp, ct, key, PFC_STRING);
224 Parrot_io_printf(interp, " PFC_OFFSET => %ld\n", ct_index);
225 detail = &ct->constants[ct_index];
226 Parrot_io_printf(interp, " DATA => '%Ss'\n",
227 detail->u.string);
228 Parrot_io_printf(interp, " },\n");
230 break;
231 case KEY_integer_FLAG | KEY_register_FLAG:
232 Parrot_io_printf(interp, " TYPE => I REGISTER\n");
233 Parrot_io_printf(interp, " DATA => %ld\n",
234 VTABLE_get_integer(interp, key));
235 Parrot_io_printf(interp, " },\n");
236 break;
237 case KEY_number_FLAG | KEY_register_FLAG:
238 Parrot_io_printf(interp, " TYPE => N REGISTER\n");
239 Parrot_io_printf(interp, " DATA => %ld\n",
240 VTABLE_get_integer(interp, key));
241 Parrot_io_printf(interp, " },\n");
242 break;
243 case KEY_string_FLAG | KEY_register_FLAG:
244 Parrot_io_printf(interp, " TYPE => S REGISTER\n");
245 Parrot_io_printf(interp, " DATA => %ld\n",
246 VTABLE_get_integer(interp, key));
247 Parrot_io_printf(interp, " },\n");
248 break;
249 case KEY_pmc_FLAG | KEY_register_FLAG:
250 Parrot_io_printf(interp, " TYPE => P REGISTER\n");
251 Parrot_io_printf(interp, " DATA => %ld\n",
252 VTABLE_get_integer(interp, key));
253 Parrot_io_printf(interp, " },\n");
254 break;
255 default:
256 Parrot_io_eprintf(NULL, "PackFile_Constant_pack: "
257 "unsupported constant type\n");
258 Parrot_exit(interp, 1);
260 GETATTR_Key_next_key(interp, key, key);
262 Parrot_io_printf(interp, " ],\n");
263 break;
264 case PFC_PMC:
265 Parrot_io_printf(interp, " [ 'PFC_PMC', {\n");
267 PMC * const pmc = self->u.key;
268 Parrot_Sub_attributes *sub;
269 STRING * const null = Parrot_str_new_constant(interp, "(null)");
270 STRING *namespace_description;
272 pobj_flag_dump(interp, (long)PObj_get_FLAGS(pmc));
273 switch (pmc->vtable->base_type) {
274 case enum_class_FixedBooleanArray:
275 case enum_class_FixedFloatArray:
276 case enum_class_FixedPMCArray:
277 case enum_class_FixedStringArray:
278 case enum_class_ResizableBooleanArray:
279 case enum_class_ResizableIntegerArray:
280 case enum_class_ResizableFloatArray:
281 case enum_class_ResizablePMCArray:
282 case enum_class_ResizableStringArray:
284 const int n = VTABLE_get_integer(interp, pmc);
285 STRING* const out_buffer = VTABLE_get_repr(interp, pmc);
286 Parrot_io_printf(interp,
287 "\t\tclass => %Ss,\n"
288 "\t\telement count => %d,\n"
289 "\t\telements => %Ss,\n",
290 pmc->vtable->whoami,
292 out_buffer);
294 break;
295 case enum_class_Sub:
296 case enum_class_Coroutine:
297 PMC_get_sub(interp, pmc, sub);
298 if (sub->namespace_name) {
299 switch (sub->namespace_name->vtable->base_type) {
300 case enum_class_String:
301 namespace_description = Parrot_str_new(interp, "'", 1);
302 namespace_description = Parrot_str_concat(interp,
303 namespace_description,
304 VTABLE_get_string(interp, sub->namespace_name));
305 namespace_description = Parrot_str_concat(interp,
306 namespace_description,
307 Parrot_str_new(interp, "'", 1));
308 break;
309 case enum_class_Key:
310 namespace_description =
311 key_set_to_string(interp, sub->namespace_name);
312 break;
313 default:
314 namespace_description = sub->namespace_name->vtable->whoami;
317 else {
318 namespace_description = null;
320 Parrot_io_printf(interp,
321 "\t\tclass => %Ss,\n"
322 "\t\tstart_offs => %d,\n"
323 "\t\tend_offs => %d,\n"
324 "\t\tname => '%Ss',\n"
325 "\t\tsubid => '%Ss',\n"
326 "\t\tmethod => '%Ss',\n"
327 "\t\tnsentry => '%Ss',\n"
328 "\t\tnamespace => %Ss,\n"
329 "\t\tHLL_id => %d,\n"
330 "\t\tn_regs_used => [ %d, %d, %d, %d ],\n",
331 pmc->vtable->whoami,
332 sub->start_offs,
333 sub->end_offs,
334 sub->name,
335 sub->subid,
336 sub->method_name,
337 sub->ns_entry_name,
338 namespace_description,
339 sub->HLL_id,
340 sub->n_regs_used[0],
341 sub->n_regs_used[1],
342 sub->n_regs_used[2],
343 sub->n_regs_used[3]);
344 break;
345 case enum_class_FixedIntegerArray:
346 Parrot_io_printf(interp,
347 "\t\tclass => %Ss,\n"
348 "\t\trepr => '%Ss'\n",
349 pmc->vtable->whoami,
350 VTABLE_get_repr(interp, pmc));
351 break;
352 default:
353 Parrot_io_printf(interp, "\t\tno dump info for PMC %ld %Ss\n",
354 pmc->vtable->base_type, pmc->vtable->whoami);
355 Parrot_io_printf(interp, "\t\tclass => %Ss,\n", pmc->vtable->whoami);
358 Parrot_io_printf(interp, " } ],\n");
359 break;
360 default:
361 Parrot_io_printf(interp, " [ 'PFC_\?\?\?', type '0x%x' ],\n",
362 self->type);
363 break;
369 =item C<void PackFile_Fixup_dump(PARROT_INTERP, const PackFile_FixupTable *ft)>
371 Dumps the fix-up table C<ft>.
373 =cut
377 PARROT_EXPORT
378 void
379 PackFile_Fixup_dump(PARROT_INTERP, ARGIN(const PackFile_FixupTable *ft))
381 ASSERT_ARGS(PackFile_Fixup_dump)
382 opcode_t i;
384 for (i = 0; i < ft->fixup_count; ++i) {
385 Parrot_io_printf(interp, "\t#%d\n", (int) i);
386 switch (ft->fixups[i].type) {
387 case enum_fixup_sub:
388 Parrot_io_printf(interp,
389 "\ttype => %d offs => %8d name => '%s',\n",
390 (int)ft->fixups[i].type,
391 (int)ft->fixups[i].offset,
392 ft->fixups[i].name);
393 break;
394 default:
395 Parrot_io_printf(interp, "\ttype => %d ???,\n",
396 (int) ft->fixups[i].type);
397 break;
404 =back
406 =head1 SEE ALSO
408 F<src/pbc_dump.c>.
410 =cut
416 * Local variables:
417 * c-file-style: "parrot"
418 * End:
419 * vim: expandtab shiftwidth=4: