{
djSP;
AV *av = GvAV((GV*)cSVOP->op_sv);
- SV** svp = av_fetch(av, op->op_private, op->op_flags & OPf_MOD);
- PUSHs(svp ? *svp : &sv_undef);
+ U32 lval = op->op_flags & OPf_MOD;
+ SV** svp = av_fetch(av, op->op_private, lval);
+ SV *sv = (svp ? *svp : &sv_undef);
+ EXTEND(SP, 1);
+ if (!lval && SvGMAGICAL(sv)) /* see note in pp_helem() */
+ sv = sv_mortalcopy(sv);
+ PUSHs(sv);
RETURN;
}
}
else {
dTARGET;
- /* This bit is OK even when hv is really an AV */
+ if (SvTYPE(hv) == SVt_PVAV)
+ hv = avhv_keys((AV*)hv);
if (HvFILL(hv))
sv_setpvf(TARG, "%ld/%ld",
(long)HvFILL(hv), (long)HvMAX(hv) + 1);
hv_clear(hash);
while (relem < lastrelem) { /* gobble up all the rest */
- STRLEN len;
HE *didstore;
if (*relem)
sv = *(relem++);
}
TAINT_NOT;
}
- if (relem == lastrelem && dowarn)
- warn("Odd number of elements in hash list");
+ if (relem == lastrelem) {
+ if (*relem) {
+ HE *didstore;
+ if (dowarn) {
+ if (relem == firstrelem &&
+ SvROK(*relem) &&
+ ( SvTYPE(SvRV(*relem)) == SVt_PVAV ||
+ SvTYPE(SvRV(*relem)) == SVt_PVHV ) )
+ warn("Reference found where even-sized list expected");
+ else
+ warn("Odd number of elements in hash assignment");
+ }
+ tmpstr = NEWSV(29,0);
+ didstore = hv_store_ent(hash,*relem,tmpstr,0);
+ if (magic) {
+ if (SvSMAGICAL(tmpstr))
+ mg_set(tmpstr);
+ if (!didstore)
+ SvREFCNT_dec(tmpstr);
+ }
+ TAINT_NOT;
+ }
+ relem++;
+ }
}
break;
default:
if (SvTHINKFIRST(sv)) {
if (SvREADONLY(sv) && curcop != &compiling) {
- if (sv != &sv_undef && sv != &sv_yes && sv != &sv_no)
+ if (!SvIMMORTAL(sv))
DIE(no_modify);
if (relem <= lastrelem)
relem++;
I32 global;
I32 safebase;
char *truebase;
- register REGEXP *prx = pm->op_pmregexp;
+ register REGEXP *rx = pm->op_pmregexp;
+ bool rxtainted;
I32 gimme = GIMME;
STRLEN len;
I32 minmatch = 0;
strend = s + len;
if (!s)
DIE("panic: do_match");
+ rxtainted = ((pm->op_pmdynflags & PMdf_TAINTED) ||
+ (tainted && (pm->op_pmflags & PMf_RETAINT)));
TAINT_NOT;
- if (pm->op_pmflags & PMf_USED) {
+ if (pm->op_pmdynflags & PMdf_USED) {
failure:
if (gimme == G_ARRAY)
RETURN;
RETPUSHNO;
}
- if (!prx->prelen && curpm) {
+ if (!rx->prelen && curpm) {
pm = curpm;
- prx = pm->op_pmregexp;
+ rx = pm->op_pmregexp;
}
- if (prx->minlen > len) goto failure;
+ if (rx->minlen > len) goto failure;
- screamer = ( (SvSCREAM(TARG) && prx->check_substr
- && SvTYPE(prx->check_substr) == SVt_PVBM
- && SvVALID(prx->check_substr))
+ screamer = ( (SvSCREAM(TARG) && rx->check_substr
+ && SvTYPE(rx->check_substr) == SVt_PVBM
+ && SvVALID(rx->check_substr))
? TARG : Nullsv);
truebase = t = s;
if (global = pm->op_pmflags & PMf_GLOBAL) {
- prx->startp[0] = 0;
+ rx->startp[0] = 0;
if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) {
MAGIC* mg = mg_find(TARG, 'g');
if (mg && mg->mg_len >= 0) {
- prx->endp[0] = prx->startp[0] = s + mg->mg_len;
+ rx->endp[0] = rx->startp[0] = s + mg->mg_len;
minmatch = (mg->mg_flags & MGf_MINMATCH);
update_minmatch = 0;
}
}
}
- if (!prx->nparens && !global)
+ if (!rx->nparens && !global)
gimme = G_SCALAR; /* accidental array context? */
- safebase = (((gimme == G_ARRAY) || global || !prx->nparens)
+ safebase = (((gimme == G_ARRAY) || global || !rx->nparens)
&& !sawampersand);
safebase = safebase ? 0 : REXEC_COPY_STR ;
if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) {
}
play_it_again:
- if (global && prx->startp[0]) {
- t = s = prx->endp[0];
- if ((s + prx->minlen) > strend)
+ if (global && rx->startp[0]) {
+ t = s = rx->endp[0];
+ if ((s + rx->minlen) > strend)
goto nope;
if (update_minmatch++)
- minmatch = (s == prx->startp[0]);
+ minmatch = (s == rx->startp[0]);
}
- if (prx->check_substr) {
- if (!(prx->reganch & ROPT_NOSCAN)) { /* Floating checkstring. */
+ if (rx->check_substr) {
+ if (!(rx->reganch & ROPT_NOSCAN)) { /* Floating checkstring. */
if ( screamer ) {
I32 p = -1;
- if (screamfirst[BmRARE(prx->check_substr)] < 0)
+ if (screamfirst[BmRARE(rx->check_substr)] < 0)
goto nope;
- else if (!(s = screaminstr(TARG, prx->check_substr,
- prx->check_offset_min, 0, &p, 0)))
+ else if (!(s = screaminstr(TARG, rx->check_substr,
+ rx->check_offset_min, 0, &p, 0)))
goto nope;
- else if ((prx->reganch & ROPT_CHECK_ALL)
- && !sawampersand && !SvTAIL(prx->check_substr))
+ else if ((rx->reganch & ROPT_CHECK_ALL)
+ && !sawampersand && !SvTAIL(rx->check_substr))
goto yup;
}
- else if (!(s = fbm_instr((unsigned char*)s + prx->check_offset_min,
+ else if (!(s = fbm_instr((unsigned char*)s + rx->check_offset_min,
(unsigned char*)strend,
- prx->check_substr)))
+ rx->check_substr, 0)))
goto nope;
- else if ((prx->reganch & ROPT_CHECK_ALL) && !sawampersand)
+ else if ((rx->reganch & ROPT_CHECK_ALL) && !sawampersand)
goto yup;
- if (s && prx->check_offset_max < t - s) {
- ++BmUSEFUL(prx->check_substr);
- s -= prx->check_offset_max;
+ if (s && rx->check_offset_max < s - t) {
+ ++BmUSEFUL(rx->check_substr);
+ s -= rx->check_offset_max;
}
else
s = t;
beginning of match, and the match is anchored at s. */
else if (!multiline) { /* Anchored near beginning of string. */
I32 slen;
- if (*SvPVX(prx->check_substr) != s[prx->check_offset_min]
- || ((slen = SvCUR(prx->check_substr)) > 1
- && memNE(SvPVX(prx->check_substr),
- s + prx->check_offset_min, slen)))
+ if (*SvPVX(rx->check_substr) != s[rx->check_offset_min]
+ || ((slen = SvCUR(rx->check_substr)) > 1
+ && memNE(SvPVX(rx->check_substr),
+ s + rx->check_offset_min, slen)))
goto nope;
}
- if (!prx->naughty && --BmUSEFUL(prx->check_substr) < 0
- && prx->check_substr == prx->float_substr) {
- SvREFCNT_dec(prx->check_substr);
- prx->check_substr = Nullsv; /* opt is being useless */
- prx->float_substr = Nullsv;
+ if (!rx->naughty && --BmUSEFUL(rx->check_substr) < 0
+ && rx->check_substr == rx->float_substr) {
+ SvREFCNT_dec(rx->check_substr);
+ rx->check_substr = Nullsv; /* opt is being useless */
+ rx->float_substr = Nullsv;
}
}
- if (regexec_flags(prx, s, strend, truebase, minmatch,
+ if (CALLREGEXEC(rx, s, strend, truebase, minmatch,
screamer, NULL, safebase))
{
curpm = pm;
if (pm->op_pmflags & PMf_ONCE)
- pm->op_pmflags |= PMf_USED;
+ pm->op_pmdynflags |= PMdf_USED;
goto gotcha;
}
else
/*NOTREACHED*/
gotcha:
- TAINT_IF(RX_MATCH_TAINTED(prx));
+ if (rxtainted)
+ RX_MATCH_TAINTED_on(rx);
+ TAINT_IF(RX_MATCH_TAINTED(rx));
if (gimme == G_ARRAY) {
I32 iters, i, len;
- iters = prx->nparens;
+ iters = rx->nparens;
if (global && !iters)
i = 1;
else
for (i = !i; i <= iters; i++) {
PUSHs(sv_newmortal());
/*SUPPRESS 560*/
- if ((s = prx->startp[i]) && prx->endp[i] ) {
- len = prx->endp[i] - s;
+ if ((s = rx->startp[i]) && rx->endp[i] ) {
+ len = rx->endp[i] - s;
sv_setpvn(*SP, s, len);
}
}
if (global) {
- truebase = prx->subbeg;
- strend = prx->subend;
- if (prx->startp[0] && prx->startp[0] == prx->endp[0])
- ++prx->endp[0];
+ truebase = rx->subbeg;
+ strend = rx->subend;
+ if (rx->startp[0] && rx->startp[0] == rx->endp[0])
+ ++rx->endp[0];
PUTBACK; /* EVAL blocks may use stack */
goto play_it_again;
}
sv_magic(TARG, (SV*)0, 'g', Nullch, 0);
mg = mg_find(TARG, 'g');
}
- if (prx->startp[0]) {
- mg->mg_len = prx->endp[0] - prx->subbeg;
- if (prx->startp[0] == prx->endp[0])
+ if (rx->startp[0]) {
+ mg->mg_len = rx->endp[0] - rx->subbeg;
+ if (rx->startp[0] == rx->endp[0])
mg->mg_flags |= MGf_MINMATCH;
else
mg->mg_flags &= ~MGf_MINMATCH;
}
yup: /* Confirmed by check_substr */
- TAINT_IF(RX_MATCH_TAINTED(prx));
- ++BmUSEFUL(prx->check_substr);
+ if (rxtainted)
+ RX_MATCH_TAINTED_on(rx);
+ TAINT_IF(RX_MATCH_TAINTED(rx));
+ ++BmUSEFUL(rx->check_substr);
curpm = pm;
if (pm->op_pmflags & PMf_ONCE)
- pm->op_pmflags |= PMf_USED;
- Safefree(prx->subbase);
- prx->subbase = Nullch;
+ pm->op_pmdynflags |= PMdf_USED;
+ Safefree(rx->subbase);
+ rx->subbase = Nullch;
if (global) {
- prx->subbeg = truebase;
- prx->subend = strend;
- prx->startp[0] = s;
- prx->endp[0] = s + SvCUR(prx->check_substr);
+ rx->subbeg = truebase;
+ rx->subend = strend;
+ rx->startp[0] = s;
+ rx->endp[0] = s + SvCUR(rx->check_substr);
goto gotcha;
}
if (sawampersand) {
char *tmps;
- tmps = prx->subbase = savepvn(t, strend-t);
- prx->subbeg = tmps;
- prx->subend = tmps + (strend-t);
- tmps = prx->startp[0] = tmps + (s - t);
- prx->endp[0] = tmps + SvCUR(prx->check_substr);
+ tmps = rx->subbase = savepvn(t, strend-t);
+ rx->subbeg = tmps;
+ rx->subend = tmps + (strend-t);
+ tmps = rx->startp[0] = tmps + (s - t);
+ rx->endp[0] = tmps + SvCUR(rx->check_substr);
}
LEAVE_SCOPE(oldsave);
RETPUSHYES;
nope:
- if (prx->check_substr)
- ++BmUSEFUL(prx->check_substr);
+ if (rx->check_substr)
+ ++BmUSEFUL(rx->check_substr);
ret_no:
if (global && !(pm->op_pmflags & PMf_CONTINUE)) {
IoFLAGS(io) &= ~IOf_START;
IoLINES(io) = 0;
if (av_len(GvAVn(last_in_gv)) < 0) {
- SV *tmpstr = newSVpv("-", 1); /* assume stdin */
- av_push(GvAVn(last_in_gv), tmpstr);
+ do_open(last_in_gv,"-",1,FALSE,0,0,Nullfp);
+ sv_setpvn(GvSV(last_in_gv), "-", 1);
+ SvSETMAGIC(GvSV(last_in_gv));
+ fp = IoIFP(io);
+ goto have_fp;
}
}
fp = nextargv(last_in_gv);
}
}
if ((tmpfp = PerlIO_open(tmpfnam,"w+","fop=dlt")) != NULL) {
- ok = ((wilddsc.dsc$a_pointer = tovmsspec(SvPVX(tmpglob),vmsspec)) != NULL);
+ Stat_t st;
+ if (!PerlLIO_stat(SvPVX(tmpglob),&st) && S_ISDIR(st.st_mode))
+ ok = ((wilddsc.dsc$a_pointer = tovmspath(SvPVX(tmpglob),vmsspec)) != NULL);
+ else ok = ((wilddsc.dsc$a_pointer = tovmsspec(SvPVX(tmpglob),vmsspec)) != NULL);
if (ok) wilddsc.dsc$w_length = (unsigned short int) strlen(wilddsc.dsc$a_pointer);
while (ok && ((sts = lib$find_file(&wilddsc,&rsdsc,&cxt,
&dfltdsc,NULL,NULL,NULL))&1)) {
}
RETURN;
}
+ have_fp:
if (gimme == G_SCALAR) {
sv = TARG;
if (SvROK(sv))
HV *hv = (HV*)POPs;
U32 lval = op->op_flags & OPf_MOD;
U32 defer = op->op_private & OPpLVAL_DEFER;
+ SV *sv;
if (SvTYPE(hv) == SVt_PVHV) {
he = hv_fetch_ent(hv, keysv, lval && !defer, 0);
else if (op->op_private & OPpDEREF)
vivify_ref(*svp, op->op_private & OPpDEREF);
}
- PUSHs(svp ? *svp : &sv_undef);
+ sv = (svp ? *svp : &sv_undef);
+ /* This makes C<local $tied{foo} = $tied{foo}> possible.
+ * Pushing the magical RHS on to the stack is useless, since
+ * that magic is soon destined to be misled by the local(),
+ * and thus the later pp_sassign() will fail to mg_get() the
+ * old value. This should also cure problems with delayed
+ * mg_get()s. GSAR 98-07-03 */
+ if (!lval && SvGMAGICAL(sv))
+ sv = sv_mortalcopy(sv);
+ PUSHs(sv);
RETURN;
}
DIE("panic: pp_iter");
av = cx->blk_loop.iterary;
+ if (SvTYPE(av) != SVt_PVAV) {
+ /* iterate ($min .. $max) */
+ if (cx->blk_loop.iterlval) {
+ /* string increment */
+ register SV* cur = cx->blk_loop.iterlval;
+ STRLEN maxlen;
+ char *max = SvPV((SV*)av, maxlen);
+ if (!SvNIOK(cur) && SvCUR(cur) <= maxlen) {
+ sv_setsv(*cx->blk_loop.itervar, cur);
+ if (strEQ(SvPVX(cur), max))
+ sv_setiv(cur, 0); /* terminate next time */
+ else
+ sv_inc(cur);
+ RETPUSHYES;
+ }
+ RETPUSHNO;
+ }
+ /* integer increment */
+ if (cx->blk_loop.iterix > cx->blk_loop.itermax)
+ RETPUSHNO;
+
+ /* we know that the loop index SV is IV capable, so we can save
+ * some time by doing the essential work of sv_setiv() ourself.
+ */
+ sv = *cx->blk_loop.itervar;
+ (void)SvIOK_only(sv);
+ SvIVX(sv) = cx->blk_loop.iterix++;
+
+ RETPUSHYES;
+ }
+
+ /* iterate array */
if (cx->blk_loop.iterix >= (av == curstack ? cx->blk_oldsp : AvFILL(av)))
RETPUSHNO;
bool rxtainted;
char *orig;
I32 safebase;
- register REGEXP *prx = pm->op_pmregexp;
+ register REGEXP *rx = pm->op_pmregexp;
STRLEN len;
int force_on_match = 0;
I32 oldsave = savestack_ix;
s = SvPV(TARG, len);
if (!SvPOKp(TARG) || SvTYPE(TARG) == SVt_PVGV)
force_on_match = 1;
+ rxtainted = ((pm->op_pmdynflags & PMdf_TAINTED) ||
+ (tainted && (pm->op_pmflags & PMf_RETAINT)));
+ if (tainted)
+ rxtainted |= 2;
TAINT_NOT;
force_it:
strend = s + len;
maxiters = (strend - s) + 10;
- if (!prx->prelen && curpm) {
+ if (!rx->prelen && curpm) {
pm = curpm;
- prx = pm->op_pmregexp;
+ rx = pm->op_pmregexp;
}
- screamer = ( (SvSCREAM(TARG) && prx->check_substr
- && SvTYPE(prx->check_substr) == SVt_PVBM
- && SvVALID(prx->check_substr))
+ screamer = ( (SvSCREAM(TARG) && rx->check_substr
+ && SvTYPE(rx->check_substr) == SVt_PVBM
+ && SvVALID(rx->check_substr))
? TARG : Nullsv);
- safebase = (!prx->nparens && !sawampersand) ? 0 : REXEC_COPY_STR;
+ safebase = (!rx->nparens && !sawampersand) ? 0 : REXEC_COPY_STR;
if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) {
SAVEINT(multiline);
multiline = pm->op_pmflags & PMf_MULTILINE;
}
orig = m = s;
- if (prx->check_substr) {
- if (!(prx->reganch & ROPT_NOSCAN)) { /* It floats. */
+ if (rx->check_substr) {
+ if (!(rx->reganch & ROPT_NOSCAN)) { /* It floats. */
if (screamer) {
I32 p = -1;
- if (screamfirst[BmRARE(prx->check_substr)] < 0)
+ if (screamfirst[BmRARE(rx->check_substr)] < 0)
goto nope;
- else if (!(s = screaminstr(TARG, prx->check_substr, prx->check_offset_min, 0, &p, 0)))
+ else if (!(s = screaminstr(TARG, rx->check_substr, rx->check_offset_min, 0, &p, 0)))
goto nope;
}
- else if (!(s = fbm_instr((unsigned char*)s + prx->check_offset_min,
+ else if (!(s = fbm_instr((unsigned char*)s + rx->check_offset_min,
(unsigned char*)strend,
- prx->check_substr)))
+ rx->check_substr, 0)))
goto nope;
- if (s && prx->check_offset_max < s - m) {
- ++BmUSEFUL(prx->check_substr);
- s -= prx->check_offset_max;
+ if (s && rx->check_offset_max < s - m) {
+ ++BmUSEFUL(rx->check_substr);
+ s -= rx->check_offset_max;
}
else
s = m;
beginning of match, and the match is anchored at s. */
else if (!multiline) { /* Anchored at beginning of string. */
I32 slen;
- if (*SvPVX(prx->check_substr) != s[prx->check_offset_min]
- || ((slen = SvCUR(prx->check_substr)) > 1
- && memNE(SvPVX(prx->check_substr),
- s + prx->check_offset_min, slen)))
+ if (*SvPVX(rx->check_substr) != s[rx->check_offset_min]
+ || ((slen = SvCUR(rx->check_substr)) > 1
+ && memNE(SvPVX(rx->check_substr),
+ s + rx->check_offset_min, slen)))
goto nope;
}
- if (!prx->naughty && --BmUSEFUL(prx->check_substr) < 0
- && prx->check_substr == prx->float_substr) {
- SvREFCNT_dec(prx->check_substr);
- prx->check_substr = Nullsv; /* opt is being useless */
- prx->float_substr = Nullsv;
+ if (!rx->naughty && --BmUSEFUL(rx->check_substr) < 0
+ && rx->check_substr == rx->float_substr) {
+ SvREFCNT_dec(rx->check_substr);
+ rx->check_substr = Nullsv; /* opt is being useless */
+ rx->float_substr = Nullsv;
}
}
c = dstr ? SvPV(dstr, clen) : Nullch;
/* can do inplace substitution? */
- if (c && clen <= prx->minlen && (once || !(safebase & REXEC_COPY_STR))
- && !(prx->reganch & ROPT_LOOKBEHIND_SEEN)) {
- if (!regexec_flags(prx, s, strend, orig, 0, screamer, NULL, safebase)) {
+ if (c && clen <= rx->minlen && (once || !(safebase & REXEC_COPY_STR))
+ && !(rx->reganch & ROPT_LOOKBEHIND_SEEN)) {
+ if (!CALLREGEXEC(rx, s, strend, orig, 0, screamer, NULL, safebase)) {
SPAGAIN;
PUSHs(&sv_no);
LEAVE_SCOPE(oldsave);
curpm = pm;
SvSCREAM_off(TARG); /* disable possible screamer */
if (once) {
- rxtainted = RX_MATCH_TAINTED(prx);
- if (prx->subbase) {
- m = orig + (prx->startp[0] - prx->subbase);
- d = orig + (prx->endp[0] - prx->subbase);
+ rxtainted |= RX_MATCH_TAINTED(rx);
+ if (rx->subbase) {
+ m = orig + (rx->startp[0] - rx->subbase);
+ d = orig + (rx->endp[0] - rx->subbase);
} else {
- m = prx->startp[0];
- d = prx->endp[0];
+ m = rx->startp[0];
+ d = rx->endp[0];
}
s = orig;
if (m - s > strend - d) { /* faster to shorten from end */
else {
sv_chop(TARG, d);
}
- TAINT_IF(rxtainted);
+ TAINT_IF(rxtainted & 1);
SPAGAIN;
PUSHs(&sv_yes);
}
else {
- rxtainted = 0;
do {
if (iters++ > maxiters)
DIE("Substitution loop");
- rxtainted |= RX_MATCH_TAINTED(prx);
- m = prx->startp[0];
+ rxtainted |= RX_MATCH_TAINTED(rx);
+ m = rx->startp[0];
/*SUPPRESS 560*/
if (i = m - s) {
if (s != d)
Copy(c, d, clen, char);
d += clen;
}
- s = prx->endp[0];
- } while (regexec_flags(prx, s, strend, orig, s == m,
+ s = rx->endp[0];
+ } while (CALLREGEXEC(rx, s, strend, orig, s == m,
Nullsv, NULL, 0)); /* don't match same null twice */
if (s != d) {
i = strend - s;
SvCUR_set(TARG, d - SvPVX(TARG) + i);
Move(s, d, i+1, char); /* include the NUL */
}
- TAINT_IF(rxtainted);
+ TAINT_IF(rxtainted & 1);
SPAGAIN;
PUSHs(sv_2mortal(newSViv((I32)iters)));
}
(void)SvPOK_only(TARG);
+ TAINT_IF(rxtainted);
if (SvSMAGICAL(TARG)) {
PUTBACK;
mg_set(TARG);
RETURN;
}
- if (regexec_flags(prx, s, strend, orig, 0, screamer, NULL, safebase)) {
+ if (CALLREGEXEC(rx, s, strend, orig, 0, screamer, NULL, safebase)) {
if (force_on_match) {
force_on_match = 0;
s = SvPV_force(TARG, len);
goto force_it;
}
- rxtainted = RX_MATCH_TAINTED(prx);
+ rxtainted |= RX_MATCH_TAINTED(rx);
dstr = NEWSV(25, len);
sv_setpvn(dstr, m, s-m);
curpm = pm;
do {
if (iters++ > maxiters)
DIE("Substitution loop");
- rxtainted |= RX_MATCH_TAINTED(prx);
- if (prx->subbase && prx->subbase != orig) {
+ rxtainted |= RX_MATCH_TAINTED(rx);
+ if (rx->subbase && rx->subbase != orig) {
m = s;
s = orig;
- orig = prx->subbase;
+ orig = rx->subbase;
s = orig + (m - s);
strend = s + (strend - m);
}
- m = prx->startp[0];
+ m = rx->startp[0];
sv_catpvn(dstr, s, m-s);
- s = prx->endp[0];
+ s = rx->endp[0];
if (clen)
sv_catpvn(dstr, c, clen);
if (once)
break;
- } while (regexec_flags(prx, s, strend, orig, s == m, Nullsv, NULL, safebase));
+ } while (CALLREGEXEC(rx, s, strend, orig, s == m, Nullsv, NULL, safebase));
sv_catpvn(dstr, s, strend - s);
- TAINT_IF(rxtainted);
-
(void)SvOOK_off(TARG);
Safefree(SvPVX(TARG));
SvPVX(TARG) = SvPVX(dstr);
SvPVX(dstr) = 0;
sv_free(dstr);
+ TAINT_IF(rxtainted & 1);
+ SPAGAIN;
+ PUSHs(sv_2mortal(newSViv((I32)iters)));
+
(void)SvPOK_only(TARG);
+ TAINT_IF(rxtainted);
SvSETMAGIC(TARG);
SvTAINT(TARG);
- SPAGAIN;
- PUSHs(sv_2mortal(newSViv((I32)iters)));
LEAVE_SCOPE(oldsave);
RETURN;
}
goto ret_no;
nope:
- ++BmUSEFUL(prx->check_substr);
+ ++BmUSEFUL(rx->check_substr);
ret_no:
SPAGAIN;
TAINT_NOT;
if (gimme == G_SCALAR) {
MARK = newsp + 1;
- if (MARK <= SP)
- *MARK = SvTEMP(TOPs) ? TOPs : sv_mortalcopy(TOPs);
- else {
+ if (MARK <= SP) {
+ if (cxsub.cv && CvDEPTH(cxsub.cv) > 1) {
+ if (SvTEMP(TOPs)) {
+ *MARK = SvREFCNT_inc(TOPs);
+ FREETMPS;
+ sv_2mortal(*MARK);
+ } else {
+ FREETMPS;
+ *MARK = sv_mortalcopy(TOPs);
+ }
+ } else
+ *MARK = SvTEMP(TOPs) ? TOPs : sv_mortalcopy(TOPs);
+ } else {
MEXTEND(MARK, 0);
*MARK = &sv_undef;
}
get_db_sub(SV **svp, CV *cv)
{
dTHR;
- SV *oldsv = *svp;
- GV *gv;
+ SV *dbsv = GvSV(DBsub);
+
+ if (!PERLDB_SUB_NN) {
+ GV *gv = CvGV(cv);
- *svp = GvSV(DBsub);
- save_item(*svp);
- gv = CvGV(cv);
- if ( (CvFLAGS(cv) & (CVf_ANON | CVf_CLONED))
- || strEQ(GvNAME(gv), "END")
- || ((GvCV(gv) != cv) && /* Could be imported, and old sub redefined. */
- !( (SvTYPE(oldsv) == SVt_PVGV) && (GvCV((GV*)oldsv) == cv)
- && (gv = (GV*)oldsv) ))) {
- /* Use GV from the stack as a fallback. */
- /* GV is potentially non-unique, or contain different CV. */
- sv_setsv(*svp, newRV((SV*)cv));
+ save_item(dbsv);
+ if ( (CvFLAGS(cv) & (CVf_ANON | CVf_CLONED))
+ || strEQ(GvNAME(gv), "END")
+ || ((GvCV(gv) != cv) && /* Could be imported, and old sub redefined. */
+ !( (SvTYPE(*svp) == SVt_PVGV) && (GvCV((GV*)*svp) == cv)
+ && (gv = (GV*)*svp) ))) {
+ /* Use GV from the stack as a fallback. */
+ /* GV is potentially non-unique, or contain different CV. */
+ sv_setsv(dbsv, newRV((SV*)cv));
+ }
+ else {
+ gv_efullname3(dbsv, gv, Nullch);
+ }
}
else {
- gv_efullname3(*svp, gv, Nullch);
+ SvUPGRADE(dbsv, SVt_PVIV);
+ SvIOK_on(dbsv);
+ SAVEIV(SvIVX(dbsv));
+ SvIVX(dbsv) = (IV)cv; /* Do it the quickest way */
}
- cv = GvCV(DBsub);
+
if (CvXSUB(cv))
curcopdb = curcop;
+ cv = GvCV(DBsub);
return cv;
}
* (3) instead of (2) so we'd have to clone. Would the fact
* that we released the mutex more quickly make up for this?
*/
- svp = hv_fetch(thr->cvcache, (char *)cv, sizeof(cv), FALSE);
- if (svp) {
+ if (threadnum &&
+ (svp = hv_fetch(thr->cvcache, (char *)cv, sizeof(cv), FALSE)))
+ {
/* We already have a clone to use */
MUTEX_UNLOCK(CvMUTEXP(cv));
cv = *(CV**)svp;
curcopdb = NULL;
}
/* Do we need to open block here? XXXX */
- (void)(*CvXSUB(cv))(THIS_ cv);
+ (void)(*CvXSUB(cv))(cv _PERL_OBJECT_THIS);
/* Enforce some sanity in scalar context. */
if (gimme == G_SCALAR && ++markix != stack_sp - stack_base ) {
AV* av = (AV*)POPs;
U32 lval = op->op_flags & OPf_MOD;
U32 defer = (op->op_private & OPpLVAL_DEFER) && (elem > AvFILL(av));
+ SV *sv;
if (elem > 0)
elem -= curcop->cop_arybase;
else if (op->op_private & OPpDEREF)
vivify_ref(*svp, op->op_private & OPpDEREF);
}
- PUSHs(svp ? *svp : &sv_undef);
+ sv = (svp ? *svp : &sv_undef);
+ if (!lval && SvGMAGICAL(sv)) /* see note in pp_helem() */
+ sv = sv_mortalcopy(sv);
+ PUSHs(sv);
RETURN;
}
!(ob=(SV*)GvIO(iogv)))
{
if (!packname || !isIDFIRST(*packname))
- DIE("Can't call method \"%s\" without a package or object reference", name);
+ DIE("Can't call method \"%s\" %s", name,
+ SvOK(sv)? "without a package or object reference"
+ : "on an undefined value");
stash = gv_stashpvn(packname, packlen, TRUE);
goto fetch;
}