X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2Fautovivification.git;a=blobdiff_plain;f=autovivification.xs;h=d92b0b7b01bb92d6a94d7cc92f545ca2b79a609c;hp=a6bf2af1c79124370f9a643ee8800b810ea5a81e;hb=0c93e9f08676e6d77f7381a87e15c6dcc898683a;hpb=8140a099db6b1e60014ad468182815974e1a3650 diff --git a/autovivification.xs b/autovivification.xs index a6bf2af..d92b0b7 100644 --- a/autovivification.xs +++ b/autovivification.xs @@ -210,8 +210,6 @@ STATIC void a_ptable_clone(pTHX_ ptable_ent *ent, void *ud_) { #endif /* A_WORKAROUND_REQUIRE_PROPAGATION */ -#include "reap.h" - STATIC void a_thread_cleanup(pTHX_ void *ud) { dMY_CXT; @@ -221,6 +219,29 @@ STATIC void a_thread_cleanup(pTHX_ void *ud) { ptable_seen_free(MY_CXT.seen); } +STATIC int a_endav_free(pTHX_ SV *sv, MAGIC *mg) { + SAVEDESTRUCTOR_X(a_thread_cleanup, NULL); + + return 0; +} + +STATIC MGVTBL a_endav_vtbl = { + 0, + 0, + 0, + 0, + a_endav_free +#if MGf_COPY + , 0 +#endif +#if MGf_DUP + , 0 +#endif +#if MGf_LOCAL + , 0 +#endif +}; + #endif /* A_THREADSAFE */ #if A_WORKAROUND_REQUIRE_PROPAGATION @@ -980,11 +1001,22 @@ STATIC void a_peep_rec(pTHX_ OP *o, ptable *seen) { const a_op_info *oi = NULL; UV flags = 0; +#if !A_HAS_RPEEP if (ptable_fetch(seen, o)) break; ptable_seen_store(seen, o, o); +#endif switch (o->op_type) { +#if A_HAS_RPEEP + case OP_NEXTSTATE: + case OP_DBSTATE: + case OP_STUB: + if (ptable_fetch(seen, o)) + return; + ptable_seen_store(seen, o, o); + break; +#endif case OP_PADSV: if (o->op_ppaddr != a_pp_deref) { oi = a_map_fetch(o); @@ -1222,6 +1254,7 @@ PREINIT: ptable *t; #endif ptable *s; + GV *gv; PPCODE: { dMY_CXT; @@ -1245,7 +1278,23 @@ PPCODE: #endif MY_CXT.seen = s; } - reap(3, a_thread_cleanup, NULL); + gv = gv_fetchpv(__PACKAGE__ "::_THREAD_CLEANUP", 0, SVt_PVCV); + if (gv) { + CV *cv = GvCV(gv); + if (!PL_endav) + PL_endav = newAV(); + SvREFCNT_inc(cv); + if (!av_store(PL_endav, av_len(PL_endav) + 1, (SV *) cv)) + SvREFCNT_dec(cv); + sv_magicext((SV *) PL_endav, NULL, PERL_MAGIC_ext, &a_endav_vtbl, NULL, 0); + } + XSRETURN(0); + +void +_THREAD_CLEANUP(...) +PROTOTYPE: DISABLE +PPCODE: + a_thread_cleanup(aTHX_ NULL); XSRETURN(0); #endif /* A_THREADSAFE */