--- Devel-FindRef/FindRef.xs 2011/04/28 06:39:04 1.21 +++ Devel-FindRef/FindRef.xs 2018/07/31 22:55:47 1.27 @@ -6,13 +6,13 @@ (PERL_REVISION > (a) \ || (PERL_REVISION == (a) \ && (PERL_VERSION > (b) \ - || (PERL_VERSION == (b) && PERLSUBVERSION >= (c))))) + || (PERL_VERSION == (b) && PERL_SUBVERSION >= (c))))) #if !PERL_VERSION_ATLEAST (5,8,9) # define SVt_LAST 16 #endif -#if !PERL_VERSION_ATLEAST (5,10,0) +#ifndef SvPAD_OUR # define SvPAD_OUR(dummy) 0 #endif @@ -21,6 +21,27 @@ # define GvNAME_HEK(sv) 1 #endif +#ifndef PadARRAY +typedef AV PADNAMELIST; +typedef SV PADNAME; +# define PadnamePV(sv) SvPVX (sv) +# define PadnameLEN(sv) SvCUR (sv) +# define PadARRAY(pad) AvARRAY (pad) +# define PadlistARRAY(pl) ((PAD **)AvARRAY (pl)) +#endif + +#ifndef PadMAX +# define PadMAX(pad) AvFILLp (pad) +#endif + +#ifndef padnamelist_fetch +# define padnamelist_fetch(a,b) *av_fetch (a, b, FALSE) +#endif + +#ifndef PadlistNAMES +# define PadlistNAMES(padlist) *PadlistARRAY (padlist) +#endif + #define res_pair(text) \ do { \ AV *av = newAV (); \ @@ -97,6 +118,7 @@ if (SvTYPE (sv) >= SVt_PVMG) { +#if !PERL_VERSION_ATLEAST (5,21,6) if (SvTYPE (sv) == SVt_PVMG && SvPAD_OUR (sv)) { /* I have no clue what this is */ @@ -104,6 +126,8 @@ /* it doesn't seem to reference anything, so we should be able to ignore it */ } else +#endif + if (SvMAGICAL (sv)) /* name-pads use SvMAGIC for other purposes */ { MAGIC *mg = SvMAGIC (sv); @@ -145,41 +169,42 @@ while ((he = hv_iternext ((HV *)sv))) if (HeVAL (he) == targ) - res_pair (form ("in the hash member '%.*s' of", HeKLEN (he), HeKEY (he))); + res_pair (form ("the hash member '%.*s' of", HeKLEN (he), HeKEY (he))); } break; case SVt_PVCV: { - int depth = CvDEPTH (sv); + PADLIST *padlist = CvISXSUB (cv) ? 0 : CvPADLIST (sv); - /* Anonymous subs have a padlist but zero depth */ - if (CvANON (sv) && !depth && CvPADLIST (sv)) - depth = 1; - - if (depth) + if (padlist) { - AV *padlist = CvPADLIST (sv); + int depth = CvDEPTH (sv); + + /* Anonymous subs have a padlist but zero depth */ + /* some hacks switch CvANON off, so we just blindly assume a minimum of 1 */ + if (!depth && !PERL_VERSION_ATLEAST (5,21,6)) + depth = 1; while (depth) { - AV *pad = (AV *)AvARRAY (padlist)[depth]; + PAD *pad = PadlistARRAY (padlist)[depth]; av_push (excl, newSVuv (PTR2UV (pad))); /* exclude pads themselves from being found */ /* The 0th pad slot is @_ */ - if (AvARRAY (pad)[0] == targ) + if (PadARRAY (pad)[0] == targ) res_pair ("the argument array for"); - for (i = AvFILLp (pad) + 1; --i; ) - if (AvARRAY (pad)[i] == targ) + for (i = PadMAX (pad) + 1; --i; ) + if (PadARRAY (pad)[i] == targ) { /* Values from constant functions are stored in the pad without any name */ - SV *name_sv = AvARRAY (AvARRAY (padlist)[0])[i]; + PADNAME *name = padnamelist_fetch (PadlistNAMES (padlist), i); - if (name_sv && SvPOK (name_sv)) - res_pair (form ("the lexical '%s' in", SvPVX (name_sv))); + if (name && PadnamePV (name) && *PadnamePV (name)) + res_pair (form ("the lexical '%s' in", PadnamePV (name))); else res_pair ("an unnamed lexical in"); }