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++;
}