/* ... Safe version of call_sv() ........................................... */
-#define VMG_SAVE_LAST_CX (!VMG_HAS_PERL(5, 8, 4) || VMG_HAS_PERL(5, 9, 5))
-
STATIC I32 vmg_call_sv(pTHX_ SV *sv, I32 flags, SV *dsv) {
#define vmg_call_sv(S, F, D) vmg_call_sv(aTHX_ (S), (F), (D))
- I32 ret, cxix = 0, in_eval = 0;
-#if VMG_SAVE_LAST_CX
+ I32 ret, cxix, in_eval = 0;
PERL_CONTEXT saved_cx;
-#endif
SV *old_err = NULL;
if (SvTRUE(ERRSV)) {
}
if (cxstack_ix < cxstack_max) {
- cxix = cxstack_ix + 1;
- if (dsv && CxTYPE(cxstack + cxix) == CXt_EVAL)
- in_eval = 1;
+ cxix = cxstack_ix + 1;
+ in_eval = CxTYPE(cxstack + cxix) == CXt_EVAL;
+ } else {
+ cxix = Perl_cxinc(aTHX);
}
-
-#if VMG_SAVE_LAST_CX
/* The last popped context will be reused by call_sv(), but our callers may
* still need its previous value. Back it up so that it isn't clobbered. */
saved_cx = cxstack[cxix];
-#endif
ret = call_sv(sv, flags | G_EVAL);
-#if VMG_SAVE_LAST_CX
cxstack[cxix] = saved_cx;
-#endif
if (SvTRUE(ERRSV)) {
if (old_err) {
#if VMG_UVAR
STATIC I32 vmg_svt_val(pTHX_ IV, SV *);
+typedef struct {
+ struct ufuncs new_uf;
+ struct ufuncs old_uf;
+} vmg_uvar_ud;
+
STATIC void vmg_uvar_del(SV *sv, MAGIC *prevmagic, MAGIC *mg, MAGIC *moremagic) {
if (prevmagic) {
prevmagic->mg_moremagic = moremagic;
#if VMG_UVAR
if (w->uvar) {
MAGIC *prevmagic, *moremagic = NULL;
- struct ufuncs uf[2];
+ vmg_uvar_ud ud;
- uf[0].uf_val = vmg_svt_val;
- uf[0].uf_set = NULL;
- uf[0].uf_index = 0;
- uf[1].uf_val = NULL;
- uf[1].uf_set = NULL;
- uf[1].uf_index = 0;
+ ud.new_uf.uf_val = vmg_svt_val;
+ ud.new_uf.uf_set = NULL;
+ ud.new_uf.uf_index = 0;
+ ud.old_uf.uf_val = NULL;
+ ud.old_uf.uf_set = NULL;
+ ud.old_uf.uf_index = 0;
/* One uvar magic in the chain is enough. */
for (prevmagic = NULL, mg = SvMAGIC(sv); mg; prevmagic = mg, mg = moremagic) {
}
if (mg) { /* Found another uvar magic. */
- struct ufuncs *olduf = (struct ufuncs *) mg->mg_ptr;
- if (olduf->uf_val == vmg_svt_val) {
+ struct ufuncs *uf = (struct ufuncs *) mg->mg_ptr;
+ if (uf->uf_val == vmg_svt_val) {
/* 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;
+ ud.old_uf = *uf;
vmg_uvar_del(sv, prevmagic, mg, moremagic);
}
}
- sv_magic(sv, NULL, PERL_MAGIC_uvar, (const char *) &uf, sizeof(uf));
+ sv_magic(sv, NULL, PERL_MAGIC_uvar, (const char *) &ud, sizeof(ud));
vmg_mg_magical(sv);
/* Our hash now carries uvar magic. The uvar/clear shortcoming has to be
* handled by our uvar callback. */
}
if (uvars == 1) {
- struct ufuncs *uf;
+ vmg_uvar_ud *ud;
+
for (prevmagic = NULL, mg = SvMAGIC(sv); mg; prevmagic = mg, mg = moremagic){
moremagic = mg->mg_moremagic;
if (mg->mg_type == PERL_MAGIC_uvar)
break;
}
- uf = (struct ufuncs *) mg->mg_ptr;
- if (uf[1].uf_val || uf[1].uf_set) {
+
+ ud = (vmg_uvar_ud *) mg->mg_ptr;
+ if (ud->old_uf.uf_val || ud->old_uf.uf_set) {
/* Revert the original uvar magic. */
- uf[0] = uf[1];
- Renew(uf, 1, struct ufuncs);
+ struct ufuncs *uf;
+ Newx(uf, 1, struct ufuncs);
+ *uf = ud->old_uf;
+ Safefree(ud);
mg->mg_ptr = (char *) uf;
- mg->mg_len = sizeof(struct ufuncs);
+ mg->mg_len = sizeof(*uf);
} else {
/* Remove the uvar magic. */
vmg_uvar_del(sv, prevmagic, mg, moremagic);
}
STATIC I32 vmg_svt_val(pTHX_ IV action, SV *sv) {
- struct ufuncs *uf;
+ vmg_uvar_ud *ud;
MAGIC *mg, *umg;
SV *key = NULL, *newkey = NULL;
int tied = 0;
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;
+ ud = (vmg_uvar_ud *) umg->mg_ptr;
- if (uf[1].uf_val)
- uf[1].uf_val(aTHX_ action, sv);
- if (uf[1].uf_set)
- uf[1].uf_set(aTHX_ action, sv);
+ if (ud->old_uf.uf_val)
+ ud->old_uf.uf_val(aTHX_ action, sv);
+ if (ud->old_uf.uf_set)
+ ud->old_uf.uf_set(aTHX_ action, sv);
for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
const vmg_wizard *w;