/* #define PL_OP_SLAB_ALLOC */
-#ifdef PL_OP_SLAB_ALLOC
+#ifdef PL_OP_SLAB_ALLOC
#define SLAB_SIZE 8192
static char *PL_OpPtr = NULL;
static int PL_OpSpace = 0;
var = (type *) Slab_Alloc(m,c*sizeof(type)); \
} while (0)
-STATIC void *
+STATIC void *
S_Slab_Alloc(pTHX_ int m, size_t sz)
-{
+{
Newz(m,PL_OpPtr,SLAB_SIZE,char);
PL_OpSpace = SLAB_SIZE - sz;
return PL_OpPtr += PL_OpSpace;
}
-#else
+#else
#define NewOp(m, var, c, type) Newz(m, var, c, type)
#endif
/*
&& strEQ(name, SvPVX(sv)))
{
Perl_warner(aTHX_ WARN_MISC,
- "\"%s\" variable %s masks earlier declaration in same %s",
+ "\"%s\" variable %s masks earlier declaration in same %s",
(PL_in_my == KEY_our ? "our" : "my"),
name,
(SvIVX(sv) == PAD_MAX ? "scope" : "statement"));
}
}
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));
if (CxREALEVAL(cx))
saweval = i;
break;
+ case OP_DOFILE:
case OP_REQUIRE:
- /* require must have its own scope */
+ /* require/do must have their own scope */
return 0;
}
break;
(sv = names[PL_padix]) && sv != &PL_sv_undef)
continue;
sv = *av_fetch(PL_comppad, PL_padix, TRUE);
- if (!(SvFLAGS(sv) & (SVs_PADTMP|SVs_PADMY)) && !IS_PADGV(sv))
+ if (!(SvFLAGS(sv) & (SVs_PADTMP|SVs_PADMY)) &&
+ !IS_PADGV(sv) && !IS_PADCONST(sv))
break;
}
retval = PL_padix;
break;
case ';':
sv_setpv(sv, "\034");
- sv_magic(sv, 0, 0, name, 1);
+ sv_magic(sv, 0, 0, name, 1);
break;
case '&':
case '`':
/* case '!': */
default:
- sv_magic(sv, 0, 0, name, 1);
+ sv_magic(sv, 0, 0, name, 1);
}
DEBUG_S(PerlIO_printf(Perl_error_log,
"find_threadsv: new SV %p for $%s%c\n",
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));
{
return scalar(o); /* As if inside SASSIGN */
}
-
+
o->op_flags = (o->op_flags & ~OPf_WANT) | OPf_WANT_VOID;
switch (o->op_type) {
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) {
{
return o; /* As if inside SASSIGN */
}
-
+
o->op_flags = (o->op_flags & ~OPf_WANT) | OPf_WANT_LIST;
switch (o->op_type) {
{
return o;
}
-
+
switch (o->op_type) {
case OP_UNDEF:
PL_modcount++;
newop->op_private |= OPpLVAL_INTRO;
break;
}
-
+
if (kid->op_type != OP_RV2CV)
Perl_croak(aTHX_
"panic: unexpected lvalue entersub "
}
cv = GvCV(kGVOP_gv);
- if (!cv)
+ if (!cv)
goto restore_2cv;
if (CvLVALUE(cv))
break;
o->op_flags |= OPf_MOD;
}
break;
-
+
case OP_THREADSV:
o->op_flags |= OPf_MOD; /* XXX ??? */
break;
STATIC void
S_apply_attrs(pTHX_ HV *stash, SV *target, OP *attrs)
{
- OP *modname; /* for 'use' */
SV *stashsv;
/* fake up C<use attributes $pkg,$rv,@attrs> */
stashsv = newSVpv(HvNAME(stash), 0);
else
stashsv = &PL_sv_no;
+
#define ATTRSMODULE "attributes"
- modname = newSVOP(OP_CONST, 0,
- newSVpvn(ATTRSMODULE, sizeof(ATTRSMODULE)-1));
- modname->op_private |= OPpCONST_BARE;
- /* that flag is required to make 'use' work right */
- utilize(1, start_subparse(FALSE, 0),
- Nullop, /* version */
- modname,
- prepend_elem(OP_LIST,
- newSVOP(OP_CONST, 0, stashsv),
- prepend_elem(OP_LIST,
- newSVOP(OP_CONST, 0, newRV(target)),
- dup_attrlist(attrs))));
+
+ Perl_load_module(aTHX_ PERL_LOADMOD_IMPORT_OPS,
+ newSVpvn(ATTRSMODULE, sizeof(ATTRSMODULE)-1),
+ Nullsv,
+ prepend_elem(OP_LIST,
+ newSVOP(OP_CONST, 0, stashsv),
+ prepend_elem(OP_LIST,
+ newSVOP(OP_CONST, 0,
+ newRV(target)),
+ dup_attrlist(attrs))));
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)
{
left->op_type == OP_PADAV)
? "@array" : "%hash");
Perl_warner(aTHX_ WARN_MISC,
- "Applying %s to %s will act on scalar(%s)",
+ "Applying %s to %s will act on scalar(%s)",
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);
PL_pad_reset_pending = FALSE;
SAVEHINTS();
PL_hints &= ~HINT_BLOCK_SCOPE;
- SAVESPTR(PL_compiling.cop_warnings);
+ SAVESPTR(PL_compiling.cop_warnings);
if (! specialWARN(PL_compiling.cop_warnings)) {
PL_compiling.cop_warnings = newSVsv(PL_compiling.cop_warnings) ;
SAVEFREESV(PL_compiling.cop_warnings) ;
first->op_children += last->op_children;
if (first->op_children)
first->op_flags |= OPf_KIDS;
-
+
#ifdef PL_OP_SLAB_ALLOC
#else
- Safefree(last);
+ Safefree(last);
#endif
return (OP*)first;
}
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);
SV* transv = 0;
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;
if (PL_hints & HINT_UTF8)
pm->op_pmdynflags |= PMdf_UTF8;
if (pm->op_pmflags & PMf_KEEP || !(PL_hints & HINT_RE_EVAL))
- expr = newUNOP((!(PL_hints & HINT_RE_EVAL)
+ expr = newUNOP((!(PL_hints & HINT_RE_EVAL)
? OP_REGCRESET
: OP_REGCMAYBE),0,expr);
rcop->op_type = OP_REGCOMP;
rcop->op_ppaddr = PL_ppaddr[OP_REGCOMP];
rcop->op_first = scalar(expr);
- rcop->op_flags |= ((PL_hints & HINT_RE_EVAL)
+ rcop->op_flags |= ((PL_hints & HINT_RE_EVAL)
? (OPf_SPECIAL | OPf_KIDS)
: OPf_KIDS);
rcop->op_private = 1;
}
}
if (curop == repl
- && !(repl_has_vars
- && (!pm->op_pmregexp
+ && !(repl_has_vars
+ && (!pm->op_pmregexp
|| pm->op_pmregexp->reganch & ROPT_EVAL_SEEN))) {
pm->op_pmflags |= PMf_CONST; /* const for long enough */
pm->op_pmpermflags |= PMf_CONST; /* const for long enough */
PL_expect = XSTATE;
}
+void
+Perl_load_module(pTHX_ U32 flags, SV *name, SV *ver, ...)
+{
+ va_list args;
+ va_start(args, ver);
+ vload_module(flags, name, ver, &args);
+ va_end(args);
+}
+
+#ifdef PERL_IMPLICIT_CONTEXT
+void
+Perl_load_module_nocontext(U32 flags, SV *name, SV *ver, ...)
+{
+ dTHX;
+ va_list args;
+ va_start(args, ver);
+ vload_module(flags, name, ver, &args);
+ va_end(args);
+}
+#endif
+
+void
+Perl_vload_module(pTHX_ U32 flags, SV *name, SV *ver, va_list *args)
+{
+ OP *modname, *veop, *imop;
+
+ modname = newSVOP(OP_CONST, 0, name);
+ modname->op_private |= OPpCONST_BARE;
+ if (ver) {
+ veop = newSVOP(OP_CONST, 0, ver);
+ }
+ else
+ veop = Nullop;
+ if (flags & PERL_LOADMOD_NOIMPORT) {
+ imop = sawparens(newNULLLIST());
+ }
+ else if (flags & PERL_LOADMOD_IMPORT_OPS) {
+ imop = va_arg(*args, OP*);
+ }
+ else {
+ SV *sv;
+ imop = Nullop;
+ sv = va_arg(*args, SV*);
+ while (sv) {
+ imop = append_elem(OP_LIST, imop, newSVOP(OP_CONST, 0, sv));
+ sv = va_arg(*args, SV*);
+ }
+ }
+ {
+ 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 *
Perl_dofile(pTHX_ OP *term)
{
cop->cop_arybase = PL_curcop->cop_arybase;
if (specialWARN(PL_curcop->cop_warnings))
cop->cop_warnings = PL_curcop->cop_warnings ;
- else
+ else
cop->cop_warnings = newSVsv(PL_curcop->cop_warnings) ;
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);
}
if (first->op_type == OP_CONST) {
if (ckWARN(WARN_BAREWORD) && (first->op_private & OPpCONST_BARE))
- Perl_warner(aTHX_ WARN_BAREWORD, "Bareword found in conditional");
+ Perl_warner(aTHX_ WARN_BAREWORD, "Bareword found in conditional");
if ((type == OP_AND) == (SvTRUE(((SVOP*)first)->op_sv))) {
op_free(first);
*firstp = Nullop;
case OP_NULL:
if (k2 && k2->op_type == OP_READLINE
&& (k2->op_flags & OPf_STACKED)
- && ((k1->op_flags & OPf_WANT) == OPf_WANT_SCALAR))
+ && ((k1->op_flags & OPf_WANT) == OPf_WANT_SCALAR))
{
warnop = k2->op_type;
}
OP *k1 = ((UNOP*)expr)->op_first;
OP *k2 = (k1) ? k1->op_sibling : NULL;
switch (expr->op_type) {
- case OP_NULL:
+ case OP_NULL:
if (k2 && k2->op_type == OP_READLINE
&& (k2->op_flags & OPf_STACKED)
- && ((k1->op_flags & OPf_WANT) == OPf_WANT_SCALAR))
+ && ((k1->op_flags & OPf_WANT) == OPf_WANT_SCALAR))
expr = newUNOP(OP_DEFINED, 0, expr);
- break;
+ break;
case OP_SASSIGN:
if (k1->op_type == OP_READDIR
OP *k1 = ((UNOP*)expr)->op_first;
OP *k2 = (k1) ? k1->op_sibling : NULL;
switch (expr->op_type) {
- case OP_NULL:
+ case OP_NULL:
if (k2 && k2->op_type == OP_READLINE
&& (k2->op_flags & OPf_STACKED)
- && ((k1->op_flags & OPf_WANT) == OPf_WANT_SCALAR))
+ && ((k1->op_flags & OPf_WANT) == OPf_WANT_SCALAR))
expr = newUNOP(OP_DEFINED, 0, expr);
- break;
+ break;
case OP_SASSIGN:
if (k1->op_type == OP_READDIR
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;
}
#else
Renew(loop, 1, LOOP);
-#endif
+#endif
loop->op_targ = padoff;
wop = newWHILEOP(flags, 1, loop, forline, newOP(OP_ITER, 0), block, cont);
PL_copline = forline;
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 (!o)
return Nullsv;
-
- if (o->op_type == OP_LINESEQ && cLISTOPo->op_first)
+
+ if (o->op_type == OP_LINESEQ && cLISTOPo->op_first)
o = cLISTOPo->op_first->op_sibling;
for (; o; o = o->op_next) {
OPCODE type = o->op_type;
- if (sv && o->op_next == o)
+ if (sv && o->op_next == o)
return sv;
if (type == OP_NEXTSTATE || type == OP_NULL || type == OP_PUSHMARK)
continue;
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
Perl_oopsHV(pTHX_ OP *o)
{
dTHR;
-
+
switch (o->op_type) {
case OP_PADSV:
case OP_PADAV:
}
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;
break;
}
if (badthing)
- Perl_croak(aTHX_
+ Perl_croak(aTHX_
"Can't use bareword (\"%s\") as %s ref while \"strict refs\" in use",
name, badthing);
}
#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);
#if !defined(PERL_EXTERNAL_GLOB)
/* XXX this can be tightened up and made more failsafe. */
if (!gv) {
- OP *modname = newSVOP(OP_CONST, 0, newSVpvn("File::Glob", 10));
- modname->op_private |= OPpCONST_BARE;
ENTER;
- utilize(1, start_subparse(FALSE, 0), Nullop, modname,
- newSVOP(OP_CONST, 0, newSVpvn(":globally", 9)));
+ Perl_load_module(aTHX_ 0, newSVpvn("File::Glob", 10), Nullsv,
+ /* null-terminated import list */
+ newSVpvn(":globally", 9), Nullsv);
gv = gv_fetchpv("CORE::GLOBAL::glob", FALSE, SVt_PVCV);
LEAVE;
}
if ((o->op_flags & OPf_KIDS) && ckWARN(WARN_DEPRECATED)) {
switch (cUNOPo->op_first->op_type) {
case OP_RV2AV:
- break; /* Globals via GV can be undef */
+ /* This is needed for
+ if (defined %stash::)
+ to work. Do not break Tk.
+ */
+ break; /* Globals via GV can be undef */
case OP_PADAV:
case OP_AASSIGN: /* Is this a good idea? */
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 */
+ /* This is needed for
+ if (defined %stash::)
+ to work. Do not break Tk.
+ */
+ break; /* Globals via GV can be undef */
case OP_PADHV:
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 */
SV* sv = kSVOP->op_sv;
if (!(strchr(SvPVX(sv), ':') || strchr(SvPVX(sv), '\''))) {
OP *cmop;
- (void)SvUPGRADE(sv, SVt_PVIV);
- (void)SvIOK_on(sv);
- PERL_HASH(SvUVX(sv), SvPVX(sv), SvCUR(sv));
+ if (!SvREADONLY(sv) || !SvFAKE(sv)) {
+ sv = newSVpvn_share(SvPVX(sv), SvCUR(sv), 0);
+ }
+ else {
+ kSVOP->op_sv = Nullsv;
+ }
cmop = newSVOP(OP_METHOD_NAMED, 0, sv);
- kSVOP->op_sv = Nullsv;
op_free(o);
return cmop;
}
}
OP *
+Perl_ck_open(pTHX_ OP *o)
+{
+ HV *table = GvHV(PL_hintgv);
+ if (table) {
+ SV **svp;
+ I32 mode;
+ svp = hv_fetch(table, "open_IN", 7, FALSE);
+ if (svp && *svp) {
+ mode = mode_from_discipline(*svp);
+ if (mode & O_BINARY)
+ o->op_private |= OPpOPEN_IN_RAW;
+ else if (mode & O_TEXT)
+ o->op_private |= OPpOPEN_IN_CRLF;
+ }
+
+ svp = hv_fetch(table, "open_OUT", 8, FALSE);
+ if (svp && *svp) {
+ mode = mode_from_discipline(*svp);
+ if (mode & O_BINARY)
+ o->op_private |= OPpOPEN_OUT_RAW;
+ else if (mode & O_TEXT)
+ o->op_private |= OPpOPEN_OUT_CRLF;
+ }
+ }
+ if (o->op_type == OP_BACKTICK)
+ return o;
+ return ck_fun(o);
+}
+
+OP *
Perl_ck_repeat(pTHX_ OP *o)
{
if (cBINOPo->op_first->op_flags & OPf_PARENS) {
--SvCUR(kid->op_sv);
}
}
- sv_catpvn(kid->op_sv, ".pm", 3);
+ if (SvREADONLY(kid->op_sv)) {
+ SvREADONLY_off(kid->op_sv);
+ sv_catpvn(kid->op_sv, ".pm", 3);
+ SvREADONLY_on(kid->op_sv);
+ }
+ else
+ sv_catpvn(kid->op_sv, ".pm", 3);
}
}
return ck_fun(o);
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;
}
GV *gv;
if (!(o->op_flags & OPf_STACKED))
return;
- GvMULTI_on(gv_fetchpv("a", TRUE, SVt_PV));
- GvMULTI_on(gv_fetchpv("b", TRUE, SVt_PV));
+ GvMULTI_on(gv_fetchpv("a", TRUE, SVt_PV));
+ GvMULTI_on(gv_fetchpv("b", TRUE, SVt_PV));
kid = kUNOP->op_first; /* get past null */
if (kid->op_type != OP_SCOPE)
return;
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);
}
OP *
-Perl_ck_join(pTHX_ OP *o)
+Perl_ck_join(pTHX_ OP *o)
{
if (ckWARN(WARN_SYNTAX)) {
OP *kid = cLISTOPo->op_first->op_sibling;
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;
}
#endif
- /* FALL THROUGH */
- case OP_UC:
- case OP_UCFIRST:
- case OP_LC:
- case OP_LCFIRST:
+ o->op_seq = PL_op_seqmax++;
+ break;
+
case OP_CONCAT:
- case OP_JOIN:
- case OP_QUOTEMETA:
if (o->op_next && o->op_next->op_type == OP_STRINGIFY) {
if (o->op_next->op_private & OPpTARGET_MY) {
if (o->op_flags & OPf_STACKED) /* chained concats */
goto ignore_optimization;
else {
+ /* assert(PL_opargs[o->op_type] & OA_TARGLEX); */
o->op_targ = o->op_next->op_targ;
o->op_next->op_targ = 0;
o->op_private |= OPpTARGET_MY;
case OP_EXEC:
o->op_seq = PL_op_seqmax++;
- if (ckWARN(WARN_SYNTAX) && o->op_next
+ if (ckWARN(WARN_SYNTAX) && o->op_next
&& o->op_next->op_type == OP_NEXTSTATE) {
if (o->op_next->op_sibling &&
o->op_next->op_sibling->op_type != OP_EXIT &&
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);
}
}
GV **fields;
SV **svp, **indsvp, *sv;
I32 ind;
- char *key;
+ char *key = NULL;
STRLEN keylen;
o->op_seq = PL_op_seqmax++;
- if ((o->op_private & (OPpLVAL_INTRO))
- || ((BINOP*)o)->op_last->op_type != OP_CONST)
+
+ if (((BINOP*)o)->op_last->op_type != OP_CONST)
+ break;
+
+ /* Make the CONST have a shared SV */
+ svp = cSVOPx_svp(((BINOP*)o)->op_last);
+ if ((!SvFAKE(sv = *svp) || !SvREADONLY(sv)) && !IS_PADCONST(sv)) {
+ key = SvPV(sv, keylen);
+ lexname = newSVpvn_share(key, keylen, 0);
+ SvREFCNT_dec(sv);
+ *svp = lexname;
+ }
+
+ if ((o->op_private & (OPpLVAL_INTRO)))
break;
+
rop = (UNOP*)((BINOP*)o)->op_first;
if (rop->op_type != OP_RV2HV || rop->op_first->op_type != OP_PADSV)
break;
fields = (GV**)hv_fetch(SvSTASH(lexname), "FIELDS", 6, FALSE);
if (!fields || !GvHV(*fields))
break;
- svp = cSVOPx_svp(((BINOP*)o)->op_last);
key = SvPV(*svp, keylen);
indsvp = hv_fetch(GvHV(*fields), key, keylen, FALSE);
if (!indsvp) {
while (r->op_sibling)
r = r->op_sibling;
- if (r->op_next == o
+ if (r->op_next == o
|| (r->op_next->op_type == OP_LIST
&& r->op_next->op_next == o))
{