The attached patch adds decoding of call/return registers to the
disassembler, and also fixes a segfault; both are byproducts of a long
and otherwise fruitless debugging session. Please let me know what you
think.
-- Bob Rogers
http://rgrjr.dyndns.org/
* src/debug.c:
+ (PDB_disassemble_op): Add special decoding for the signature used
in args/returns. Needs better abstraction, may need better error
checking.
+ (PDB_disassemble): Bug fix: Initialize pline-label, lest the
caller segfault on output.
Diffs between last version checked in and current workfile(s):
Index: src/debug.c
===
--- src/debug.c (revision 24244)
+++ src/debug.c (working copy)
@@ -1594,8 +1594,7 @@
/* If the opcode jumps and this is the last argument,
that means this is a label */
if ((j == info-op_count - 1)
-(info-jump PARROT_JUMP_RELATIVE))
-{
+(info-jump PARROT_JUMP_RELATIVE)) {
if (file) {
dest[size++] = 'L';
i= PDB_add_label(file, op, op[j]);
@@ -1757,6 +1756,79 @@
dest[size++] = ',';
}
+/* Special decoding for the signature used in args/returns. Such ops have
+ one fixed parameter (the signature vector), plus a varying number of
+ registers/constants. For each value, we show the register and decode
its
+ flags. */
+if (*(op) == PARROT_OP_set_args_pc ||
+*(op) == PARROT_OP_get_results_pc ||
+*(op) == PARROT_OP_get_params_pc ||
+*(op) == PARROT_OP_set_returns_pc) {
+char buf[1000];
+PMC * const sig = interp-code-const_table-constants[op[1]]-u.key;
+int n_values = SIG_ELEMS(sig);
+const char *regs = ISPN;
+/* This is from Call_bits_enum_t (with which it should probably be
+ colocated):
+ ' ' = ignore (this is the reg type, decoded elsewhere)
+ '!' = undefined
+ 'C' = constant
+ 'F' = :flat or :slurpy
+ 'O' = :optional
+ '?' = :opt_flag
+ 'N' = named param.
+*/
+const char *flag_chars = !!CF!O?N;
+int sig_value;
+
+dest[size++] = '=';
+dest[size++] = '(';
+for (j = 0; j n_values; j++) {
+unsigned int idx = 0;
+int sig_value = VTABLE_get_integer_keyed_int(interp, sig, j);
+
+/* Print the register name, e.g. P37. */
+if (j)
+buf[idx++] = ',';
+buf[idx++] = regs[sig_value PARROT_ARG_TYPE_MASK];
+Parrot_snprintf(interp, buf[idx], sizeof(buf)-idx,
+INTVAL_FMT, op[j+2]);
+idx = strlen(buf);
+
+/* Add flags, if we have any. */
+{
+int flag_idx = 0;
+int flag_p = 0;
+int flags = sig_value;
+
+/* End when we run out of flags, off the end of flag_chars, or
+ get too close to the end of buf. */
+while (flags idx sizeof(buf)-10) {
+char flag_char = flag_chars[flag_idx];
+if (! flag_char)
+break;
+if (flags 1 flag_char != ' ') {
+if (! flag_p) {
+buf[idx++] = '[';
+flag_p = 1;
+}
+buf[idx++] = flag_char;
+}
+flags = 1;
+flag_idx++;
+}
+if (flag_p)
+buf[idx++] = ']';
+}
+
+/* Add it to dest. */
+buf[idx++] = '\0';
+strcpy(dest[size], buf);
+size += strlen(buf);
+}
+dest[size++] = ')';
+}
+
dest[size] = '\0';
return ++size;
}
@@ -1793,6 +1865,7 @@
PDB_free_file(interp);
pline-number= 1;
+pline-label = NULL;
pfile-line = pline;
pfile-label = NULL;
pfile-size = 0;
End of diffs.