X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=op.c;h=282027a7dd0510418b881e013c023dc7d0faa0d6;hb=140554665c10264faba3f60819106d3921665365;hp=052d1c13fe43d98e9dba5ac418d1cc967762abbd;hpb=7e363e51b620b0068542ae9460f4c9c09bf7914e;p=p5sagit%2Fp5-mst-13.2.git diff --git a/op.c b/op.c index 052d1c1..282027a 100644 --- a/op.c +++ b/op.c @@ -26,7 +26,7 @@ #define OP_REFCNT_LOCK NOOP #define OP_REFCNT_UNLOCK NOOP #define OpREFCNT_set(o,n) NOOP -#define OpREFCNT_dec(o) 0 +#define OpREFCNT_dec(o) ((o)->op_targ--) #ifdef PL_OP_SLAB_ALLOC #define SLAB_SIZE 8192 @@ -448,7 +448,7 @@ Perl_pad_alloc(pTHX_ I32 optype, U32 tmptype) (sv = names[PL_padix]) && sv != &PL_sv_undef) continue; sv = *av_fetch(PL_comppad, PL_padix, TRUE); - if (!(SvFLAGS(sv) & (SVs_PADTMP|SVs_PADMY))) + if (!(SvFLAGS(sv) & (SVs_PADTMP|SVs_PADMY)) && !IS_PADGV(sv)) break; } retval = PL_padix; @@ -475,13 +475,13 @@ Perl_pad_sv(pTHX_ PADOFFSET po) dTHR; #ifdef USE_THREADS DEBUG_X(PerlIO_printf(Perl_debug_log, - "0x%"UVxf" Pad 0x%"UVxf" sv %d\n", - PTR2UV(thr), PTR2UV(PL_curpad), po)); + "0x%"UVxf" Pad 0x%"UVxf" sv %"IVdf"\n", + PTR2UV(thr), PTR2UV(PL_curpad), (IV)po)); #else if (!po) Perl_croak(aTHX_ "panic: pad_sv po"); - DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%"UVxf" sv %d\n", - PTR2UV(PL_curpad), po)); + DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%"UVxf" sv %"IVdf"\n", + PTR2UV(PL_curpad), (IV)po)); #endif /* USE_THREADS */ return PL_curpad[po]; /* eventually we'll turn this into a macro */ } @@ -498,11 +498,11 @@ Perl_pad_free(pTHX_ PADOFFSET po) Perl_croak(aTHX_ "panic: pad_free po"); #ifdef USE_THREADS DEBUG_X(PerlIO_printf(Perl_debug_log, - "0x%"UVxf" Pad 0x%"UVxf" free %d\n", - PTR2UV(thr), PTR2UV(PL_curpad), po)); + "0x%"UVxf" Pad 0x%"UVxf" free %"IVd"\n", + PTR2UV(thr), PTR2UV(PL_curpad), (IV)po)); #else - DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%"UVxf" free %d\n", - PTR2UV(PL_curpad), po)); + DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%"UVxf" free %"IVdf"\n", + PTR2UV(PL_curpad), (IV)po)); #endif /* USE_THREADS */ if (PL_curpad[po] && PL_curpad[po] != &PL_sv_undef) SvPADTMP_off(PL_curpad[po]); @@ -520,11 +520,11 @@ Perl_pad_swipe(pTHX_ PADOFFSET po) Perl_croak(aTHX_ "panic: pad_swipe po"); #ifdef USE_THREADS DEBUG_X(PerlIO_printf(Perl_debug_log, - "0x%"UVxf" Pad 0x%"UVxf" swipe %d\n", - PTR2UV(thr), PTR2UV(PL_curpad), po)); + "0x%"UVxf" Pad 0x%"UVxf" swipe %"IVdf"\n", + PTR2UV(thr), PTR2UV(PL_curpad), (IV)po)); #else - DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%"UVxf" swipe %d\n", - PTR2UV(PL_curpad), po)); + DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad 0x%"UVxf" swipe %"IVdf"\n", + PTR2UV(PL_curpad), (IV)po)); #endif /* USE_THREADS */ SvPADTMP_off(PL_curpad[po]); PL_curpad[po] = NEWSV(1107,0); @@ -659,6 +659,7 @@ Perl_op_free(pTHX_ OP *o) OP_REFCNT_UNLOCK; return; } + o->op_targ = 0; /* XXXXXX */ OP_REFCNT_UNLOCK; break; default: @@ -718,14 +719,18 @@ S_op_clear(pTHX_ OP *o) case OP_GV: case OP_AELEMFAST: #ifdef USE_ITHREADS - if (PL_curpad) { - SvREFCNT_dec(cGVOPo); - PL_curpad[cPADOPo->op_padix] = Nullsv; + if (cPADOPo->op_padix > 0) { + if (PL_curpad) { + GV *gv = cGVOPo; + pad_swipe(cPADOPo->op_padix); + /* No GvIN_PAD_off(gv) here, because other references may still + * exist on the pad */ + SvREFCNT_dec(gv); + } + cPADOPo->op_padix = 0; } - pad_free(cPADOPo->op_padix); - cPADOPo->op_padix = 0; #else - SvREFCNT_dec(cGVOPo); + SvREFCNT_dec(cSVOPo->op_sv); cSVOPo->op_sv = Nullsv; #endif break; @@ -752,25 +757,48 @@ S_op_clear(pTHX_ OP *o) break; case OP_SUBST: op_free(cPMOPo->op_pmreplroot); - cPMOPo->op_pmreplroot = Nullop; - /* FALL THROUGH */ + goto clear_pmop; case OP_PUSHRE: +#ifdef USE_ITHREADS + if ((PADOFFSET)cPMOPo->op_pmreplroot) { + if (PL_curpad) { + GV *gv = (GV*)PL_curpad[(PADOFFSET)cPMOPo->op_pmreplroot]; + pad_swipe((PADOFFSET)cPMOPo->op_pmreplroot); + /* No GvIN_PAD_off(gv) here, because other references may still + * exist on the pad */ + SvREFCNT_dec(gv); + } + } +#else + SvREFCNT_dec((SV*)cPMOPo->op_pmreplroot); +#endif + /* FALL THROUGH */ case OP_MATCH: case OP_QR: +clear_pmop: + cPMOPo->op_pmreplroot = Nullop; ReREFCNT_dec(cPMOPo->op_pmregexp); cPMOPo->op_pmregexp = (REGEXP*)NULL; break; } - if (o->op_targ > 0) + if (o->op_targ > 0) { pad_free(o->op_targ); + o->op_targ = 0; + } } STATIC void S_cop_free(pTHX_ COP* cop) { Safefree(cop->cop_label); +#ifdef USE_ITHREADS + Safefree(CopFILE(cop)); /* XXXXX share in a pvtable? */ + Safefree(CopSTASHPV(cop)); /* XXXXX share in a pvtable? */ +#else + /* NOTE: COP.cop_stash is not refcounted */ SvREFCNT_dec(CopFILEGV(cop)); +#endif if (! specialWARN(cop->cop_warnings)) SvREFCNT_dec(cop->cop_warnings); } @@ -831,12 +859,12 @@ S_scalarboolean(pTHX_ OP *o) if (o->op_type == OP_SASSIGN && cBINOPo->op_first->op_type == OP_CONST) { dTHR; if (ckWARN(WARN_SYNTAX)) { - line_t oldline = PL_curcop->cop_line; + line_t oldline = CopLINE(PL_curcop); if (PL_copline != NOLINE) - PL_curcop->cop_line = PL_copline; + CopLINE_set(PL_curcop, PL_copline); Perl_warner(aTHX_ WARN_SYNTAX, "Found = in conditional, should be =="); - PL_curcop->cop_line = oldline; + CopLINE_set(PL_curcop, oldline); } } return scalar(o); @@ -1298,7 +1326,7 @@ Perl_mod(pTHX_ OP *o, I32 type) } else { /* lvalue subroutine call */ o->op_private |= OPpLVAL_INTRO; - if (type == OP_GREPSTART || type == OP_ENTERSUB) { + if (type == OP_GREPSTART || type == OP_ENTERSUB || type == OP_REFGEN) { /* Backward compatibility mode: */ o->op_private |= OPpENTERSUB_INARGS; break; @@ -2807,8 +2835,8 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl) OP *curop; if (pm->op_pmflags & PMf_EVAL) { curop = 0; - if (PL_curcop->cop_line < PL_multi_end) - PL_curcop->cop_line = PL_multi_end; + if (CopLINE(PL_curcop) < PL_multi_end) + CopLINE_set(PL_curcop, PL_multi_end); } #ifdef USE_THREADS else if (repl->op_type == OP_THREADSV @@ -2935,6 +2963,7 @@ Perl_newGVOP(pTHX_ I32 type, I32 flags, GV *gv) { dTHR; #ifdef USE_ITHREADS + GvIN_PAD_on(gv); return newPADOP(type, flags, SvREFCNT_inc(gv)); #else return newSVOP(type, flags, SvREFCNT_inc(gv)); @@ -3229,7 +3258,13 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right) { tmpop = ((UNOP*)left)->op_first; if (tmpop->op_type == OP_GV && !pm->op_pmreplroot) { - pm->op_pmreplroot = (OP*)((SVOP*)tmpop)->op_sv; /* XXXXXX */ +#ifdef USE_ITHREADS + pm->op_pmreplroot = (OP*)cPADOPx(tmpop)->op_padix; + cPADOPx(tmpop)->op_padix = 0; /* steal it */ +#else + pm->op_pmreplroot = (OP*)cSVOPx(tmpop)->op_sv; + cSVOPx(tmpop)->op_sv = Nullsv; /* steal it */ +#endif pm->op_pmflags |= PMf_ONCE; tmpop = cUNOPo->op_first; /* to list (nulled) */ tmpop = ((UNOP*)tmpop)->op_first; /* to pushmark */ @@ -3282,7 +3317,7 @@ Perl_newSTATEOP(pTHX_ I32 flags, char *label, OP *o) register COP *cop; NewOp(1101, cop, 1, COP); - if (PERLDB_LINE && PL_curcop->cop_line && PL_curstash != PL_debstash) { + if (PERLDB_LINE && CopLINE(PL_curcop) && PL_curstash != PL_debstash) { cop->op_type = OP_DBSTATE; cop->op_ppaddr = PL_ppaddr[ OP_DBSTATE ]; } @@ -3311,20 +3346,29 @@ Perl_newSTATEOP(pTHX_ I32 flags, char *label, OP *o) if (PL_copline == NOLINE) - cop->cop_line = PL_curcop->cop_line; + CopLINE_set(cop, CopLINE(PL_curcop)); else { - cop->cop_line = PL_copline; + CopLINE_set(cop, PL_copline); PL_copline = NOLINE; } +#ifdef USE_ITHREADS + CopFILE_set(cop, CopFILE(PL_curcop)); /* XXXXX share in a pvtable? */ +#else CopFILEGV_set(cop, (GV*)SvREFCNT_inc(CopFILEGV(PL_curcop))); - cop->cop_stash = PL_curstash; +#endif + CopSTASH_set(cop, PL_curstash); if (PERLDB_LINE && PL_curstash != PL_debstash) { SV **svp = av_fetch(CopFILEAV(PL_curcop), (I32)CopLINE(cop), FALSE); if (svp && *svp != &PL_sv_undef && !SvIOK(*svp)) { (void)SvIOK_on(*svp); SvIVX(*svp) = 1; +#ifndef USE_ITHREADS + /* XXX This nameless kludge interferes with cloning SVs. :-( + * What's more, it seems entirely redundant when considering + * PL_DBsingle exists to do the same thing */ SvSTASH(*svp) = (HV*)cop; +#endif } } @@ -3436,14 +3480,14 @@ S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp) break; } if (warnop) { - line_t oldline = PL_curcop->cop_line; - PL_curcop->cop_line = PL_copline; + line_t oldline = CopLINE(PL_curcop); + CopLINE_set(PL_curcop, PL_copline); Perl_warner(aTHX_ WARN_UNSAFE, "Value of %s%s can be \"0\"; test with defined()", PL_op_desc[warnop], ((warnop == OP_READLINE || warnop == OP_GLOB) ? " construct" : "() operator")); - PL_curcop->cop_line = oldline; + CopLINE_set(PL_curcop, oldline); } } @@ -3739,11 +3783,13 @@ Perl_newFOROP(pTHX_ I32 flags,char *label,line_t forline,OP *sv,OP *expr,OP *blo } else if (sv->op_type == OP_PADSV) { /* private variable */ padoff = sv->op_targ; + sv->op_targ = 0; op_free(sv); sv = Nullop; } else if (sv->op_type == OP_THREADSV) { /* per-thread variable */ padoff = sv->op_targ; + sv->op_targ = 0; iterflags |= OPf_SPECIAL; op_free(sv); sv = Nullop; @@ -3898,9 +3944,9 @@ Perl_cv_undef(pTHX_ CV *cv) } } -#ifdef DEBUG_CLOSURES +#ifdef DEBUGGING STATIC void -cv_dump(CV *cv) +S_cv_dump(pTHX_ CV *cv) { CV *outside = CvOUTSIDE(cv); AV* padlist = CvPADLIST(cv); @@ -3943,7 +3989,7 @@ cv_dump(CV *cv) SvIVX(pname[ix])); } } -#endif /* DEBUG_CLOSURES */ +#endif /* DEBUGGING */ STATIC CV * S_cv_clone2(pTHX_ CV *proto, CV *outside) @@ -3980,6 +4026,7 @@ S_cv_clone2(pTHX_ CV *proto, CV *outside) MUTEX_INIT(CvMUTEXP(cv)); CvOWNER(cv) = 0; #endif /* USE_THREADS */ + CvFILE(cv) = CvFILE(proto); CvGV(cv) = (GV*)SvREFCNT_inc(CvGV(proto)); CvSTASH(cv) = CvSTASH(proto); CvROOT(cv) = CvROOT(proto); @@ -4038,6 +4085,9 @@ S_cv_clone2(pTHX_ CV *proto, CV *outside) PL_curpad[ix] = sv; } } + else if (IS_PADGV(ppad[ix])) { + PL_curpad[ix] = SvREFCNT_inc(ppad[ix]); + } else { SV* sv = NEWSV(0,0); SvPADTMP_on(sv); @@ -4242,12 +4292,12 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block) && HvNAME(GvSTASH(CvGV(cv))) && strEQ(HvNAME(GvSTASH(CvGV(cv))), "autouse"))) { - line_t oldline = PL_curcop->cop_line; - PL_curcop->cop_line = PL_copline; + line_t oldline = CopLINE(PL_curcop); + CopLINE_set(PL_curcop, PL_copline); Perl_warner(aTHX_ WARN_REDEFINE, const_sv ? "Constant subroutine %s redefined" : "Subroutine %s redefined", name); - PL_curcop->cop_line = oldline; + CopLINE_set(PL_curcop, oldline); } SvREFCNT_dec(cv); cv = Nullcv; @@ -4305,6 +4355,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block) } } CvGV(cv) = (GV*)SvREFCNT_inc(gv); + CvFILE(cv) = CopFILE(PL_curcop); CvSTASH(cv) = PL_curstash; #ifdef USE_THREADS CvOWNER(cv) = 0; @@ -4351,7 +4402,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block) for (ix = AvFILLp(PL_comppad); ix > 0; ix--) { SV *namesv; - if (SvIMMORTAL(PL_curpad[ix])) + if (SvIMMORTAL(PL_curpad[ix]) || IS_PADGV(PL_curpad[ix])) continue; /* * The only things that a clonable function needs in its @@ -4375,7 +4426,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block) AvFLAGS(av) = AVf_REIFY; for (ix = AvFILLp(PL_comppad); ix > 0; ix--) { - if (SvIMMORTAL(PL_curpad[ix])) + if (SvIMMORTAL(PL_curpad[ix]) || IS_PADGV(PL_curpad[ix])) continue; if (!SvPADMY(PL_curpad[ix])) SvPADTMP_on(PL_curpad[ix]); @@ -4427,8 +4478,8 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block) if (strEQ(s, "BEGIN")) { I32 oldscope = PL_scopestack_ix; ENTER; - SAVESPTR(CopFILEGV(&PL_compiling)); - SAVEI16(PL_compiling.cop_line); + SAVECOPFILE(&PL_compiling); + SAVECOPLINE(&PL_compiling); save_svref(&PL_rs); sv_setsv(PL_rs, PL_nrs); @@ -4476,15 +4527,24 @@ void Perl_newCONSTSUB(pTHX_ HV *stash, char *name, SV *sv) { dTHR; - U32 oldhints = PL_hints; - HV *old_cop_stash = PL_curcop->cop_stash; - HV *old_curstash = PL_curstash; - line_t oldline = PL_curcop->cop_line; - PL_curcop->cop_line = PL_copline; + ENTER; + SAVECOPLINE(PL_curcop); + SAVEHINTS(); + + CopLINE_set(PL_curcop, PL_copline); PL_hints &= ~HINT_BLOCK_SCOPE; - if(stash) - PL_curstash = PL_curcop->cop_stash = stash; + + if (stash) { + SAVESPTR(PL_curstash); + SAVECOPSTASH(PL_curcop); + PL_curstash = stash; +#ifdef USE_ITHREADS + CopSTASHPV(PL_curcop) = stash ? HvNAME(stash) : Nullch; +#else + CopSTASH(PL_curcop) = stash; +#endif + } newATTRSUB( start_subparse(FALSE, 0), @@ -4494,10 +4554,7 @@ Perl_newCONSTSUB(pTHX_ HV *stash, char *name, SV *sv) newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv)) ); - PL_hints = oldhints; - PL_curcop->cop_stash = old_cop_stash; - PL_curstash = old_curstash; - PL_curcop->cop_line = oldline; + LEAVE; } CV * @@ -4518,11 +4575,11 @@ Perl_newXS(pTHX_ char *name, XSUBADDR_t subaddr, char *filename) if (ckWARN(WARN_REDEFINE) && !(CvGV(cv) && GvSTASH(CvGV(cv)) && HvNAME(GvSTASH(CvGV(cv))) && strEQ(HvNAME(GvSTASH(CvGV(cv))), "autouse"))) { - line_t oldline = PL_curcop->cop_line; + line_t oldline = CopLINE(PL_curcop); if (PL_copline != NOLINE) - PL_curcop->cop_line = PL_copline; + CopLINE_set(PL_curcop, PL_copline); Perl_warner(aTHX_ WARN_REDEFINE, "Subroutine %s redefined",name); - PL_curcop->cop_line = oldline; + CopLINE_set(PL_curcop, oldline); } SvREFCNT_dec(cv); cv = 0; @@ -4547,6 +4604,8 @@ Perl_newXS(pTHX_ char *name, XSUBADDR_t subaddr, char *filename) CvOWNER(cv) = 0; #endif /* USE_THREADS */ (void)gv_fetchfile(filename); + CvFILE(cv) = filename; /* NOTE: not copied, as it is expected to be + an external constant string */ CvXSUB(cv) = subaddr; if (name) { @@ -4606,17 +4665,18 @@ Perl_newFORM(pTHX_ I32 floor, OP *o, OP *block) GvMULTI_on(gv); if (cv = GvFORM(gv)) { if (ckWARN(WARN_REDEFINE)) { - line_t oldline = PL_curcop->cop_line; + line_t oldline = CopLINE(PL_curcop); - PL_curcop->cop_line = PL_copline; + CopLINE_set(PL_curcop, PL_copline); Perl_warner(aTHX_ WARN_REDEFINE, "Format %s redefined",name); - PL_curcop->cop_line = oldline; + CopLINE_set(PL_curcop, oldline); } SvREFCNT_dec(cv); } cv = PL_compcv; GvFORM(gv) = cv; CvGV(cv) = (GV*)SvREFCNT_inc(gv); + CvFILE(cv) = CopFILE(PL_curcop); for (ix = AvFILLp(PL_comppad); ix > 0; ix--) { if (!SvPADMY(PL_curpad[ix]) && !SvIMMORTAL(PL_curpad[ix])) @@ -5046,6 +5106,7 @@ Perl_ck_rvconst(pTHX_ register OP *o) #ifdef USE_ITHREADS /* XXXXXX hack: dependence on sizeof(PADOP) <= sizeof(SVOP) */ kPADOP->op_padix = pad_alloc(OP_GV, SVs_PADTMP); + GvIN_PAD_on(gv); PL_curpad[kPADOP->op_padix] = SvREFCNT_inc(gv); #else kid->op_sv = SvREFCNT_inc(gv); @@ -5062,10 +5123,10 @@ Perl_ck_ftst(pTHX_ OP *o) dTHR; I32 type = o->op_type; - if (o->op_flags & OPf_REF) - return o; - - if (o->op_flags & OPf_KIDS && cUNOPo->op_first->op_type != OP_STUB) { + if (o->op_flags & OPf_REF) { + /* nothing */ + } + else if (o->op_flags & OPf_KIDS && cUNOPo->op_first->op_type != OP_STUB) { SVOP *kid = (SVOP*)cUNOPo->op_first; if (kid->op_type == OP_CONST && (kid->op_private & OPpCONST_BARE)) { @@ -5073,17 +5134,24 @@ Perl_ck_ftst(pTHX_ OP *o) OP *newop = newGVOP(type, OPf_REF, gv_fetchpv(SvPVx(kid->op_sv, n_a), TRUE, SVt_PVIO)); op_free(o); - return newop; + o = newop; } } else { op_free(o); if (type == OP_FTTTY) - return newGVOP(type, OPf_REF, gv_fetchpv("main::STDIN", TRUE, + o = newGVOP(type, OPf_REF, gv_fetchpv("main::STDIN", TRUE, SVt_PVIO)); else - return newUNOP(type, 0, newDEFSVOP()); + o = newUNOP(type, 0, newDEFSVOP()); + } +#ifdef USE_LOCALE + if (type == OP_FTTEXT || type == OP_FTBINARY) { + o->op_private = 0; + if (PL_hints & HINT_LOCALE) + o->op_private |= OPpLOCALE; } +#endif return o; } @@ -5515,6 +5583,7 @@ Perl_ck_sassign(pTHX_ OP *o) return o; } kid->op_targ = kkid->op_targ; + kkid->op_targ = 0; /* Now we do not need PADSV and SASSIGN. */ kid->op_sibling = o->op_sibling; /* NULL */ cLISTOPo->op_first = NULL; @@ -6099,11 +6168,13 @@ Perl_peep(pTHX_ register OP *o) && (((LISTOP*)o)->op_first->op_sibling->op_type == OP_PADSV) && (((LISTOP*)o)->op_first->op_sibling->op_targ - == o->op_next->op_targ))) { + == o->op_next->op_targ))) + { goto ignore_optimization; } else { o->op_targ = o->op_next->op_targ; + o->op_next->op_targ = 0; o->op_private |= OPpTARGET_MY; } } @@ -6223,12 +6294,12 @@ Perl_peep(pTHX_ register OP *o) o->op_next->op_sibling->op_type != OP_EXIT && o->op_next->op_sibling->op_type != OP_WARN && o->op_next->op_sibling->op_type != OP_DIE) { - line_t oldline = PL_curcop->cop_line; + line_t oldline = CopLINE(PL_curcop); - PL_curcop->cop_line = ((COP*)o->op_next)->cop_line; + CopLINE_set(PL_curcop, CopLINE((COP*)o->op_next)); Perl_warner(aTHX_ WARN_SYNTAX, "Statement unlikely to be reached"); Perl_warner(aTHX_ WARN_SYNTAX, "(Maybe you meant system() when you said exec()?)\n"); - PL_curcop->cop_line = oldline; + CopLINE_set(PL_curcop, oldline); } } break;