# define HvNAMELEN_get(H) strlen(HvNAME_get(H))
#endif
-#ifndef SvREFCNT_inc_simple_NN
-# define SvREFCNT_inc_simple_NN SvREFCNT_inc
+#ifndef SvREFCNT_inc_simple_void_NN
+# define SvREFCNT_inc_simple_void_NN(S) ((void) SvREFCNT_inc(S))
#endif
/* ... Thread safety and multiplicity ...................................... */
# define aMY_CXT_
#endif
+#if defined(OP_CHECK_MUTEX_LOCK) && defined(OP_CHECK_MUTEX_UNLOCK)
+# define LT_CHECK_MUTEX_LOCK OP_CHECK_MUTEX_LOCK
+# define LT_CHECK_MUTEX_UNLOCK OP_CHECK_MUTEX_UNLOCK
+#else
+# define LT_CHECK_MUTEX_LOCK OP_REFCNT_LOCK
+# define LT_CHECK_MUTEX_UNLOCK OP_REFCNT_UNLOCK
+#endif
+
+typedef OP *(*lt_ck_t)(pTHX_ OP *);
+
+#ifdef wrap_op_checker
+
+# define lt_ck_replace(T, NC, OCP) wrap_op_checker((T), (NC), (OCP))
+
+#else
+
+STATIC void lt_ck_replace(pTHX_ OPCODE type, lt_ck_t new_ck, lt_ck_t *old_ck_p){
+#define lt_ck_replace(T, NC, OCP) lt_ck_replace(aTHX_ (T), (NC), (OCP))
+ LT_CHECK_MUTEX_LOCK;
+ if (!*old_ck_p) {
+ *old_ck_p = PL_check[type];
+ PL_check[type] = new_ck;
+ }
+ LT_CHECK_MUTEX_UNLOCK;
+}
+
+#endif
+
+STATIC void lt_ck_restore(pTHX_ OPCODE type, lt_ck_t *old_ck_p) {
+#define lt_ck_restore(T, OCP) lt_ck_restore(aTHX_ (T), (OCP))
+ LT_CHECK_MUTEX_LOCK;
+ if (*old_ck_p) {
+ PL_check[type] = *old_ck_p;
+ *old_ck_p = 0;
+ }
+ LT_CHECK_MUTEX_UNLOCK;
+}
+
/* --- Helpers ------------------------------------------------------------- */
/* ... Thread-safe hints ................................................... */
/* ... "Seen" pointer table ................................................ */
-#if !LT_HAS_RPEEP
-
#define PTABLE_NAME ptable_seen
#define PTABLE_VAL_FREE(V) NOOP
#define ptable_seen_clear(T) ptable_seen_clear(aPTBLMS_ (T))
#define ptable_seen_free(T) ptable_seen_free(aPTBLMS_ (T))
-#endif /* !LT_HAS_RPEEP */
-
/* ... Global data ......................................................... */
#define MY_CXT_KEY __PACKAGE__ "::_guts" XS_VERSION
ptable *tbl; /* It really is a ptable_hints */
tTHX owner;
#endif
-#if !LT_HAS_RPEEP
ptable *seen; /* It really is a ptable_seen */
-#endif
SV *default_meth;
} my_cxt_t;
dMY_CXT;
ptable_hints_free(MY_CXT.tbl);
-#if !LT_HAS_RPEEP
ptable_seen_free(MY_CXT.seen);
-#endif /* !LT_HAS_RPEEP */
}
#endif /* LT_THREADSAFE */
value = SvRV(value);
if (SvTYPE(value) >= SVt_PVCV) {
code = value;
- SvREFCNT_inc_simple_NN(code);
+ SvREFCNT_inc_simple_void_NN(code);
}
}
0,
lt_hash);
#else
- SV **val = hv_fetch(GvHV(PL_hintgv), __PACKAGE__, __PACKAGE_LEN__, lt_hash);
+ SV **val = hv_fetch(GvHV(PL_hintgv), __PACKAGE__, __PACKAGE_LEN__, 0);
if (!val)
return 0;
hint = *val;
if (!type_pkg) {
type_pkg = orig_pkg;
- SvREFCNT_inc(orig_pkg);
+ SvREFCNT_inc_simple_void_NN(orig_pkg);
}
if (!type_meth) {
type_meth = orig_meth;
- SvREFCNT_inc(orig_meth);
+ SvREFCNT_inc_simple_void_NN(orig_meth);
}
lt_map_store(o, orig_pkg, type_pkg, type_meth, o->op_ppaddr);
STATIC peep_t lt_old_peep = 0; /* This is actually the rpeep past 5.13.5 */
-#if !LT_HAS_RPEEP
-# define LT_PEEP_REC_PROTO STATIC void lt_peep_rec(pTHX_ OP *o, ptable *seen)
-#else /* !LT_HAS_RPEEP */
-# define LT_PEEP_REC_PROTO STATIC void lt_peep_rec(pTHX_ OP *o)
-#endif /* LT_HAS_RPEEP */
-
-LT_PEEP_REC_PROTO;
-LT_PEEP_REC_PROTO {
-#if !LT_HAS_RPEEP
-# define lt_peep_rec(O) lt_peep_rec(aTHX_ (O), seen)
-#else /* !LT_HAS_RPEEP */
-# define lt_peep_rec(O) lt_peep_rec(aTHX_ (O))
-#endif /* LT_HAS_RPEEP */
-
-#if !LT_HAS_RPEEP
- if (ptable_fetch(seen, o))
- return;
-#endif
-
+STATIC void lt_peep_rec(pTHX_ OP *o, ptable *seen) {
+#define lt_peep_rec(O) lt_peep_rec(aTHX_ (O), seen)
for (; o; o = o->op_next) {
lt_op_info *oi = NULL;
-#if !LT_HAS_RPEEP
+ if (ptable_fetch(seen, o))
+ break;
ptable_seen_store(seen, o, o);
-#endif
+
switch (o->op_type) {
case OP_PADSV:
if (o->op_ppaddr != lt_pp_padsv && o->op_private & OPpLVAL_INTRO) {
}
STATIC void lt_peep(pTHX_ OP *o) {
-#if !LT_HAS_RPEEP
dMY_CXT;
ptable *seen = MY_CXT.seen;
- ptable_seen_clear(seen);
-#endif /* !LT_HAS_RPEEP */
-
lt_old_peep(aTHX_ o);
+
+ ptable_seen_clear(seen);
lt_peep_rec(o);
+ ptable_seen_clear(seen);
}
/* --- Interpreter setup/teardown ------------------------------------------ */
#if LT_THREADSAFE
ptable_hints_free(MY_CXT.tbl);
#endif
-#if !LT_HAS_RPEEP
ptable_seen_free(MY_CXT.seen);
-#endif
SvREFCNT_dec(MY_CXT.default_meth);
}
- PL_check[OP_PADANY] = MEMBER_TO_FPTR(lt_old_ck_padany);
- lt_old_ck_padany = 0;
- PL_check[OP_PADSV] = MEMBER_TO_FPTR(lt_old_ck_padsv);
- lt_old_ck_padsv = 0;
+ lt_ck_restore(OP_PADANY, <_old_ck_padany);
+ lt_ck_restore(OP_PADSV, <_old_ck_padsv);
#if LT_HAS_RPEEP
PL_rpeepp = lt_old_peep;
MY_CXT.tbl = ptable_new();
MY_CXT.owner = aTHX;
#endif
-#if !LT_HAS_RPEEP
MY_CXT.seen = ptable_new();
-#endif
MY_CXT.default_meth = newSVpvn("TYPEDSCALAR", 11);
SvREADONLY_on(MY_CXT.default_meth);
}
- lt_old_ck_padany = PL_check[OP_PADANY];
- PL_check[OP_PADANY] = MEMBER_TO_FPTR(lt_ck_padany);
- lt_old_ck_padsv = PL_check[OP_PADSV];
- PL_check[OP_PADSV] = MEMBER_TO_FPTR(lt_ck_padsv);
+ lt_ck_replace(OP_PADANY, lt_ck_padany, <_old_ck_padany);
+ lt_ck_replace(OP_PADSV, lt_ck_padsv, <_old_ck_padsv);
#if LT_HAS_RPEEP
lt_old_peep = PL_rpeepp;
PROTOTYPE: DISABLE
PREINIT:
ptable *t;
-#if !LT_HAS_RPEEP
ptable *s;
-#endif
SV *cloned_default_meth;
PPCODE:
{
cloned_default_meth = lt_dup_inc(MY_CXT.default_meth, &ud);
lt_ptable_clone_ud_deinit(ud);
}
-#if !LT_HAS_RPEEP
s = ptable_new();
-#endif
}
{
MY_CXT_CLONE;
MY_CXT.tbl = t;
MY_CXT.owner = aTHX;
-#if !LT_HAS_RPEEP
MY_CXT.seen = s;
-#endif
MY_CXT.default_meth = cloned_default_meth;
}
reap(3, lt_thread_cleanup, NULL);