Re: Disassembler enhancement for review

2007-12-29 Thread Allison Randal

Bob Rogers wrote:

   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.


Looks good. Go ahead and commit. Better abstraction for signature 
decoding can be added later.


Allison


Re: Disassembler enhancement for review

2007-12-29 Thread Bob Rogers
   From: Allison Randal [EMAIL PROTECTED]
   Date: Sat, 29 Dec 2007 12:08:10 +0200

   Looks good. Go ahead and commit. Better abstraction for signature 
   decoding can be added later.

   Allison

Thanks; done in r24268.  I also changed it to use PIR syntax, so we
wouldn't have a new syntax to document.

-- Bob


Disassembler enhancement for review

2007-12-28 Thread Bob Rogers
   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.