Clone-Closure

 view release on metacpan or  search on metacpan

lib/Clone/Closure.xs  view on Meta::CPAN

                mg->mg_obj);
            }
        }

        if (shared > 0) {
#ifdef SvSHARE
            TRACE_SV("share", "SV", clone);
            SvSHARE(clone);
#else
            croak("can't share values in this version of perl");
#endif
        }
    }

    if (!recurse) {
        TRACE_SV("skip", "SV", clone);
    }
    else if ( SvTYPE(ref) == SVt_PVHV ) {
        hv_clone(SEEN, (HV *)ref, (HV *)clone);
    }
    else if ( SvTYPE(ref) == SVt_PVAV ) {
        av_clone(SEEN, (AV *)ref, (AV *)clone);
    }
    else if ( SvTYPE(ref) == SVt_PVCV ) {
        if (CvCLONED((CV *)ref)) {
            pad_clone(SEEN, (CV *)ref, (CV *)clone);
        }
    }
    /* 3: REFERENCE (inlined for speed) */
    else if (SvROK(ref)) {
        TRACE_SV("ref", "RV", ref);

        SvROK_on(clone);
        SvRV(clone) = sv_clone(SEEN, SvRV(ref));

        if (sv_isobject(ref)) {
            sv_bless(clone, SvSTASH(SvRV(ref)));
        }

        if (SvWEAKREF(ref)) {
            TRACE_SV("weaken", "RV", clone);
            sv_rvweaken(clone);
        }

        TRACE_SV("clone", "RV", clone);
    }

    if (SvREADONLY(ref))
        SvREADONLY_on(clone);

    TRACE_SV("clone", "SV", clone);
    return clone;
}

MODULE = Clone::Closure		PACKAGE = Clone::Closure

PROTOTYPES: ENABLE

void
_breakpoint()
    PPCODE:
        XSRETURN_UNDEF;

void
clone(ref)
	SV *ref
    PREINIT:
	SV *clone;
        HV *SEEN;
    PPCODE:
        SEEN = newHV();

        TRACE_SV("ref", "clone", ref);
	clone = sv_clone(SEEN, ref);
        TRACE_SV("clone", "clone", clone);

        SvREFCNT_dec(SEEN);

	EXTEND(SP,1);
	PUSHs(sv_2mortal(clone));



( run in 0.829 second using v1.01-cache-2.11-cpan-71847e10f99 )