[svn:parrot] r40448 - in trunk: . docs include/parrot src t/tools

dukeleto at svn.parrot.org dukeleto at svn.parrot.org
Sat Aug 8 08:16:44 UTC 2009


Author: dukeleto
Date: Sat Aug  8 08:16:40 2009
New Revision: 40448
URL: https://trac.parrot.org/parrot/changeset/40448

Log:
[debugger] Add ability to assign to registers

Currently assigning to PMC registers is not supported.

Modified:
   trunk/DEPRECATED.pod
   trunk/docs/debugger.pod
   trunk/include/parrot/debugger.h
   trunk/src/debug.c
   trunk/t/tools/parrot_debugger.t

Modified: trunk/DEPRECATED.pod
==============================================================================
--- trunk/DEPRECATED.pod	Sat Aug  8 02:40:06 2009	(r40447)
+++ trunk/DEPRECATED.pod	Sat Aug  8 08:16:40 2009	(r40448)
@@ -114,6 +114,10 @@
 
 [Nothing at this time.]
 
+=head1 Debugger
+
+Assigning to registers [experimental]
+
 =head1 PIR syntax
 
 =over 4

Modified: trunk/docs/debugger.pod
==============================================================================
--- trunk/docs/debugger.pod	Sat Aug  8 02:40:06 2009	(r40447)
+++ trunk/docs/debugger.pod	Sat Aug  8 08:16:40 2009	(r40448)
@@ -381,10 +381,10 @@
 
 =over 4
 
-=item src/pdb.c
+=item src/parrot_debugger.c
 
-This is the file that will produce the executable.  Nothing fancy here, only
-the C<main> function.
+This is the file that will produce the executable.  Nothing fancy here, it
+mostly consists of the C<main> function.
 
 =item src/debug.c
 
@@ -395,7 +395,7 @@
 
 C<Parrot_debug>, the function which launches the debugger, is implemented here.
 
-=item include/parrot/debug.h
+=item include/parrot/debugger.h
 
 This defines all the PDB structures, which hold data used by the debugger.
 

Modified: trunk/include/parrot/debugger.h
==============================================================================
--- trunk/include/parrot/debugger.h	Sat Aug  8 02:40:06 2009	(r40447)
+++ trunk/include/parrot/debugger.h	Sat Aug  8 08:16:40 2009	(r40448)
@@ -1,9 +1,9 @@
 /*
- * Copyright (C) 2002-2008, Parrot Foundation.
+ * Copyright (C) 2002-2009, Parrot Foundation.
  */
 
 /*
- * debug.h
+ * debugger.h
  *
  * SVN Info
  *    $Id$
@@ -222,6 +222,10 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*file);
 
+void PDB_assign(PARROT_INTERP, ARGIN(const char *command))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
 void PDB_backtrace(PARROT_INTERP)
         __attribute__nonnull__(1);
 
@@ -377,6 +381,9 @@
 #define ASSERT_ARGS_PDB_add_label __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(file) \
     || PARROT_ASSERT_ARG(cur_opcode)
+#define ASSERT_ARGS_PDB_assign __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(command)
 #define ASSERT_ARGS_PDB_backtrace __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_PDB_break __attribute__unused__ int _ASSERT_ARGS_CHECK = \

Modified: trunk/src/debug.c
==============================================================================
--- trunk/src/debug.c	Sat Aug  8 02:40:06 2009	(r40447)
+++ trunk/src/debug.c	Sat Aug  8 08:16:40 2009	(r40448)
@@ -48,6 +48,11 @@
 /* Length of command line buffers */
 #define DEBUG_CMD_BUFFER_LENGTH 255
 
+/* Easier register access */
+#define IREG(i) REG_INT(interp, (i))
+#define NREG(i) REG_NUM(interp, (i))
+#define SREG(i) REG_STR(interp, (i))
+#define PREG(i) REG_PMC(interp, (i))
 
 typedef struct DebuggerCmd DebuggerCmd;
 typedef struct DebuggerCmdList DebuggerCmdList;
@@ -207,6 +212,13 @@
     }
 }
 
+static void dbg_assign(PDB_t * pdb, const char * cmd) /* HEADERIZER SKIP */
+{
+    TRACEDEB_MSG("dbg_assign");
+
+    PDB_assign(pdb->debugee, cmd);
+}
+
 static void dbg_break(PDB_t * pdb, const char * cmd) /* HEADERIZER SKIP */
 {
     TRACEDEB_MSG("dbg_break");
@@ -395,6 +407,14 @@
 };
 
 static const DebuggerCmd
