X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=Magic.xs;h=76e88216920933deb17c06986a20112e7060d73f;hb=ed1f29a02e9894bb90bb4f3f3d42d7fe0fd3e545;hp=73536b861649b32eb497cc082f611ba15e567fdc;hpb=03eb870636b3e9f56a04a7a5291752e26f36829e;p=perl%2Fmodules%2FVariable-Magic.git diff --git a/Magic.xs b/Magic.xs index 73536b8..76e8821 100644 --- a/Magic.xs +++ b/Magic.xs @@ -325,6 +325,7 @@ STATIC UV vmg_cast(pTHX_ SV *sv, SV *wiz, AV *args) { MAGIC *mg = NULL, *moremagic = NULL; MGWIZ *w; SV *data; + U32 oldgmg = SvGMAGICAL(sv); w = SV2MGWIZ(wiz); @@ -355,10 +356,18 @@ STATIC UV vmg_cast(pTHX_ SV *sv, SV *wiz, AV *args) { if (SvTYPE(sv) < SVt_PVHV) goto done; + /* The GMAGICAL flag only says that a hash is tied or has uvar magic - get + * magic is actually never called for them. If the GMAGICAL flag was off before + * calling sv_magicext(), the hash isn't tied and has no uvar magic. If it's + * now on, then this wizard has get magic. Hence we can work around the + * get/clear shortcoming by turning the GMAGICAL flag off. If the current magic + * has uvar callbacks, it will be turned back on later. */ + if (!oldgmg && SvGMAGICAL(sv)) + SvGMAGICAL_off(sv); + #if VMG_UVAR if (w->uvar) { MAGIC *prevmagic; - int add_uvar = 1; struct ufuncs uf[2]; uf[0].uf_val = vmg_svt_val; @@ -377,24 +386,19 @@ STATIC UV vmg_cast(pTHX_ SV *sv, SV *wiz, AV *args) { if (mg) { /* Found another uvar magic. */ struct ufuncs *olduf = (struct ufuncs *) mg->mg_ptr; if (olduf->uf_val == vmg_svt_val) { - /* It's our uvar magic, nothing to do. */ - add_uvar = 0; + /* It's our uvar magic, nothing to do. oldgmg was true. */ + goto done; } else { /* It's another uvar magic, backup it and replace it by ours. */ uf[1] = *olduf; vmg_uvar_del(sv, prevmagic, mg, moremagic); } - } else if (w->cb_get) - SvGMAGICAL_off(sv); - - if (add_uvar) { - vmg_sv_magicuvar(sv, (const char *) &uf, sizeof(uf)); } + vmg_sv_magicuvar(sv, (const char *) &uf, sizeof(uf)); + /* Our hash now carries uvar magic. The uvar/clear shortcoming has to be + * handled by our uvar callback. */ } -#else - if (w->cb_get) - SvGMAGICAL_off(sv); #endif /* VMG_UVAR */ done: @@ -546,7 +550,6 @@ STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) { U32 ret; dSP; - int count; has_array = SvTYPE(sv) == SVt_PVAV; @@ -566,7 +569,7 @@ STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) { } PUTBACK; - count = call_sv(SV2MGWIZ(mg->mg_ptr)->cb_len, G_SCALAR); + call_sv(SV2MGWIZ(mg->mg_ptr)->cb_len, G_SCALAR); SPAGAIN; svr = POPs;