-/* op.c
+ /* op.c
*
* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- * 2000, 2001, 2002, 2003, 2004, 2005, by Larry Wall and others
+ * 2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
void
Perl_Slab_Free(pTHX_ void *op)
{
- I32 ** const ptr = (I32 **) op;
+ I32 * const * const ptr = (I32 **) op;
I32 * const slab = ptr[-1];
assert( ptr-1 > (I32 **) slab );
assert( ptr < ( (I32 **) slab + PERL_SLAB_SIZE) );
S_gv_ename(pTHX_ GV *gv)
{
SV* const tmpsv = sv_newmortal();
- gv_efullname3(tmpsv, gv, Nullch);
+ gv_efullname3(tmpsv, gv, NULL);
return SvPV_nolen_const(tmpsv);
}
Perl_allocmy(pTHX_ char *name)
{
PADOFFSET off;
+ const bool is_our = (PL_in_my == KEY_our);
/* complain about "my $_" etc etc */
- if (!(PL_in_my == KEY_our ||
+ if (*name &&
+ !(is_our ||
isALPHA(name[1]) ||
(USE_UTF8_IN_NAMES && UTF8_IS_START(name[1])) ||
- (name[1] == '_' && (int)strlen(name) > 2)))
+ (name[1] == '_' && name[2])))
{
+ /* name[2] is true if strlen(name) > 2 */
if (!isPRINT(name[1]) || strchr("\t\n\r\f", name[1])) {
/* 1999-02-27 mjd@plover.com */
char *p;
p = strchr(name, '\0');
/* The next block assumes the buffer is at least 205 chars
long. At present, it's always at least 256 chars. */
- if (p-name > 200) {
- strcpy(name+200, "...");
- p = name+199;
+ if (p - name > 200) {
+#ifdef HAS_STRLCPY
+ strlcpy(name + 200, "...", 4);
+#else
+ strcpy(name + 200, "...");
+#endif
+ p = name + 199;
}
else {
p[1] = '\0';
yyerror(Perl_form(aTHX_ "Can't use global %s in \"my\"",name));
}
/* check for duplicate declaration */
- pad_check_dup(name,
- (bool)(PL_in_my == KEY_our),
- (PL_curstash ? PL_curstash : PL_defstash)
- );
+ pad_check_dup(name, is_our, (PL_curstash ? PL_curstash : PL_defstash));
if (PL_in_my_stash && *name != '$') {
yyerror(Perl_form(aTHX_
"Can't declare class for non-scalar %s in \"%s\"",
- name, PL_in_my == KEY_our ? "our" : "my"));
+ name, is_our ? "our" : "my"));
}
/* allocate a spare slot and store the name in that slot */
off = pad_add_name(name,
PL_in_my_stash,
- (PL_in_my == KEY_our
+ (is_our
? (PL_curstash ? PL_curstash : PL_defstash)
- : Nullhv
+ : NULL
),
0 /* not fake */
);
if (svp)
MUTEX_UNLOCK(&thr->mutex);
else {
- SV *sv = NEWSV(0, 0);
+ SV *sv = newSV(0);
av_store(thr->threadsv, key, sv);
thr->threadsvp = AvARRAY(thr->threadsv);
MUTEX_UNLOCK(&thr->mutex);
}
#else
SvREFCNT_dec(cSVOPo->op_sv);
- cSVOPo->op_sv = Nullsv;
+ cSVOPo->op_sv = NULL;
#endif
}
break;
case OP_METHOD_NAMED:
case OP_CONST:
SvREFCNT_dec(cSVOPo->op_sv);
- cSVOPo->op_sv = Nullsv;
+ cSVOPo->op_sv = NULL;
#ifdef USE_ITHREADS
/** Bug #15654
Even if op_clear does a pad_free for the target of the op,
case OP_TRANS:
if (o->op_private & (OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF)) {
SvREFCNT_dec(cSVOPo->op_sv);
- cSVOPo->op_sv = Nullsv;
+ cSVOPo->op_sv = NULL;
}
else {
Safefree(cPVOPo->op_pv);
- cPVOPo->op_pv = Nullch;
+ cPVOPo->op_pv = NULL;
}
break;
case OP_SUBST:
case OP_QR:
clear_pmop:
{
- HV *pmstash = PmopSTASH(cPMOPo);
- if (pmstash && SvREFCNT(pmstash)) {
+ HV * const pmstash = PmopSTASH(cPMOPo);
+ if (pmstash && !SvIS_FREED(pmstash)) {
PMOP *pmop = HvPMROOT(pmstash);
PMOP *lastpmop = NULL;
while (pmop) {
SvREFCNT_dec(cop->cop_io);
#endif
}
+ if (PL_curcop == cop)
+ PL_curcop = NULL;
}
void
OP *
Perl_linklist(pTHX_ OP *o)
{
+ OP *first;
if (o->op_next)
return o->op_next;
/* establish postfix order */
- if (cUNOPo->op_first) {
+ first = cUNOPo->op_first;
+ if (first) {
register OP *kid;
- o->op_next = LINKLIST(cUNOPo->op_first);
- for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) {
- if (kid->op_sibling)
+ o->op_next = LINKLIST(first);
+ kid = first;
+ for (;;) {
+ if (kid->op_sibling) {
kid->op_next = LINKLIST(kid->op_sibling);
- else
+ kid = kid->op_sibling;
+ } else {
kid->op_next = o;
+ break;
+ }
}
}
else
OP *kid;
/* assumes no premature commitment */
- if (!o || (o->op_flags & OPf_WANT) || PL_error_count
+ if (!o || PL_error_count || (o->op_flags & OPf_WANT)
|| o->op_type == OP_RETURN)
{
return o;
Perl_scalarvoid(pTHX_ OP *o)
{
OP *kid;
- const char* useless = 0;
+ const char* useless = NULL;
SV* sv;
U8 want;
built upon these three nroff macros being used in
void context. The pink camel has the details in
the script wrapman near page 319. */
- if (strnEQ(SvPVX_const(sv), "di", 2) ||
- strnEQ(SvPVX_const(sv), "ds", 2) ||
- strnEQ(SvPVX_const(sv), "ig", 2))
+ const char * const maybe_macro = SvPVX_const(sv);
+ if (strnEQ(maybe_macro, "di", 2) ||
+ strnEQ(maybe_macro, "ds", 2) ||
+ strnEQ(maybe_macro, "ig", 2))
useless = 0;
}
}
o->op_ppaddr = PL_ppaddr[OP_PREDEC];
break;
+ case OP_I_POSTINC:
+ o->op_type = OP_I_PREINC; /* pre-increment is faster */
+ o->op_ppaddr = PL_ppaddr[OP_I_PREINC];
+ break;
+
+ case OP_I_POSTDEC:
+ o->op_type = OP_I_PREDEC; /* pre-decrement is faster */
+ o->op_ppaddr = PL_ppaddr[OP_I_PREDEC];
+ break;
+
case OP_OR:
case OP_AND:
case OP_COND_EXPR:
if ((type == OP_UNDEF || type == OP_REFGEN) &&
!(o->op_flags & OPf_STACKED)) {
o->op_type = OP_RV2CV; /* entersub => rv2cv */
+ /* The default is to set op_private to the number of children,
+ which for a UNOP such as RV2CV is always 1. And w're using
+ the bit for a flag in RV2CV, so we need it clear. */
+ o->op_private &= ~1;
o->op_ppaddr = PL_ppaddr[OP_RV2CV];
assert(cUNOPo->op_first->op_type == OP_NULL);
op_null(((LISTOP*)cUNOPo->op_first)->op_first);/* disable pushmark */
newop->op_next = (OP*)newop;
kid->op_sibling = (OP*)newop;
newop->op_private |= OPpLVAL_INTRO;
+ newop->op_private &= ~1;
break;
}
okid->op_targ = 0;
okid->op_ppaddr = PL_ppaddr[OP_RV2CV];
okid->op_private |= OPpLVAL_INTRO;
+ okid->op_private &= ~1;
break;
}
}
OP *
-Perl_ref(pTHX_ OP *o, I32 type)
+Perl_doref(pTHX_ OP *o, I32 type, bool set_op_ref)
{
OP *kid;
assert(cUNOPo->op_first->op_type == OP_NULL);
op_null(((LISTOP*)cUNOPo->op_first)->op_first); /* disable pushmark */
o->op_flags |= OPf_SPECIAL;
+ o->op_private &= ~1;
}
break;
case OP_COND_EXPR:
for (kid = cUNOPo->op_first->op_sibling; kid; kid = kid->op_sibling)
- ref(kid, type);
+ doref(kid, type, set_op_ref);
break;
case OP_RV2SV:
if (type == OP_DEFINED)
o->op_flags |= OPf_SPECIAL; /* don't create GV */
- ref(cUNOPo->op_first, o->op_type);
+ doref(cUNOPo->op_first, o->op_type, set_op_ref);
/* FALL THROUGH */
case OP_PADSV:
if (type == OP_RV2SV || type == OP_RV2AV || type == OP_RV2HV) {
}
break;
+#ifdef USE_5005THREADS
case OP_THREADSV:
o->op_flags |= OPf_MOD; /* XXX ??? */
break;
+#endif
case OP_RV2AV:
case OP_RV2HV:
- o->op_flags |= OPf_REF;
+ if (set_op_ref)
+ o->op_flags |= OPf_REF;
/* FALL THROUGH */
case OP_RV2GV:
if (type == OP_DEFINED)
o->op_flags |= OPf_SPECIAL; /* don't create GV */
- ref(cUNOPo->op_first, o->op_type);
+ doref(cUNOPo->op_first, o->op_type, set_op_ref);
break;
case OP_PADAV:
case OP_PADHV:
- o->op_flags |= OPf_REF;
+ if (set_op_ref)
+ o->op_flags |= OPf_REF;
break;
case OP_SCALAR:
case OP_NULL:
if (!(o->op_flags & OPf_KIDS))
break;
- ref(cBINOPo->op_first, type);
+ doref(cBINOPo->op_first, type, set_op_ref);
break;
case OP_AELEM:
case OP_HELEM:
- ref(cBINOPo->op_first, o->op_type);
+ doref(cBINOPo->op_first, o->op_type, set_op_ref);
if (type == OP_RV2SV || type == OP_RV2AV || type == OP_RV2HV) {
o->op_private |= (type == OP_RV2AV ? OPpDEREF_AV
: type == OP_RV2HV ? OPpDEREF_HV
case OP_SCOPE:
case OP_LEAVE:
+ set_op_ref = FALSE;
+ /* FALL THROUGH */
case OP_ENTER:
case OP_LIST:
if (!(o->op_flags & OPf_KIDS))
break;
- ref(cLISTOPo->op_last, type);
+ doref(cLISTOPo->op_last, type, set_op_ref);
break;
default:
break;
STATIC OP *
S_dup_attrlist(pTHX_ OP *o)
{
- OP *rop = Nullop;
+ OP *rop;
/* An attrlist is either a simple OP_CONST or an OP_LIST with kids,
* where the first kid is OP_PUSHMARK and the remaining ones
* are OP_CONST. We need to push the OP_CONST values.
*/
if (o->op_type == OP_CONST)
- rop = newSVOP(OP_CONST, o->op_flags, SvREFCNT_inc(cSVOPo->op_sv));
+ rop = newSVOP(OP_CONST, o->op_flags, SvREFCNT_inc_NN(cSVOPo->op_sv));
else {
assert((o->op_type == OP_LIST) && (o->op_flags & OPf_KIDS));
+ rop = Nullop;
for (o = cLISTOPo->op_first; o; o=o->op_sibling) {
if (o->op_type == OP_CONST)
rop = append_elem(OP_LIST, rop,
newSVOP(OP_CONST, o->op_flags,
- SvREFCNT_inc(cSVOPo->op_sv)));
+ SvREFCNT_inc_NN(cSVOPo->op_sv)));
}
}
return rop;
if (for_my) {
/* Don't force the C<use> if we don't need it. */
- SV **svp = hv_fetch(GvHVn(PL_incgv), ATTRSMODULE_PM,
- sizeof(ATTRSMODULE_PM)-1, 0);
+ SV * const * const svp = hv_fetchs(GvHVn(PL_incgv), ATTRSMODULE_PM, FALSE);
if (svp && *svp != &PL_sv_undef)
; /* already in %INC */
else
Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT,
- newSVpvn(ATTRSMODULE, sizeof(ATTRSMODULE)-1),
- Nullsv);
+ newSVpvs(ATTRSMODULE), NULL);
}
else {
Perl_load_module(aTHX_ PERL_LOADMOD_IMPORT_OPS,
- newSVpvn(ATTRSMODULE, sizeof(ATTRSMODULE)-1),
- Nullsv,
+ newSVpvs(ATTRSMODULE),
+ NULL,
prepend_elem(OP_LIST,
newSVOP(OP_CONST, 0, stashsv),
prepend_elem(OP_LIST,
apply_attrs(stash, PAD_SV(target->op_targ), attrs, TRUE);
/* Need package name for method call. */
- pack = newSVOP(OP_CONST, 0, newSVpvn(ATTRSMODULE, sizeof(ATTRSMODULE)-1));
+ pack = newSVOP(OP_CONST, 0, newSVpvs(ATTRSMODULE));
/* Build up the real arg-list. */
if (stash)
dup_attrlist(attrs)));
/* Fake up a method call to import */
- meth = newSVpvn("import", 6);
- (void)SvUPGRADE(meth, SVt_PVIV);
- (void)SvIOK_on(meth);
- {
- U32 hash;
- PERL_HASH(hash, SvPVX_const(meth), SvCUR(meth));
- SvUV_set(meth, hash);
- }
+ meth = newSVpvs("import");
imop = convert(OP_ENTERSUB, OPf_STACKED|OPf_SPECIAL|OPf_WANT_VOID,
append_elem(OP_LIST,
prepend_elem(OP_LIST, pack, list(arg)),
}
Perl_load_module(aTHX_ PERL_LOADMOD_IMPORT_OPS,
- newSVpvn(ATTRSMODULE, sizeof(ATTRSMODULE)-1),
- Nullsv, prepend_elem(OP_LIST,
+ newSVpvs(ATTRSMODULE),
+ NULL, prepend_elem(OP_LIST,
newSVOP(OP_CONST, 0, newSVpv(stashpv,0)),
prepend_elem(OP_LIST,
newSVOP(OP_CONST, 0,
yyerror(Perl_form(aTHX_ "Can't declare %s in %s",
OP_DESC(o), PL_in_my == KEY_our ? "our" : "my"));
} else if (attrs) {
- GV *gv = cGVOPx_gv(cUNOPo->op_first);
+ GV * const gv = cGVOPx_gv(cUNOPo->op_first);
PL_in_my = FALSE;
- PL_in_my_stash = Nullhv;
+ PL_in_my_stash = NULL;
apply_attrs(GvSTASH(gv),
(type == OP_RV2SV ? GvSV(gv) :
type == OP_RV2AV ? (SV*)GvAV(gv) :
HV *stash;
PL_in_my = FALSE;
- PL_in_my_stash = Nullhv;
+ PL_in_my_stash = NULL;
/* check for C<my Dog $spot> when deciding package */
stash = PAD_COMPNAME_TYPE(o->op_targ);
OP *
Perl_my_attrs(pTHX_ OP *o, OP *attrs)
{
- OP *rops = Nullop;
+ OP *rops;
int maybe_scalar = 0;
/* [perl #17376]: this appears to be premature, and results in code such as
#endif
if (attrs)
SAVEFREEOP(attrs);
+ rops = Nullop;
o = my_kid(o, attrs, &rops);
if (rops) {
if (maybe_scalar && o->op_type == OP_PADSV) {
o = append_list(OP_LIST, (LISTOP*)o, (LISTOP*)rops);
}
PL_in_my = FALSE;
- PL_in_my_stash = Nullhv;
+ PL_in_my_stash = NULL;
return o;
}
{
OP *o;
- if (ckWARN(WARN_MISC) &&
- (left->op_type == OP_RV2AV ||
+ if ( (left->op_type == OP_RV2AV ||
left->op_type == OP_RV2HV ||
left->op_type == OP_PADAV ||
- left->op_type == OP_PADHV)) {
- const char *desc = PL_op_desc[(right->op_type == OP_SUBST ||
+ left->op_type == OP_PADHV)
+ && ckWARN(WARN_MISC))
+ {
+ const char * const desc = PL_op_desc[(right->op_type == OP_SUBST ||
right->op_type == OP_TRANS)
? right->op_type : OP_MATCH];
- const char *sample = ((left->op_type == OP_RV2AV ||
+ const char * const sample = ((left->op_type == OP_RV2AV ||
left->op_type == OP_PADAV)
? "@array" : "%hash");
Perl_warner(aTHX_ packWARN(WARN_MISC),
o->op_type = OP_SCOPE;
o->op_ppaddr = PL_ppaddr[OP_SCOPE];
kid = ((LISTOP*)o)->op_first;
- if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE)
+ if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) {
op_null(kid);
+
+ /* The following deals with things like 'do {1 for 1}' */
+ kid = kid->op_sibling;
+ if (kid &&
+ (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE))
+ op_null(kid);
+ }
}
else
o = newLISTOP(OP_SCOPE, 0, o, Nullop);
return o;
}
-/* XXX kept for BINCOMPAT only */
-void
-Perl_save_hints(pTHX)
-{
- Perl_croak(aTHX_ "internal error: obsolete function save_hints() called");
-}
-
int
Perl_block_start(pTHX_ int full)
{
Perl_block_end(pTHX_ I32 floor, OP *seq)
{
const int needblockscope = PL_hints & HINT_BLOCK_SCOPE;
- OP* retval = scalarseq(seq);
+ OP* const retval = scalarseq(seq);
/* If there were syntax errors, don't try to close a block */
if (PL_yynerrs) return retval;
LEAVE_SCOPE(floor);
S_newDEFSVOP(pTHX)
{
#ifdef USE_5005THREADS
- OP *o = newOP(OP_THREADSV, 0);
+ OP *const o = newOP(OP_THREADSV, 0);
o->op_targ = find_threadsv("_");
return o;
#else
/* Register with debugger */
if (PERLDB_INTER) {
- CV *cv = get_cv("DB::postponed", FALSE);
+ CV * const cv = get_cv("DB::postponed", FALSE);
if (cv) {
dSP;
PUSHMARK(SP);
;
#endif
else {
- if (ckWARN(WARN_PARENTHESIS)
- && PL_bufptr > PL_oldbufptr && PL_bufptr[-1] == ',')
+ if ( PL_bufptr > PL_oldbufptr && PL_bufptr[-1] == ','
+ && ckWARN(WARN_PARENTHESIS))
{
char *s = PL_bufptr;
bool sigil = FALSE;
else
o = mod(o, OP_NULL); /* a bit kludgey */
PL_in_my = FALSE;
- PL_in_my_stash = Nullhv;
+ PL_in_my_stash = NULL;
return o;
}
Perl_jmaybe(pTHX_ OP *o)
{
if (o->op_type == OP_LIST) {
- OP *o2;
#ifdef USE_5005THREADS
- o2 = newOP(OP_THREADSV, 0);
+ OP * const o2 = newOP(OP_THREADSV, 0);
o2->op_targ = find_threadsv(";");
#else
- o2 = newSVREF(newGVOP(OP_GV, 0, gv_fetchpv(";", TRUE, SVt_PV))),
+ OP * const o2
+ = newSVREF(newGVOP(OP_GV, 0, gv_fetchpvs(";", GV_ADD|GV_NOTQUAL,
+ SVt_PV)));
#endif /* USE_5005THREADS */
o = convert(OP_JOIN, 0, prepend_elem(OP_LIST, o2, o));
}
return o;
}
+#ifdef PERL_FLEXIBLE_EXCEPTIONS
+STATIC void *
+S_vcall_runops(pTHX_ va_list args)
+{
+ CALLRUNOPS(aTHX);
+ return NULL;
+}
+#endif
+
OP *
Perl_fold_constants(pTHX_ register OP *o)
{
register OP *curop;
I32 type = o->op_type;
SV *sv;
+ int ret = 0;
+ I32 oldscope;
+ OP *old_next;
+ dJMPENV;
if (PL_opargs[type] & OA_RETSCALAR)
scalar(o);
/* XXX might want a ck_negate() for this */
cUNOPo->op_first->op_private &= ~OPpCONST_STRICT;
break;
- case OP_SPRINTF:
case OP_UCFIRST:
case OP_LCFIRST:
case OP_UC:
}
curop = LINKLIST(o);
+ old_next = o->op_next;
o->op_next = 0;
PL_op = curop;
- CALLRUNOPS(aTHX);
- sv = *(PL_stack_sp--);
- if (o->op_targ && sv == PAD_SV(o->op_targ)) /* grab pad temp? */
- pad_swipe(o->op_targ, FALSE);
- else if (SvTEMP(sv)) { /* grab mortal temp? */
- (void)SvREFCNT_inc(sv);
- SvTEMP_off(sv);
+
+ oldscope = PL_scopestack_ix;
+
+ /* we're trying to emulate pp_entertry() here */
+ {
+ register PERL_CONTEXT *cx;
+ const I32 gimme = GIMME_V;
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), PL_stack_sp);
+ PUSHEVAL(cx, 0, 0);
+ PL_eval_root = PL_op; /* Only needed so that goto works right. */
+
+ PL_in_eval = EVAL_INEVAL;
+ sv_setpvn(ERRSV,"",0);
+ }
+
+#ifdef PERL_FLEXIBLE_EXCEPTIONS
+ CALLPROTECT(aTHX_ pcur_env, &ret, MEMBER_TO_FPTR(S_vcall_runops));
+#else
+ JMPENV_PUSH(ret);
+#endif
+ switch (ret) {
+ case 0:
+#ifndef PERL_FLEXIBLE_EXCEPTIONS
+ CALLRUNOPS(aTHX);
+#endif
+ sv = *(PL_stack_sp--);
+ if (o->op_targ && sv == PAD_SV(o->op_targ)) /* grab pad temp? */
+ pad_swipe(o->op_targ, FALSE);
+ else if (SvTEMP(sv)) { /* grab mortal temp? */
+ SvREFCNT_inc_simple_void(sv);
+ SvTEMP_off(sv);
+ }
+ break;
+ case 3:
+ /* Something tried to die. Abandon constant folding. */
+ /* Pretend the error never happened. */
+ sv_setpvn(ERRSV,"",0);
+ o->op_next = old_next;
+ break;
+ default:
+ JMPENV_POP;
+ /* Don't expect 1 (setjmp failed) or 2 (something called my_exit) */
+ Perl_croak(aTHX_ "panic: fold_constants JMPENV_PUSH returned %d", ret);
+ }
+
+ JMPENV_POP;
+ if (PL_scopestack_ix > oldscope) {
+ SV **newsp;
+ PMOP *newpm;
+ I32 gimme;
+ register PERL_CONTEXT *cx;
+ I32 optype;
+
+ POPBLOCK(cx,newpm);
+ POPEVAL(cx);
+ PL_curpm = newpm;
+ LEAVE;
+ PERL_UNUSED_VAR(newsp);
+ PERL_UNUSED_VAR(gimme);
+ PERL_UNUSED_VAR(optype);
}
+
+ if (ret)
+ goto nope;
+
op_free(o);
if (type == OP_RV2GV)
return newGVOP(OP_GV, 0, (GV*)sv);
return newSVOP(OP_CONST, 0, sv);
- nope:
+ nope:
return o;
}
pp_pushmark();
CALLRUNOPS(aTHX);
PL_op = curop;
+ assert (!(curop->op_flags & OPf_SPECIAL));
+ assert(curop->op_type == OP_RANGE);
pp_anonlist();
PL_tmps_floor = oldtmps_floor;
o->op_flags |= OPf_PARENS; /* and flatten \(1..2,3) */
o->op_seq = 0; /* needs to be revisited in peep() */
curop = ((UNOP*)o)->op_first;
- ((UNOP*)o)->op_first = newSVOP(OP_CONST, 0, SvREFCNT_inc(*PL_stack_sp--));
+ ((UNOP*)o)->op_first = newSVOP(OP_CONST, 0, SvREFCNT_inc_NN(*PL_stack_sp--));
op_free(curop);
linklist(o);
return list(o);
listop->op_first = first;
listop->op_last = last;
if (type == OP_LIST) {
- OP* pushop;
- pushop = newOP(OP_PUSHMARK, 0);
+ OP* const pushop = newOP(OP_PUSHMARK, 0);
pushop->op_sibling = first;
listop->op_first = pushop;
listop->op_flags |= OPf_KIDS;
unop->op_type = (OPCODE)type;
unop->op_ppaddr = PL_ppaddr[type];
unop->op_first = first;
- unop->op_flags = flags | OPf_KIDS;
+ unop->op_flags = (U8)(flags | OPf_KIDS);
unop->op_private = (U8)(1 | (flags >> 8));
unop = (UNOP*) CHECKOP(type, unop);
if (unop->op_next)
binop->op_type = (OPCODE)type;
binop->op_ppaddr = PL_ppaddr[type];
binop->op_first = first;
- binop->op_flags = flags | OPf_KIDS;
+ binop->op_flags = (U8)(flags | OPf_KIDS);
if (!last) {
last = first;
binop->op_private = (U8)(1 | (flags >> 8));
const U8 *r = (U8*)SvPV_const(rstr, rlen);
register I32 i;
register I32 j;
- I32 del;
- I32 complement;
- I32 squash;
I32 grows = 0;
register short *tbl;
+ const I32 complement = o->op_private & OPpTRANS_COMPLEMENT;
+ const I32 squash = o->op_private & OPpTRANS_SQUASH;
+ I32 del = o->op_private & OPpTRANS_DELETE;
PL_hints |= HINT_BLOCK_SCOPE;
- 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;
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;
+ SV* const listsv = newSVpvs("# comment\n");
+ SV* transv = NULL;
const U8* tend = t + tlen;
const U8* rend = r + rlen;
STRLEN ulen;
I32 bits;
I32 havefinal = 0;
U32 final = 0;
- I32 from_utf = o->op_private & OPpTRANS_FROM_UTF;
- I32 to_utf = o->op_private & OPpTRANS_TO_UTF;
+ const I32 from_utf = o->op_private & OPpTRANS_FROM_UTF;
+ const I32 to_utf = o->op_private & OPpTRANS_TO_UTF;
U8* tsave = NULL;
U8* rsave = NULL;
UV nextmin = 0;
Newx(cp, 2*tlen, UV);
i = 0;
- transv = newSVpvn("",0);
+ transv = newSVpvs("");
while (t < tend) {
cp[2*i] = utf8n_to_uvuni((U8 *)t, tend-t, &ulen, 0);
t += ulen;
Safefree(cPVOPo->op_pv);
cSVOPo->op_sv = (SV*)swash_init("utf8", "", listsv, bits, none);
SvREFCNT_dec(listsv);
- if (transv)
- SvREFCNT_dec(transv);
+ SvREFCNT_dec(transv);
if (!del && havefinal && rlen)
(void)hv_store((HV*)SvRV((cSVOPo->op_sv)), "FINAL", 5,
if (grows)
o->op_private |= OPpTRANS_GROWS;
- if (tsave)
- Safefree(tsave);
- if (rsave)
- Safefree(rsave);
+ Safefree(tsave);
+ Safefree(rsave);
op_free(expr);
op_free(repl);
j = rlen - 1;
else
cPVOPo->op_pv = (char*)Renew(tbl, 0x101+rlen-j, short);
- tbl[0x100] = rlen - j;
+ tbl[0x100] = (short)(rlen - j);
for (i=0; i < (I32)rlen - j; i++)
tbl[0x101+i] = r[j+i];
}
pmop->op_pmflags = pmop->op_pmpermflags;
#ifdef USE_ITHREADS
- {
- SV* repointer;
- if(av_len((AV*) PL_regex_pad[0]) > -1) {
- repointer = av_pop((AV*)PL_regex_pad[0]);
- pmop->op_pmoffset = SvIV(repointer);
- SvREPADTMP_off(repointer);
- sv_setiv(repointer,0);
- } else {
- repointer = newSViv(0);
- av_push(PL_regex_padav,SvREFCNT_inc(repointer));
- pmop->op_pmoffset = av_len(PL_regex_padav);
- PL_regex_pad = AvARRAY(PL_regex_padav);
- }
+ if (av_len((AV*) PL_regex_pad[0]) > -1) {
+ SV * const repointer = av_pop((AV*)PL_regex_pad[0]);
+ pmop->op_pmoffset = SvIV(repointer);
+ SvREPADTMP_off(repointer);
+ sv_setiv(repointer,0);
+ } else {
+ SV * const repointer = newSViv(0);
+ av_push(PL_regex_padav, SvREFCNT_inc_simple_NN(repointer));
+ pmop->op_pmoffset = av_len(PL_regex_padav);
+ PL_regex_pad = AvARRAY(PL_regex_padav);
}
#endif
if (expr->op_type == OP_CONST) {
STRLEN plen;
- SV *pat = ((SVOP*)expr)->op_sv;
+ SV * const pat = ((SVOP*)expr)->op_sv;
const char *p = SvPV_const(pat, plen);
if ((o->op_flags & OPf_SPECIAL) && (*p == ' ' && p[1] == '\0')) {
U32 was_readonly = SvREADONLY(pat);
if (repl) {
OP *curop;
if (pm->op_pmflags & PMf_EVAL) {
- curop = 0;
+ curop = NULL;
if (CopLINE(PL_curcop) < (line_t)PL_multi_end)
CopLINE_set(PL_curcop, (line_t)PL_multi_end);
}
else if (repl->op_type == OP_CONST)
curop = repl;
else {
- OP *lastop = 0;
+ OP *lastop = NULL;
for (curop = LINKLIST(repl); curop!=repl; curop = LINKLIST(curop)) {
if (PL_opargs[curop->op_type] & OA_DANGEROUS) {
#ifdef USE_5005THREADS
}
#else
if (curop->op_type == OP_GV) {
- GV *gv = cGVOPx_gv(curop);
+ GV * const gv = cGVOPx_gv(curop);
repl_has_vars = 1;
if (strchr("&`'123456789+-\016\022", *GvENAME(gv)))
break;
#ifdef USE_ITHREADS
if (gv)
GvIN_PAD_on(gv);
- return newPADOP(type, flags, SvREFCNT_inc(gv));
+ return newPADOP(type, flags, SvREFCNT_inc_simple(gv));
#else
- return newSVOP(type, flags, SvREFCNT_inc(gv));
+ return newSVOP(type, flags, SvREFCNT_inc_simple(gv));
#endif
}
veop = Nullop;
if (version) {
- SV *vesv = ((SVOP*)version)->op_sv;
+ SV * const vesv = ((SVOP*)version)->op_sv;
if (!arg && !SvNIOKp(vesv)) {
arg = version;
pack = newSVOP(OP_CONST, 0, newSVsv(((SVOP*)idop)->op_sv));
/* Fake up a method call to VERSION */
- meth = newSVpvn("VERSION",7);
+ meth = newSVpvs("VERSION");
sv_upgrade(meth, SVt_PVIV);
(void)SvIOK_on(meth);
{
imop = arg; /* no import on explicit () */
else if (SvNIOKp(((SVOP*)idop)->op_sv)) {
imop = Nullop; /* use 5.0; */
+ if (!aver)
+ idop->op_private |= OPpCONST_NOVER;
}
else {
SV *meth;
pack = newSVOP(OP_CONST, 0, newSVsv(((SVOP*)idop)->op_sv));
/* Fake up a method call to import/unimport */
- meth = aver ? newSVpvn("import",6) : newSVpvn("unimport", 8);
+ meth = aver ? newSVpvs("import") : newSVpvs("unimport");
(void)SvUPGRADE(meth, SVt_PVIV);
(void)SvIOK_on(meth);
{
/* Fake up the BEGIN {}, which does its thing immediately. */
newATTRSUB(floor,
- newSVOP(OP_CONST, 0, newSVpvn("BEGIN", 5)),
+ newSVOP(OP_CONST, 0, newSVpvs("BEGIN")),
Nullop,
Nullop,
append_elem(OP_LINESEQ,
append_elem(OP_LINESEQ,
- newSTATEOP(0, Nullch, newUNOP(OP_REQUIRE, 0, idop)),
- newSTATEOP(0, Nullch, veop)),
- newSTATEOP(0, Nullch, imop) ));
+ newSTATEOP(0, NULL, newUNOP(OP_REQUIRE, 0, idop)),
+ newSTATEOP(0, NULL, veop)),
+ newSTATEOP(0, NULL, imop) ));
/* The "did you use incorrect case?" warning used to be here.
* The problem is that on case-insensitive filesystems one
void
Perl_vload_module(pTHX_ U32 flags, SV *name, SV *ver, va_list *args)
{
- OP *modname, *veop, *imop;
+ OP *veop, *imop;
- modname = newSVOP(OP_CONST, 0, name);
+ OP * const modname = newSVOP(OP_CONST, 0, name);
modname->op_private |= OPpCONST_BARE;
if (ver) {
veop = newSVOP(OP_CONST, 0, ver);
OP *
Perl_dofile(pTHX_ OP *term)
{
+ return dofile2(term, 0);
+}
+
+OP *
+Perl_dofile2(pTHX_ OP *term, I32 force_builtin)
+{
OP *doop;
- GV *gv;
+ GV *gv = Nullgv;
- gv = gv_fetchpv("do", FALSE, SVt_PVCV);
- if (!(gv && GvCVu(gv) && GvIMPORTED_CV(gv)))
- gv = gv_fetchpv("CORE::GLOBAL::do", FALSE, SVt_PVCV);
+ if (!force_builtin) {
+ gv = gv_fetchpvs("do", GV_NOTQUAL, SVt_PVCV);
+ if (!(gv && GvCVu(gv) && GvIMPORTED_CV(gv))) {
+ GV * const * const gvp = (GV**)hv_fetchs(PL_globalstash, "do", FALSE);
+ gv = gvp ? *gvp : Nullgv;
+ }
+ }
if (gv && GvCVu(gv) && GvIMPORTED_CV(gv)) {
doop = ck_subr(newUNOP(OP_ENTERSUB, OPf_STACKED,
OP *curop;
PL_modcount = 0;
- PL_eval_start = right; /* Grandfathering $[ assignment here. Bletch.*/
+ /* Grandfathering $[ assignment here. Bletch.*/
+ /* Only simple assignments like C<< ($[) = 1 >> are allowed */
+ PL_eval_start = (left->op_type == OP_CONST) ? right : 0;
left = mod(left, OP_AASSIGN);
if (PL_eval_start)
PL_eval_start = 0;
- else {
- op_free(left);
- op_free(right);
- return Nullop;
- }
- /* optimise C<my @x = ()> to C<my @x>, and likewise for hashes */
- if ((left->op_type == OP_PADAV || left->op_type == OP_PADHV)
- && right->op_type == OP_STUB
- && (left->op_private & OPpLVAL_INTRO))
- {
- op_free(right);
- left->op_flags &= ~(OPf_REF|OPf_SPECIAL);
- return left;
+ else if (left->op_type == OP_CONST) {
+ /* Result of assignment is always 1 (or we'd be dead already) */
+ return newSVOP(OP_CONST, 0, newSViv(1));
}
curop = list(force_list(left));
o = newBINOP(OP_AASSIGN, flags, list(force_list(right)), curop);
if ((tmpop = ((LISTOP*)right)->op_first) &&
tmpop->op_type == OP_PUSHRE)
{
- PMOP *pm = (PMOP*)tmpop;
+ PMOP * const pm = (PMOP*)tmpop;
if (left->op_type == OP_RV2AV &&
!(left->op_private & OPpLVAL_INTRO) &&
!(o->op_private & OPpASSIGN_COMMON) )
cPADOPx(tmpop)->op_padix = 0; /* steal it */
#else
pm->op_pmreplroot = (OP*)cSVOPx(tmpop)->op_sv;
- cSVOPx(tmpop)->op_sv = Nullsv; /* steal it */
+ cSVOPx(tmpop)->op_sv = NULL; /* steal it */
#endif
pm->op_pmflags |= PMf_ONCE;
tmpop = cUNOPo->op_first; /* to list (nulled) */
if (PL_eval_start)
PL_eval_start = 0;
else {
- op_free(o);
- return Nullop;
+ o = newSVOP(OP_CONST, 0, newSViv(PL_compiling.cop_arybase));
}
}
return o;
CopSTASH_set(cop, PL_curstash);
if (PERLDB_LINE && PL_curstash != PL_debstash) {
- SV ** const svp = av_fetch(CopFILEAV(PL_curcop), (I32)CopLINE(cop), FALSE);
+ SV * const * const svp = av_fetch(CopFILEAVx(PL_curcop), (I32)CopLINE(cop), FALSE);
if (svp && *svp != &PL_sv_undef ) {
(void)SvIOK_on(*svp);
SvIV_set(*svp, PTR2IV(cop));
if (first->op_type == OP_CONST) {
if (first->op_private & OPpCONST_STRICT)
no_bareword_allowed(first);
- else if (ckWARN(WARN_BAREWORD) && (first->op_private & OPpCONST_BARE))
+ else if ((first->op_private & OPpCONST_BARE) && ckWARN(WARN_BAREWORD))
Perl_warner(aTHX_ packWARN(WARN_BAREWORD), "Bareword found in conditional");
if ((type == OP_AND) == (SvTRUE(((SVOP*)first)->op_sv))) {
op_free(first);
return first;
}
}
- else if (ckWARN(WARN_MISC) && (first->op_flags & OPf_KIDS)) {
+ else if ((first->op_flags & OPf_KIDS) && ckWARN(WARN_MISC)) {
const OP * const k1 = ((UNOP*)first)->op_first;
const OP * const k2 = k1->op_sibling;
OPCODE warnop = 0;
logop->op_type = (OPCODE)type;
logop->op_ppaddr = PL_ppaddr[type];
logop->op_first = first;
- logop->op_flags = flags | OPf_KIDS;
+ logop->op_flags = (U8)(flags | OPf_KIDS);
logop->op_other = LINKLIST(other);
logop->op_private = (U8)(1 | (flags >> 8));
logop->op_type = OP_COND_EXPR;
logop->op_ppaddr = PL_ppaddr[OP_COND_EXPR];
logop->op_first = first;
- logop->op_flags = flags | OPf_KIDS;
+ logop->op_flags = (U8)(flags | OPf_KIDS);
logop->op_private = (U8)(1 | (flags >> 8));
logop->op_other = LINKLIST(trueop);
logop->op_next = LINKLIST(falseop);
return o;
}
+
+OP *
+Perl_newWHILEOP(pTHX_ I32 flags, I32 debuggable, LOOP *loop,
+ I32 whileline, OP *expr, OP *block, OP *cont)
+{
+ return newWHILEOP8(flags, debuggable, loop, whileline, expr, block, cont,
+ 0);
+}
+
OP *
-Perl_newWHILEOP(pTHX_ I32 flags, I32 debuggable, LOOP *loop, I32 whileline, OP *expr, OP *block, OP *cont)
+Perl_newWHILEOP8(pTHX_ I32 flags, I32 debuggable, LOOP *loop, I32
+whileline, OP *expr, OP *block, OP *cont, I32 has_my)
{
OP *redo;
- OP *next = 0;
+ OP *next = NULL;
OP *listop;
OP *o;
U8 loopflags = 0;
if (!block)
block = newOP(OP_NULL, 0);
- else if (cont) {
+ else if (cont || has_my) {
block = scope(block);
}
next = LINKLIST(cont);
}
if (expr) {
- OP *unstack = newOP(OP_UNSTACK, 0);
+ OP * const unstack = newOP(OP_UNSTACK, 0);
if (!next)
next = unstack;
cont = append_elem(OP_LINESEQ, cont, unstack);
op_free(sv);
sv = Nullop;
}
+#ifdef USE_5005THREADS
else if (sv->op_type == OP_THREADSV) { /* per-thread variable */
padoff = sv->op_targ;
sv->op_targ = 0;
op_free(sv);
sv = Nullop;
}
+#endif
else
Perl_croak(aTHX_ "Can't use %s for loop variable", PL_op_desc[sv->op_type]);
}
* set the STACKED flag to indicate that these values are to be
* treated as min/max values by 'pp_iterinit'.
*/
- UNOP* flip = (UNOP*)((UNOP*)((BINOP*)expr)->op_first)->op_first;
- LOGOP* range = (LOGOP*) flip->op_first;
+ UNOP* const flip = (UNOP*)((UNOP*)((BINOP*)expr)->op_first)->op_first;
+ LOGOP* const range = (LOGOP*) flip->op_first;
OP* const left = range->op_first;
OP* const right = left->op_sibling;
LISTOP* listop;
Renew(loop, 1, LOOP);
#endif
loop->op_targ = padoff;
- wop = newWHILEOP(flags, 1, loop, forline, newOP(OP_ITER, 0), block, cont);
+ wop = newWHILEOP8(flags, 1, loop, forline, newOP(OP_ITER, 0), block, cont,
+ 0);
PL_copline = forline;
return newSTATEOP(0, label, wop);
}
LEAVE;
}
SvPOK_off((SV*)cv); /* forget prototype */
- CvGV(cv) = Nullgv;
+ CvGV(cv) = NULL;
pad_undef(cv);
{
if (((!p != !SvPOK(cv)) || (p && strNE(p, SvPVX_const(cv)))) && ckWARN_d(WARN_PROTOTYPE)) {
SV* const msg = sv_newmortal();
- SV* name = Nullsv;
+ SV* name = NULL;
if (gv)
- gv_efullname3(name = sv_newmortal(), gv, Nullch);
+ gv_efullname3(name = sv_newmortal(), gv, NULL);
sv_setpv(msg, "Prototype mismatch:");
if (name)
Perl_sv_catpvf(aTHX_ msg, " sub %"SVf, name);
if (SvPOK(cv))
Perl_sv_catpvf(aTHX_ msg, " (%"SVf")", (const SV *)cv);
else
- Perl_sv_catpv(aTHX_ msg, ": none");
- sv_catpv(msg, " vs ");
+ sv_catpvs(msg, ": none");
+ sv_catpvs(msg, " vs ");
if (p)
Perl_sv_catpvf(aTHX_ msg, "(%s)", p);
else
- sv_catpv(msg, "none");
+ sv_catpvs(msg, "none");
Perl_warner(aTHX_ packWARN(WARN_PROTOTYPE), "%"SVf, msg);
}
}
SV *
Perl_cv_const_sv(pTHX_ CV *cv)
{
- if (!cv || !CvCONST(cv))
- return Nullsv;
- return (SV*)CvXSUBANY(cv).any_ptr;
+ if (!cv)
+ return NULL;
+ if (!(SvTYPE(cv) == SVt_PVCV || SvTYPE(cv) == SVt_PVFM))
+ return NULL;
+ return CvCONST(cv) ? (SV*)CvXSUBANY(cv).any_ptr : NULL;
}
SV *
Perl_op_const_sv(pTHX_ OP *o, CV *cv)
{
- SV *sv = Nullsv;
+ SV *sv = NULL;
if (!o)
- return Nullsv;
+ return NULL;
if (o->op_type == OP_LINESEQ && cLISTOPo->op_first)
o = cLISTOPo->op_first->op_sibling;
if (type == OP_LEAVESUB || type == OP_RETURN)
break;
if (sv)
- return Nullsv;
+ return NULL;
if (type == OP_CONST && cSVOPo->op_sv)
sv = cSVOPo->op_sv;
else if ((type == OP_PADSV || type == OP_CONST) && cv) {
sv = PAD_BASE_SV(CvPADLIST(cv), o->op_targ);
if (!sv)
- return Nullsv;
+ return NULL;
if (CvCONST(cv)) {
/* We get here only from cv_clone2() while creating a closure.
Copy the const value here instead of in cv_clone2 so that
return Nullsv;
}
else
- return Nullsv;
+ return NULL;
}
if (sv)
SvREADONLY_on(sv);
GV *gv;
const char *ps;
STRLEN ps_len;
- register CV *cv=0;
+ register CV *cv = NULL;
SV *const_sv;
-
- const char * const name = o ? SvPVx_nolen_const(cSVOPo->op_sv) : Nullch;
+ /* If the subroutine has no body, no attributes, and no builtin attributes
+ then it's just a sub declaration, and we may be able to get away with
+ storing with a placeholder scalar in the symbol table, rather than a
+ full GV and CV. If anything is present then it will take a full CV to
+ store it. */
+ const I32 gv_fetch_flags
+ = (block || attrs || (CvFLAGS(PL_compcv) & CVf_BUILTIN_ATTRS))
+ ? GV_ADDMULTI : GV_ADDMULTI | GV_NOINIT;
+ const char * const name = o ? SvPVx_nolen_const(cSVOPo->op_sv) : NULL;
if (proto) {
assert(proto->op_type == OP_CONST);
ps = SvPVx_const(((SVOP*)proto)->op_sv, ps_len);
}
else
- ps = Nullch;
+ ps = NULL;
if (!name && PERLDB_NAMEANON && CopLINE(PL_curcop)) {
SV * const sv = sv_newmortal();
aname = SvPVX_const(sv);
}
else
- aname = Nullch;
- gv = gv_fetchpv(name ? name : (aname ? aname :
- (PL_curstash ? "__ANON__" : "__ANON__::__ANON__")),
- GV_ADDMULTI | ((block || attrs) ? 0 : GV_NOINIT),
- SVt_PVCV);
+ aname = NULL;
+
+ /* There may be future conflict here as change 23766 is not yet merged. */
+ gv = name ? gv_fetchsv(cSVOPo->op_sv, gv_fetch_flags, SVt_PVCV)
+ : gv_fetchpv(aname ? aname
+ : (PL_curstash ? "__ANON__" : "__ANON__::__ANON__"),
+ gv_fetch_flags, SVt_PVCV);
if (o)
SAVEFREEOP(o);
}
#endif
- if (!block || !ps || *ps || attrs)
- const_sv = Nullsv;
+ if (!block || !ps || *ps || attrs || (CvFLAGS(PL_compcv) & CVf_BUILTIN_ATTRS))
+ const_sv = NULL;
else
const_sv = op_const_sv(block, Nullcv);
SAVEFREESV(PL_compcv);
goto done;
}
- /* ahem, death to those who redefine active sort subs */
- if (PL_curstackinfo->si_type == PERLSI_SORT && PL_sortcop == CvSTART(cv))
- Perl_croak(aTHX_ "Can't redefine active sort subroutine %s", name);
if (block) {
if (ckWARN(WARN_REDEFINE)
|| (CvCONST(cv)
}
}
if (const_sv) {
- (void)SvREFCNT_inc(const_sv);
+ SvREFCNT_inc_simple_void_NN(const_sv);
if (cv) {
assert(!CvROOT(cv) && !CvCONST(cv));
sv_setpvn((SV*)cv, "", 0); /* prototype is "" */
/* This makes sub {}; work as expected. */
if (block->op_type == OP_STUB) {
op_free(block);
- block = newSTATEOP(0, Nullch, 0);
+ block = newSTATEOP(0, NULL, 0);
}
CvROOT(cv) = newUNOP(OP_LEAVESUB, 0, scalarseq(block));
}
if (name || aname) {
const char *s;
- const char *tname = (name ? name : aname);
+ const char * const tname = (name ? name : aname);
if (PERLDB_SUBLINE && PL_curstash != PL_debstash) {
- SV *sv = NEWSV(0,0);
- SV *tmpstr = sv_newmortal();
- GV *db_postponed = gv_fetchpv("DB::postponed", GV_ADDMULTI, SVt_PVHV);
- CV *pcv;
+ SV * const sv = newSV(0);
+ SV * const tmpstr = sv_newmortal();
+ GV * const db_postponed = gv_fetchpvs("DB::postponed",
+ GV_ADDMULTI, SVt_PVHV);
HV *hv;
Perl_sv_setpvf(aTHX_ sv, "%s:%ld-%ld",
CopFILE(PL_curcop),
(long)PL_subline, (long)CopLINE(PL_curcop));
- gv_efullname3(tmpstr, gv, Nullch);
+ gv_efullname3(tmpstr, gv, NULL);
hv_store(GvHV(PL_DBsub), SvPVX_const(tmpstr), SvCUR(tmpstr), sv, 0);
hv = GvHVn(db_postponed);
- if (HvFILL(hv) > 0 && hv_exists(hv, SvPVX_const(tmpstr), SvCUR(tmpstr))
- && (pcv = GvCV(db_postponed)))
- {
- dSP;
- PUSHMARK(SP);
- XPUSHs(tmpstr);
- PUTBACK;
- call_sv((SV*)pcv, G_DISCARD);
+ if (HvFILL(hv) > 0 && hv_exists(hv, SvPVX_const(tmpstr), SvCUR(tmpstr))) {
+ CV * const pcv = GvCV(db_postponed);
+ if (pcv) {
+ dSP;
+ PUSHMARK(SP);
+ XPUSHs(tmpstr);
+ PUTBACK;
+ call_sv((SV*)pcv, G_DISCARD);
+ }
}
}
CvCONST_on(cv);
sv_setpvn((SV*)cv, "", 0); /* prototype is "" */
+#ifdef USE_ITHREADS
if (stash)
CopSTASH_free(PL_curcop);
-
+#endif
LEAVE;
return cv;
if (cv) /* must reuse cv if autoloaded */
cv_undef(cv);
else {
- cv = (CV*)NEWSV(1105,0);
+ cv = (CV*)newSV(0);
sv_upgrade((SV *)cv, SVt_PVCV);
if (name) {
GvCV(gv) = cv;
Perl_newFORM(pTHX_ I32 floor, OP *o, OP *block)
{
register CV *cv;
- char *name;
- GV *gv;
- STRLEN n_a;
- if (o)
- name = SvPVx(cSVOPo->op_sv, n_a);
- else
- name = "STDOUT";
- gv = gv_fetchpv(name,TRUE, SVt_PVFM);
+ GV * const gv = o
+ ? gv_fetchsv(cSVOPo->op_sv, TRUE, SVt_PVFM)
+ : gv_fetchpvs("STDOUT", GV_ADD|GV_NOTQUAL, SVt_PVFM);
+
#ifdef GV_UNIQUE_CHECK
if (GvUNIQUE(gv)) {
Perl_croak(aTHX_ "Bad symbol for form (GV is unique)");
const line_t oldline = CopLINE(PL_curcop);
if (PL_copline != NOLINE)
CopLINE_set(PL_curcop, PL_copline);
- Perl_warner(aTHX_ packWARN(WARN_REDEFINE), "Format %s redefined",name);
+ Perl_warner(aTHX_ packWARN(WARN_REDEFINE),
+ o ? "Format %"SVf" redefined"
+ : "Format STDOUT redefined" ,cSVOPo->op_sv);
CopLINE_set(PL_curcop, oldline);
}
SvREFCNT_dec(cv);
OP *
Perl_newANONLIST(pTHX_ OP *o)
{
- return newUNOP(OP_REFGEN, 0,
- mod(list(convert(OP_ANONLIST, 0, o)), OP_REFGEN));
+ return convert(OP_ANONLIST, OPf_SPECIAL, o);
}
OP *
Perl_newANONHASH(pTHX_ OP *o)
{
- return newUNOP(OP_REFGEN, 0,
- mod(list(convert(OP_ANONHASH, 0, o)), OP_REFGEN));
+ return convert(OP_ANONHASH, OPf_SPECIAL, o);
}
OP *
}
OP *
-Perl_oopsCV(pTHX_ OP *o)
-{
- Perl_croak(aTHX_ "NOT IMPL LINE %d",__LINE__);
- /* STUB */
- PERL_UNUSED_ARG(o);
- NORETURN_FUNCTION_END;
-}
-
-OP *
Perl_newCVREF(pTHX_ I32 flags, OP *o)
{
return newUNOP(OP_RV2CV, flags, scalar(o));
o->op_ppaddr = PL_ppaddr[OP_PADSV];
return o;
}
+#ifdef USE_5005THREADS
else if (o->op_type == OP_THREADSV && !(o->op_flags & OPpDONE_SVREF)) {
o->op_flags |= OPpDONE_SVREF;
return o;
}
+#endif
return newUNOP(OP_RV2SV, 0, scalar(o));
}
Perl_ck_anoncode(pTHX_ OP *o)
{
cSVOPo->op_targ = pad_add_anon(cSVOPo->op_sv, o->op_type);
- cSVOPo->op_sv = Nullsv;
+ cSVOPo->op_sv = NULL;
return o;
}
OP *
Perl_ck_concat(pTHX_ OP *o)
{
- const OP *kid = cUNOPo->op_first;
+ const OP * const kid = cUNOPo->op_first;
if (kid->op_type == OP_CONCAT && !(kid->op_private & OPpTARGET_MY) &&
!(kUNOP->op_first->op_flags & OPf_MOD))
o->op_flags |= OPf_STACKED;
o = ck_fun(o);
o->op_private = 0;
if (o->op_flags & OPf_KIDS) {
- OP *kid = cUNOPo->op_first;
+ OP * const kid = cUNOPo->op_first;
switch (kid->op_type) {
case OP_ASLICE:
o->op_flags |= OPf_SPECIAL;
Perl_ck_exit(pTHX_ OP *o)
{
#ifdef VMS
- HV *table = GvHV(PL_hintgv);
+ HV * const table = GvHV(PL_hintgv);
if (table) {
- SV **svp = hv_fetch(table, "vmsish_exit", 11, FALSE);
+ SV * const * const svp = hv_fetchs(table, "vmsish_exit", FALSE);
if (svp && *svp && SvTRUE(*svp))
o->op_private |= OPpEXIT_VMSISH;
}
OP *
Perl_ck_rvconst(pTHX_ register OP *o)
{
- SVOP *kid = (SVOP*)cUNOPo->op_first;
+ SVOP * const kid = (SVOP*)cUNOPo->op_first;
o->op_private |= (PL_hints & HINT_STRICT_REFS);
+ if (o->op_type == OP_RV2CV)
+ o->op_private &= ~1;
+
if (kid->op_type == OP_CONST) {
- char *name;
int iscv;
GV *gv;
SV * const kidsv = kid->op_sv;
- STRLEN n_a;
/* Is it a constant from cv_const_sv()? */
if (SvROK(kidsv) && SvREADONLY(kidsv)) {
- SV *rsv = SvRV(kidsv);
+ SV * const rsv = SvRV(kidsv);
const int svtype = SvTYPE(rsv);
- const char *badtype = Nullch;
+ const char *badtype = NULL;
switch (o->op_type) {
case OP_RV2SV:
Perl_croak(aTHX_ "Constant is not %s reference", badtype);
return o;
}
- name = SvPV(kidsv, n_a);
if ((PL_hints & HINT_STRICT_REFS) && (kid->op_private & OPpCONST_BARE)) {
- const char *badthing = Nullch;
+ const char *badthing = NULL;
switch (o->op_type) {
case OP_RV2SV:
badthing = "a SCALAR";
}
if (badthing)
Perl_croak(aTHX_
- "Can't use bareword (\"%s\") as %s ref while \"strict refs\" in use",
- name, badthing);
+ "Can't use bareword (\"%"SVf"\") as %s ref while \"strict refs\" in use",
+ kidsv, badthing);
}
/*
* This is a little tricky. We only want to add the symbol if we
*/
iscv = (o->op_type == OP_RV2CV) * 2;
do {
- gv = gv_fetchpv(name,
+ gv = gv_fetchsv(kidsv,
iscv | !(kid->op_private & OPpCONST_ENTERED),
iscv
? SVt_PVCV
kPADOP->op_padix = pad_alloc(OP_GV, SVs_PADTMP);
SvREFCNT_dec(PAD_SVl(kPADOP->op_padix));
GvIN_PAD_on(gv);
- PAD_SETSV(kPADOP->op_padix, (SV*) SvREFCNT_inc(gv));
+ PAD_SETSV(kPADOP->op_padix, (SV*) SvREFCNT_inc_simple_NN(gv));
#else
- kid->op_sv = SvREFCNT_inc(gv);
+ kid->op_sv = SvREFCNT_inc_simple_NN(gv);
#endif
kid->op_private = 0;
kid->op_ppaddr = PL_ppaddr[OP_GV];
/* nothing */
}
else if (o->op_flags & OPf_KIDS && cUNOPo->op_first->op_type != OP_STUB) {
- SVOP *kid = (SVOP*)cUNOPo->op_first;
+ SVOP * const kid = (SVOP*)cUNOPo->op_first;
if (kid->op_type == OP_CONST && (kid->op_private & OPpCONST_BARE)) {
- STRLEN n_a;
- OP *newop = newGVOP(type, OPf_REF,
- gv_fetchpv(SvPVx(kid->op_sv, n_a), TRUE, SVt_PVIO));
+ OP * const newop = newGVOP(type, OPf_REF,
+ gv_fetchsv(kid->op_sv, GV_ADD, SVt_PVIO));
op_free(o);
o = newop;
}
}
if (o->op_flags & OPf_KIDS) {
- STRLEN n_a;
OP **tokid = &cLISTOPo->op_first;
register OP *kid = cLISTOPo->op_first;
OP *sibl;
if (kid->op_type == OP_CONST &&
(kid->op_private & OPpCONST_BARE))
{
- char *name = SvPVx(((SVOP*)kid)->op_sv, n_a);
- OP *newop = newAVREF(newGVOP(OP_GV, 0,
- gv_fetchpv(name, TRUE, SVt_PVAV) ));
+ OP * const newop = newAVREF(newGVOP(OP_GV, 0,
+ gv_fetchsv(((SVOP*)kid)->op_sv, GV_ADD, SVt_PVAV) ));
if (ckWARN2(WARN_DEPRECATED, WARN_SYNTAX))
Perl_warner(aTHX_ packWARN2(WARN_DEPRECATED, WARN_SYNTAX),
- "Array @%s missing the @ in argument %"IVdf" of %s()",
- name, (IV)numargs, PL_op_desc[type]);
+ "Array @%"SVf" missing the @ in argument %"IVdf" of %s()",
+ ((SVOP*)kid)->op_sv, (IV)numargs, PL_op_desc[type]);
op_free(kid);
kid = newop;
kid->op_sibling = sibl;
if (kid->op_type == OP_CONST &&
(kid->op_private & OPpCONST_BARE))
{
- char *name = SvPVx(((SVOP*)kid)->op_sv, n_a);
- OP *newop = newHVREF(newGVOP(OP_GV, 0,
- gv_fetchpv(name, TRUE, SVt_PVHV) ));
+ OP * const newop = newHVREF(newGVOP(OP_GV, 0,
+ gv_fetchsv(((SVOP*)kid)->op_sv, GV_ADD, SVt_PVHV) ));
if (ckWARN2(WARN_DEPRECATED, WARN_SYNTAX))
Perl_warner(aTHX_ packWARN2(WARN_DEPRECATED, WARN_SYNTAX),
- "Hash %%%s missing the %% in argument %"IVdf" of %s()",
- name, (IV)numargs, PL_op_desc[type]);
+ "Hash %%%"SVf" missing the %% in argument %"IVdf" of %s()",
+ ((SVOP*)kid)->op_sv, (IV)numargs, PL_op_desc[type]);
op_free(kid);
kid = newop;
kid->op_sibling = sibl;
break;
case OA_CVREF:
{
- OP *newop = newUNOP(OP_NULL, 0, kid);
+ OP * const newop = newUNOP(OP_NULL, 0, kid);
kid->op_sibling = 0;
linklist(kid);
newop->op_next = newop;
if (kid->op_type == OP_CONST &&
(kid->op_private & OPpCONST_BARE))
{
- OP *newop = newGVOP(OP_GV, 0,
- gv_fetchpv(SvPVx(((SVOP*)kid)->op_sv, n_a), TRUE,
- SVt_PVIO) );
+ OP * const newop = newGVOP(OP_GV, 0,
+ gv_fetchsv(((SVOP*)kid)->op_sv, GV_ADD, SVt_PVIO));
if (!(o->op_private & 1) && /* if not unop */
kid == cLISTOPo->op_last)
cLISTOPo->op_last = newop;
/* is this op a FH constructor? */
if (is_handle_constructor(o,numargs)) {
- const char *name = Nullch;
+ const char *name = NULL;
STRLEN len = 0;
flags = 0;
else if (kid->op_type == OP_RV2SV
&& kUNOP->op_first->op_type == OP_GV)
{
- GV *gv = cGVOPx_gv(kUNOP->op_first);
+ GV * const gv = cGVOPx_gv(kUNOP->op_first);
name = GvNAME(gv);
len = GvNAMELEN(gv);
}
else if (kid->op_type == OP_AELEM
|| kid->op_type == OP_HELEM)
{
- OP *op;
-
- name = 0;
- if ((op = ((BINOP*)kid)->op_first)) {
- SV *tmpstr = Nullsv;
- const char *a =
+ OP *op = ((BINOP*)kid)->op_first;
+ name = NULL;
+ if (op) {
+ SV *tmpstr = NULL;
+ const char * const a =
kid->op_type == OP_AELEM ?
"[]" : "{}";
if (((op->op_type == OP_RV2AV) ||
(op = ((UNOP*)op)->op_first) &&
(op->op_type == OP_GV)) {
/* packagevar $a[] or $h{} */
- GV *gv = cGVOPx_gv(op);
+ GV * const gv = cGVOPx_gv(op);
if (gv)
tmpstr =
Perl_newSVpvf(aTHX_
else if (op->op_type == OP_PADAV
|| op->op_type == OP_PADHV) {
/* lexicalvar $a[] or $h{} */
- const char *padname =
+ const char * const padname =
PAD_COMPNAME_PV(op->op_targ);
if (padname)
tmpstr =
"%s%c...%c",
padname + 1,
a[0], a[1]);
-
}
if (tmpstr) {
name = SvPV_const(tmpstr, len);
if ((o->op_flags & OPf_KIDS) && !cLISTOPo->op_first->op_sibling)
append_elem(OP_GLOB, o, newDEFSVOP());
- if (!((gv = gv_fetchpv("glob", FALSE, SVt_PVCV))
+ if (!((gv = gv_fetchpvs("glob", GV_NOTQUAL, SVt_PVCV))
&& GvCVu(gv) && GvIMPORTED_CV(gv)))
{
- gv = gv_fetchpv("CORE::GLOBAL::glob", FALSE, SVt_PVCV);
+ gv = gv_fetchpvs("CORE::GLOBAL::glob", 0, SVt_PVCV);
}
#if !defined(PERL_EXTERNAL_GLOB)
GV *glob_gv;
ENTER;
Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT,
- newSVpvn("File::Glob", 10), Nullsv, Nullsv, Nullsv);
- gv = gv_fetchpv("CORE::GLOBAL::glob", FALSE, SVt_PVCV);
- glob_gv = gv_fetchpv("File::Glob::csh_glob", FALSE, SVt_PVCV);
+ newSVpvs("File::Glob"), NULL, NULL, NULL);
+ gv = gv_fetchpvs("CORE::GLOBAL::glob", 0, SVt_PVCV);
+ glob_gv = gv_fetchpvs("File::Glob::csh_glob", 0, SVt_PVCV);
GvCV(gv) = GvCV(glob_gv);
- (void)SvREFCNT_inc((SV*)GvCV(gv));
+ SvREFCNT_inc_void((SV*)GvCV(gv));
GvIMPORTED_CV_on(gv);
LEAVE;
}
/* Cannot steal the second time! */
&& !(kid->op_private & OPpTARGET_MY))
{
- OP *kkid = kid->op_sibling;
+ OP * const kkid = kid->op_sibling;
/* Can just relocate the target. */
if (kkid && kkid->op_type == OP_PADSV
return kid;
}
}
- /* optimise C<my $x = undef> to C<my $x> */
- if (kid->op_type == OP_UNDEF) {
- OP *kkid = kid->op_sibling;
- if (kkid && kkid->op_type == OP_PADSV
- && (kkid->op_private & OPpLVAL_INTRO))
- {
- cLISTOPo->op_first = NULL;
- kid->op_sibling = NULL;
- op_free(o);
- op_free(kid);
- return kkid;
- }
- }
return o;
}
OP *
Perl_ck_method(pTHX_ OP *o)
{
- OP *kid = cUNOPo->op_first;
+ OP * const kid = cUNOPo->op_first;
if (kid->op_type == OP_CONST) {
SV* sv = kSVOP->op_sv;
- if (!(strchr(SvPVX_const(sv), ':') || strchr(SvPVX_const(sv), '\''))) {
+ const char * const method = SvPVX_const(sv);
+ if (!(strchr(method, ':') || strchr(method, '\''))) {
OP *cmop;
if (!SvREADONLY(sv) || !SvFAKE(sv)) {
- sv = newSVpvn_share(SvPVX_const(sv), SvCUR(sv), 0);
+ sv = newSVpvn_share(method, SvCUR(sv), 0);
}
else {
- kSVOP->op_sv = Nullsv;
+ kSVOP->op_sv = NULL;
}
cmop = newSVOP(OP_METHOD_NAMED, 0, sv);
op_free(o);
OP *
Perl_ck_open(pTHX_ OP *o)
{
- HV *table = GvHV(PL_hintgv);
+ HV * const table = GvHV(PL_hintgv);
if (table) {
- SV **svp;
- I32 mode;
- svp = hv_fetch(table, "open_IN", 7, FALSE);
+ SV **svp = hv_fetchs(table, "open_IN", FALSE);
if (svp && *svp) {
- mode = mode_from_discipline(*svp);
+ const I32 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);
+ svp = hv_fetchs(table, "open_OUT", FALSE);
if (svp && *svp) {
- mode = mode_from_discipline(*svp);
+ const I32 mode = mode_from_discipline(*svp);
if (mode & O_BINARY)
o->op_private |= OPpOPEN_OUT_RAW;
else if (mode & O_TEXT)
{
/* In case of three-arg dup open remove strictness
* from the last arg if it is a bareword. */
- OP *first = cLISTOPx(o)->op_first; /* The pushmark. */
- OP *last = cLISTOPx(o)->op_last; /* The bareword. */
+ OP * const first = cLISTOPx(o)->op_first; /* The pushmark. */
+ OP * const last = cLISTOPx(o)->op_last; /* The bareword. */
OP *oa;
const char *mode;
(last->op_private & OPpCONST_STRICT) &&
(oa = first->op_sibling) && /* The fh. */
(oa = oa->op_sibling) && /* The mode. */
+ (oa->op_type == OP_CONST) &&
SvPOK(((SVOP*)oa)->op_sv) &&
(mode = SvPVX_const(((SVOP*)oa)->op_sv)) &&
mode[0] == '>' && mode[1] == '&' && /* A dup open. */
OP *
Perl_ck_require(pTHX_ OP *o)
{
- GV* gv;
+ GV* gv = Nullgv;
if (o->op_flags & OPf_KIDS) { /* Shall we supply missing .pm? */
- SVOP *kid = (SVOP*)cUNOPo->op_first;
+ SVOP * const kid = (SVOP*)cUNOPo->op_first;
if (kid->op_type == OP_CONST && (kid->op_private & OPpCONST_BARE)) {
- SV *sv = kid->op_sv;
+ SV * const sv = kid->op_sv;
U32 was_readonly = SvREADONLY(sv);
char *s;
for (s = SvPVX(sv); *s; s++) {
if (*s == ':' && s[1] == ':') {
+ const STRLEN len = strlen(s+2)+1;
*s = '/';
- Move(s+2, s+1, strlen(s+2)+1, char);
+ Move(s+2, s+1, len, char);
SvCUR_set(sv, SvCUR(sv) - 1);
}
}
- sv_catpvn(sv, ".pm", 3);
+ sv_catpvs(sv, ".pm");
SvFLAGS(sv) |= was_readonly;
}
}
- /* handle override, if any */
- gv = gv_fetchpv("require", FALSE, SVt_PVCV);
- if (!(gv && GvCVu(gv) && GvIMPORTED_CV(gv)))
- gv = gv_fetchpv("CORE::GLOBAL::require", FALSE, SVt_PVCV);
+ if (!(o->op_flags & OPf_SPECIAL)) { /* Wasn't written as CORE::require */
+ /* handle override, if any */
+ gv = gv_fetchpvs("require", GV_NOTQUAL, SVt_PVCV);
+ if (!(gv && GvCVu(gv) && GvIMPORTED_CV(gv))) {
+ GV * const * const gvp = (GV**)hv_fetchs(PL_globalstash, "require", FALSE);
+ gv = gvp ? *gvp : Nullgv;
+ }
+ }
if (gv && GvCVu(gv) && GvIMPORTED_CV(gv)) {
- OP *kid = cUNOPo->op_first;
+ OP * const kid = cUNOPo->op_first;
cUNOPo->op_first = 0;
op_free(o);
return ck_subr(newUNOP(OP_ENTERSUB, OPf_STACKED,
return o;
}
-#if 0
-OP *
-Perl_ck_retarget(pTHX_ OP *o)
-{
- Perl_croak(aTHX_ "NOT IMPL LINE %d",__LINE__);
- /* STUB */
- return o;
-}
-#endif
-
OP *
Perl_ck_select(pTHX_ OP *o)
{
const char *gvname;
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_fetchpvs("a", GV_ADD|GV_NOTQUAL, SVt_PV));
+ GvMULTI_on(gv_fetchpvs("b", GV_ADD|GV_NOTQUAL, SVt_PV));
kid = kUNOP->op_first; /* get past null */
if (kid->op_type != OP_SCOPE)
return;
op_free(cLISTOPo->op_first);
cLISTOPo->op_first = kid;
if (!kid) {
- cLISTOPo->op_first = kid = newSVOP(OP_CONST, 0, newSVpvn(" ", 1));
+ cLISTOPo->op_first = kid = newSVOP(OP_CONST, 0, newSVpvs(" "));
cLISTOPo->op_last = kid; /* There was only one element previously */
}
if (kid->op_type != OP_MATCH || kid->op_flags & OPf_STACKED) {
- OP *sibl = kid->op_sibling;
+ OP * const sibl = kid->op_sibling;
kid->op_sibling = 0;
kid = pmruntime( newPMOP(OP_MATCH, OPf_SPECIAL), kid, Nullop);
if (cLISTOPo->op_first == cLISTOPo->op_last)
kid->op_type = OP_PUSHRE;
kid->op_ppaddr = PL_ppaddr[OP_PUSHRE];
scalar(kid);
- if (ckWARN(WARN_REGEXP) && ((PMOP *)kid)->op_pmflags & PMf_GLOBAL) {
+ if (((PMOP *)kid)->op_pmflags & PMf_GLOBAL && ckWARN(WARN_REGEXP)) {
Perl_warner(aTHX_ packWARN(WARN_REGEXP),
"Use of /g modifier is meaningless in split");
}
OP *
Perl_ck_join(pTHX_ OP *o)
{
- if (ckWARN(WARN_SYNTAX)) {
- const OP *kid = cLISTOPo->op_first->op_sibling;
- if (kid && kid->op_type == OP_MATCH) {
+ const OP * const kid = cLISTOPo->op_first->op_sibling;
+ if (kid && kid->op_type == OP_MATCH) {
+ if (ckWARN(WARN_SYNTAX)) {
const REGEXP *re = PM_GETRE(kPMOP);
const char *pmstr = re ? re->precomp : "STRING";
Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
? cUNOPo : ((UNOP*)cUNOPo->op_first))->op_first;
OP *o2 = prev->op_sibling;
OP *cvop;
- char *proto = 0;
- CV *cv = 0;
- GV *namegv = 0;
+ char *proto = NULL;
+ CV *cv = NULL;
+ GV *namegv = NULL;
int optional = 0;
I32 arg = 0;
I32 contextclass = 0;
- char *e = 0;
+ char *e = NULL;
o->op_private |= OPpENTERSUB_HASTARG;
for (cvop = o2; cvop->op_sibling; cvop = cvop->op_sibling) ;
if (o2->op_type == OP_CONST)
o2->op_private &= ~OPpCONST_STRICT;
else if (o2->op_type == OP_LIST) {
- OP *o = ((UNOP*)o2)->op_first->op_sibling;
+ OP * const o = ((UNOP*)o2)->op_first->op_sibling;
if (o && o->op_type == OP_CONST)
o->op_private &= ~OPpCONST_STRICT;
}
(gvop = ((UNOP*)gvop)->op_first) &&
gvop->op_type == OP_GV)
{
- GV *gv = cGVOPx_gv(gvop);
- OP *sibling = o2->op_sibling;
- SV *n = newSVpvn("",0);
+ GV * const gv = cGVOPx_gv(gvop);
+ OP * const sibling = o2->op_sibling;
+ SV * const n = newSVpvs("");
op_free(o2);
gv_fullname4(n, gv, "", FALSE);
o2 = newSVOP(OP_CONST, 0, n);
break;
case ']':
if (contextclass) {
+ /* XXX We shouldn't be modifying proto, so we can const proto */
char *p = proto;
const char s = *p;
contextclass = 0;
if (o2->op_type == OP_RV2SV ||
o2->op_type == OP_PADSV ||
o2->op_type == OP_HELEM ||
- o2->op_type == OP_AELEM ||
- o2->op_type == OP_THREADSV)
+ o2->op_type == OP_AELEM
+#ifdef USE_5005THREADS
+ || o2->op_type == OP_THREADSV
+#endif
+ )
goto wrapref;
if (!contextclass)
bad_type(arg, "scalar", gv_ename(namegv), o2);
break;
wrapref:
{
- OP* kid = o2;
- OP* sib = kid->op_sibling;
+ OP* const kid = o2;
+ OP* const sib = kid->op_sibling;
kid->op_sibling = 0;
o2 = newUNOP(OP_REFGEN, 0, kid);
o2->op_sibling = sib;
mod(o2, OP_ENTERSUB);
prev = o2;
o2 = o2->op_sibling;
- }
+ } /* while */
if (proto && !optional &&
(*proto && *proto != '@' && *proto != '%' && *proto != ';'))
return too_few_arguments(o, gv_ename(namegv));
void
Perl_peep(pTHX_ register OP *o)
{
- register OP* oldop = 0;
+ register OP* oldop = NULL;
STRLEN n_a;
if (!o || o->op_seq)
SvREADONLY_on(PAD_SVl(ix));
SvREFCNT_dec(cSVOPo->op_sv);
}
+ else if (o->op_type == OP_CONST
+ && cSVOPo->op_sv == &PL_sv_undef) {
+ /* PL_sv_undef is hack - it's unsafe to store it in the
+ AV that is the pad, because av_fetch treats values of
+ PL_sv_undef as a "free" AV entry and will merrily
+ replace them with a new SV, causing pad_alloc to think
+ that this pad slot is free. (When, clearly, it is not)
+ */
+ SvOK_off(PAD_SVl(ix));
+ SvPADTMP_on(PAD_SVl(ix));
+ SvREADONLY_on(PAD_SVl(ix));
+ }
else {
SvREFCNT_dec(PAD_SVl(ix));
SvPADTMP_on(cSVOPo->op_sv);
/* XXX I don't know how this isn't readonly already. */
SvREADONLY_on(PAD_SVl(ix));
}
- cSVOPo->op_sv = Nullsv;
+ cSVOPo->op_sv = NULL;
o->op_targ = ix;
}
#endif
case OP_PADAV:
case OP_GV:
if (o->op_type == OP_PADAV || o->op_next->op_type == OP_RV2AV) {
- OP* pop = (o->op_type == OP_PADAV) ?
+ OP* const pop = (o->op_type == OP_PADAV) ?
o->op_next : o->op_next->op_next;
IV i;
if (pop && pop->op_type == OP_CONST &&
}
}
else if ((o->op_private & OPpEARLY_CV) && ckWARN(WARN_PROTOTYPE)) {
- GV *gv = cGVOPo_gv;
+ GV * const gv = cGVOPo_gv;
if (SvTYPE(gv) == SVt_PVGV && GvCV(gv) && SvPVX_const(GvCV(gv))) {
/* XXX could check prototype here instead of just carping */
- SV *sv = sv_newmortal();
- gv_efullname3(sv, gv, Nullch);
+ SV * const sv = sv_newmortal();
+ gv_efullname3(sv, gv, NULL);
Perl_warner(aTHX_ packWARN(WARN_PROTOTYPE),
"%"SVf"() called too early to check prototype",
sv);
case OP_EXEC:
o->op_seq = PL_op_seqmax++;
- if (ckWARN(WARN_SYNTAX) && o->op_next
- && o->op_next->op_type == OP_NEXTSTATE) {
+ if (o->op_next && o->op_next->op_type == OP_NEXTSTATE
+ && ckWARN(WARN_SYNTAX))
+ {
if (o->op_next->op_sibling &&
o->op_next->op_sibling->op_type != OP_EXIT &&
o->op_next->op_sibling->op_type != OP_WARN &&
lexname = *av_fetch(PL_comppad_name, rop->op_first->op_targ, TRUE);
if (!(SvFLAGS(lexname) & SVpad_TYPED))
break;
- fields = (GV**)hv_fetch(SvSTASH(lexname), "FIELDS", 6, FALSE);
+ fields = (GV**)hv_fetchs(SvSTASH(lexname), "FIELDS", FALSE);
if (!fields || !GvHV(*fields))
break;
key = SvPV_const(*svp, keylen);
lexname = *av_fetch(PL_comppad_name, rop->op_first->op_targ, TRUE);
if (!(SvFLAGS(lexname) & SVpad_TYPED))
break;
- fields = (GV**)hv_fetch(SvSTASH(lexname), "FIELDS", 6, FALSE);
+ fields = (GV**)hv_fetchs(SvSTASH(lexname), "FIELDS", FALSE);
if (!fields || !GvHV(*fields))
break;
/* Again guessing that the pushmark can be jumped over.... */
case OP_SORT: {
/* will point to RV2AV or PADAV op on LHS/RHS of assign */
- OP *oleft, *oright;
+ OP *oleft;
OP *o2;
/* check that RHS of sort is a single plain array */
- oright = cUNOPo->op_first;
+ OP *oright = cUNOPo->op_first;
if (!oright || oright->op_type != OP_PUSHMARK)
break;
/* reverse sort ... can be optimised. */
if (!cUNOPo->op_sibling) {
/* Nothing follows us on the list. */
- OP *reverse = o->op_next;
+ OP * const reverse = o->op_next;
if (reverse->op_type == OP_REVERSE &&
(reverse->op_flags & OPf_WANT) == OPf_WANT_LIST) {
- OP *pushmark = cUNOPx(reverse)->op_first;
+ OP * const pushmark = cUNOPx(reverse)->op_first;
if (pushmark && (pushmark->op_type == OP_PUSHMARK)
&& (cUNOPx(pushmark)->op_sibling == o)) {
/* reverse -> pushmark -> sort */
break;
}
+
+ case OP_SASSIGN: {
+ OP *rv2gv;
+ UNOP *refgen, *rv2cv;
+ LISTOP *exlist;
+
+ /* I do not understand this, but if o->op_opt isn't set to 1,
+ various tests in ext/B/t/bytecode.t fail with no readily
+ apparent cause. */
+ /* Converted from op_opt to op_seq for 5.8.x. */
+
+ o->op_seq = PL_op_seqmax++;
+
+
+ if ((o->op_flags && OPf_WANT) != OPf_WANT_VOID)
+ break;
+
+ if ((o->op_private & ~OPpASSIGN_BACKWARDS) != 2)
+ break;
+
+ rv2gv = ((BINOP *)o)->op_last;
+ if (!rv2gv || rv2gv->op_type != OP_RV2GV)
+ break;
+
+ refgen = (UNOP *)((BINOP *)o)->op_first;
+
+ if (!refgen || refgen->op_type != OP_REFGEN)
+ break;
+
+ exlist = (LISTOP *)refgen->op_first;
+ if (!exlist || exlist->op_type != OP_NULL
+ || exlist->op_targ != OP_LIST)
+ break;
+
+ if (exlist->op_first->op_type != OP_PUSHMARK)
+ break;
+
+ rv2cv = (UNOP*)exlist->op_last;
+
+ if (rv2cv->op_type != OP_RV2CV)
+ break;
+
+ assert ((rv2gv->op_private & OPpDONT_INIT_GV) == 0);
+ assert ((o->op_private & OPpASSIGN_CV_TO_GV) == 0);
+ assert ((rv2cv->op_private & OPpMAY_RETURN_CONSTANT) == 0);
+
+ o->op_private |= OPpASSIGN_CV_TO_GV;
+ rv2gv->op_private |= OPpDONT_INIT_GV;
+ rv2cv->op_private |= OPpMAY_RETURN_CONSTANT;
+
+ break;
+ }
+
default:
o->op_seq = PL_op_seqmax++;
HE* he;
if (!PL_custom_op_names) /* This probably shouldn't happen */
- return PL_op_name[OP_CUSTOM];
+ return (char *)PL_op_name[OP_CUSTOM];
keysv = sv_2mortal(newSViv(index));
he = hv_fetch_ent(PL_custom_op_names, keysv, 0, 0);
if (!he)
- return PL_op_name[OP_CUSTOM]; /* Don't know who you are */
+ return (char *)PL_op_name[OP_CUSTOM]; /* Don't know who you are */
return SvPV_nolen(HeVAL(he));
}
HE* he;
if (!PL_custom_op_descs)
- return PL_op_desc[OP_CUSTOM];
+ return (char *)PL_op_desc[OP_CUSTOM];
keysv = sv_2mortal(newSViv(index));
he = hv_fetch_ent(PL_custom_op_descs, keysv, 0, 0);
if (!he)
- return PL_op_desc[OP_CUSTOM];
+ return (char *)PL_op_desc[OP_CUSTOM];
return SvPV_nolen(HeVAL(he));
}