#if VMG_UVAR
STATIC I32 vmg_svt_val(pTHX_ IV action, SV *sv) {
struct ufuncs *uf;
- MAGIC *mg;
- SV *key = NULL;
+ MAGIC *mg, *umg;
+ SV *key = NULL, *newkey = NULL;
- mg = mg_find(sv, PERL_MAGIC_uvar);
- /* mg can't be NULL or we wouldn't be there. */
- key = mg->mg_obj;
- uf = (struct ufuncs *) mg->mg_ptr;
+ umg = mg_find(sv, PERL_MAGIC_uvar);
+ /* umg can't be NULL or we wouldn't be there. */
+ key = umg->mg_obj;
+ uf = (struct ufuncs *) umg->mg_ptr;
if (uf[1].uf_val != NULL) { uf[1].uf_val(aTHX_ action, sv); }
if (uf[1].uf_set != NULL) { uf[1].uf_set(aTHX_ action, sv); }
|| (mg->mg_private < SIG_MIN)
|| (mg->mg_private > SIG_MAX)) { continue; }
w = SV2MGWIZ(mg->mg_ptr);
- if (!w->uvar) { continue; }
+ switch (w->uvar) {
+ case 0:
+ continue;
+ case 2:
+ if (!newkey)
+ newkey = key = umg->mg_obj = sv_2mortal(newSVsv(umg->mg_obj));
+ }
switch (action) {
case 0:
if (w->cb_fetch) { vmg_cb_call2(w->cb_fetch, sv, mg->mg_obj, key); }
+ 1
#endif /* MGf_LOCAL */
#if VMG_UVAR
- + 4
+ + 5
#endif /* VMG_UVAR */
) { croak(vmg_wrongargnum); }
VMG_SET_CB(ST(i++), store);
VMG_SET_CB(ST(i++), exists);
VMG_SET_CB(ST(i++), delete);
+ cb = ST(i++);
+ if (w->cb_fetch || w->cb_store || w->cb_exists || w->cb_delete)
+ w->uvar = SvTRUE(cb) ? 2 : 1;
+ else
+ w->uvar = 0;
#endif /* VMG_UVAR */
#if VMG_MULTIPLICITY
w->owner = aTHX;
#endif /* VMG_MULTIPLICITY */
-
- w->vtbl = t;
- w->sig = sig;
-#if VMG_UVAR
- w->uvar = (w->cb_fetch || w->cb_store || w->cb_exists || w->cb_delete);
-#endif /* VMG_UVAR */
+ w->vtbl = t;
+ w->sig = sig;
sv = MGWIZ2SV(w);
mg = sv_magicext(sv, NULL, PERL_MAGIC_ext, &vmg_wizard_vtbl, NULL, 0);