# define Newx(v, n, c) New(0, v, n, c)
#endif
-#ifndef NewOp
-# define NewOp(m, var, c, type) Newz(m, var, c, type)
-#endif
-
#ifndef SvMAGIC_set
# define SvMAGIC_set(sv, val) (SvMAGIC(sv) = (val))
#endif
};
STATIC opclass vmg_opclass(const OP *o) {
+#if 0
if (!o)
return OPc_NULL;
+#endif
if (o->op_type == 0)
return (o->op_flags & OPf_KIDS) ? OPc_UNOP : OPc_BASEOP;
START_MY_CXT
+/* --- Error messages ------------------------------------------------------ */
+
+STATIC const char vmg_invalid_wiz[] = "Invalid wizard object";
+STATIC const char vmg_invalid_sig[] = "Invalid numeric signature";
+STATIC const char vmg_wrongargnum[] = "Wrong number of arguments";
+STATIC const char vmg_toomanysigs[] = "Too many magic signatures used";
+STATIC const char vmg_argstorefailed[] = "Error while storing arguments";
+STATIC const char vmg_globstorefail[] = "Couldn't store global wizard information";
+
/* --- Signatures ---------------------------------------------------------- */
#define SIG_MIN ((U16) 0u)
char buf[8];
dMY_CXT;
+ if (HvKEYS(MY_CXT.wizards) >= SIG_NBR)
+ croak(vmg_toomanysigs);
+
do {
sig = SIG_NBR * Drand01() + SIG_MIN;
} while (hv_exists(MY_CXT.wizards, buf, sprintf(buf, "%u", sig)));
#define VMG_OP_INFO_NAME 1
#define VMG_OP_INFO_OBJECT 2
+#if VMG_THREADSAFE
+STATIC perl_mutex vmg_op_name_init_mutex;
+#endif
+
STATIC U32 vmg_op_name_init = 0;
STATIC unsigned char vmg_op_name_len[MAXO] = { 0 };
#define vmg_op_info_init(W) vmg_op_info_init(aTHX_ (W))
switch (opinfo) {
case VMG_OP_INFO_NAME:
+#if VMG_THREADSAFE
+ MUTEX_LOCK(&vmg_op_name_init_mutex);
+#endif
if (!vmg_op_name_init) {
OPCODE t;
for (t = 0; t < OP_max; ++t)
vmg_op_name_len[t] = strlen(PL_op_name[t]);
vmg_op_name_init = 1;
}
+#if VMG_THREADSAFE
+ MUTEX_UNLOCK(&vmg_op_name_init_mutex);
+#endif
break;
case VMG_OP_INFO_OBJECT: {
dMY_CXT;
#endif /* MGf_LOCAL */
};
-STATIC const char vmg_invalid_wiz[] = "Invalid wizard object";
-STATIC const char vmg_invalid_sig[] = "Invalid numeric signature";
-STATIC const char vmg_wrongargnum[] = "Wrong number of arguments";
-STATIC const char vmg_toomanysigs[] = "Too many magic signatures used";
-STATIC const char vmg_argstorefailed[] = "Error while storing arguments";
-STATIC const char vmg_globstorefail[] = "Couldn't store global wizard information";
-
STATIC U16 vmg_sv2sig(pTHX_ SV *sv) {
#define vmg_sv2sig(S) vmg_sv2sig(aTHX_ (S))
IV sig;
STATIC U16 vmg_wizard_sig(pTHX_ SV *wiz) {
#define vmg_wizard_sig(W) vmg_wizard_sig(aTHX_ (W))
- char buf[8];
U16 sig;
if (SvROK(wiz)) {
{
dMY_CXT;
- if (!hv_fetch(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), 0))
+ char buf[8];
+ SV **old = hv_fetch(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), 0);
+ if (!(old && SV2MGWIZ(*old)))
croak(vmg_invalid_wiz);
}
STATIC SV *vmg_wizard_wiz(pTHX_ SV *wiz) {
#define vmg_wizard_wiz(W) vmg_wizard_wiz(aTHX_ (W))
- char buf[8];
- SV **old;
U16 sig;
if (SvROK(wiz)) {
{
dMY_CXT;
- return (old = hv_fetch(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), 0))
- ? *old : NULL;
+ char buf[8];
+ SV **old = hv_fetch(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), 0);
+ if (!(old && SV2MGWIZ(*old)))
+ croak(vmg_invalid_wiz);
+
+ return *old;
}
}
MY_CXT.wizards = newHV();
hv_iterinit(MY_CXT.wizards); /* Allocate iterator */
MY_CXT.b__op_stashes[0] = NULL;
+#if VMG_THREADSAFE
+ MUTEX_INIT(&vmg_op_name_init_mutex);
+#endif
+
stash = gv_stashpv(__PACKAGE__, 1);
newCONSTSUB(stash, "SIG_MIN", newSVuv(SIG_MIN));
newCONSTSUB(stash, "SIG_MAX", newSVuv(SIG_MAX));
STRLEN len;
char *sig = HePV(key, len);
SV *sv;
- const MGWIZ *w;
- MAGIC *mg;
- w = SV2MGWIZ(HeVAL(key));
- w = vmg_wizard_clone(w);
- sv = MGWIZ2SV(w);
- mg = sv_magicext(sv, NULL, PERL_MAGIC_ext, &vmg_wizard_vtbl, NULL, 0);
- mg->mg_private = SIG_WZO;
+ const MGWIZ *w = SV2MGWIZ(HeVAL(key));
+ if (w) {
+ MAGIC *mg;
+ w = vmg_wizard_clone(w);
+ sv = MGWIZ2SV(w);
+ mg = sv_magicext(sv, NULL, PERL_MAGIC_ext, &vmg_wizard_vtbl, NULL, 0);
+ mg->mg_private = SIG_WZO;
+ } else {
+ sv = MGWIZ2SV(NULL);
+ }
SvREADONLY_on(sv);
if (!hv_store(hv, sig, len, sv, HeHASH(key))) croak("%s during CLONE", vmg_globstorefail);
}
if (SvOK(svsig)) {
SV **old;
sig = vmg_sv2sig(svsig);
- if ((old = hv_fetch(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), 0))) {
+ old = hv_fetch(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), 0);
+ if (old && SV2MGWIZ(*old)) {
ST(0) = sv_2mortal(newRV_inc(*old));
XSRETURN(1);
}
} else {
- if (HvKEYS(MY_CXT.wizards) >= SIG_NBR) { croak(vmg_toomanysigs); }
sig = vmg_gensig();
}
SV *gensig()
PROTOTYPE:
+PREINIT:
+ U16 sig;
+ char buf[8];
CODE:
dMY_CXT;
- if (HvKEYS(MY_CXT.wizards) >= SIG_NBR) { croak(vmg_toomanysigs); }
- RETVAL = newSVuv(vmg_gensig());
+ sig = vmg_gensig();
+ if (!hv_store(MY_CXT.wizards, buf, sprintf(buf, "%u", sig), MGWIZ2SV(NULL), 0)) croak(vmg_globstorefail);
+ RETVAL = newSVuv(sig);
OUTPUT:
RETVAL
SV *ret;
CODE:
wiz = vmg_wizard_wiz(wiz);
- if (!wiz)
- XSRETURN_UNDEF;
if (items > 2) {
I32 i;
args = newAV();