- if (PL_dirty) /* During global destruction, the context is already freed */
- return 0;
-
- w = SV2MGWIZ(wiz);
-#if VMG_MULTIPLICITY
- if (w->owner != aTHX)
- return 0;
- w->owner = NULL;
-#endif /* VMG_MULTIPLICITY */
-
- {
- dMY_CXT;
- if (hv_delete(MY_CXT.wizards, buf, sprintf(buf, "%u", w->sig), 0) != wiz)
- return 0;
- }
-
- /* Unmortalize the wizard to avoid it being freed in weird places. */
- if (SvTEMP(wiz) && !SvREFCNT(wiz)) {
- const I32 myfloor = PL_tmps_floor;
- I32 i;
- for (i = PL_tmps_ix; i > myfloor; --i) {
- if (PL_tmps_stack[i] == wiz)
- PL_tmps_stack[i] = NULL;
- }
- }
-
- if (w->cb_data) SvREFCNT_dec(SvRV(w->cb_data));
- if (w->cb_get) SvREFCNT_dec(SvRV(w->cb_get));
- if (w->cb_set) SvREFCNT_dec(SvRV(w->cb_set));
- if (w->cb_len) SvREFCNT_dec(SvRV(w->cb_len));
- if (w->cb_clear) SvREFCNT_dec(SvRV(w->cb_clear));
- if (w->cb_free) SvREFCNT_dec(SvRV(w->cb_free));
-#if MGf_COPY
- if (w->cb_copy) SvREFCNT_dec(SvRV(w->cb_copy));
-#endif /* MGf_COPY */
-#if 0 /* MGf_DUP */
- if (w->cb_dup) SvREFCNT_dec(SvRV(w->cb_dup));
-#endif /* MGf_DUP */
-#if MGf_LOCAL
- if (w->cb_local) SvREFCNT_dec(SvRV(w->cb_local));
-#endif /* MGf_LOCAL */
-#if VMG_UVAR
- if (w->cb_fetch) SvREFCNT_dec(SvRV(w->cb_fetch));
- if (w->cb_store) SvREFCNT_dec(SvRV(w->cb_store));
- if (w->cb_exists) SvREFCNT_dec(SvRV(w->cb_exists));
- if (w->cb_delete) SvREFCNT_dec(SvRV(w->cb_delete));
-#endif /* VMG_UVAR */
-
- Safefree(w->vtbl);
- Safefree(w);
-
- return 0;
-}
-
-STATIC MGVTBL vmg_wizard_vtbl = {
- NULL, /* get */
- NULL, /* set */
- NULL, /* len */
- NULL, /* clear */
- vmg_wizard_free, /* free */
-#if MGf_COPY
- NULL, /* copy */
-#endif /* MGf_COPY */
-#if MGf_DUP
- NULL, /* dup */
-#endif /* MGf_DUP */
-#if MGf_LOCAL
- NULL, /* local */
-#endif /* MGf_LOCAL */
-};
-
-STATIC U16 vmg_sv2sig(pTHX_ SV *sv) {
-#define vmg_sv2sig(S) vmg_sv2sig(aTHX_ (S))
- IV sig;
-
- if (SvIOK(sv)) {
- sig = SvIVX(sv);
- } else if (SvNOK(sv)) {
- sig = SvNVX(sv);
- } else if ((SvPOK(sv) && grok_number(SvPVX(sv), SvCUR(sv), NULL))) {
- sig = SvIV(sv);
- } else {
- croak(vmg_invalid_sig);
- }
-
- if (sig < SIG_MIN || sig > SIG_MAX)
- croak(vmg_invalid_sig);
-
- return sig;
-}
-
-STATIC U16 vmg_wizard_sig(pTHX_ SV *wiz) {
-#define vmg_wizard_sig(W) vmg_wizard_sig(aTHX_ (W))
- U16 sig;
-
- if (SvROK(wiz)) {
- sig = SV2MGWIZ(SvRV(wiz))->sig;
- } else if (SvOK(wiz)) {
- sig = vmg_sv2sig(wiz);
- } else {
- croak(vmg_invalid_wiz);
- }
-
- {
- dMY_CXT;
- char buf[8];
- SV **old = hv_fetch(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), 0);
- if (!(old && SV2MGWIZ(*old)))
- croak(vmg_invalid_wiz);
- }