# 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 */