/* pp_hot.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.
}
if (PL_tainting && PL_tainted && !SvTAINTED(left))
TAINT_NOT;
+ if (PL_op->op_private & OPpASSIGN_CV_TO_GV) {
+ SV *cv = SvRV(left);
+ const U32 cv_type = SvTYPE(cv);
+ const U32 gv_type = SvTYPE(right);
+ bool got_coderef = cv_type == SVt_PVCV || cv_type == SVt_PVFM;
+
+ if (!got_coderef) {
+ assert(SvROK(cv));
+ }
+
+ /* Can do the optimisation if right (LVAUE) is not a typeglob,
+ left (RVALUE) is a reference to something, and we're in void
+ context. */
+ if (!got_coderef && gv_type != SVt_PVGV && GIMME_V == G_VOID) {
+ /* Is the target symbol table currently empty? */
+ GV *gv = gv_fetchsv(right, GV_NOINIT, SVt_PVGV);
+ if (SvTYPE(gv) != SVt_PVGV && !SvOK(gv)) {
+ /* Good. Create a new proxy constant subroutine in the target.
+ The gv becomes a(nother) reference to the constant. */
+ SV *const value = SvRV(cv);
+
+ SvUPGRADE((SV *)gv, SVt_RV);
+ SvROK_on(gv);
+ SvRV_set(gv, value);
+ SvREFCNT_inc(value);
+ SETs(right);
+ RETURN;
+ }
+ }
+
+ /* Need to fix things up. */
+ if (gv_type != SVt_PVGV) {
+ /* Need to fix GV. */
+ right = (SV*)gv_fetchsv(right, GV_ADD, SVt_PVGV);
+ }
+
+ if (!got_coderef) {
+ /* We've been returned a constant rather than a full subroutine,
+ but they expect a subroutine reference to apply. */
+ ENTER;
+ SvREFCNT_inc(SvRV(cv));
+ /* newCONSTSUB takes a reference count on the passed in SV
+ from us. We set the name to NULL, otherwise we get into
+ all sorts of fun as the reference to our new sub is
+ donated to the GV that we're about to assign to.
+ */
+ SvRV_set(left, (SV *)newCONSTSUB(GvSTASH(right), NULL,
+ SvRV(cv)));
+ SvREFCNT_dec(cv);
+ LEAVE;
+ }
+
+ }
SvSetMagicSV(right, left);
SETs(right);
RETURN;
PP(pp_aelemfast)
{
dSP;
- AV *av = PL_op->op_flags & OPf_SPECIAL ?
+ AV * const av = PL_op->op_flags & OPf_SPECIAL ?
(AV*)PAD_SV(PL_op->op_targ) : GvAV(cGVOP_gv);
const U32 lval = PL_op->op_flags & OPf_MOD;
SV** const svp = av_fetch(av, PL_op->op_private, lval);
I32 i;
int magic;
int duplicates = 0;
- SV **firsthashrelem = 0; /* "= 0" keeps gcc 2.95 quiet */
+ SV **firsthashrelem = NULL; /* "= 0" keeps gcc 2.95 quiet */
PL_delaymagic = DM_DELAY; /* catch simultaneous items */
if ((global = dynpm->op_pmflags & PMf_GLOBAL)) {
rx->startp[0] = -1;
if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) {
- MAGIC* mg = mg_find(TARG, PERL_MAGIC_regex_global);
+ MAGIC* const mg = mg_find(TARG, PERL_MAGIC_regex_global);
if (mg && mg->mg_len >= 0) {
if (!(rx->reganch & ROPT_GPOS_SEEN))
rx->endp[0] = rx->startp[0] = mg->mg_len;
}
else {
if (global) {
- MAGIC* mg = 0;
+ MAGIC* mg;
if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG))
mg = mg_find(TARG, PERL_MAGIC_regex_global);
+ else
+ mg = NULL;
if (!mg) {
sv_magic(TARG, (SV*)0, PERL_MAGIC_regex_global, Nullch, 0);
mg = mg_find(TARG, PERL_MAGIC_regex_global);
continue;
}
} else if (SvUTF8(sv)) { /* OP_READLINE, OP_RCATLINE */
- const U8 *s = (const U8*)SvPVX_const(sv) + offset;
+ const U8 * const s = (const U8*)SvPVX_const(sv) + offset;
const STRLEN len = SvCUR(sv) - offset;
const U8 *f;
dSP;
HE* he;
SV **svp;
- SV *keysv = POPs;
- HV *hv = (HV*)POPs;
+ SV * const keysv = POPs;
+ HV * const hv = (HV*)POPs;
const U32 lval = PL_op->op_flags & OPf_MOD || LVRET;
const U32 defer = PL_op->op_private & OPpLVAL_DEFER;
SV *sv;
RETPUSHNO;
if (SvMAGICAL(av) || AvREIFY(av)) {
- SV ** const svp = av_fetch(av, --cx->blk_loop.iterix, FALSE);
+ SV * const * const svp = av_fetch(av, --cx->blk_loop.iterix, FALSE);
sv = svp ? *svp : Nullsv;
}
else {
RETPUSHNO;
if (SvMAGICAL(av) || AvREIFY(av)) {
- SV ** const svp = av_fetch(av, ++cx->blk_loop.iterix, FALSE);
+ SV * const * const svp = av_fetch(av, ++cx->blk_loop.iterix, FALSE);
sv = svp ? *svp : Nullsv;
}
else {