+    cmd_assign = {
+        & dbg_assign,
+        "assign to a register",
+"Assign a value to a register. For example:\n\
+    a I0 42\n\
+    a N1 3.14\n\
+The first command sets I0 to 42 and the second sets N1 to 3.14."
+    },
     cmd_break = {
         & dbg_break,
         "add a breakpoint",
@@ -549,6 +569,7 @@
 };
 
 DebuggerCmdList DebCmdList [] = {
+    { "assign",      'a',  &cmd_assign },
     { "break",       '\0', &cmd_break },
     { "continue",    '\0', &cmd_continue },
     { "delete",      'd',  &cmd_delete },
@@ -3162,6 +3183,59 @@
 
 /*
 
+=item C<void PDB_assign(PARROT_INTERP, const char *command)>
+
+Assign to registers.
+
+=cut
+
+*/
+
+void
+PDB_assign(PARROT_INTERP, ARGIN(const char *command))
+{
+    ASSERT_ARGS(PDB_assign)
+    unsigned long register_num;
+    char reg_type;
+    char *string;
+    int t;
+
+    /* smallest valid commad length is 4, i.e. "I0 1" */
+    if (strlen(command) < 4) {
+        fprintf(stderr, "Must give a register number and value to assign\n");
+        return;
+    }
+    reg_type = (char) command[0];
+    command++;
+    register_num   = get_ulong(&command, 0);
+
+    switch (reg_type) {
+        case 'I':
+                t                  = REGNO_INT;
+                IREG(register_num) = get_ulong(&command, 0);
+                break;
+        case 'N':
+                t                  = REGNO_NUM;
+                NREG(register_num) = atof(command);
+                break;
+        case 'S':
+                t                  = REGNO_STR;
+                SREG(register_num) = Parrot_str_new(interp, command, strlen(command));
+                break;
+        case 'P':
+                t = REGNO_PMC;
+                fprintf(stderr, "Assigning to PMCs is not currently supported\n");
+                return;
+        default:
+            fprintf(stderr, "Invalid register type %c\n", reg_type);
+            return;
+    }
+    Parrot_io_eprintf(interp, "\n  %c%u = ", reg_type, register_num);
+    Parrot_io_eprintf(interp, "%s\n", GDB_print_reg(interp, t, register_num));
+}
+
+/*
+
 =item C<void PDB_list(PARROT_INTERP, const char *command)>
 
 Show lines from the source code file.
@@ -3321,6 +3395,8 @@
 {
     ASSERT_ARGS(PDB_print)
     const char * const s = GDB_P(interp->pdb->debugee, command);
+
+    TRACEDEB_MSG("PDB_print");
     Parrot_io_eprintf(interp, "%s\n", s);
 }
 
@@ -3554,24 +3630,32 @@
 GDB_print_reg(PARROT_INTERP, int t, int n)
 {
     ASSERT_ARGS(GDB_print_reg)
+    char * string;
 
     if (n >= 0 && n < CONTEXT(interp)->n_regs_used[t]) {
         switch (t) {
             case REGNO_INT:
-                return Parrot_str_from_int(interp, REG_INT(interp, n))->strstart;
+                return Parrot_str_from_int(interp, IREG(n))->strstart;
             case REGNO_NUM:
-                return Parrot_str_from_num(interp, REG_NUM(interp, n))->strstart;
+                return Parrot_str_from_num(interp, NREG(n))->strstart;
             case REGNO_STR:
-                return REG_STR(interp, n)->strstart;
+                /* This hack is needed because we occasionally are told
+                that we have string registers when we actually don't */
+                string = (char *) SREG(n);
+
+                if (string == '\0')
+                    return "";
+                else
+                    return SREG(n)->strstart;
             case REGNO_PMC:
                 /* prints directly */
-                trace_pmc_dump(interp, REG_PMC(interp, n));
+                trace_pmc_dump(interp, PREG(n));
                 return "";
             default:
                 break;
         }
     }
-    return "no such reg";
+    return "no such register";
 }
 
 /*
@@ -3597,11 +3681,13 @@
     int t;
     char reg_type;
 
+    TRACEDEB_MSG("GDB_P");
     /* Skip leading whitespace. */
     while (isspace((unsigned char)*s))
         s++;
 
     reg_type = (unsigned char) toupper((unsigned char)*s);
+
     switch (reg_type) {
         case 'I': t = REGNO_INT; break;
         case 'N': t = REGNO_NUM; break;
@@ -3626,7 +3712,7 @@
         return GDB_print_reg(interp, t, n);
     }
     else
-        return "no such reg";
+        return "no such register";
 
 }
 

Modified: trunk/t/tools/parrot_debugger.t
==============================================================================
--- trunk/t/tools/parrot_debugger.t	Sat Aug  8 02:40:06 2009	(r40447)
+++ trunk/t/tools/parrot_debugger.t	Sat Aug  8 08:16:40 2009	(r40448)
@@ -234,7 +234,43 @@
 
 }
 
-BEGIN { $tests += 35 }
+pdb_output_like( <<PIR, "pir", "t\na I0 17", qr/I0 = 17/, 'assign to an integer register');
+.sub main :main
+    \$I0 = 242
+.end
+PIR
+
+pdb_output_like( <<PIR, "pir", "a Z0 42", qr/Invalid register type Z/, 'assign to an invalid register');
+.sub main :main
+    \$I0 = 242
+.end
+PIR
+
+pdb_output_like( <<PIR, "pir", "a foo", qr/Must give a register number and value to assign/, 'invalid assignment command');
+.sub main :main
+    \$I0 = 242
+.end
+PIR
+
+pdb_output_like( <<PIR, "pir", "t\na N0 3.14", qr/N0 = 3.14/, 'assign to a numeric register');
+.sub main :main
+    \$N0 = 9.99
+.end
+PIR
+
+pdb_output_like( <<PIR, "pir", "t\np S", qr/S0 = foobar/, 'print string registers');
+.sub main :main
+    \$S0 = "foobar"
+.end
+PIR
+
+pdb_output_like( <<PIR, "pir", "t\na S0 foobar", qr/S0 = no such register/, 'print string registers when none exist');
+.sub main :main
+    new \$P0, 'ResizableIntegerArray'
+.end
+PIR
+
+BEGIN { $tests += 41 }
 
 BEGIN { plan tests => $tests; }
 


More information about the parrot-commits mailing list