ref = (SV*)GvCV(gv);
break;
case 'F':
- if (strEQ(elem, "FILEHANDLE"))
+ if (strEQ(elem, "FILEHANDLE")) /* XXX deprecate in 5.005 */
ref = (SV*)GvIOp(gv);
break;
case 'G':
if (strEQ(elem, "HASH"))
ref = (SV*)GvHV(gv);
break;
+ case 'I':
+ if (strEQ(elem, "IO"))
+ ref = (SV*)GvIOp(gv);
+ break;
case 'N':
if (strEQ(elem, "NAME"))
sv = newSVpv(GvNAME(gv), GvNAMELEN(gv));
return NORMAL;
}
-PP(pp_seq)
-{
- dSP; tryAMAGICbinSET(seq,0);
- {
- dPOPTOPssrl;
- bool eq = ((op->op_private & OPpLOCALE)
- ? (sv_cmp_locale(left, right) == 0)
- : sv_eq(left, right));
- SETs( eq ? &sv_yes : &sv_no );
- RETURN;
- }
-}
-
PP(pp_concat)
{
dSP; dATARGET; tryAMAGICbin(concat,opASSIGN);
if (op->op_flags & OPf_MOD) {
if (op->op_private & OPpLVAL_INTRO)
SAVECLEARSV(curpad[op->op_targ]);
- else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV))
+ else if (op->op_private & OPpDEREF)
provide_ref(op, curpad[op->op_targ]);
}
RETURN;
SP = lastrelem;
else
SP = firstrelem + (lastlelem - firstlelem);
+ while (relem <= SP)
+ *relem++ = &sv_undef;
RETURN;
}
else {
}
if (!rx->nparens && !global)
gimme = G_SCALAR; /* accidental array context? */
- safebase = (gimme == G_ARRAY) || global;
+ safebase = (((gimme == G_ARRAY) || global) && !sawampersand);
if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) {
SAVEINT(multiline);
multiline = pm->op_pmflags & PMf_MULTILINE;
play_it_again:
if (global && rx->startp[0]) {
t = s = rx->endp[0];
- if (s > strend)
+ if (s >= strend)
goto nope;
minmatch = (s == rx->startp[0]);
}
else if (!multiline) {
if (*SvPVX(pm->op_pmshort) != *s
|| (pm->op_pmslen > 1
- && memcmp(SvPVX(pm->op_pmshort), s, pm->op_pmslen)))
+ && memNE(SvPVX(pm->op_pmshort), s, pm->op_pmslen)))
goto nope;
}
if (!rx->naughty && --BmUSEFUL(pm->op_pmshort) < 0) {
}
if (global) {
truebase = rx->subbeg;
+ strend = rx->subend;
if (rx->startp[0] && rx->startp[0] == rx->endp[0])
++rx->endp[0];
goto play_it_again;
mg = mg_find(TARG, 'g');
}
if (rx->startp[0]) {
- mg->mg_len = rx->endp[0] - truebase;
+ mg->mg_len = rx->endp[0] - rx->subbeg;
if (rx->startp[0] == rx->endp[0])
mg->mg_flags |= MGf_MINMATCH;
else
curpm = pm;
if (pm->op_pmflags & PMf_ONCE)
pm->op_pmflags |= PMf_USED;
+ Safefree(rx->subbase);
+ rx->subbase = Nullch;
if (global) {
rx->subbeg = truebase;
rx->subend = strend;
if (sawampersand) {
char *tmps;
- if (rx->subbase)
- Safefree(rx->subbase);
tmps = rx->subbase = savepvn(t, strend-t);
rx->subbeg = tmps;
rx->subend = tmps + (strend-t);
if (lval) {
if (!he || HeVAL(he) == &sv_undef)
DIE(no_helem, SvPV(keysv, na));
- if (op->op_private & OPpLVAL_INTRO)
- save_svref(&HeVAL(he));
- else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV))
+ if (op->op_private & OPpLVAL_INTRO) {
+ if (HvNAME(hv) && isGV(HeVAL(he)))
+ save_gp((GV*)HeVAL(he), !(op->op_flags & OPf_SPECIAL));
+ else
+ save_svref(&HeVAL(he));
+ }
+ else if (op->op_private & OPpDEREF)
provide_ref(op, HeVAL(he));
}
PUSHs(he ? HeVAL(he) : &sv_undef);
{
dSP;
register CONTEXT *cx;
- SV *sv;
+ SV* sv;
AV* av;
EXTEND(sp, 1);
if (cx->blk_loop.iterix >= AvFILL(av))
RETPUSHNO;
- if (sv = AvARRAY(av)[++cx->blk_loop.iterix]) {
+ if (sv = AvARRAY(av)[++cx->blk_loop.iterix])
SvTEMP_off(sv);
- *cx->blk_loop.itervar = sv;
- }
else
- *cx->blk_loop.itervar = &sv_undef;
-
+ sv = &sv_undef;
+ if (av != curstack && SvIMMORTAL(sv)) {
+ SV *lv = cx->blk_loop.iterlval;
+ if (lv)
+ SvREFCNT_dec(LvTARG(lv));
+ else {
+ lv = cx->blk_loop.iterlval = newSVsv(sv);
+ sv_upgrade(lv, SVt_PVLV);
+ sv_magic(lv, Nullsv, 'y', Nullch, 0);
+ LvTYPE(lv) = 'y';
+ }
+ LvTARG(lv) = SvREFCNT_inc(av);
+ LvTARGOFF(lv) = cx->blk_loop.iterix;
+ LvTARGLEN(lv) = 1;
+ sv = (SV*)lv;
+ }
+ *cx->blk_loop.itervar = sv;
RETPUSHYES;
}
pm = curpm;
rx = pm->op_pmregexp;
}
- safebase = ((!rx || !rx->nparens) && !sawampersand);
+ safebase = (!rx->nparens && !sawampersand);
if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) {
SAVEINT(multiline);
multiline = pm->op_pmflags & PMf_MULTILINE;
else if (!multiline) {
if (*SvPVX(pm->op_pmshort) != *s
|| (pm->op_pmslen > 1
- && memcmp(SvPVX(pm->op_pmshort), s, pm->op_pmslen)))
+ && memNE(SvPVX(pm->op_pmshort), s, pm->op_pmslen)))
goto nope;
}
if (!rx->naughty && --BmUSEFUL(pm->op_pmshort) < 0) {
else
c = Nullch;
if (pregexec(rx, s, strend, orig, 0,
- SvSCREAM(TARG) ? TARG : Nullsv, safebase)) {
+ SvSCREAM(TARG) ? TARG : Nullsv, safebase)) {
long_way:
if (force_on_match) {
force_on_match = 0;
sv_catpvn(dstr, c, clen);
if (once)
break;
- } while (pregexec(rx, s, strend, orig, s == m, Nullsv,
- safebase));
+ } while (pregexec(rx, s, strend, orig, s == m, Nullsv, safebase));
sv_catpvn(dstr, s, strend - s);
(void)SvOOK_off(TARG);
if (CvDEPTH(cv) < 2)
(void)SvREFCNT_inc(cv);
else { /* save temporaries on recursion? */
- if (CvDEPTH(cv) == 100 && dowarn)
+ if (CvDEPTH(cv) == 100 && dowarn
+ && !(perldb && cv == GvCV(DBsub)))
warn("Deep recursion on subroutine \"%s\"",GvENAME(CvGV(cv)));
if (CvDEPTH(cv) > AvFILL(padlist)) {
AV *av;
for ( ;ix > 0; ix--) {
if (svp[ix] != &sv_undef) {
char *name = SvPVX(svp[ix]);
- if (SvFLAGS(svp[ix]) & SVf_FAKE) { /* outer lexical? */
- av_store(newpad, ix,
- SvREFCNT_inc(oldpad[ix]) );
+ if ((SvFLAGS(svp[ix]) & SVf_FAKE) /* outer lexical? */
+ || *name == '&') /* anonymous code? */
+ {
+ av_store(newpad, ix, SvREFCNT_inc(oldpad[ix]));
}
else { /* our own lexical */
if (*name == '@')
DIE(no_aelem, elem);
if (op->op_private & OPpLVAL_INTRO)
save_svref(svp);
- else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV))
+ else if (op->op_private & OPpDEREF)
provide_ref(op, *svp);
}
PUSHs(svp ? *svp : &sv_undef);
if (!SvOK(sv)) {
if (SvREADONLY(sv))
croak(no_modify);
- (void)SvUPGRADE(sv, SVt_RV);
- SvRV(sv) = (op->op_private & OPpDEREF_HV ?
- (SV*)newHV() : (SV*)newAV());
+ if (SvTYPE(sv) < SVt_RV)
+ sv_upgrade(sv, SVt_RV);
+ else if (SvTYPE(sv) >= SVt_PV) {
+ (void)SvOOK_off(sv);
+ Safefree(SvPVX(sv));
+ SvLEN(sv) = SvCUR(sv) = 0;
+ }
+ switch (op->op_private & OPpDEREF)
+ {
+ case OPpDEREF_SV:
+ SvRV(sv) = newSV(0);
+ break;
+ case OPpDEREF_AV:
+ SvRV(sv) = (SV*)newAV();
+ break;
+ case OPpDEREF_HV:
+ SvRV(sv) = (SV*)newHV();
+ break;
+ }
SvROK_on(sv);
SvSETMAGIC(sv);
}