X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=Magic.xs;h=85d7c85133e4df513efd0fddb77fee7e22758594;hb=d8122850f4c201c5b849cebb1f9b7f2630ae4c15;hp=2cd4e7cdd34a48c41b08491d8e7ed36e8a255002;hpb=91aec4cfae75e61ff8eeb79448501a8739b0d240;p=perl%2Fmodules%2FVariable-Magic.git diff --git a/Magic.xs b/Magic.xs index 2cd4e7c..85d7c85 100644 --- a/Magic.xs +++ b/Magic.xs @@ -40,6 +40,10 @@ # 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 @@ -63,7 +67,8 @@ # 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_PERL_PATCHLEVEL >= 28419) || (!VMG_PERL_PATCHLEVEL && PERL_VERSION_GE(5, 9, 4)) # define VMG_UVAR 1 #else # define VMG_UVAR 0 @@ -90,26 +95,24 @@ #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); } } @@ -307,8 +310,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)); } } @@ -418,8 +420,8 @@ STATIC int vmg_cb_call(pTHX_ SV *cb, SV *sv, SV *data, unsigned int args, ...) { PUSHs(data ? data : &PL_sv_undef); va_start(ap, args); for (i = 0; i < args; ++i) { - SV *sv = va_arg(ap, SV *); - PUSHs(sv ? sv : &PL_sv_undef); + SV *sva = va_arg(ap, SV *); + PUSHs(sva ? sva : &PL_sv_undef); } va_end(ap); PUTBACK; @@ -469,8 +471,9 @@ STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) { PUSHs(mg->mg_obj ? mg->mg_obj : &PL_sv_undef); if (SvTYPE(sv) == SVt_PVAV) { len = av_len((AV *) sv) + 1; - PUSHs(sv_2mortal(newSViv(len))); + mPUSHi(len); } else { + len = 1; PUSHs(&PL_sv_undef); } PUTBACK; @@ -481,8 +484,7 @@ STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) { if (count != 1) { croak("Callback needs to return 1 scalar\n"); } svr = POPs; - ret = SvOK(svr) ? SvUV(svr) - : ((SvTYPE(sv) == SVt_PVAV) ? len : 1); + ret = SvOK(svr) ? SvUV(svr) : len; PUTBACK;