cvsuser     03/11/18 23:29:41

  Modified:    imcc     symreg.c symreg.h pcc.c
  Log:
  Fix several nasty bugs in argument handling for subroutines.
  Add a lot of trace as well. TRACE++
  Add a symbol dump routine.
  Overflow arguments now work correctly.
  
  Revision  Changes    Path
  1.41      +52 -3     parrot/imcc/symreg.c
  
  Index: symreg.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/symreg.c,v
  retrieving revision 1.40
  retrieving revision 1.41
  diff -u -w -r1.40 -r1.41
  --- symreg.c  17 Nov 2003 00:48:03 -0000      1.40
  +++ symreg.c  19 Nov 2003 07:29:40 -0000      1.41
  @@ -85,6 +85,31 @@
       return _mk_symreg(cur_unit->hash, name, t);
   }
   
  +/*
  + * Dump a SymReg to a printable format.
  + */
  +char *
  +symreg_to_str(SymReg * s)
  +{
  +    char buf[8192];
  +    int t = s->type;
  +    sprintf(buf, "symbol [%s]  set [%c]  color [%d]  type [",
  +                 s->name, s->set, s->color);
  +    if(t & VTCONST)      { strcat(buf, "VTCONST ");      }
  +    if(t & VTREG)        { strcat(buf, "VTREG ");        }
  +    if(t & VTIDENTIFIER) { strcat(buf, "VTIDENTIFIER "); }
  +    if(t & VTADDRESS)    { strcat(buf, "VTADDRESS ");    }
  +    if(t & VTREGKEY)     { strcat(buf, "VTREGKEY ");     }
  +    if(t & VTPASM)       { strcat(buf, "VTPASM ");       }
  +    if(t & VT_REGP)      { strcat(buf, "VT_REGP ");      }
  +    if(t & VT_CONSTP)    { strcat(buf, "VT_CONSTP ");    }
  +    if(t & VT_PCC_SUB)   { strcat(buf, "VT_PCC_SUB ");   }
  +    if(t & VT_FLATTEN)   { strcat(buf, "VT_FLATTEN ");   }
  +    strcat(buf, "]");
  +    return str_dup(buf);
  +}
  +
  +
   SymReg *
   mk_temp_reg(int t)
   {
  @@ -102,14 +127,38 @@
       return r;
   }
   
  +/*
  + * Add make a pointer to a register or constant
  + * and add to the subroutine structure arg list.
  + * If arg is a pointer, deref the symbol first.
  + */
   void
   add_pcc_arg(SymReg *r, SymReg * arg)
   {
       int n = r->pcc_sub->nargs;
       r->pcc_sub->args = realloc(r->pcc_sub->args, (n + 1) * sizeof(SymReg *));
  +    if(arg->type & (VTCONST)) {
  +        r->pcc_sub->args[n] = dup_sym(arg);
  +        r->pcc_sub->args[n]->reg = arg;
  +        r->pcc_sub->args[n]->type = VT_CONSTP;
  +    }
  +    else if(arg->type & (VTREGISTER)) {
       r->pcc_sub->args[n] = dup_sym(arg);
       r->pcc_sub->args[n]->reg = arg;
       r->pcc_sub->args[n]->type = VT_REGP;
  +    }
  +    /* If this is already a pointer, dup the symbol
  +     * that it point to, not the pointer itself.
  +     */
  +    else if(arg->type & (VT_CONSTP)) {
  +        r->pcc_sub->args[n] = dup_sym(arg->reg);
  +        r->pcc_sub->args[n]->reg = arg->reg;
  +        r->pcc_sub->args[n]->type = VT_CONSTP;
  +    }
  +    else
  +        fataly(EX_SOFTWARE, sourcefile, line,
  +                "sub argument is not a valid arg (const, constp or reg) '%s'\n%s",
  +                     arg->name, symreg_to_str(arg));
       r->pcc_sub->nargs++;
   }
   
  
  
  
  1.36      +1 -0      parrot/imcc/symreg.h
  
  Index: symreg.h
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/symreg.h,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -w -r1.35 -r1.36
  --- symreg.h  13 Nov 2003 07:03:23 -0000      1.35
  +++ symreg.h  19 Nov 2003 07:29:40 -0000      1.36
  @@ -97,6 +97,7 @@
   SymReg * mk_const_ident(char *, int t, SymReg *, int);
   SymReg * mk_address(char *, int uniq);
   SymReg * mk_pcc_sub(char *, int proto);
  +char * symreg_to_str(SymReg *);    
   void add_pcc_arg(SymReg *r, SymReg * arg);
   void add_pcc_sub(SymReg *r, SymReg * arg);
   void add_pcc_cc(SymReg *r, SymReg * arg);
  
  
  
  1.34      +47 -12    parrot/imcc/pcc.c
  
  Index: pcc.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/pcc.c,v
  retrieving revision 1.33
  retrieving revision 1.34
  diff -u -w -r1.33 -r1.34
  --- pcc.c     17 Nov 2003 00:48:03 -0000      1.33
  +++ pcc.c     19 Nov 2003 07:29:40 -0000      1.34
  @@ -91,7 +91,7 @@
       /*
        * generate check subroutine if not done yet
        */
  -    what = mk_symreg(str_dup("#what"), 'I');
  +    what = mk_symreg(str_dup("_#what"), 'I');
       strcpy(buf, "_#check_params");
       check_sub = _get_sym(ghash, buf);
       if (!check_sub) {
  @@ -103,7 +103,7 @@
            * first time check: amount of params, elements in P3
            * we can globber I0
            */
  -        err_nparam = mk_address(str_dup("#check_err_nparam"), U_add_uniq_label);
  +        err_nparam = mk_address(str_dup("_#check_err_nparam"), U_add_uniq_label);
           if (p3) {
               if (!i0)
                   i0 = mk_pasm_reg(str_dup("I0"));
  @@ -147,7 +147,7 @@
           regs[1] = p3;
           regs[2] = mk_const(str_dup("0"), 'I');
           INS(interpreter, unit, "typeof", NULL, regs, 3, 4, 1);
  -        err_type = mk_address(str_dup("#check_err_type"), U_add_uniq_label);
  +        err_type = mk_address(str_dup("_#check_err_type"), U_add_uniq_label);
           regs[0] = i0;
           regs[1] = what;
           regs[2] = err_type;
  @@ -241,7 +241,7 @@
        /* subroutine can handle both */
        i0 = mk_pasm_reg(str_dup("I0"));
        regs[0] = i0;
  -     sprintf(buf, "#sub_%s_p1", sub->name);
  +     sprintf(buf, "_#sub_%s_p1", sub->name);
           regs[1] = label1 = mk_address(str_dup(buf), U_add_uniq_label);
        ins = insINS(interpreter, unit, ins, "if", regs, 2);
   
  @@ -257,8 +257,18 @@
                    (arg->set == 'P' && next[2] < 16)) {
                for (j = 0; j < 4; j++) {
                    if (arg->set == types[j]) {
  -                     if (next[j] == 16)
  +                     if (next[j] == 16) {
  +#if IMC_TRACE
  +                            PIO_eprintf(NULL, "expand_sub nextreg[%d]: switching to 
arg overflow\n", next[j]);
  +#endif
                            goto overflow;
  +                        } 
  +                        else if(next[j] >= 17) {
  +                            PIO_eprintf(NULL,
  +                                "imcc internal error: next reg(%d) > 16 for PCC 
convention\n",
  +                                    next[j]);
  +                            abort();
  +                        }
                        if (arg->color == next[j]) {
                            next[j]++;
                            break;
  @@ -324,7 +334,7 @@
           if (ps != pe) {
               if (!proto) {
                   /* branch to the end */
  -                sprintf(buf, "#sub_%s_p0", sub->name);
  +                sprintf(buf, "_#sub_%s_p0", sub->name);
                   regs[0] = label2 = mk_address(str_dup(buf), U_add_uniq_label);
                   ins = insINS(interpreter, unit, ins, "branch", regs, 1);
                   tmp = INS_LABEL(unit, label1, 0);
  @@ -647,13 +657,13 @@
           ins = insINS(interpreter, unit, ins, "set", regs, 2);
       }
       lin = ins->line;
  -    sprintf(buf, "#arg_loop_%d_%d", lin, i);
  +    sprintf(buf, "_#arg_loop_%d_%d", lin, i);
       loop = mk_address(str_dup(buf), U_add_uniq_label);
  -    sprintf(buf, "#next_arg_%d_%d", lin, i);
  +    sprintf(buf, "_#next_arg_%d_%d", lin, i);
       next = mk_address(str_dup(buf), U_add_uniq_label);
  -    sprintf(buf, "#over_flow_%d_1_%d", lin, i);
  +    sprintf(buf, "_#over_flow_%d_1_%d", lin, i);
       over1 = mk_address(str_dup(buf), U_add_uniq_label);
  -    sprintf(buf, "#over_flow_%d_%d", lin, i);
  +    sprintf(buf, "_#over_flow_%d_%d", lin, i);
       over = mk_address(str_dup(buf), U_add_uniq_label);
   
       if (arg->type & VT_FLATTEN) {
  @@ -723,6 +733,16 @@
   /*
    * Expand a PCC subroutine call (IMC) into its PASM instructions
    * This is the nuts and bolts of Perl6/Parrot routine call style
  + * 
  + * XXX FIXME: VTCONST and VT_CONSTP, VTREG and VT_REGP are
  + * mixed and matched here. There should only be pointer types
  + * in sub->args. Trim out non-pointer type checks and verify
  + * correctness. (see symreg.c: add_pcc_arg())
  + * This potentially applies to much of the flow analysis code
  + * that is currently lazy and checks for too many things, which
  + * is fine but it was the source of a really nasty bug when add_pcc_arg()
  + * was not setting arg->type correctly. 
  + * And THAT is the reason for all this nasty TRACE code. -Mel
    */
   void
   expand_pcc_sub_call(Parrot_Interp interp, IMC_Unit * unit, Instruction *ins)
  @@ -774,8 +794,15 @@
       /*
        * insert arguments
        */
  -#if IMC_TRACE
  +#if IMC_TRACE_HIGH
       PIO_eprintf(NULL, "expand_pcc_sub_call: nargs = %d\n", sub->pcc_sub->nargs);
  +    PIO_eprintf(NULL, "args (");
  +    for(i = 0; i < sub->pcc_sub->nargs; i++) {
  +       arg = sub->pcc_sub->args[i];
  +       PIO_eprintf(NULL, " (%c%s)%s", arg->set,
  +                          (arg->type & (VTCONST|VT_CONSTP)) ? "c":"", arg->name);
  +    }
  +    PIO_eprintf(NULL, ")\n");
   #endif
       n = sub->pcc_sub->nargs;
       for (i = 0; i < n; i++) {
  @@ -783,6 +810,10 @@
            * if prototyped, first 11 I,S,N go into regs
            */
           arg = sub->pcc_sub->args[i];
  +#if IMC_TRACE_HIGH
  +        PIO_eprintf(NULL, "    arg(%c%s)%s\n", arg->set,
  +                          (arg->type & (VTCONST|VT_CONSTP)) ? "c":"", arg->name);
  +#endif
           arg_reg = arg->reg;
           if (sub->pcc_sub->prototyped ||
                   (arg->set == 'P' && next[2] < 16)) {
  @@ -843,8 +874,12 @@
               }
               if (flatten || (arg_reg->type & VT_FLATTEN))
                   goto flatten;
  +#if IMC_TRACE_HIGH
  +            PIO_eprintf(NULL, "expand_pcc_sub_call: overflow (%c%s)%s\n", arg->set,
  +                        (arg->type & (VTCONST|VT_CONSTP)) ? "c":"",  arg->name);
  +#endif
               regs[0] = p3;
  -            regs[1] = arg;
  +            regs[1] = arg_reg;
               ins = insINS(interp, unit, ins, "push", regs, 2);
               n_p3++;
           }
  
  
  

Reply via email to