if (!(cx->sb_rxtainted & 2) && SvTAINTED(TOPs))
cx->sb_rxtainted |= 2;
sv_catsv(dstr, POPs);
+ /* XXX: adjust for positive offsets of \G for instance s/(.)\G//g with positive pos() */
+ s -= RX_GOFS(rx);
/* Are we done */
- if (CxONCE(cx) || !CALLREGEXEC(rx, s, cx->sb_strend, orig,
- s == m, cx->sb_targ, NULL,
- ((cx->sb_rflags & REXEC_COPY_STR)
- ? (REXEC_IGNOREPOS|REXEC_NOT_FIRST)
- : (REXEC_COPY_STR|REXEC_IGNOREPOS|REXEC_NOT_FIRST))))
+ if (CxONCE(cx) || s < orig ||
+ !CALLREGEXEC(rx, s, cx->sb_strend, orig,
+ (s == m) + RX_GOFS(rx), cx->sb_targ, NULL,
+ ((cx->sb_rflags & REXEC_COPY_STR)
+ ? (REXEC_IGNOREPOS|REXEC_NOT_FIRST)
+ : (REXEC_COPY_STR|REXEC_IGNOREPOS|REXEC_NOT_FIRST))))
{
SV * const targ = cx->sb_targ;
const int off = AvARRAY(ary) - AvALLOC(ary);
if (!PL_dbargs) {
- GV* const tmpgv = gv_fetchpvs("DB::args", GV_ADD, SVt_PVAV);
- PL_dbargs = GvAV(gv_AVadd(tmpgv));
- GvMULTI_on(tmpgv);
+ PL_dbargs = GvAV(gv_AVadd(gv_fetchpvs("DB::args", GV_ADDMULTI,
+ SVt_PVAV)));
AvREAL_off(PL_dbargs); /* XXX should be REIFY (see av.h) */
}
case CXt_LOOP_LAZYSV:
case CXt_LOOP_FOR:
case CXt_LOOP_PLAIN:
+ case CXt_GIVEN:
+ case CXt_WHEN:
gotoprobe = cx->blk_oldcop->op_sibling;
break;
case CXt_SUBST:
Perl_load_module(aTHX_ 0, newSVpvs("feature"), NULL, importsv, NULL);
LEAVE;
}
+ /* If a version >= 5.11.0 is requested, strictures are on by default! */
+ if (PL_compcv &&
+ vcmp(sv, sv_2mortal(upg_version(newSVnv(5.011000), FALSE))) >= 0) {
+ PL_hints |= (HINT_STRICT_REFS | HINT_STRICT_SUBS | HINT_STRICT_VARS);
+ }
RETPUSHYES;
}
/* Adjust file name if the hook has set an %INC entry */
svp = hv_fetch(GvHVn(PL_incgv), name, len, 0);
if (svp)
- tryname = SvPVX_const(*svp);
+ tryname = SvPV_nolen_const(*svp);
if (count > 0) {
int i = 0;
tryname = SvPVX_const(namesv);
tryrsfp = doopen_pm(tryname, SvCUR(namesv));
if (tryrsfp) {
- if (tryname[0] == '.' && tryname[1] == '/')
- tryname += 2;
+ if (tryname[0] == '.' && tryname[1] == '/') {
+ ++tryname;
+ while (*++tryname == '/');
+ }
break;
}
else if (errno == EMFILE)
SAVEHINTS();
PL_hints = 0;
- if (PL_compiling.cop_hints_hash) {
- Perl_refcounted_he_free(aTHX_ PL_compiling.cop_hints_hash);
- PL_compiling.cop_hints_hash = NULL;
- }
+ hv_clear(GvHV(PL_hintgv));
SAVECOMPILEWARNINGS();
if (PL_dowarn & G_WARN_ALL_ON)
introduced within evals. See force_ident(). GSAR 96-10-12 */
SAVEHINTS();
PL_hints = PL_op->op_targ;
- if (saved_hh)
+ if (saved_hh) {
+ /* SAVEHINTS created a new HV in PL_hintgv, which we need to GC */
+ SvREFCNT_dec(GvHV(PL_hintgv));
GvHV(PL_hintgv) = saved_hh;
+ }
SAVECOMPILEWARNINGS();
PL_compiling.cop_warnings = DUP_WARNINGS(PL_curcop->cop_warnings);
if (PL_compiling.cop_hints_hash) {
ENTER;
SAVETMPS;
- if (PL_op->op_targ == 0) {
- SV ** const defsv_p = &GvSV(PL_defgv);
- *defsv_p = newSVsv(POPs);
- SAVECLEARSV(*defsv_p);
- }
- else
- sv_setsv(PAD_SV(PL_op->op_targ), POPs);
+ sv_setsv(PAD_SV(PL_op->op_targ), POPs);
PUSHBLOCK(cx, CXt_GIVEN, SP);
PUSHGIVEN(cx);
/* Do a smart match */
PP(pp_smartmatch)
{
+ DEBUG_M(Perl_deb(aTHX_ "Starting smart match resolution\n"));
return do_smartmatch(NULL, NULL);
}
/* First of all, handle overload magic of the rightmost argument */
if (SvAMAGIC(e)) {
- SV * const tmpsv = amagic_call(d, e, smart_amg, 0);
+ SV * tmpsv;
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Object\n"));
+ DEBUG_M(Perl_deb(aTHX_ " attempting overload\n"));
+
+ tmpsv = amagic_call(d, e, smart_amg, 0);
if (tmpsv) {
SPAGAIN;
(void)POPs;
SETs(tmpsv);
RETURN;
}
+ DEBUG_M(Perl_deb(aTHX_ " failed to run overload method; continuing...\n"));
}
SP -= 2; /* Pop the values */
/* ~~ undef */
if (!SvOK(e)) {
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Any-undef\n"));
if (SvOK(d))
RETPUSHNO;
else
RETPUSHYES;
}
- if (sv_isobject(e) && (SvTYPE(SvRV(e)) != SVt_REGEXP))
+ if (sv_isobject(e) && (SvTYPE(SvRV(e)) != SVt_REGEXP)) {
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Object\n"));
Perl_croak(aTHX_ "Smart matching a non-overloaded object breaks encapsulation");
+ }
if (sv_isobject(d) && (SvTYPE(SvRV(d)) != SVt_REGEXP))
object_on_left = TRUE;
bool andedresults = TRUE;
HV *hv = (HV*) SvRV(d);
I32 numkeys = hv_iterinit(hv);
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Hash-CodeRef\n"));
if (numkeys == 0)
RETPUSHYES;
while ( (he = hv_iternext(hv)) ) {
+ DEBUG_M(Perl_deb(aTHX_ " testing hash key...\n"));
ENTER;
SAVETMPS;
PUSHMARK(SP);
bool andedresults = TRUE;
AV *av = (AV*) SvRV(d);
const I32 len = av_len(av);
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Array-CodeRef\n"));
if (len == -1)
RETPUSHYES;
for (i = 0; i <= len; ++i) {
SV * const * const svp = av_fetch(av, i, FALSE);
+ DEBUG_M(Perl_deb(aTHX_ " testing array element...\n"));
ENTER;
SAVETMPS;
PUSHMARK(SP);
}
else {
sm_any_sub:
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Any-CodeRef\n"));
ENTER;
SAVETMPS;
PUSHMARK(SP);
goto sm_any_hash; /* Treat objects like scalars */
}
else if (!SvOK(d)) {
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Hash ($a undef)\n"));
RETPUSHNO;
}
else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVHV) {
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;
(void) hv_iterinit(hv);
while ( (he = hv_iternext(hv)) ) {
SV *key = hv_iterkeysv(he);
-
+
+ DEBUG_M(Perl_deb(aTHX_ " comparing hash key...\n"));
++ this_key_count;
if(!hv_exists_ent(other_hv, key, 0)) {
I32 i;
HV *hv = MUTABLE_HV(SvRV(e));
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Array-Hash\n"));
for (i = 0; i < other_len; ++i) {
SV ** const svp = av_fetch(other_av, i, FALSE);
+ DEBUG_M(Perl_deb(aTHX_ " checking for key existence...\n"));
if (svp) { /* ??? When can this not happen? */
if (hv_exists_ent(hv, *svp, 0))
RETPUSHYES;
RETPUSHNO;
}
else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_REGEXP) {
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Regex-Hash\n"));
sm_regex_hash:
{
PMOP * const matcher = make_matcher((REGEXP*) SvRV(d));
(void) hv_iterinit(hv);
while ( (he = hv_iternext(hv)) ) {
+ DEBUG_M(Perl_deb(aTHX_ " testing key against pattern...\n"));
if (matcher_matches_sv(matcher, hv_iterkeysv(he))) {
(void) hv_iterinit(hv);
destroy_matcher(matcher);
}
else {
sm_any_hash:
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Hash\n"));
if (hv_exists_ent(MUTABLE_HV(SvRV(e)), d, 0))
RETPUSHYES;
else
const I32 other_len = av_len(other_av) + 1;
I32 i;
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Hash-Array\n"));
for (i = 0; i < other_len; ++i) {
SV ** const svp = av_fetch(other_av, i, FALSE);
+
+ DEBUG_M(Perl_deb(aTHX_ " testing for key existence...\n"));
if (svp) { /* ??? When can this not happen? */
if (hv_exists_ent(MUTABLE_HV(SvRV(d)), *svp, 0))
RETPUSHYES;
}
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))
RETPUSHNO;
else {
PUSHs(*this_elem);
PUTBACK;
+ DEBUG_M(Perl_deb(aTHX_ " recursively comparing array element...\n"));
(void) do_smartmatch(seen_this, seen_other);
SPAGAIN;
+ DEBUG_M(Perl_deb(aTHX_ " recursion finished\n"));
if (!SvTRUEx(POPs))
RETPUSHNO;
}
}
else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_REGEXP) {
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Regex-Array\n"));
sm_regex_array:
{
PMOP * const matcher = make_matcher((REGEXP*) SvRV(d));
for(i = 0; i <= this_len; ++i) {
SV * const * const svp = av_fetch(MUTABLE_AV(SvRV(e)), i, FALSE);
+ DEBUG_M(Perl_deb(aTHX_ " testing element against pattern...\n"));
if (svp && matcher_matches_sv(matcher, *svp)) {
destroy_matcher(matcher);
RETPUSHYES;
const I32 this_len = av_len(MUTABLE_AV(SvRV(e)));
I32 i;
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Undef-Array\n"));
for (i = 0; i <= this_len; ++i) {
SV * const * const svp = av_fetch(MUTABLE_AV(SvRV(e)), i, FALSE);
+ DEBUG_M(Perl_deb(aTHX_ " testing for undef element...\n"));
if (!svp || !SvOK(*svp))
RETPUSHYES;
}
I32 i;
const I32 this_len = av_len(MUTABLE_AV(SvRV(e)));
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Array\n"));
for (i = 0; i <= this_len; ++i) {
SV * const * const svp = av_fetch(MUTABLE_AV(SvRV(e)), i, FALSE);
if (!svp)
PUSHs(*svp);
PUTBACK;
/* infinite recursion isn't supposed to happen here */
+ DEBUG_M(Perl_deb(aTHX_ " recursively testing array element...\n"));
(void) do_smartmatch(NULL, NULL);
SPAGAIN;
+ DEBUG_M(Perl_deb(aTHX_ " recursion finished\n"));
if (SvTRUEx(POPs))
RETPUSHYES;
}
else if (SvROK(e) && SvTYPE(SvRV(e)) == SVt_REGEXP) {
if (!object_on_left && SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVHV) {
SV *t = d; d = e; e = t;
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Hash-Regex\n"));
goto sm_regex_hash;
}
else if (!object_on_left && SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVAV) {
SV *t = d; d = e; e = t;
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Array-Regex\n"));
goto sm_regex_array;
}
else {
PMOP * const matcher = make_matcher((REGEXP*) SvRV(e));
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Regex\n"));
PUTBACK;
PUSHs(matcher_matches_sv(matcher, d)
? &PL_sv_yes
/* See if there is overload magic on left */
else if (object_on_left && SvAMAGIC(d)) {
SV *tmpsv;
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Object-Any\n"));
+ DEBUG_M(Perl_deb(aTHX_ " attempting overload\n"));
PUSHs(d); PUSHs(e);
PUTBACK;
tmpsv = amagic_call(d, e, smart_amg, AMGf_noright);
RETURN;
}
SP -= 2;
+ DEBUG_M(Perl_deb(aTHX_ " failed to run overload method; falling back...\n"));
goto sm_any_scalar;
}
+ else if (!SvOK(d)) {
+ /* undef ~~ scalar ; we already know that the scalar is SvOK */
+ DEBUG_M(Perl_deb(aTHX_ " applying rule undef-Any\n"));
+ RETPUSHNO;
+ }
else
sm_any_scalar:
if (SvNIOK(e) || (SvPOK(e) && looks_like_number(e) && SvNIOK(d))) {
+ DEBUG_M(if (SvNIOK(e))
+ Perl_deb(aTHX_ " applying rule Any-Num\n");
+ else
+ Perl_deb(aTHX_ " applying rule Num-numish\n");
+ );
/* numeric comparison */
PUSHs(d); PUSHs(e);
PUTBACK;
}
/* As a last resort, use string comparison */
+ DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Any\n"));
PUSHs(d); PUSHs(e);
PUTBACK;
return pp_seq();