X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=Upper.xs;h=f8a35c72449129d26f58cfd96f98ce6df420ae95;hb=7a192f2ff19c1882fb55fccabac1fc6d9105fb29;hp=b3f6e4eaf297845dcac4e206d4d669e16e3f058e;hpb=97ca54131bb4b6f68ab55f906b64f238e104ebba;p=perl%2Fmodules%2FScope-Upper.git diff --git a/Upper.xs b/Upper.xs index b3f6e4e..f8a35c7 100644 --- a/Upper.xs +++ b/Upper.xs @@ -48,6 +48,10 @@ # define SvREFCNT_inc_simple_void(sv) SvREFCNT_inc(sv) #endif +#ifndef GvCV_set +# define GvCV_set(G, C) (GvCV(G) = (C)) +#endif + #ifndef HvNAME_get # define HvNAME_get(H) HvNAME(H) #endif @@ -161,7 +165,7 @@ START_MY_CXT # define SU_SAVE_HELEM_OR_HDELETE_SIZE SU_SAVE_HELEM_SIZE #endif -#define SU_SAVE_SPTR_SIZE 3 +#define SU_SAVE_GVCV_SIZE SU_SAVE_DESTRUCTOR_SIZE #if !SU_HAS_PERL(5, 8, 9) # define SU_SAVE_GP_SIZE 6 @@ -312,6 +316,43 @@ STATIC void su_save_helem(pTHX_ HV *hv, SV *keysv, SV *val) { } } +/* ... Saving code slots from a glob ....................................... */ + +#if !SU_HAS_PERL(5, 10, 0) && !defined(mro_method_changed_in) +# define mro_method_changed_in(G) PL_sub_generation++ +#endif + +typedef struct { + GV *gv; + CV *old_cv; +} su_save_gvcv_ud; + +STATIC void su_restore_gvcv(pTHX_ void *ud_) { + su_save_gvcv_ud *ud = ud_; + GV *gv = ud->gv; + + GvCV_set(gv, ud->old_cv); + GvCVGEN(gv) = 0; + mro_method_changed_in(GvSTASH(gv)); + + Safefree(ud); +} + +STATIC void su_save_gvcv(pTHX_ GV *gv) { +#define su_save_gvcv(G) su_save_gvcv(aTHX_ (G)) + su_save_gvcv_ud *ud; + + Newx(ud, 1, su_save_gvcv_ud); + ud->gv = gv; + ud->old_cv = GvCV(gv); + + GvCV_set(gv, NULL); + GvCVGEN(gv) = 0; + mro_method_changed_in(GvSTASH(gv)); + + SAVEDESTRUCTOR_X(su_restore_gvcv, ud); +} + /* --- Actions ------------------------------------------------------------- */ typedef struct { @@ -477,7 +518,7 @@ STATIC I32 su_ud_localize_init(pTHX_ su_ud_localize *ud, SV *sv, SV *val, SV *el deref = 0; break; case SVt_PVCV: - size = SU_SAVE_SPTR_SIZE; + size = SU_SAVE_GVCV_SIZE; deref = 0; break; default: @@ -545,8 +586,7 @@ STATIC void su_localize(pTHX_ void *ud_) { save_gp(gv, 1); /* hide previous entry in symtab */ break; case SVt_PVCV: - SAVESPTR(GvCV(gv)); - GvCV(gv) = NULL; + su_save_gvcv(gv); break; default: gv = (GV *) save_scalar(gv);