}
}
if (PL_in_my == KEY_our) {
- while (off <= top) {
+ do {
if ((sv = svp[off])
&& sv != &PL_sv_undef
+ && (SvIVX(sv) == PAD_MAX || SvIVX(sv) == 0)
&& ((SvFLAGS(sv) & SVpad_OUR) && GvSTASH(sv) == ourstash)
&& strEQ(name, SvPVX(sv)))
{
Perl_warner(aTHX_ WARN_MISC,
"\"our\" variable %s redeclared", name);
Perl_warner(aTHX_ WARN_MISC,
- "(Did you mean \"local\" instead of \"our\"?)\n");
+ "\t(Did you mean \"local\" instead of \"our\"?)\n");
break;
}
- --off;
- }
+ } while ( off-- > 0 );
}
}
off = pad_alloc(OP_PADSV, SVs_PADMY);
}
}
else if (!CvUNIQUE(PL_compcv)) {
- if (ckWARN(WARN_CLOSURE) && !SvFAKE(sv) && !CvUNIQUE(cv))
+ if (ckWARN(WARN_CLOSURE) && !SvFAKE(sv) && !CvUNIQUE(cv)
+ && !(SvFLAGS(sv) & SVpad_OUR))
+ {
Perl_warner(aTHX_ WARN_CLOSURE,
"Variable \"%s\" will not stay shared", name);
+ }
}
}
av_store(PL_comppad, newoff, SvREFCNT_inc(oldsv));
cSVOPo->op_sv = Nullsv;
#endif
break;
+ case OP_METHOD_NAMED:
case OP_CONST:
SvREFCNT_dec(cSVOPo->op_sv);
cSVOPo->op_sv = Nullsv;
{
Safefree(cop->cop_label);
#ifdef USE_ITHREADS
- Safefree(CopFILE(cop)); /* XXXXX share in a pvtable? */
- Safefree(CopSTASHPV(cop)); /* XXXXX share in a pvtable? */
+ Safefree(CopFILE(cop)); /* XXX share in a pvtable? */
+ Safefree(CopSTASHPV(cop)); /* XXX share in a pvtable? */
#else
/* NOTE: COP.cop_stash is not refcounted */
SvREFCNT_dec(CopFILEGV(cop));
case OP_DBSTATE:
case OP_ENTERTRY:
case OP_ENTER:
- case OP_SCALAR:
if (!(o->op_flags & OPf_KIDS))
break;
/* FALL THROUGH */
case OP_REQUIRE:
/* all requires must return a boolean value */
o->op_flags &= ~OPf_WANT;
+ /* FALL THROUGH */
+ case OP_SCALAR:
return scalar(o);
case OP_SPLIT:
if ((kid = cLISTOPo->op_first) && kid->op_type == OP_PUSHRE) {
LEAVE;
}
+void
+Perl_apply_attrs_string(pTHX_ char *stashpv, CV *cv,
+ char *attrstr, STRLEN len)
+{
+ OP *attrs = Nullop;
+
+ if (!len) {
+ len = strlen(attrstr);
+ }
+
+ while (len) {
+ for (; isSPACE(*attrstr) && len; --len, ++attrstr) ;
+ if (len) {
+ char *sstr = attrstr;
+ for (; !isSPACE(*attrstr) && len; --len, ++attrstr) ;
+ attrs = append_elem(OP_LIST, attrs,
+ newSVOP(OP_CONST, 0,
+ newSVpvn(sstr, attrstr-sstr)));
+ }
+ }
+
+ Perl_load_module(aTHX_ PERL_LOADMOD_IMPORT_OPS,
+ newSVpvn(ATTRSMODULE, sizeof(ATTRSMODULE)-1),
+ Nullsv, prepend_elem(OP_LIST,
+ newSVOP(OP_CONST, 0, newSVpv(stashpv,0)),
+ prepend_elem(OP_LIST,
+ newSVOP(OP_CONST, 0,
+ newRV((SV*)cv)),
+ attrs)));
+}
+
STATIC OP *
S_my_kid(pTHX_ OP *o, OP *attrs)
{
desc, sample, sample);
}
- if (right->op_type == OP_MATCH ||
+ if (!(right->op_flags & OPf_STACKED) &&
+ (right->op_type == OP_MATCH ||
right->op_type == OP_SUBST ||
- right->op_type == OP_TRANS) {
+ right->op_type == OP_TRANS)) {
right->op_flags |= OPf_STACKED;
- if (right->op_type != OP_MATCH)
+ if (right->op_type != OP_MATCH &&
+ ! (right->op_type == OP_TRANS &&
+ right->op_private & OPpTRANS_IDENTICAL))
left = mod(left, right->op_type);
if (right->op_type == OP_TRANS)
o = newBINOP(OP_NULL, OPf_STACKED, scalar(left), right);
complement = o->op_private & OPpTRANS_COMPLEMENT;
del = o->op_private & OPpTRANS_DELETE;
squash = o->op_private & OPpTRANS_SQUASH;
+
+ if (SvUTF8(tstr))
+ o->op_private |= OPpTRANS_FROM_UTF;
+
+ if (SvUTF8(rstr))
+ o->op_private |= OPpTRANS_TO_UTF;
if (o->op_private & (OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF)) {
SV* listsv = newSVpvn("# comment\n",10);
r = t; rlen = tlen; rend = tend;
}
if (!squash) {
- if (to_utf && from_utf) { /* only counting characters */
- if (t == r || (tlen == rlen && memEQ(t, r, tlen)))
- o->op_private |= OPpTRANS_IDENTICAL;
- }
- else { /* straight latin-1 translation */
- if (tlen == 4 && memEQ(t, "\0\377\303\277", 4) &&
- rlen == 4 && memEQ(r, "\0\377\303\277", 4))
+ if (t == r ||
+ (tlen == rlen && memEQ((char *)t, (char *)r, tlen)))
+ {
o->op_private |= OPpTRANS_IDENTICAL;
- }
+ }
}
while (t < tend || tfirst <= tlast) {
SvREFCNT_dec(transv);
if (!del && havefinal)
- (void)hv_store((HV*)SvRV((cSVOPo->op_sv)), "FINAL", 5, newSViv((IV)final), 0);
+ (void)hv_store((HV*)SvRV((cSVOPo->op_sv)), "FINAL", 5,
+ newSVuv((UV)final), 0);
if (grows && to_utf)
o->op_private |= OPpTRANS_GROWS;
sv = va_arg(*args, SV*);
}
}
- utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(FALSE, 0),
- veop, modname, imop);
+ {
+ line_t ocopline = PL_copline;
+ int oexpect = PL_expect;
+
+ utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(FALSE, 0),
+ veop, modname, imop);
+ PL_expect = oexpect;
+ PL_copline = ocopline;
+ }
}
OP *
PL_copline = NOLINE;
}
#ifdef USE_ITHREADS
- CopFILE_set(cop, CopFILE(PL_curcop)); /* XXXXX share in a pvtable? */
+ CopFILE_set(cop, CopFILE(PL_curcop)); /* XXX share in a pvtable? */
#else
- CopFILEGV_set(cop, (GV*)SvREFCNT_inc(CopFILEGV(PL_curcop)));
+ CopFILEGV_set(cop, CopFILEGV(PL_curcop));
#endif
CopSTASH_set(cop, PL_curstash);
loopflags |= OPpLOOP_CONTINUE;
}
if (expr) {
- cont = append_elem(OP_LINESEQ, cont, newOP(OP_UNSTACK, 0));
+ OP *unstack = newOP(OP_UNSTACK, 0);
+ if (!next)
+ next = unstack;
+ cont = append_elem(OP_LINESEQ, cont, unstack);
if ((line_t)whileline != NOLINE) {
PL_copline = whileline;
cont = append_elem(OP_LINESEQ, cont,
if (listop)
((LISTOP*)listop)->op_last->op_next = condop =
(o == listop ? redo : LINKLIST(o));
- if (!next)
- next = condop;
}
else
o = listop;
cv = PL_compcv = (CV*)NEWSV(1104,0);
sv_upgrade((SV *)cv, SvTYPE(proto));
+ CvFLAGS(cv) = CvFLAGS(proto) & ~CVf_CLONE;
CvCLONED_on(cv);
- if (CvANON(proto))
- CvANON_on(cv);
#ifdef USE_THREADS
New(666, CvMUTEXP(cv), 1, perl_mutex);
if (!name || GvCVGEN(gv))
cv = Nullcv;
else if ((cv = GvCV(gv))) {
- cv_ckproto(cv, gv, ps);
+ bool exists = CvROOT(cv) || CvXSUB(cv);
+ /* if the subroutine doesn't exist and wasn't pre-declared
+ * with a prototype, assume it will be AUTOLOADed,
+ * skipping the prototype check
+ */
+ if (exists || SvPOK(cv))
+ cv_ckproto(cv, gv, ps);
/* already defined (or promised)? */
- if (CvROOT(cv) || CvXSUB(cv) || GvASSUMECV(gv)) {
+ if (exists || GvASSUMECV(gv)) {
SV* const_sv;
bool const_changed = TRUE;
if (!block && !attrs) {
goto withattrs;
if ((const_sv = cv_const_sv(cv)))
const_changed = sv_cmp(const_sv, op_const_sv(block, Nullcv));
- if ((const_sv || const_changed) && ckWARN(WARN_REDEFINE))
+ if ((const_sv && const_changed) || ckWARN(WARN_REDEFINE))
{
line_t oldline = CopLINE(PL_curcop);
CopLINE_set(PL_curcop, PL_copline);
if (!PL_beginav)
PL_beginav = newAV();
DEBUG_x( dump_sub(gv) );
- av_push(PL_beginav, SvREFCNT_inc(cv));
- GvCV(gv) = 0;
+ av_push(PL_beginav, (SV*)cv);
+ GvCV(gv) = 0; /* cv has been hijacked */
call_list(oldscope, PL_beginav);
PL_curcop = &PL_compiling;
PL_endav = newAV();
DEBUG_x( dump_sub(gv) );
av_unshift(PL_endav, 1);
- av_store(PL_endav, 0, SvREFCNT_inc(cv));
- GvCV(gv) = 0;
+ av_store(PL_endav, 0, (SV*)cv);
+ GvCV(gv) = 0; /* cv has been hijacked */
}
else if (strEQ(s, "CHECK") && !PL_error_count) {
if (!PL_checkav)
PL_checkav = newAV();
DEBUG_x( dump_sub(gv) );
+ if (PL_main_start && ckWARN(WARN_VOID))
+ Perl_warner(aTHX_ WARN_VOID, "Too late to run CHECK block");
av_unshift(PL_checkav, 1);
- av_store(PL_checkav, 0, SvREFCNT_inc(cv));
- GvCV(gv) = 0;
+ av_store(PL_checkav, 0, (SV*)cv);
+ GvCV(gv) = 0; /* cv has been hijacked */
}
else if (strEQ(s, "INIT") && !PL_error_count) {
if (!PL_initav)
PL_initav = newAV();
DEBUG_x( dump_sub(gv) );
- av_push(PL_initav, SvREFCNT_inc(cv));
- GvCV(gv) = 0;
+ if (PL_main_start && ckWARN(WARN_VOID))
+ Perl_warner(aTHX_ WARN_VOID, "Too late to run INIT block");
+ av_push(PL_initav, (SV*)cv);
+ GvCV(gv) = 0; /* cv has been hijacked */
}
}
dTHR;
ENTER;
- SAVECOPLINE(PL_curcop);
- SAVEHINTS();
+ SAVECOPLINE(PL_curcop);
CopLINE_set(PL_curcop, PL_copline);
+
+ SAVEHINTS();
PL_hints &= ~HINT_BLOCK_SCOPE;
if (stash) {
if (strEQ(s, "BEGIN")) {
if (!PL_beginav)
PL_beginav = newAV();
- av_push(PL_beginav, SvREFCNT_inc(cv));
- GvCV(gv) = 0;
+ av_push(PL_beginav, (SV*)cv);
+ GvCV(gv) = 0; /* cv has been hijacked */
}
else if (strEQ(s, "END")) {
if (!PL_endav)
PL_endav = newAV();
av_unshift(PL_endav, 1);
- av_store(PL_endav, 0, SvREFCNT_inc(cv));
- GvCV(gv) = 0;
+ av_store(PL_endav, 0, (SV*)cv);
+ GvCV(gv) = 0; /* cv has been hijacked */
}
else if (strEQ(s, "CHECK")) {
if (!PL_checkav)
PL_checkav = newAV();
+ if (PL_main_start && ckWARN(WARN_VOID))
+ Perl_warner(aTHX_ WARN_VOID, "Too late to run CHECK block");
av_unshift(PL_checkav, 1);
- av_store(PL_checkav, 0, SvREFCNT_inc(cv));
- GvCV(gv) = 0;
+ av_store(PL_checkav, 0, (SV*)cv);
+ GvCV(gv) = 0; /* cv has been hijacked */
}
else if (strEQ(s, "INIT")) {
if (!PL_initav)
PL_initav = newAV();
- av_push(PL_initav, SvREFCNT_inc(cv));
- GvCV(gv) = 0;
+ if (PL_main_start && ckWARN(WARN_VOID))
+ Perl_warner(aTHX_ WARN_VOID, "Too late to run INIT block");
+ av_push(PL_initav, (SV*)cv);
+ GvCV(gv) = 0; /* cv has been hijacked */
}
}
else
}
OP *
+Perl_ck_exit(pTHX_ OP *o)
+{
+#ifdef VMS
+ HV *table = GvHV(PL_hintgv);
+ if (table) {
+ SV **svp = hv_fetch(table, "vmsish_exit", 11, FALSE);
+ if (svp && *svp && SvTRUE(*svp))
+ o->op_private |= OPpEXIT_VMSISH;
+ }
+#endif
+ return ck_fun(o);
+}
+
+OP *
Perl_ck_exec(pTHX_ OP *o)
{
OP *kid;
#ifdef USE_ITHREADS
/* XXX hack: dependence on sizeof(PADOP) <= sizeof(SVOP) */
kPADOP->op_padix = pad_alloc(OP_GV, SVs_PADTMP);
+ SvREFCNT_dec(PL_curpad[kPADOP->op_padix]);
GvIN_PAD_on(gv);
PL_curpad[kPADOP->op_padix] = SvREFCNT_inc(gv);
#else
name = GvNAME(gv);
len = GvNAMELEN(gv);
}
+ else if (kid->op_type == OP_AELEM
+ || kid->op_type == OP_HELEM)
+ {
+ name = "__ANONIO__";
+ len = 10;
+ mod(kid,type);
+ }
if (name) {
SV *namesv;
targ = pad_alloc(OP_RV2GV, SVs_PADTMP);
Perl_warner(aTHX_ WARN_DEPRECATED,
"defined(@array) is deprecated");
Perl_warner(aTHX_ WARN_DEPRECATED,
- "(Maybe you should just omit the defined()?)\n");
+ "\t(Maybe you should just omit the defined()?)\n");
break;
case OP_RV2HV:
break; /* Globals via GV can be undef */
Perl_warner(aTHX_ WARN_DEPRECATED,
"defined(%%hash) is deprecated");
Perl_warner(aTHX_ WARN_DEPRECATED,
- "(Maybe you should just omit the defined()?)\n");
+ "\t(Maybe you should just omit the defined()?)\n");
break;
default:
/* no warning */
OP *
Perl_ck_sort(pTHX_ OP *o)
{
+ OP *firstkid;
o->op_private = 0;
#ifdef USE_LOCALE
if (PL_hints & HINT_LOCALE)
if (o->op_type == OP_SORT && o->op_flags & OPf_STACKED)
simplify_sort(o);
- if (o->op_flags & OPf_STACKED) { /* may have been cleared */
- OP *kid = cLISTOPo->op_first->op_sibling; /* get past pushmark */
+ firstkid = cLISTOPo->op_first->op_sibling; /* get past pushmark */
+ if (o->op_flags & OPf_STACKED) { /* may have been cleared */
OP *k;
- kid = kUNOP->op_first; /* get past null */
+ OP *kid = cUNOPx(firstkid)->op_first; /* get past null */
if (kid->op_type == OP_SCOPE || kid->op_type == OP_LEAVE) {
linklist(kid);
for (k = kLISTOP->op_first->op_next; k; k = k->op_next) {
if (k->op_next == kid)
k->op_next = 0;
+ /* don't descend into loops */
+ else if (k->op_type == OP_ENTERLOOP
+ || k->op_type == OP_ENTERITER)
+ {
+ k = cLOOPx(k)->op_lastop;
+ }
}
}
else
}
peep(k);
- kid = cLISTOPo->op_first->op_sibling; /* get past pushmark */
- if (o->op_type == OP_SORT)
+ kid = firstkid;
+ if (o->op_type == OP_SORT) {
+ /* provide scalar context for comparison function/block */
+ kid = scalar(kid);
kid->op_next = kid;
+ }
else
kid->op_next = k;
o->op_flags |= OPf_SPECIAL;
}
else if (kid->op_type == OP_RV2SV || kid->op_type == OP_PADSV)
- null(cLISTOPo->op_first->op_sibling);
+ null(firstkid);
+
+ firstkid = firstkid->op_sibling;
}
+ /* provide list context for arguments */
+ if (o->op_type == OP_SORT)
+ list(firstkid);
+
return o;
}
cLISTOPo->op_last = kid; /* There was only one element previously */
}
- if (kid->op_type != OP_MATCH) {
+ if (kid->op_type != OP_MATCH || kid->op_flags & OPf_STACKED) {
OP *sibl = kid->op_sibling;
kid->op_sibling = 0;
kid = pmruntime( newPMOP(OP_MATCH, OPf_SPECIAL), kid, Nullop);
proto++;
arg++;
if (o2->op_type != OP_REFGEN && o2->op_type != OP_UNDEF)
- bad_type(arg, "block", gv_ename(namegv), o2);
+ bad_type(arg,
+ arg == 1 ? "block or sub {}" : "sub {}",
+ gv_ename(namegv), o2);
break;
case '*':
/* '*' allows any scalar type, including bareword */
bad_type(arg, "symbol", gv_ename(namegv), o2);
goto wrapref;
case '&':
- if (o2->op_type != OP_RV2CV)
- bad_type(arg, "sub", gv_ename(namegv), o2);
+ if (o2->op_type != OP_ENTERSUB)
+ bad_type(arg, "subroutine entry", gv_ename(namegv), o2);
goto wrapref;
case '$':
if (o2->op_type != OP_RV2SV
* for reference counts, sv_upgrade() etc. */
if (cSVOP->op_sv) {
PADOFFSET ix = pad_alloc(OP_CONST, SVs_PADTMP);
- SvREFCNT_dec(PL_curpad[ix]);
- SvPADTMP_on(cSVOPo->op_sv);
- PL_curpad[ix] = cSVOPo->op_sv;
+ if (SvPADTMP(cSVOPo->op_sv)) {
+ /* If op_sv is already a PADTMP then it is being used by
+ * another pad, so make a copy. */
+ sv_setsv(PL_curpad[ix],cSVOPo->op_sv);
+ SvREADONLY_on(PL_curpad[ix]);
+ SvREFCNT_dec(cSVOPo->op_sv);
+ }
+ else {
+ SvREFCNT_dec(PL_curpad[ix]);
+ SvPADTMP_on(cSVOPo->op_sv);
+ PL_curpad[ix] = cSVOPo->op_sv;
+ }
cSVOPo->op_sv = Nullsv;
o->op_targ = ix;
}
Perl_warner(aTHX_ WARN_EXEC,
"Statement unlikely to be reached");
Perl_warner(aTHX_ WARN_EXEC,
- "(Maybe you meant system() when you said exec()?)\n");
+ "\t(Maybe you meant system() when you said exec()?)\n");
CopLINE_set(PL_curcop, oldline);
}
}