# New Ticket Created by  Steve Fink 
# Please include the string:  [perl #17573]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=17573 >


- In imcc.y:main(), the stacktop was being set to an uninitialized
  value, making stackwalking sometimes *really* slow, sometimes crash,
  and sometimes work perfectly fine.

- My bison does not accept actions that do not end in a semicolon, eg
  { $$ = 0 }

- BRANCH is generated by imcc.l, but is never referred to in imcc.y,
  and so is considered an error. I copied the action of GOTO, which
  may not be correct, but perhaps the right fix would to be to merge
  BRANCH and GOTO in the lexer? Or just delete BRANCH from the lexer
  and let it be dealt with as a pasm op? I haven't looked into it,
  since I'm sure Leo will know the answer right away.

- Some key parsing still doesn't work for me. For example,
    set $P0[0], 0
  is the nonexistent op set_p_ic_ic because the constant zero is
  reused in the symreg hashtable, and so its VTKEY bit is cleared when
  it is encountered for the second time in the same instruction. I
  don't think this is doable in the flags. The hashtable could keep
  separate entries for keyed and non-keyed versions, but that would
  break register allocation. So I think another global along with
  args[] is necessary. This patch adds a 'keyvec' bitmap for this
  purpose, and removes the VTKEY flag which (I think) is now
  unnecessary.

After this patch, all tests pass, but there's a warning from
t/compiler/6_6.imc because it has a multiply-defined local variable.
But that's a perl6 problem. It is possible, but highly unlikely, that
this is a result of my local modifications to perl6 (but they're all
only in the regex code.)


-- attachment  1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/38556/31344/94296c/imcc-keys2.patch

? 1.trace
? 1a.trace
? 2.trace
? 2_3.imc
? 2a.trace
? Makefile.leo
? Makefile.tmp
? Weird
? a.pasm
? away-BUGS
? away-ChangeLog
? away-optimizer.c
? away-optimizer.h
? away-pbc.c
? away-pbc.h
? i.imc
? imclexer.c
? imcparser.c
? imcparser.h
? opt_cp.c
? tc
Index: imcc.y
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/imcc.y,v
retrieving revision 1.22
diff -p -u -r1.22 imcc.y
--- imcc.y      22 Sep 2002 17:38:47 -0000      1.22
+++ imcc.y      25 Sep 2002 03:07:55 -0000
@@ -35,10 +35,14 @@ int         expect_pasm;
 
 
 static SymReg *regs[IMCC_MAX_REGS];
+/* Bit vector saying whether argument i is a key */
+static int keyvec = 0;
 static int nargs = 0;
 static SymReg *keys[IMCC_MAX_REGS];
 static int nkeys = 0;
 
