4 #include "caps.h" /* XSH_HAS_PERL(), XSH_THREADSAFE */
5 #include "util.h" /* XSH_ASSERT(), NOOP */
8 # error threads.h must be loaded at the very end
12 # define XSH_HAS_RPEEP XSH_HAS_PERL(5, 13, 5)
15 #define PTABLE_USE_DEFAULT 1
16 #define PTABLE_NEED_DELETE 0
20 #define ptable_seen_store(T, K, V) ptable_default_store(aPTBL_ (T), (K), (V))
21 #define ptable_seen_clear(T) ptable_default_clear(aPTBL_ (T))
22 #define ptable_seen_free(T) ptable_default_free(aPTBL_ (T))
24 #define XSH_THREADS_PEEP_CONTEXT 1
35 static xsh_peep_cxt_t *xsh_peep_get_cxt(pTHX);
37 static void xsh_peep_rec(pTHX_ OP *o, ptable *seen);
41 static void xsh_rpeep(pTHX_ OP *o) {
43 xsh_peep_cxt_t *cxt = xsh_peep_get_cxt(aTHX);
45 cxt->old_rpeep(aTHX_ o);
50 ptable_seen_clear(seen);
52 xsh_peep_rec(aTHX_ o, seen);
54 ptable_seen_clear(seen);
59 #define xsh_peep_maybe_recurse(O, S) NOOP
61 #else /* XSH_HAS_RPEEP */
63 static void xsh_peep(pTHX_ OP *o) {
65 xsh_peep_cxt_t *cxt = xsh_peep_get_cxt(aTHX);
67 cxt->old_peep(aTHX_ o); /* Will call the rpeep */
72 ptable_seen_clear(seen);
74 xsh_peep_rec(aTHX_ o, seen);
76 ptable_seen_clear(seen);
81 static void xsh_peep_maybe_recurse(pTHX_ OP *o, ptable *seen) {
82 #define xsh_peep_maybe_recurse(O, S) xsh_peep_maybe_recurse(aTHX_ (O), (S))
92 #if XSH_HAS_PERL(5, 10, 0)
97 xsh_peep_rec(aTHX_ cLOGOPo->op_other, seen);
101 xsh_peep_rec(aTHX_ cLOOPo->op_redoop, seen);
102 xsh_peep_rec(aTHX_ cLOOPo->op_nextop, seen);
103 xsh_peep_rec(aTHX_ cLOOPo->op_lastop, seen);
105 #if XSH_HAS_PERL(5, 9, 5)
107 xsh_peep_rec(aTHX_ cPMOPo->op_pmstashstartu.op_pmreplstart, seen);
113 xsh_peep_rec(aTHX_ cPMOPo->op_pmreplstart, seen);
121 #endif /* !XSH_HAS_RPEEP */
123 static int xsh_peep_seen(pTHX_ OP *o, ptable *seen) {
124 #define xsh_peep_seen(O, S) xsh_peep_seen(aTHX_ (O), (S))
126 switch (o->op_type) {
135 #endif /* XSH_HAS_RPEEP */
137 if (ptable_fetch(seen, o))
140 ptable_seen_store(seen, o, o);
145 static void xsh_peep_local_setup(pTHX_ xsh_peep_cxt_t *cxt) {
147 if (PL_rpeepp != xsh_rpeep) {
148 cxt->old_rpeep = PL_rpeepp;
149 PL_rpeepp = xsh_rpeep;
154 if (PL_peepp != xsh_peep) {
155 cxt->old_peep = PL_peepp;
162 cxt->seen = ptable_new(32);
165 static void xsh_peep_local_teardown(pTHX_ xsh_peep_cxt_t *cxt) {
166 ptable_seen_free(cxt->seen);
170 if (cxt->old_rpeep) {
171 PL_rpeepp = cxt->old_rpeep;
176 PL_peepp = cxt->old_peep;
184 static void xsh_peep_clone(pTHX_ const xsh_peep_cxt_t *old_cxt, xsh_peep_cxt_t *new_cxt) {
185 new_cxt->seen = ptable_new(32);
190 #endif /* XSH_PEEP_H */