X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=Magic.xs;h=89df570ec4d896ae54599ad0408221dccbcb1a64;hb=201d2874479e003bb82662085516a07aa04391e2;hp=2ae40a1df5d383bea56c687e04731f2d36dbfd4f;hpb=763ba8093427f3668368fa885741618ac6289d41;p=perl%2Fmodules%2FVariable-Magic.git diff --git a/Magic.xs b/Magic.xs index 2ae40a1..89df570 100644 --- a/Magic.xs +++ b/Magic.xs @@ -1,6 +1,8 @@ /* This file is part of the Variable::Magic Perl module. * See http://search.cpan.org/dist/Variable-Magic/ */ +#include /* , va_{start,arg,end}, ... */ + #include /* sprintf() */ #define PERL_NO_GET_CONTEXT @@ -12,9 +14,21 @@ #define R(S) fprintf(stderr, "R(" #S ") = %d\n", SvREFCNT(S)) +#define PERL_VERSION_GE(R, V, S) (PERL_REVISION > (R) || (PERL_REVISION == (R) && (PERL_VERSION > (V) || (PERL_VERSION == (V) && (PERL_SUBVERSION >= (S)))))) + #define PERL_VERSION_LE(R, V, S) (PERL_REVISION < (R) || (PERL_REVISION == (R) && (PERL_VERSION < (V) || (PERL_VERSION == (V) && (PERL_SUBVERSION <= (S)))))) -#define PERL_API_VERSION_GE(R, V, S) (PERL_API_REVISION > (R) || (PERL_API_REVISION == (R) && (PERL_API_VERSION > (V) || (PERL_API_VERSION == (V) && (PERL_API_SUBVERSION >= (S)))))) +#ifndef VMG_PERL_PATCHLEVEL +# ifdef PERL_PATCHNUM +# define VMG_PERL_PATCHLEVEL PERL_PATCHNUM +# else +# define VMG_PERL_PATCHLEVEL 0 +# endif +#endif + +#define VMG_HAS_PERL_OR(P, R, V, S) ((VMG_PERL_PATCHLEVEL >= (P)) || (!VMG_PERL_PATCHLEVEL && PERL_VERSION_GE((R), (V), (S)))) + +#define VMG_HAS_PERL_AND(P, R, V, S) (PERL_VERSION_GE((R), (V), (S)) && (!VMG_PERL_PATCHLEVEL || (VMG_PERL_PATCHLEVEL >= (P)))) /* --- Compatibility ------------------------------------------------------- */ @@ -26,11 +40,24 @@ # define SvMAGIC_set(sv, val) (SvMAGIC(sv) = (val)) #endif +#ifndef mPUSHi +# define mPUSHi(I) PUSHs(sv_2mortal(newSViv(I))) +#endif + #ifndef dMY_CXT -# define MY_CXT vmg_globaldata # define dMY_CXT +# undef MY_CXT +# define MY_CXT vmg_globaldata +# undef START_MY_CXT # define START_MY_CXT STATIC my_cxt_t MY_CXT; +# undef MY_CXT_INIT # define MY_CXT_INIT +# undef MY_CXT_CLONE +# undef aMY_CXT +# undef pMY_CXT +# define VMG_THREADSAFE 0 +#else +# define VMG_THREADSAFE 1 #endif #ifndef PERL_MAGIC_ext @@ -41,7 +68,6 @@ # define MGf_COPY 0 #endif -#undef MGf_DUP /* Disable it for now. */ #ifndef MGf_DUP # define MGf_DUP 0 #endif @@ -50,34 +76,52 @@ # define MGf_LOCAL 0 #endif -#if PERL_API_VERSION_GE(5, 10, 0) +/* uvar magic and Hash::Util::FieldHash were commited with p28419 */ +#if VMG_HAS_PERL_AND(28419, 5, 9, 4) # define VMG_UVAR 1 #else # define VMG_UVAR 0 #endif +#if !defined(VMG_COMPAT_ARRAY_PUSH_NOLEN) && VMG_HAS_PERL_OR(25854, 5, 9, 3) +# define VMG_COMPAT_ARRAY_PUSH_NOLEN 1 +#else +# define VMG_COMPAT_ARRAY_PUSH_NOLEN 0 +#endif + +/* since 5.9.5 - see #43357 */ +#if VMG_HAS_PERL_OR(31473, 5, 9, 5) +# define VMG_COMPAT_ARRAY_UNDEF_CLEAR 1 +#else +# define VMG_COMPAT_ARRAY_UNDEF_CLEAR 0 +#endif + +#if VMG_HAS_PERL_OR(32969, 5, 11, 0) +# define VMG_COMPAT_SCALAR_LENGTH_NOLEN 1 +#else +# define VMG_COMPAT_SCALAR_LENGTH_NOLEN 0 +#endif + #if VMG_UVAR -/* Bug-free mg_magical - see http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2008-01/msg00036.html */ -STATIC void vmg_mg_magical(pTHX_ SV *sv) { -#define vmg_mg_magical(S) vmg_mg_magical(aTHX_ (S)) +/* Bug-free mg_magical - see http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2008-01/msg00036.html - but specialized to our needs. */ +STATIC void vmg_sv_magicuvar(pTHX_ SV *sv, const char *uf, I32 len) { +#define vmg_sv_magicuvar(S, U, L) vmg_sv_magicuvar(aTHX_ (S), (U), (L)) const MAGIC* mg; + sv_magic(sv, NULL, PERL_MAGIC_uvar, uf, len); + /* uvar magic has set and get magic, hence this has set SVs_GMG and SVs_SMG. */ PERL_UNUSED_CONTEXT; if ((mg = SvMAGIC(sv))) { SvRMAGICAL_off(sv); do { const MGVTBL* const vtbl = mg->mg_virtual; if (vtbl) { - if (vtbl->svt_get && !(mg->mg_flags & MGf_GSKIP)) - SvGMAGICAL_on(sv); - if (vtbl->svt_set) - SvSMAGICAL_on(sv); - if (vtbl->svt_clear) + if (vtbl->svt_clear) { SvRMAGICAL_on(sv); + break; + } } } while ((mg = mg->mg_moremagic)); - if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG))) - SvRMAGICAL_on(sv); } } @@ -94,12 +138,29 @@ typedef struct { START_MY_CXT +STATIC void vmg_cxt_init +#if defined(pMY_CXT) && defined(aMY_CXT) + (pTHX_ pMY_CXT) { +# define vmg_cxt_init() vmg_cxt_init(aTHX_ aMY_CXT) +#else + (pTHX) { + dMY_CXT; +# define vmg_cxt_init() vmg_cxt_init(aTHX) +#endif + MY_CXT.wizz = newHV(); +#ifdef USE_ITHREADS + HvSHAREKEYS_off(MY_CXT.wizz); +#endif + MY_CXT.count = 0; + return; +} + /* --- Signatures ---------------------------------------------------------- */ #define SIG_MIN ((U16) (1u << 8)) -#define SIG_MAX ((U16) (1u << 16 - 1)) +#define SIG_MAX ((U16) ((1u << 16) - 1)) #define SIG_NBR (SIG_MAX - SIG_MIN + 1) -#define SIG_WIZ ((U16) (1u << 8 - 1)) +#define SIG_WIZ ((U16) ((1u << 8) - 1)) /* ... Generate signatures ................................................. */ @@ -146,6 +207,7 @@ typedef struct { STATIC SV *vmg_data_new(pTHX_ SV *ctor, SV *sv, AV *args) { #define vmg_data_new(C, S, A) vmg_data_new(aTHX_ (C), (S), (A)) SV *nsv; + I32 i, alen = (args == NULL) ? 0 : av_len(args); dSP; int count; @@ -154,11 +216,10 @@ STATIC SV *vmg_data_new(pTHX_ SV *ctor, SV *sv, AV *args) { SAVETMPS; PUSHMARK(SP); - XPUSHs(sv_2mortal(newRV_inc(sv))); - if (args != NULL) { - I32 i, alen = av_len(args); - for (i = 0; i < alen; ++i) { XPUSHs(*av_fetch(args, i, 0)); } - } + EXTEND(SP, alen + 1); + PUSHs(sv_2mortal(newRV_inc(sv))); + for (i = 0; i < alen; ++i) + PUSHs(*av_fetch(args, i, 0)); PUTBACK; count = call_sv(ctor, G_SCALAR); @@ -183,7 +244,6 @@ STATIC SV *vmg_data_new(pTHX_ SV *ctor, SV *sv, AV *args) { STATIC SV *vmg_data_get(SV *sv, U16 sig) { MAGIC *mg, *moremagic; - MGWIZ *w; if (SvTYPE(sv) >= SVt_PVMG) { for (mg = SvMAGIC(sv); mg; mg = moremagic) { @@ -198,6 +258,7 @@ STATIC SV *vmg_data_get(SV *sv, U16 sig) { /* ... Magic cast/dispell .................................................. */ +#if VMG_UVAR STATIC I32 vmg_svt_val(pTHX_ IV, SV *); STATIC void vmg_uvar_del(SV *sv, MAGIC *prevmagic, MAGIC *mg, MAGIC *moremagic) { @@ -210,6 +271,7 @@ STATIC void vmg_uvar_del(SV *sv, MAGIC *prevmagic, MAGIC *mg, MAGIC *moremagic) Safefree(mg->mg_ptr); Safefree(mg); } +#endif /* VMG_UVAR */ STATIC UV vmg_cast(pTHX_ SV *sv, SV *wiz, AV *args) { #define vmg_cast(S, W, A) vmg_cast(aTHX_ (S), (W), (A)) @@ -230,17 +292,18 @@ STATIC UV vmg_cast(pTHX_ SV *sv, SV *wiz, AV *args) { data = (w->cb_data) ? vmg_data_new(w->cb_data, sv, args) : NULL; mg = sv_magicext(sv, data, PERL_MAGIC_ext, w->vtbl, (const char *) wiz, HEf_SVKEY); mg->mg_private = w->sig; - mg->mg_flags = mg->mg_flags #if MGf_COPY - | MGf_COPY + if (w->cb_copy) + mg->mg_flags |= MGf_COPY; #endif /* MGf_COPY */ #if MGf_DUP - | MGf_DUP + if (w->cb_dup) + mg->mg_flags |= MGf_DUP; #endif /* MGf_DUP */ #if MGf_LOCAL - | MGf_LOCAL + if (w->cb_local) + mg->mg_flags |= MGf_LOCAL; #endif /* MGf_LOCAL */ - ; #if VMG_UVAR if (w->uvar && SvTYPE(sv) >= SVt_PVHV) { @@ -274,8 +337,7 @@ STATIC UV vmg_cast(pTHX_ SV *sv, SV *wiz, AV *args) { } if (add_uvar) { - sv_magic(sv, NULL, PERL_MAGIC_uvar, (const char *) &uf, sizeof(uf)); - vmg_mg_magical(sv); + vmg_sv_magicuvar(sv, (const char *) &uf, sizeof(uf)); } } @@ -296,15 +358,19 @@ STATIC UV vmg_dispell(pTHX_ SV *sv, U16 sig) { for (prevmagic = NULL, mg = SvMAGIC(sv); mg; prevmagic = mg, mg = moremagic) { moremagic = mg->mg_moremagic; if (mg->mg_type == PERL_MAGIC_ext) { -#if VMG_UVAR - MGWIZ *w = SV2MGWIZ(mg->mg_ptr); - if (w->uvar) { ++uvars; } -#endif /* VMG_UVAR */ if (mg->mg_private == sig) { #if VMG_UVAR - if (!w->uvar) { uvars = 0; } /* Short-circuit uvar deletion. */ + /* If the current has no uvar, short-circuit uvar deletion. */ + uvars = (SV2MGWIZ(mg->mg_ptr)->uvar) ? (uvars + 1) : 0; #endif /* VMG_UVAR */ break; +#if VMG_UVAR + } else if ((mg->mg_private >= SIG_MIN) && + (mg->mg_private <= SIG_MAX) && + SV2MGWIZ(mg->mg_ptr)->uvar) { + ++uvars; + /* We can't break here since we need to find the ext magic to delete. */ +#endif /* VMG_UVAR */ } } } @@ -326,7 +392,10 @@ STATIC UV vmg_dispell(pTHX_ SV *sv, U16 sig) { /* mg was the first ext magic in the chain that had uvar */ for (mg = moremagic; mg; mg = mg->mg_moremagic) { - if ((mg->mg_type == PERL_MAGIC_ext) && SV2MGWIZ(mg->mg_ptr)->uvar) { + if ((mg->mg_type == PERL_MAGIC_ext) && + (mg->mg_private >= SIG_MIN) && + (mg->mg_private <= SIG_MAX) && + SV2MGWIZ(mg->mg_ptr)->uvar) { ++uvars; break; } @@ -345,6 +414,7 @@ STATIC UV vmg_dispell(pTHX_ SV *sv, U16 sig) { /* Revert the original uvar magic. */ uf[0] = uf[1]; Renew(uf, 1, struct ufuncs); + mg->mg_ptr = (char *) uf; mg->mg_len = sizeof(struct ufuncs); } else { /* Remove the uvar magic. */ @@ -359,9 +429,11 @@ STATIC UV vmg_dispell(pTHX_ SV *sv, U16 sig) { /* ... svt callbacks ....................................................... */ -STATIC int vmg_cb_call(pTHX_ SV *cb, SV *sv, SV *data) { -#define vmg_cb_call(I, S, D) vmg_cb_call(aTHX_ (I), (S), (D)) +STATIC int vmg_cb_call(pTHX_ SV *cb, SV *sv, SV *data, unsigned int args, ...) { + va_list ap; + SV *svr; int ret; + unsigned int i; dSP; int count; @@ -370,8 +442,15 @@ STATIC int vmg_cb_call(pTHX_ SV *cb, SV *sv, SV *data) { SAVETMPS; PUSHMARK(SP); - XPUSHs(sv_2mortal(newRV_inc(sv))); - if (data) { XPUSHs(data); } + EXTEND(SP, args + 2); + PUSHs(sv_2mortal(newRV_inc(sv))); + PUSHs(data ? data : &PL_sv_undef); + va_start(ap, args); + for (i = 0; i < args; ++i) { + SV *sva = va_arg(ap, SV *); + PUSHs(sva ? sva : &PL_sv_undef); + } + va_end(ap); PUTBACK; count = call_sv(cb, G_SCALAR); @@ -379,7 +458,8 @@ STATIC int vmg_cb_call(pTHX_ SV *cb, SV *sv, SV *data) { SPAGAIN; if (count != 1) { croak("Callback needs to return 1 scalar\n"); } - ret = POPi; + svr = POPs; + ret = SvOK(svr) ? SvIV(svr) : 0; PUTBACK; @@ -389,48 +469,21 @@ STATIC int vmg_cb_call(pTHX_ SV *cb, SV *sv, SV *data) { return ret; } -#if MGf_COPY || VMG_UVAR -STATIC int vmg_cb_call2(pTHX_ SV *cb, SV *sv, SV *data, SV *sv2) { -#define vmg_cb_call2(I, S, D, S2) vmg_cb_call2(aTHX_ (I), (S), (D), (S2)) - int ret; - - dSP; - int count; - - ENTER; - SAVETMPS; - - PUSHMARK(SP); - XPUSHs(sv_2mortal(newRV_inc(sv))); - XPUSHs(data ? data : &PL_sv_undef); - if (sv2) { XPUSHs(sv2); } - PUTBACK; - - count = call_sv(cb, G_SCALAR); - - SPAGAIN; - - if (count != 1) { croak("Callback needs to return 1 scalar\n"); } - ret = POPi; - - PUTBACK; - - FREETMPS; - LEAVE; - - return ret; -} -#endif /* MGf_COPY || VMG_UVAR */ +#define vmg_cb_call1(I, S, D) vmg_cb_call(aTHX_ (I), (S), (D), 0) +#define vmg_cb_call2(I, S, D, S2) vmg_cb_call(aTHX_ (I), (S), (D), 1, (S2)) +#define vmg_cb_call3(I, S, D, S2, S3) vmg_cb_call(aTHX_ (I), (S), (D), 2, (S2), (S3)) STATIC int vmg_svt_get(pTHX_ SV *sv, MAGIC *mg) { - return vmg_cb_call(SV2MGWIZ(mg->mg_ptr)->cb_get, sv, mg->mg_obj); + return vmg_cb_call1(SV2MGWIZ(mg->mg_ptr)->cb_get, sv, mg->mg_obj); } STATIC int vmg_svt_set(pTHX_ SV *sv, MAGIC *mg) { - return vmg_cb_call(SV2MGWIZ(mg->mg_ptr)->cb_set, sv, mg->mg_obj); + return vmg_cb_call1(SV2MGWIZ(mg->mg_ptr)->cb_set, sv, mg->mg_obj); } STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) { + SV *svr; + I32 len; U32 ret; dSP; @@ -440,10 +493,15 @@ STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) { SAVETMPS; PUSHMARK(SP); - XPUSHs(sv_2mortal(newRV_inc(sv))); - XPUSHs(mg->mg_obj ? mg->mg_obj : &PL_sv_undef); + EXTEND(SP, 3); + PUSHs(sv_2mortal(newRV_inc(sv))); + PUSHs(mg->mg_obj ? mg->mg_obj : &PL_sv_undef); if (SvTYPE(sv) == SVt_PVAV) { - XPUSHs(sv_2mortal(newSViv(av_len((AV *) sv) + 1))); + len = av_len((AV *) sv) + 1; + mPUSHi(len); + } else { + len = 1; + PUSHs(&PL_sv_undef); } PUTBACK; @@ -452,7 +510,8 @@ STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) { SPAGAIN; if (count != 1) { croak("Callback needs to return 1 scalar\n"); } - ret = POPi; + svr = POPs; + ret = SvOK(svr) ? SvUV(svr) : len; PUTBACK; @@ -463,7 +522,7 @@ STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) { } STATIC int vmg_svt_clear(pTHX_ SV *sv, MAGIC *mg) { - return vmg_cb_call(SV2MGWIZ(mg->mg_ptr)->cb_clear, sv, mg->mg_obj); + return vmg_cb_call1(SV2MGWIZ(mg->mg_ptr)->cb_clear, sv, mg->mg_obj); } STATIC int vmg_svt_free(pTHX_ SV *sv, MAGIC *mg) { @@ -471,16 +530,37 @@ STATIC int vmg_svt_free(pTHX_ SV *sv, MAGIC *mg) { SvREFCNT_inc(sv); /* Perl_mg_free will get rid of the magic and decrement mg->mg_obj and * mg->mg_ptr reference count */ - return vmg_cb_call(SV2MGWIZ(mg->mg_ptr)->cb_free, sv, mg->mg_obj); + return vmg_cb_call1(SV2MGWIZ(mg->mg_ptr)->cb_free, sv, mg->mg_obj); } #if MGf_COPY -STATIC int vmg_svt_copy(pTHX_ SV *sv, MAGIC *mg, SV *nsv, const char *name, int namelen) { - return vmg_cb_call2(SV2MGWIZ(mg->mg_ptr)->cb_copy, sv, mg->mg_obj, nsv); +STATIC int vmg_svt_copy(pTHX_ SV *sv, MAGIC *mg, SV *nsv, const char *key, +# if VMG_HAS_PERL_AND(33256, 5, 11, 0) + I32 keylen +# else + int keylen +# endif + ) { + SV *keysv; + int ret; + + if (keylen == HEf_SVKEY) { + keysv = (SV *) key; + } else { + keysv = newSVpvn(key, keylen); + } + + ret = vmg_cb_call3(SV2MGWIZ(mg->mg_ptr)->cb_copy, sv, mg->mg_obj, keysv, nsv); + + if (keylen != HEf_SVKEY) { + SvREFCNT_dec(keysv); + } + + return ret; } #endif /* MGf_COPY */ -#if MGf_DUP +#if 0 /* MGf_DUP */ STATIC int vmg_svt_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param) { return 0; } @@ -488,7 +568,7 @@ STATIC int vmg_svt_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param) { #if MGf_LOCAL STATIC int vmg_svt_local(pTHX_ SV *nsv, MAGIC *mg) { - return vmg_cb_call(SV2MGWIZ(mg->mg_ptr)->cb_local, nsv, mg->mg_obj); + return vmg_cb_call1(SV2MGWIZ(mg->mg_ptr)->cb_local, nsv, mg->mg_obj); } #endif /* MGf_LOCAL */ @@ -513,20 +593,21 @@ STATIC I32 vmg_svt_val(pTHX_ IV action, SV *sv) { || (mg->mg_private < SIG_MIN) || (mg->mg_private > SIG_MAX)) { continue; } w = SV2MGWIZ(mg->mg_ptr); + if (!w->uvar) { continue; } switch (action) { case 0: - vmg_cb_call2(w->cb_fetch, sv, mg->mg_obj, key); + if (w->cb_fetch) { vmg_cb_call2(w->cb_fetch, sv, mg->mg_obj, key); } break; case HV_FETCH_ISSTORE: case HV_FETCH_LVALUE: case (HV_FETCH_ISSTORE|HV_FETCH_LVALUE): - vmg_cb_call2(w->cb_store, sv, mg->mg_obj, key); + if (w->cb_store) { vmg_cb_call2(w->cb_store, sv, mg->mg_obj, key); } break; case HV_FETCH_ISEXISTS: - vmg_cb_call2(w->cb_exists, sv, mg->mg_obj, key); + if (w->cb_exists) { vmg_cb_call2(w->cb_exists, sv, mg->mg_obj, key); } break; case HV_DELETE: - vmg_cb_call2(w->cb_delete, sv, mg->mg_obj, key); + if (w->cb_delete) { vmg_cb_call2(w->cb_delete, sv, mg->mg_obj, key); } break; } } @@ -544,13 +625,11 @@ STATIC int vmg_wizard_free(pTHX_ SV *wiz, MAGIC *mg) { w = SV2MGWIZ(wiz); - SvREFCNT_inc(wiz); /* Fake survival - it's gonna be deleted anyway */ -#if PERL_API_VERSION_GE(5, 9, 5) - SvREFCNT_inc(wiz); /* One more push */ -#endif if (hv_delete(MY_CXT.wizz, buf, sprintf(buf, "%u", w->sig), 0)) { --MY_CXT.count; } + SvFLAGS(wiz) |= SVf_BREAK; + FREETMPS; if (w->cb_data != NULL) { SvREFCNT_dec(SvRV(w->cb_data)); } if (w->cb_get != NULL) { SvREFCNT_dec(SvRV(w->cb_get)); } @@ -563,10 +642,10 @@ STATIC int vmg_wizard_free(pTHX_ SV *wiz, MAGIC *mg) { #endif /* MGf_COPY */ #if MGf_DUP if (w->cb_dup != NULL) { SvREFCNT_dec(SvRV(w->cb_dup)); } -#endif /* MGf_COPY */ +#endif /* MGf_DUP */ #if MGf_LOCAL if (w->cb_local != NULL) { SvREFCNT_dec(SvRV(w->cb_local)); } -#endif /* MGf_COPY */ +#endif /* MGf_LOCAL */ #if VMG_UVAR if (w->cb_fetch != NULL) { SvREFCNT_dec(SvRV(w->cb_fetch)); } if (w->cb_store != NULL) { SvREFCNT_dec(SvRV(w->cb_store)); } @@ -593,7 +672,7 @@ STATIC MGVTBL vmg_wizard_vtbl = { #endif /* MGf_DUP */ #if MGf_LOCAL NULL, /* local */ -#endif /* MGf_DUP */ +#endif /* MGf_LOCAL */ }; STATIC const char vmg_invalid_wiz[] = "Invalid wizard object"; @@ -647,8 +726,7 @@ BOOT: { HV *stash; MY_CXT_INIT; - MY_CXT.wizz = newHV(); - MY_CXT.count = 0; + vmg_cxt_init(); stash = gv_stashpv(__PACKAGE__, 1); newCONSTSUB(stash, "SIG_MIN", newSVuv(SIG_MIN)); newCONSTSUB(stash, "SIG_MAX", newSVuv(SIG_MAX)); @@ -657,8 +735,25 @@ BOOT: newCONSTSUB(stash, "MGf_DUP", newSVuv(MGf_DUP)); newCONSTSUB(stash, "MGf_LOCAL", newSVuv(MGf_LOCAL)); newCONSTSUB(stash, "VMG_UVAR", newSVuv(VMG_UVAR)); + newCONSTSUB(stash, "VMG_COMPAT_ARRAY_PUSH_NOLEN", + newSVuv(VMG_COMPAT_ARRAY_PUSH_NOLEN)); + newCONSTSUB(stash, "VMG_COMPAT_ARRAY_UNDEF_CLEAR", + newSVuv(VMG_COMPAT_ARRAY_UNDEF_CLEAR)); + newCONSTSUB(stash, "VMG_COMPAT_SCALAR_LENGTH_NOLEN", + newSVuv(VMG_COMPAT_SCALAR_LENGTH_NOLEN)); + newCONSTSUB(stash, "VMG_PERL_PATCHLEVEL", newSVuv(VMG_PERL_PATCHLEVEL)); + newCONSTSUB(stash, "VMG_THREADSAFE", newSVuv(VMG_THREADSAFE)); } +void +CLONE(...) +PROTOTYPE: DISABLE +CODE: +#ifdef MY_CXT_CLONE + MY_CXT_CLONE; + vmg_cxt_init(); +#endif + SV *_wizard(...) PROTOTYPE: DISABLE PREINIT: @@ -693,7 +788,7 @@ CODE: if (SvOK(svsig)) { SV **old; sig = vmg_sv2sig(svsig); - if (old = hv_fetch(MY_CXT.wizz, buf, sprintf(buf, "%u", sig), 0)) { + if ((old = hv_fetch(MY_CXT.wizz, buf, sprintf(buf, "%u", sig), 0))) { ST(0) = sv_2mortal(newRV_inc(*old)); XSRETURN(1); } @@ -715,7 +810,10 @@ CODE: VMG_SET_SVT_CB(ST(i++), copy); #endif /* MGf_COPY */ #if MGf_DUP - VMG_SET_SVT_CB(ST(i++), dup); + /* VMG_SET_SVT_CB(ST(i++), dup); */ + i++; + t->svt_dup = NULL; + w->cb_dup = NULL; #endif /* MGf_DUP */ #if MGf_LOCAL VMG_SET_SVT_CB(ST(i++), local); @@ -739,7 +837,7 @@ CODE: hv_store(MY_CXT.wizz, buf, sprintf(buf, "%u", sig), sv, 0); ++MY_CXT.count; - + RETVAL = newRV_noinc(sv); OUTPUT: RETVAL @@ -774,7 +872,7 @@ CODE: char buf[8]; SV **old; U16 sig = vmg_sv2sig(wiz); - if (old = hv_fetch(MY_CXT.wizz, buf, sprintf(buf, "%u", sig), 0)) { + if ((old = hv_fetch(MY_CXT.wizz, buf, sprintf(buf, "%u", sig), 0))) { wiz = *old; } else { XSRETURN_UNDEF; @@ -818,7 +916,7 @@ CODE: } data = vmg_data_get(SvRV(sv), sig); if (!data) { XSRETURN_UNDEF; } - ST(0) = newSVsv(data); + ST(0) = data; XSRETURN(1); SV *dispell(SV *sv, SV *wiz)