#define MY_CXT_KEY __PACKAGE__ "::_guts" XS_VERSION
-typedef HV * my_cxt_t;
+typedef struct {
+ HV *wizards;
+ HV *b__op_stash;
+} my_cxt_t;
START_MY_CXT
do {
sig = SIG_NBR * Drand01() + SIG_MIN;
- } while (hv_exists(MY_CXT, buf, sprintf(buf, "%u", sig)));
+ } while (hv_exists(MY_CXT.wizards, buf, sprintf(buf, "%u", sig)));
return sig;
}
#define VMG_OP_INFO_NAME 1
#define VMG_OP_INFO_OBJECT 2
-STATIC U32 vmg_op_name_refcnt = 0;
-STATIC STRLEN *vmg_op_name_len = NULL;
-
-STATIC HV *vmg_b__op_stash = NULL;
+STATIC U32 vmg_op_name_init = 0;
+STATIC unsigned char vmg_op_name_len[MAXO] = { 0 };
STATIC void vmg_op_info_init(pTHX_ unsigned int opinfo) {
#define vmg_op_info_init(W) vmg_op_info_init(aTHX_ (W))
switch (opinfo) {
case VMG_OP_INFO_NAME:
- if (!vmg_op_name_len) {
+ if (!vmg_op_name_init) {
OPCODE t;
- Newx(vmg_op_name_len, MAXO, STRLEN);
for (t = 0; t < OP_max; ++t)
vmg_op_name_len[t] = strlen(PL_op_name[t]);
+ vmg_op_name_init = 1;
}
- ++vmg_op_name_refcnt;
break;
- case VMG_OP_INFO_OBJECT:
- if (!vmg_b__op_stash) {
+ case VMG_OP_INFO_OBJECT: {
+ dMY_CXT;
+ if (!MY_CXT.b__op_stash) {
require_pv("B.pm");
- vmg_b__op_stash = gv_stashpv("B::OP", 1);
+ MY_CXT.b__op_stash = gv_stashpv("B::OP", 1);
}
break;
- default:
- break;
- }
-}
-
-STATIC void vmg_op_info_deinit(unsigned int opinfo) {
- switch (opinfo) {
- case VMG_OP_INFO_NAME:
- if (vmg_op_name_refcnt > 0)
- --vmg_op_name_refcnt;
- if (!vmg_op_name_refcnt && vmg_op_name_len) {
- Safefree(vmg_op_name_len);
- vmg_op_name_len = NULL;
- }
- break;
- case VMG_OP_INFO_OBJECT:
+ }
default:
break;
}
OPCODE t = PL_op->op_type;
return sv_2mortal(newSVpvn(PL_op_name[t], vmg_op_name_len[t]));
}
- case VMG_OP_INFO_OBJECT:
+ case VMG_OP_INFO_OBJECT: {
+ dMY_CXT;
return sv_bless(sv_2mortal(newRV_noinc(newSViv(PTR2IV(PL_op)))),
- vmg_b__op_stash);
+ MY_CXT.b__op_stash);
+ }
default:
break;
}
{
dMY_CXT;
- if (hv_delete(MY_CXT, buf, sprintf(buf, "%u", w->sig), 0) != wiz)
+ if (hv_delete(MY_CXT.wizards, buf, sprintf(buf, "%u", w->sig), 0) != wiz)
return 0;
}
SvFLAGS(wiz) |= SVf_BREAK;
if (w->cb_delete != NULL) { SvREFCNT_dec(SvRV(w->cb_delete)); }
#endif /* VMG_UVAR */
- if (w->opinfo)
- vmg_op_info_deinit(w->opinfo);
-
Safefree(w->vtbl);
Safefree(w);
{
dMY_CXT;
- if (!hv_fetch(MY_CXT, buf, sprintf(buf, "%u", sig), 0))
+ if (!hv_fetch(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), 0))
sig = 0;
}
return sig;
{
dMY_CXT;
- return (old = hv_fetch(MY_CXT, buf, sprintf(buf, "%u", sig), 0))
+ return (old = hv_fetch(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), 0))
? *old : NULL;
}
}
{
HV *stash;
MY_CXT_INIT;
- MY_CXT = newHV();
- hv_iterinit(MY_CXT); /* Allocate iterator */
+ MY_CXT.wizards = newHV();
+ hv_iterinit(MY_CXT.wizards); /* Allocate iterator */
+ MY_CXT.b__op_stash = NULL;
stash = gv_stashpv(__PACKAGE__, 1);
newCONSTSUB(stash, "SIG_MIN", newSVuv(SIG_MIN));
newCONSTSUB(stash, "SIG_MAX", newSVuv(SIG_MAX));
PROTOTYPE: DISABLE
PREINIT:
HV *hv;
+ U32 had_b__op_stash = 0;
CODE:
{
HE *key;
dMY_CXT;
hv = newHV();
hv_iterinit(hv); /* Allocate iterator */
- hv_iterinit(MY_CXT);
- while ((key = hv_iternext(MY_CXT))) {
+ hv_iterinit(MY_CXT.wizards);
+ while ((key = hv_iternext(MY_CXT.wizards))) {
STRLEN len;
char *sig = HePV(key, len);
SV *sv;
SvREADONLY_on(sv);
if (!hv_store(hv, sig, len, sv, HeHASH(key))) croak("%s during CLONE", vmg_globstorefail);
}
+ if (MY_CXT.b__op_stash)
+ had_b__op_stash = 1;
}
{
MY_CXT_CLONE;
- MY_CXT = hv;
+ MY_CXT.wizards = hv;
+ MY_CXT.b__op_stash = had_b__op_stash ? gv_stashpv("B::OP", 1) : NULL;
}
#endif /* VMG_THREADSAFE */
if (SvOK(svsig)) {
SV **old;
sig = vmg_sv2sig(svsig);
- if ((old = hv_fetch(MY_CXT, buf, sprintf(buf, "%u", sig), 0))) {
+ if ((old = hv_fetch(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), 0))) {
ST(0) = sv_2mortal(newRV_inc(*old));
XSRETURN(1);
}
} else {
- if (HvKEYS(MY_CXT) >= SIG_NBR) { croak(vmg_toomanysigs); }
+ if (HvKEYS(MY_CXT.wizards) >= SIG_NBR) { croak(vmg_toomanysigs); }
sig = vmg_gensig();
}
mg->mg_private = SIG_WIZ;
SvREADONLY_on(sv);
- if (!hv_store(MY_CXT, buf, sprintf(buf, "%u", sig), sv, 0)) croak(vmg_globstorefail);
+ if (!hv_store(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), sv, 0)) croak(vmg_globstorefail);
RETVAL = newRV_noinc(sv);
OUTPUT:
PROTOTYPE:
CODE:
dMY_CXT;
- if (HvKEYS(MY_CXT) >= SIG_NBR) { croak(vmg_toomanysigs); }
+ if (HvKEYS(MY_CXT.wizards) >= SIG_NBR) { croak(vmg_toomanysigs); }
RETVAL = newSVuv(vmg_gensig());
OUTPUT:
RETVAL