#define NPtype_MAGIC 0x04
#define NPtype_OP 0x05
+/* XXX these should probably be generalizes into flag bits */
#define NPattr_LEAFSIZE 0x00
#define NPattr_NAME 0x01
#define NPattr_PADFAKE 0x02
#define NPattr_PADNAME 0x03
#define NPattr_PADTMP 0x04
#define NPattr_NOTE 0x05
+#define NPattr_PRE_ATTR 0x06
+
+#define _ADD_ATTR_NP(st, attr_type, attr_name, attr_value, np) (st->add_attr_cb && st->add_attr_cb(st, np, attr_type, attr_name, attr_value))
+#define ADD_ATTR(st, attr_type, attr_name, attr_value) _ADD_ATTR_NP(st, attr_type, attr_name, attr_value, NP-1)
+#define ADD_PRE_ATTR(st, attr_type, attr_name, attr_value) (assert(!attr_type), _ADD_ATTR_NP(st, NPattr_PRE_ATTR, attr_name, attr_value, NP-1))
#define _NPathLink(np, nid, ntype) (((np)->id=nid), ((np)->type=ntype), ((np)->seqn=0))
#define NPathLink(nid) (_NPathLink(NP, nid, NPtype_LINK), NP)
#define NPathLinkAndNode(nid, nid2) (_NPathLink(NP, nid, NPtype_LINK), _NPathLink(NP+1, nid2, NPtype_NAME), ((NP+1)->prev=NP), (NP+1))
#define NPathOpLink (NPathArg)
#define NPathAddSizeCb(st, name, bytes) (st->add_attr_cb && st->add_attr_cb(st, NP-1, NPattr_LEAFSIZE, (name), (bytes))),
-#define ADD_ATTR(st, attr_type, attr_name, attr_value) (st->add_attr_cb && st->add_attr_cb(st, NP-1, attr_type, attr_name, attr_value))
#else
SV **pname;
I32 ix;
- if (!padlist) {
+ if (!padlist)
return;
- }
+ if( 0 && !check_new(st, padlist))
+ return;
+
pad_name = MUTABLE_AV(*av_fetch(MUTABLE_AV(padlist), 0, FALSE));
pname = AvARRAY(pad_name);
namesv = NULL;
}
if (namesv) {
+ /* SvFAKE: On a pad name SV, that slot in the frame AV is a REFCNT'ed reference to a lexical from "outside" */
if (SvFAKE(namesv))
ADD_ATTR(st, NPattr_PADFAKE, SvPVX_const(namesv), ix);
else
#else
case SVt_IV: TAG;
#endif
- if(recurse && SvROK(thing))
- sv_size(aTHX_ st, NPathLink("RV"), SvRV_const(thing), recurse);
+ if(recurse && SvROK(thing)) /* XXX maybe don't follow weakrefs */
+ sv_size(aTHX_ st, (SvWEAKREF(thing) ? NPathLink("weakRV") : NPathLink("RV")), SvRV_const(thing), recurse);
TAG;break;
case SVt_PVAV: TAG;
if (recurse >= st->min_recurse_threshold) {
SSize_t i = AvFILLp(thing) + 1;
- while (i--)
+ while (i--) {
+ ADD_PRE_ATTR(st, 0, "index", i);
sv_size(aTHX_ st, NPathLink("AVelem"), AvARRAY(thing)[i], recurse);
+ }
}
}
/* Add in the bits on the other side of the beginning */
case SVt_PVFM: TAG;
padlist_size(aTHX_ st, NPathLink("CvPADLIST"), CvPADLIST(thing), recurse);
- sv_size(aTHX_ st, NPathLink("CvOUTSIDE"), (SV *)CvOUTSIDE(thing), recurse);
+ sv_size(aTHX_ st, NPathLink("CvOUTSIDE"), (SV *)CvOUTSIDE(thing), SOME_RECURSION);
if (st->go_yell && !st->fm_whine) {
carp("Devel::Size: Calculated sizes for FMs are incomplete");
case SVt_PVCV: TAG;
/* not CvSTASH, per https://rt.cpan.org/Ticket/Display.html?id=79366 */
+ ADD_ATTR(st, NPattr_NAME, CvGV(thing) ? GvNAME(CvGV(thing)) : "UNDEFINED", 0);
sv_size(aTHX_ st, NPathLink("SvSTASH"), (SV *)SvSTASH(thing), SOME_RECURSION);
sv_size(aTHX_ st, NPathLink("CvGV"), (SV *)CvGV(thing), SOME_RECURSION);
padlist_size(aTHX_ st, NPathLink("CvPADLIST"), CvPADLIST(thing), recurse);
- sv_size(aTHX_ st, NPathLink("CvOUTSIDE"), (SV *)CvOUTSIDE(thing), recurse);
+ sv_size(aTHX_ st, NPathLink("CvOUTSIDE"), (SV *)CvOUTSIDE(thing), SOME_RECURSION);
if (CvISXSUB(thing)) {
sv_size(aTHX_ st, NPathLink("cv_const_sv"), cv_const_sv((CV *)thing), recurse);
} else {