typedef struct {
su_ud_common ci;
- SV *cb;
+ SV *cb;
} su_ud_reap;
-static void su_call(pTHX_ void *ud_) {
- su_ud_reap *ud = (su_ud_reap *) ud_;
+#define SU_UD_REAP_CB(U) (((su_ud_reap *) (U))->cb)
+
+static void su_call(pTHX_ SV *cb) {
#if SU_SAVE_LAST_CX
I32 cxix;
PERL_CONTEXT saved_cx;
SU_D({
PerlIO_printf(Perl_debug_log,
- "%p: @@@ call\n%p: depth=%2d scope_ix=%2d save_ix=%2d\n",
- ud, ud, SU_UD_DEPTH(ud), PL_scopestack_ix, PL_savestack_ix);
+ "@@@ call scope_ix=%2d save_ix=%2d\n",
+ PL_scopestack_ix, PL_savestack_ix);
});
ENTER;
saved_cx = cxstack[cxix];
#endif /* SU_SAVE_LAST_CX */
- call_sv(ud->cb, G_VOID);
+ call_sv(cb, G_VOID);
#if SU_SAVE_LAST_CX
cxstack[cxix] = saved_cx;
FREETMPS;
LEAVE;
- SvREFCNT_dec(ud->cb);
- SU_UD_FREE(ud);
-}
-
-static void su_reap(pTHX_ void *ud) {
-#define su_reap(U) su_reap(aTHX_ (U))
- SU_D({
- PerlIO_printf(Perl_debug_log,
- "%p: === reap\n%p: depth=%2d scope_ix=%2d save_ix=%2d\n",
- ud, ud, SU_UD_DEPTH(ud), PL_scopestack_ix, PL_savestack_ix);
- });
+ SvREFCNT_dec(cb);
- SAVEDESTRUCTOR_X(su_call, ud);
+ return;
}
/* ... Localize & localize array/hash element .............................. */
typedef struct {
su_ud_common ci;
- SV *sv;
- SV *val;
- SV *elem;
+ SV *sv;
+ SV *val;
+ SV *elem;
} su_ud_localize;
+#define SU_UD_LOCALIZE_SV(U) (((su_ud_localize *) (U))->sv)
+#define SU_UD_LOCALIZE_VAL(U) (((su_ud_localize *) (U))->val)
+#define SU_UD_LOCALIZE_ELEM(U) (((su_ud_localize *) (U))->elem)
+
#define SU_UD_LOCALIZE_FREE(U) STMT_START { \
- SvREFCNT_dec((U)->elem); \
- SvREFCNT_dec((U)->val); \
- SvREFCNT_dec((U)->sv); \
- SU_UD_FREE(U); \
+ SvREFCNT_dec(SU_UD_LOCALIZE_ELEM(U)); \
+ SvREFCNT_dec(SU_UD_LOCALIZE_VAL(U)); \
+ SvREFCNT_dec(SU_UD_LOCALIZE_SV(U)); \
+ SU_UD_FREE(U); \
} STMT_END
static I32 su_ud_localize_init(pTHX_ su_ud_localize *ud, SV *sv, SV *val, SV *elem) {
case SVt_PVAV:
if (elem) {
su_save_aelem(GvAV(gv), elem, val);
- goto done;
+ return;
} else
save_ary(gv);
break;
case SVt_PVHV:
if (elem) {
su_save_helem(GvHV(gv), elem, val);
- goto done;
+ return;
} else
save_hash(gv);
break;
if (val)
SvSetMagicSV((SV *) gv, val);
-done:
- SU_UD_LOCALIZE_FREE(ud);
+ return;
+}
+
+/* ... Unique context ID ................................................... */
+
+typedef struct {
+ su_ud_common ci;
+ su_uid *uid;
+} su_ud_uid;
+
+#define SU_UD_UID_UID(U) (((su_ud_uid *) (U))->uid)
+
+static void su_uid_drop(pTHX_ void *ud_) {
+ su_uid *uid = ud_;
+
+ uid->flags &= ~SU_UID_ACTIVE;
+
+ return;
}
/* --- Pop a context back -------------------------------------------------- */
# define SU_CXNAME(C) su_block_type[CxTYPE(C)]
#endif
-static void su_uid_bump(pTHX_ void *);
-
-static void (*su_handler[])(pTHX_ void *) = {
- su_reap,
- su_localize,
- su_uid_bump
-};
-
static void su_pop(pTHX_ void *ud) {
#define su_pop(U) su_pop(aTHX_ (U))
I32 depth, base, mark, *origin;
ud, depth, PL_scopestack_ix, PL_savestack_ix));
SAVEDESTRUCTOR_X(su_pop, ud);
} else {
- su_handler[SU_UD_TYPE(ud)](aTHX_ ud);
+ switch (SU_UD_TYPE(ud)) {
+ case SU_UD_TYPE_REAP: {
+ SU_D({
+ PerlIO_printf(Perl_debug_log,
+ "%p: === reap\n%p: depth=%2d scope_ix=%2d save_ix=%2d\n",
+ ud, ud, SU_UD_DEPTH(ud), PL_scopestack_ix, PL_savestack_ix);
+ });
+ SAVEDESTRUCTOR_X(su_call, SU_UD_REAP_CB(ud));
+ SU_UD_FREE(ud);
+ break;
+ }
+ case SU_UD_TYPE_LOCALIZE:
+ su_localize(ud);
+ SU_UD_LOCALIZE_FREE(ud);
+ break;
+ case SU_UD_TYPE_UID:
+ SAVEDESTRUCTOR_X(su_uid_drop, SU_UD_UID_UID(ud));
+ SU_UD_FREE(ud);
+ break;
+ }
}
SU_D(PerlIO_printf(Perl_debug_log,
return uid && (uid->seq == seq) && (uid->flags & SU_UID_ACTIVE);
}
-static void su_uid_drop(pTHX_ void *ud_) {
- su_uid *uid = ud_;
-
- uid->flags &= ~SU_UID_ACTIVE;
-}
-
-static void su_uid_bump(pTHX_ void *ud_) {
- su_ud_reap *ud = ud_;
-
- SAVEDESTRUCTOR_X(su_uid_drop, ud->cb);
-
- SU_UD_FREE(ud);
-}
-
static SV *su_uid_get(pTHX_ I32 cxix) {
#define su_uid_get(I) su_uid_get(aTHX_ (I))
su_uid *uid;
uid = su_uid_storage_fetch(depth);
if (!(uid->flags & SU_UID_ACTIVE)) {
- su_ud_reap *ud;
+ su_ud_uid *ud;
- uid->seq = su_uid_seq_next(depth);
+ uid->seq = su_uid_seq_next(depth);
uid->flags |= SU_UID_ACTIVE;
- Newx(ud, 1, su_ud_reap);
- SU_UD_ORIGIN(ud) = NULL;
- SU_UD_TYPE(ud) = SU_UD_TYPE_UID;
- ud->cb = (SV *) uid;
+ Newx(ud, 1, su_ud_uid);
+ SU_UD_TYPE(ud) = SU_UD_TYPE_UID;
+ ud->uid = uid;
su_init(ud, cxix, SU_SAVE_DESTRUCTOR_SIZE);
}
SU_GET_CONTEXT(1, 1, su_context_skip_db(cxstack_ix));
cxix = su_context_normalize_down(cxix);
Newx(ud, 1, su_ud_reap);
- SU_UD_ORIGIN(ud) = NULL;
- SU_UD_TYPE(ud) = SU_UD_TYPE_REAP;
- ud->cb = newSVsv(hook);
+ SU_UD_TYPE(ud) = SU_UD_TYPE_REAP;
+ ud->cb = newSVsv(hook);
su_init(ud, cxix, SU_SAVE_DESTRUCTOR_SIZE);
void
SU_GET_CONTEXT(2, 2, su_context_skip_db(cxstack_ix));
cxix = su_context_normalize_down(cxix);
Newx(ud, 1, su_ud_localize);
- SU_UD_ORIGIN(ud) = NULL;
- SU_UD_TYPE(ud) = SU_UD_TYPE_LOCALIZE;
+ SU_UD_TYPE(ud) = SU_UD_TYPE_LOCALIZE;
size = su_ud_localize_init(ud, sv, val, NULL);
su_init(ud, cxix, size);
SU_GET_CONTEXT(3, 3, su_context_skip_db(cxstack_ix));
cxix = su_context_normalize_down(cxix);
Newx(ud, 1, su_ud_localize);
+ /* Initialize SU_UD_ORIGIN(ud) in case SU_UD_LOCALIZE_FREE(ud) needs it */
SU_UD_ORIGIN(ud) = NULL;
SU_UD_TYPE(ud) = SU_UD_TYPE_LOCALIZE;
size = su_ud_localize_init(ud, sv, val, elem);
SU_GET_CONTEXT(2, 2, su_context_skip_db(cxstack_ix));
cxix = su_context_normalize_down(cxix);
Newx(ud, 1, su_ud_localize);
- SU_UD_ORIGIN(ud) = NULL;
- SU_UD_TYPE(ud) = SU_UD_TYPE_LOCALIZE;
+ SU_UD_TYPE(ud) = SU_UD_TYPE_LOCALIZE;
size = su_ud_localize_init(ud, sv, NULL, elem);
su_init(ud, cxix, size);