+#define KEY_BIT(argnum) (1 << argnum)
+
 static SymReg ** RR(int n, ...)
 {
     va_list ap;
@@ -93,11 +97,17 @@ static Instruction * MK_I(char * fmt, Sy
  * labels and such
  */
 
-
+static void clear_state()
+{
+    nargs = 0;
+    keyvec = 0;
+    memset(regs, 0, sizeof(regs));
+}
 
 static Instruction * iLABEL(SymReg * r0) {
     Instruction *i = emitb(_mk_instruction("","%s:", R1(r0), 0));
     i->type = ITLABEL;
+    clear_state();
     return i;
 }
 
@@ -115,6 +125,7 @@ static Instruction * iINDEXFETCH(SymReg 
     if(r0->set == 'S' && r1->set == 'S' && r2->set == 'I') {
         return MK_I("substr %s, %s, %s, 1", R3(r0, r1, r2));
     }
+    keyvec |= KEY_BIT(2);
     return MK_I("set %s, %s[%s]", R3(r0,r1,r2));
 }
 
@@ -127,6 +138,7 @@ static Instruction * iINDEXSET(SymReg * 
         MK_I("substr %s, %s, 1, %s", R3(r0, r1, r2));
     }
     else if (r0->set == 'P') {
+        keyvec |= KEY_BIT(1);
        MK_I("set %s[%s], %s", R3(r0,r1,r2));
     }
     else {
@@ -185,16 +197,16 @@ op_fullname(char * dest, const char * na
             *dest++ = 'i';
             *dest++ = 'c';
             continue;
-    }
+        }
         /* if one ever wants num keys, they go with 'S' */
-        if (args[i]->type & VTKEY) {
+        if (keyvec & KEY_BIT(i)) {
             *dest++ = 'k';
             if (args[i]->set == 'S' || args[i]->set == 'N' ||
                 args[i]->set == 'K') {
                 *dest++ = 'c';
                 continue;
-    }
-    }
+            }
+        }
         *dest++ = tolower(args[i]->set);
         if (args[i]->type & VTCONST)
             *dest++ = 'c';
@@ -307,7 +319,7 @@ Instruction * iANY(char * name, char *fm
            default:
                assert(0);
            };
-            if (regs[i]->type & VTKEY) {
+            if (keyvec & KEY_BIT(i)) {
                 len = strlen(format);
                 len -= 2;
                 format[len] = '\0';
@@ -321,22 +333,16 @@ Instruction * iANY(char * name, char *fm
        format[len] = '\0';
         if (fmt && *fmt)
             strcpy(format, fmt);
-        for (i = nargs; i < IMCC_MAX_REGS; i++)
-            regs[i] = 0;
+        memset(regs + nargs, 0, sizeof(*regs) * (IMCC_MAX_REGS - nargs));
 #if 1
         debug(1,"%s %s\t%s\n", name, format, fullname);
 #endif
         /* make the instruction */
         ins = emitb(_mk_instruction(name, format, regs, dirs));
-        /* fill iin oplib's info */
+        ins->keys |= keyvec;
+        /* fill in oplib's info */
         ins->opnum = op;
         ins->opsize = info->arg_count;
-        /* reset the VTKEY flag and remeber the info in ins->keys */
-        for (i = 0; ins->r[i]; i++)
-            if (ins->r[i]->type & VTKEY) {
-                ins->r[i]->type &= ~VTKEY;
-                ins->keys |= (1<<i);
-            }
         /* set up branch flags */
         if (info->jump) {
             if (!strcmp(name, "bsr") || !strcmp(name, "ret")) {
@@ -366,6 +372,7 @@ Instruction * iANY(char * name, char *fm
         fataly(EX_SOFTWARE, "iANY", line,"op not found '%s' (%s<%d>)\n",
                 fullname, name, nargs);
     }
+    clear_state();
     return NULL;
 }
 
@@ -415,12 +422,10 @@ pasmcode: pasmline
     | pasmcode pasmline
     ;
 
-pasmline: labels  pasm_inst '\n'  { $$ = 0; }
+pasmline: labels  pasm_inst '\n'        { $$ = 0; }
     ;
-pasm_inst: PARROT_OP                       { nargs = 0;
-                                        memset(regs, 0, sizeof(regs)); }
-       pasm_args                       { $$ = iANY($1,0,regs,1); free($1); }
-    | /* none */                               { $$ = 0;}
+pasm_inst: PARROT_OP pasm_args         { $$ = iANY($1,0,regs,1); free($1); }
+    | /* none */                        { $$ = 0;}
 
     ;
 pasm_args:
@@ -428,13 +433,14 @@ pasm_args:
     ;
 
 emit:
-      EMIT   pasmcode                    { $$ = 0 }
-       EOM '\n'                                { emit_flush(); clear_tables();$$=0 }
+      EMIT   pasmcode                   { $$ = 0; }
+       EOM '\n'                                { emit_flush(); clear_tables();$$=0; }
     ;
 
 nls:
     '\n'
     | nls '\n'
+    ;
 
 subs:  subs sub
     |   sub
@@ -447,8 +453,8 @@ sub:        sub_start statements RET
          emit_flush();
          clear_tables();
         }
-        | emit{ $$=0 }
-        | nls { $$=0 }
+        | emit{ $$=0; }
+        | nls { $$=0; }
     ;
 
 sub_start: SUB IDENTIFIER '\n'
@@ -477,7 +483,7 @@ label:  LABEL               { $$ = iLABEL(mk_address(
     ;
 
 instruction:
-       labels  labeled_inst '\n'  { $$ = $2; }
+       labels  labeled_inst '\n'       { $$ = $2; }
     ;
 labeled_inst:
        assignment
@@ -499,17 +505,16 @@ labeled_inst:
                                               R1(mk_address($2, U_add_once)));}
     |   GOTO IDENTIFIER                        { $$ = MK_I("branch",
                                               R1(mk_address($2, U_add_once)));}
+    |   BRANCH IDENTIFIER              { $$ = MK_I("branch",
+                                              R1(mk_address($2, U_add_once)));}
     |   INC var                                { $$ = MK_I("inc",R1($2)); }
     |   DEC var                                { $$ = MK_I("dec",R1($2)); }
     |   PRINT var                      { $$ = MK_I("print",R1($2)); }
     |   SAVEALL                                { $$ = MK_I("saveall" ,R0()); }
     |   RESTOREALL                     { $$ = MK_I("restoreall" ,R0()); }
     |   END                            { $$ = MK_I("end" ,R0()); }
-    |  PARROT_OP                               { nargs = 0;
-                                         memset(regs, 0, sizeof(regs));
-                                       }
-       vars                            { $$ = iANY($1,0,regs, 1); free($1); }
-    | /* none */                               { $$ = 0;}
+    |  PARROT_OP vars                   { $$ = iANY($1,0,regs, 1); free($1); }
+    | /* none */                        { $$ = 0;}
     ;
 
 type:
@@ -540,7 +545,7 @@ assignment:
     |  target '=' var '&' var          { $$ = MK_I("band", R3($1, $3, $5)); }
     |  target '=' var '|' var          { $$ = MK_I("bor", R3($1, $3, $5)); }
     |  target '=' var '~' var          { $$ = MK_I("bxor", R3($1, $3, $5)); }
-    |  target '=' var '[' keylist ']'{ $$ = iINDEXFETCH($1, $3, $5); }
+    |  target '=' var '[' keylist ']'   { $$ = iINDEXFETCH($1, $3, $5); }
     |  var '[' keylist ']' '=' var     { $$ = iINDEXSET($1, $3, $6); }
     |  target '=' NEW classname                { $$ = iNEW($1, $4); }
     |  target '=' DEFINED var  { $$ = MK_I("defined %s, %s",R2($1,$4)); }
@@ -586,29 +591,31 @@ _vars: _vars COMMA _var_or_i              { $$ = reg
     |  _var_or_i
     ;
 
-_var_or_i: var_or_i                     { regs[nargs++] = $1 }
+_var_or_i: var_or_i                     { regs[nargs++] = $1; }
     | lhs '[' keylist ']'               { regs[nargs++] = $1;
-                                          regs[nargs++] = $3; $$= $1; }
+                                          keyvec |= KEY_BIT(nargs);
+                                          regs[nargs++] = $3; $$ = $1; }
     ;
 var_or_i:
        IDENTIFIER                      { $$ = mk_address($1, U_add_once); }
     |  var
-    | MACRO                             { $$ = macro($1+1); free($1)}
+    | MACRO                             { $$ = macro($1+1); free($1); }
     ;
 
 var:   VAR
     |  rc
     ;
 
-keylist:                                { nkeys=0 }
+keylist:                                { nkeys=0; }
        _keylist                         { $$ = link_keys(nkeys, keys); }
     ;
 
 _keylist: key                            { keys[nkeys++] = $1; }
-     | _keylist ';' key                  { keys[nkeys++] = $3; $$ =  keys[0] }
+     | _keylist ';' key                  { keys[nkeys++] = $3; $$ =  keys[0]; }
     ;
 
 key:  var
+    ;
 
 rc:    reg
     |  const
@@ -851,7 +858,7 @@ int main(int argc, char * argv[])
     struct PackFile *pf;
 
     interpreter = Parrot_new();
-    Parrot_init(interpreter, stacktop);
+    Parrot_init(interpreter, &stacktop);
     pf = PackFile_new();
     interpreter->code = pf;
 #ifdef OPTEST
Index: symreg.c
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/symreg.c,v
retrieving revision 1.5
diff -p -u -r1.5 symreg.c
--- symreg.c    22 Sep 2002 17:38:27 -0000      1.5
+++ symreg.c    25 Sep 2002 03:07:55 -0000
@@ -96,23 +96,22 @@ SymReg * mk_address(char * name, int uni
     return _mk_address(hash, name, uniq);
 }
 
-/* link keys to a keys structure = SymReg VTKEY
+/* link keys to a keys structure = SymReg
  *
- * whe might have
+ * we might have
  *
- * what         op      type                    pbc.c:build_key()
- * --------------------------------------------------------------
- *  int const   _kic    VTCONST | VTKEY         no
- *  int reg     _ki     VTREG   | VTKEY         no
- *  str const   _kc     VTCONST | VTKEY         yes
- *  str reg     _kc     VTREG   | VTKEY         yes
+ * what         op      type        pbc.c:build_key()
+ * --------------------------------------------------
+ *  int const   _kic    VTCONST     no
+ *  int reg     _ki     VTREG       no
+ *  str const   _kc     VTCONST     yes
+ *  str reg     _kc     VTREG       yes
  *
- *  "key" ';' "key" _kc     VTKEY -> (list of above)   yes
+ *  "key" ';' "key" _kc           -> (list of above)   yes
  *  "key" ';' $I0   _kc     VTREGKEY ->(list of above)   yes
  *
- *  actually, the VTKEY flag lives only shortly, until the
- *  instruction is built. Then the information, which reg should
- *  be passed to build_key(), is in instruction.
+ *  The information about which reg should be passed to build_key() is
+ *  in the instruction.
  *
  *  A key containing a variable has a special flag VTREGKEY
  *  because this key must be considered for life analysis for
@@ -154,10 +153,8 @@ SymReg * link_keys(int nargs, SymReg * k
     if (nargs == 0)
         fatal(1, "link_keys", "hu? no keys\n");
     first = keys[0];
-    if (nargs == 1) {
-        first->type |= VTKEY;
+    if (nargs == 1)
         return first;
-    }
     *key_str = 0;
     /* first look, if we already have this exact key chain */
     for (i = 0; i < nargs && strlen(key_str)<200; i++) {
@@ -171,7 +168,7 @@ SymReg * link_keys(int nargs, SymReg * k
     keychain = calloc(1, sizeof(SymReg));
     if (!keychain)
         fatal(1, "link_keys", "Out of mem\n");
-    keychain->type = VTKEY | VTCONST;
+    keychain->type = VTCONST;
     key = keychain;
     for (i = 0; i < nargs; i++) {
         /* if any component is a variable, we need to track it in
Index: symreg.h
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/symreg.h,v
retrieving revision 1.5
diff -p -u -r1.5 symreg.h
--- symreg.h    22 Sep 2002 17:38:27 -0000      1.5
+++ symreg.h    25 Sep 2002 03:07:56 -0000
@@ -11,9 +11,8 @@ enum VARTYPE {                /* variable type can be 
     VTREG      = 1 << 1,       /* register */
     VTIDENTIFIER= 1 << 2,      /* identifier */
     VTADDRESS  = 1 << 3,       /* address */
-    VTKEY      = 1 << 4,       /* parrot key, one key*/
-    VTREGKEY   = 1 << 5,       /* parrot [key;key..], including registers */
-    VTPASM     = 1 << 7        /* parrot register, colored from .emit */
+    VTREGKEY   = 1 << 4,       /* parrot [key;key..], including registers */
+    VTPASM     = 1 << 6        /* parrot register, colored from .emit */
 };
 
 /* this VARTYPE needs register allocation and such */

Reply via email to