modified by get-magic), to avoid incorrectly setting the
RXf_TAINTED flag with RX_TAINT_on further down. */
TAINT_set(was_tainted);
-#if NO_TAINT_SUPPORT
+#ifdef NO_TAINT_SUPPORT
PERL_UNUSED_VAR(was_tainted);
#endif
}
case FF_LINESNGL: /* process ^* */
chopspace = 0;
+ /* FALLTHROUGH */
case FF_LINEGLOB: /* process @* */
{
SAVEVPTR(PL_curpm);
src = PL_stack_base[*PL_markstack_ptr];
- if (SvPADTMP(src) && !IS_PADGV(src)) {
+ if (SvPADTMP(src)) {
+ assert(!IS_PADGV(src));
src = PL_stack_base[*PL_markstack_ptr] = sv_mortalcopy(src);
PL_tmps_floor++;
}
/* set $_ to the new source item */
src = PL_stack_base[PL_markstack_ptr[-1]];
- if (SvPADTMP(src) && !IS_PADGV(src)) src = sv_mortalcopy(src);
+ if (SvPADTMP(src)) {
+ assert(!IS_PADGV(src));
+ src = sv_mortalcopy(src);
+ }
SvTEMP_off(src);
if (PL_op->op_private & OPpGREP_LEX)
PAD_SVl(PL_op->op_targ) = src;
SvGETMAGIC(right);
if (RANGE_IS_NUMERIC(left,right)) {
- IV i, j;
- IV max;
+ IV i, j, n;
if ((SvOK(left) && !SvIOK(left) && SvNV_nomg(left) < IV_MIN) ||
(SvOK(right) && (SvIOK(right)
? SvIsUV(right) && SvUV(right) > IV_MAX
: SvNV_nomg(right) > IV_MAX)))
DIE(aTHX_ "Range iterator outside integer range");
i = SvIV_nomg(left);
- max = SvIV_nomg(right);
- if (max >= i) {
- j = max - i + 1;
- if (j > SSize_t_MAX)
- Perl_croak(aTHX_ "Out of memory during list extend");
- EXTEND_MORTAL(j);
- EXTEND(SP, j);
+ j = SvIV_nomg(right);
+ if (j >= i) {
+ /* Dance carefully around signed max. */
+ bool overflow = (i <= 0 && j > SSize_t_MAX + i - 1);
+ if (!overflow) {
+ n = j - i + 1;
+ /* The wraparound of signed integers is undefined
+ * behavior, but here we aim for count >=1, and
+ * negative count is just wrong. */
+ if (n < 1)
+ overflow = TRUE;
+ }
+ if (overflow)
+ Perl_croak(aTHX_ "Out of memory during list extend");
+ EXTEND_MORTAL(n);
+ EXTEND(SP, n);
}
else
- j = 0;
- while (j--) {
+ n = 0;
+ while (n--) {
SV * const sv = sv_2mortal(newSViv(i++));
PUSHs(sv);
}
return G_ARRAY;
default:
Perl_croak(aTHX_ "panic: bad gimme: %d\n", cxstack[cxix].blk_gimme);
- assert(0); /* NOTREACHED */
- return 0;
}
+ NOT_REACHED; /* NOTREACHED */
}
I32
I32 i;
PERL_ARGS_ASSERT_DOPOPTOSUB_AT;
+#ifndef DEBUGGING
+ PERL_UNUSED_CONTEXT;
+#endif
for (i = startingblock; i >= 0; i--) {
const PERL_CONTEXT * const cx = &cxstk[i];
* code block. Hide this faked entry from the world. */
if (cx->cx_type & CXp_SUB_RE_FAKE)
continue;
+ /* FALLTHROUGH */
case CXt_EVAL:
case CXt_FORMAT:
DEBUG_l( Perl_deb(aTHX_ "(dopoptosub_at(): found sub at cx=%ld)\n", (long)i));
}
/*
+
+=head1 CV Manipulation Functions
+
=for apidoc caller_cx
The XSUB-writer's equivalent of L<caller()|perlfunc/caller>. The
if (CxTYPE(cx) == CXt_EVAL) {
/* eval STRING */
if (CxOLD_OP_TYPE(cx) == OP_ENTEREVAL) {
- PUSHs(newSVpvn_flags(SvPVX(cx->blk_eval.cur_text),
- SvCUR(cx->blk_eval.cur_text)-2,
- SvUTF8(cx->blk_eval.cur_text)|SVs_TEMP));
+ SV *cur_text = cx->blk_eval.cur_text;
+ if (SvCUR(cur_text) >= 2) {
+ PUSHs(newSVpvn_flags(SvPVX(cur_text), SvCUR(cur_text)-2,
+ SvUTF8(cur_text)|SVs_TEMP));
+ }
+ else {
+ /* I think this is will always be "", but be sure */
+ PUSHs(sv_2mortal(newSVsv(cur_text)));
+ }
+
PUSHs(&PL_sv_no);
}
/* require */
to freed memory as the result of undef *_. So put
it in the calleeās pad, donating our refer-
ence count. */
- SvREFCNT_dec(PAD_SVl(0));
- PAD_SVl(0) = (SV *)(cx->blk_sub.argarray = arg);
+ if (arg) {
+ SvREFCNT_dec(PAD_SVl(0));
+ PAD_SVl(0) = (SV *)(cx->blk_sub.argarray = arg);
+ }
/* GvAV(PL_defgv) might have been modified on scope
exit, so restore it. */
gotoprobe = CvROOT(cx->blk_sub.cv);
break;
}
- /* FALL THROUGH */
+ /* FALLTHROUGH */
case CXt_FORMAT:
case CXt_NULL:
DIE(aTHX_ "Can't \"goto\" out of a pseudo block");
I32 oldsave;
if (ix < 0)
- ix = 0;
+ DIE(aTHX_ "panic: docatch: illegal ix=%ld", (long)ix);
dounwind(ix);
TOPBLOCK(cx);
oldsave = PL_scopestack[PL_scopestack_ix];
#endif
}
PL_exit_flags |= PERL_EXIT_EXPECTED;
-#ifdef PERL_MAD
- /* KLUDGE: disable exit 0 in BEGIN blocks when we're just compiling */
- if (anum || !(PL_minus_c && PL_madskills))
- my_exit(anum);
-#else
my_exit(anum);
-#endif
PUSHs(&PL_sv_undef);
RETURN;
}
PL_restartop = 0;
goto redo_body;
}
- /* FALL THROUGH */
+ /* FALLTHROUGH */
default:
JMPENV_POP;
PL_op = oldop;
PL_op = NULL; /* avoid PL_op and PL_curpad referring to different CVs */
- if (!PL_madskills)
- SAVEMORTALIZESV(evalcv); /* must remain until end of current statement */
+ SAVEMORTALIZESV(evalcv); /* must remain until end of current statement */
/* make sure we compile in the right package */
PL_unitcheckav = newAV();
SAVEFREESV(PL_unitcheckav);
-#ifdef PERL_MAD
- SAVEBOOL(PL_madskills);
- PL_madskills = 0;
-#endif
ENTER_with_name("evalcomp");
SAVESPTR(PL_compcv);
Stat_t pmcstat;
SvSetSV_nosteal(pmcsv,name);
- sv_catpvn(pmcsv, "c", 1);
+ sv_catpvs(pmcsv, "c");
if (PerlLIO_stat(SvPV_nolen_const(pmcsv), &pmcstat) >= 0)
return check_type_and_open(pmcsv);
first = SvIV(*av_fetch(lav,0,0));
if ( first > (int)PERL_REVISION /* probably 'use 6.0' */
|| hv_exists(MUTABLE_HV(req), "qv", 2 ) /* qv style */
- || av_len(lav) > 1 /* FP with > 3 digits */
+ || av_tindex(lav) > 1 /* FP with > 3 digits */
|| strstr(SvPVX(pv),".0") /* FP with leading 0 */
) {
DIE(aTHX_ "Perl %"SVf" required--this is only "
SV *hintsv;
I32 second = 0;
- if (av_len(lav)>=1)
+ if (av_tindex(lav)>=1)
second = SvIV(*av_fetch(lav,1,0));
second /= second >= 600 ? 100 : 10;
filter_has_file = 0;
filter_cache = NULL;
if (filter_state) {
- SvREFCNT_dec(filter_state);
+ SvREFCNT_dec_NN(filter_state);
filter_state = NULL;
}
if (filter_sub) {
- SvREFCNT_dec(filter_sub);
+ SvREFCNT_dec_NN(filter_sub);
filter_sub = NULL;
}
}
/* Avoid '<dir>//<file>' */
if (!dirlen || *(tmp-1) != '/') {
*tmp++ = '/';
+ } else {
+ /* So SvCUR_set reports the correct length below */
+ dirlen--;
}
/* name came from an SV, so it will have a '\0' at the
sv_catpv(msg, " (you may need to install the ");
for (c = name; c < e; c++) {
if (*c == '/') {
- sv_catpvn(msg, "::", 2);
+ sv_catpvs(msg, "::");
}
else {
sv_catpvn(msg, c, 1);
SvPVX_const(namesv),
SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
G_DISCARD);
- retop = Perl_die(aTHX_ "%"SVf" did not return a true value",
- SVfARG(namesv));
+ Perl_die(aTHX_ "%"SVf" did not return a true value", SVfARG(namesv));
+ NOT_REACHED; /* NOTREACHED */
/* die_unwind() did LEAVE, or we won't be here */
}
else {
SSize_t i;
bool andedresults = TRUE;
AV *av = (AV*) SvRV(d);
- const I32 len = av_len(av);
+ const I32 len = av_tindex(av);
DEBUG_M(Perl_deb(aTHX_ " applying rule Array-CodeRef\n"));
if (len == -1)
RETPUSHYES;
/* Check that the key-sets are identical */
HE *he;
HV *other_hv = MUTABLE_HV(SvRV(d));
- bool tied = FALSE;
- bool other_tied = FALSE;
+ bool tied;
+ bool other_tied;
U32 this_key_count = 0,
other_key_count = 0;
HV *hv = MUTABLE_HV(SvRV(e));
DEBUG_M(Perl_deb(aTHX_ " applying rule Hash-Hash\n"));
/* Tied hashes don't know how many keys they have. */
- if (SvTIED_mg((SV*)hv, PERL_MAGIC_tied)) {
- tied = TRUE;
- }
- else if (SvTIED_mg((const SV *)other_hv, PERL_MAGIC_tied)) {
- HV * const temp = other_hv;
- other_hv = hv;
- hv = temp;
- tied = TRUE;
+ tied = cBOOL(SvTIED_mg((SV*)hv, PERL_MAGIC_tied));
+ other_tied = cBOOL(SvTIED_mg((const SV *)other_hv, PERL_MAGIC_tied));
+ if (!tied ) {
+ if(other_tied) {
+ /* swap HV sides */
+ HV * const temp = other_hv;
+ other_hv = hv;
+ hv = temp;
+ tied = TRUE;
+ other_tied = FALSE;
+ }
+ else if(HvUSEDKEYS((const HV *) hv) != HvUSEDKEYS(other_hv))
+ RETPUSHNO;
}
- if (SvTIED_mg((const SV *)other_hv, PERL_MAGIC_tied))
- other_tied = TRUE;
-
- if (!tied && HvUSEDKEYS((const HV *) hv) != HvUSEDKEYS(other_hv))
- RETPUSHNO;
/* The hashes have the same number of keys, so it suffices
to check that one is a subset of the other. */
}
else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVAV) {
AV * const other_av = MUTABLE_AV(SvRV(d));
- const SSize_t other_len = av_len(other_av) + 1;
+ const SSize_t other_len = av_tindex(other_av) + 1;
SSize_t i;
HV *hv = MUTABLE_HV(SvRV(e));
}
else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVHV) {
AV * const other_av = MUTABLE_AV(SvRV(e));
- const SSize_t other_len = av_len(other_av) + 1;
+ const SSize_t other_len = av_tindex(other_av) + 1;
SSize_t i;
DEBUG_M(Perl_deb(aTHX_ " applying rule Hash-Array\n"));
if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVAV) {
AV *other_av = MUTABLE_AV(SvRV(d));
DEBUG_M(Perl_deb(aTHX_ " applying rule Array-Array\n"));
- if (av_len(MUTABLE_AV(SvRV(e))) != av_len(other_av))
+ if (av_tindex(MUTABLE_AV(SvRV(e))) != av_tindex(other_av))
RETPUSHNO;
else {
SSize_t i;
- const SSize_t other_len = av_len(other_av);
+ const SSize_t other_len = av_tindex(other_av);
if (NULL == seen_this) {
seen_this = newHV();
sm_regex_array:
{
PMOP * const matcher = make_matcher((REGEXP*) SvRV(d));
- const SSize_t this_len = av_len(MUTABLE_AV(SvRV(e)));
+ const SSize_t this_len = av_tindex(MUTABLE_AV(SvRV(e)));
SSize_t i;
for(i = 0; i <= this_len; ++i) {
}
else if (!SvOK(d)) {
/* undef ~~ array */
- const SSize_t this_len = av_len(MUTABLE_AV(SvRV(e)));
+ const SSize_t this_len = av_tindex(MUTABLE_AV(SvRV(e)));
SSize_t i;
DEBUG_M(Perl_deb(aTHX_ " applying rule Undef-Array\n"));
sm_any_array:
{
SSize_t i;
- const SSize_t this_len = av_len(MUTABLE_AV(SvRV(e)));
+ const SSize_t this_len = av_tindex(MUTABLE_AV(SvRV(e)));
DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Array\n"));
for (i = 0; i <= this_len; ++i) {
s++;
}
noblank = TRUE;
- /* FALL THROUGH */
+ /* FALLTHROUGH */
case ' ': case '\t':
skipspaces++;
continue;