From: Nicholas Clark Date: Sun, 24 Apr 2011 20:59:00 +0000 (+0100) Subject: total_size() and size() can be XS ALIASes, now all the logic is in sv_size() X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=13683e3a91e87cceef28a3098bc58fe96870d690;p=p5sagit%2FDevel-Size.git total_size() and size() can be XS ALIASes, now all the logic is in sv_size() --- diff --git a/CHANGES b/CHANGES index 2389b88..eea2bdc 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,8 @@ Revision history for Perl extension Devel::Size. * Fix potential SEGVs for OP_AELEMFAST on a lexical (eg $foo[3]) * Fix likely SEGVs for PVOPs (missing break) * Fix potential SEGVs for PVBMs on 5.10 and later + * Move hash and array traversal from total_size() to sv_size() + - this allows total_size() and size() to be XS ALIASes. 0.74_51 2011-04-22 nicholas * Don't count PL_sv_{undef,no,yes} in the size returned diff --git a/Size.xs b/Size.xs index dd5ea33..7ff7761 100644 --- a/Size.xs +++ b/Size.xs @@ -750,6 +750,8 @@ PROTOTYPES: DISABLE UV size(orig_thing) SV *orig_thing +ALIAS: + total_size = TOTAL_SIZE_RECURSION CODE: { SV *thing = orig_thing; @@ -767,81 +769,9 @@ CODE: } #endif - sv_size(aTHX_ st, thing, NO_RECURSION); + sv_size(aTHX_ st, thing, ix); RETVAL = st->total_size; free_state(st); } OUTPUT: RETVAL - - -UV -total_size(orig_thing) - SV *orig_thing -CODE: -{ - SV *thing = orig_thing; - /* Array with things we still need to do */ - AV *pending_array; - IV size = 0; - struct state *st = new_state(aTHX); - - /* Size starts at zero */ - RETVAL = 0; - - pending_array = newAV(); - - /* If they passed us a reference then dereference it. - This is the only way we can check the sizes of arrays and hashes. */ - if (SvROK(thing)) { - thing = SvRV(thing); - } - - /* Put it on the pending array */ - av_push(pending_array, thing); - - /* Now just yank things off the end of the array until it's done */ - while (av_len(pending_array) >= 0) { - thing = av_pop(pending_array); - /* Process it if we've not seen it */ - if (sv_size(aTHX_ st, thing, TOTAL_SIZE_RECURSION)) { - dbg_printf(("# Found type %i at %p\n", SvTYPE(thing), thing)); - switch (SvTYPE(thing)) { - /* fix for bug #24846 (Does not correctly recurse into references in a PVNV-type scalar) */ - case SVt_PVNV: TAG; - if (SvROK(thing)) - { - av_push(pending_array, SvRV(thing)); - } - TAG;break; -#if (PERL_VERSION < 11) - case SVt_RV: TAG; -#else - case SVt_IV: TAG; -#endif - dbg_printf(("# Found RV\n")); - if (SvROK(thing)) { - dbg_printf(("# Found RV\n")); - av_push(pending_array, SvRV(thing)); - } - TAG;break; - - default: - TAG;break; - } - } else { - /* check_new() returned false: */ -#ifdef DEVEL_SIZE_DEBUGGING - if (SvOK(sv)) printf("# Ignore ref copy 0x%x\n", sv); - else printf("# Ignore non-sv 0x%x\n", sv); -#endif - } - } /* end while */ - - RETVAL = st->total_size; - free_state(st); - SvREFCNT_dec(pending_array); -} -OUTPUT: - RETVAL -