X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;ds=sidebyside;f=autovivification.xs;h=7e7c1f34cd32fbb5a684c6d21695537bdd327fa1;hb=refs%2Ftags%2Frt56870;hp=cb81c0f95bfe27cc60ac3e5a0e85bb4ca2b21317;hpb=69e618ff184122b6f498b61c5e8d0b607756c4a2;p=perl%2Fmodules%2Fautovivification.git diff --git a/autovivification.xs b/autovivification.xs index cb81c0f..7e7c1f3 100644 --- a/autovivification.xs +++ b/autovivification.xs @@ -94,7 +94,18 @@ STATIC UV a_detag(pTHX_ const SV *hint) { #else /* A_WORKAROUND_REQUIRE_PROPAGATION */ #define a_tag(B) newSVuv(B) -#define a_detag(H) (((H) && SvOK(H)) ? SvUVX(H) : 0) +/* PVs fetched from the hints chain have their SvLEN set to zero, so get the UV + * from a copy. */ +#define a_detag(H) \ + ((H) \ + ? (SvIOK(H) \ + ? SvUVX(H) \ + : (SvPOK(H) \ + ? sv_2uv(SvLEN(H) ? (H) : sv_mortalcopy(H)) \ + : 0 \ + ) \ + ) \ + : 0) #endif /* !A_WORKAROUND_REQUIRE_PROPAGATION */ @@ -367,7 +378,9 @@ STATIC bool a_defined(pTHX_ SV *sv) { defined = TRUE; break; default: - defined = SvOK(sv); + SvGETMAGIC(sv); + if (SvOK(sv)) + defined = TRUE; } return defined; @@ -392,7 +405,7 @@ STATIC OP *a_pp_rv2av(pTHX) { flags = oi.flags; if (flags & A_HINT_DEREF) { - if (!SvOK(TOPs)) { + if (!a_defined(TOPs)) { /* We always need to push an empty array to fool the pp_aelem() that comes * later. */ SV *av; @@ -419,7 +432,7 @@ STATIC OP *a_pp_rv2hv_simple(pTHX) { flags = oi.flags; if (flags & A_HINT_DEREF) { - if (!SvOK(TOPs)) + if (!a_defined(TOPs)) RETURN; } else { PL_op->op_ppaddr = oi.old_pp; @@ -437,7 +450,7 @@ STATIC OP *a_pp_rv2hv(pTHX) { flags = oi.flags; if (flags & A_HINT_DEREF) { - if (!SvOK(TOPs)) { + if (!a_defined(TOPs)) { SV *hv; POPs; hv = sv_2mortal((SV *) newHV()); @@ -473,7 +486,7 @@ deref: if (flags & (A_HINT_NOTIFY|A_HINT_STORE)) { SPAGAIN; - if (!SvOK(TOPs)) { + if (!a_defined(TOPs)) { if (flags & A_HINT_STRICT) croak("Reference vivification forbidden"); else if (flags & A_HINT_WARN)